C语言基础4数组和字符串

目录

一、一维数组

1.概念:

2.引用

3.初始化

二、二维数组

1.概念

2.存放顺序

3.二维数组和一维数组的区别

4.引用和初始化

5.多维数组

思考

三、字符数组

1.概念

2.初始化

3.字符数组访问

4.二维字符数组初始化

四、字符串

1.概念

2.函数用法

strlen

strcpy

strcat

strcmp

3.扩展用法

strncpy(p,p1,n)复制指定长度字符串

strncat(p,p1,n)附加指定长度字符串

strcasecmp忽略大小写比较字符串

strncmp(p,p1,n)比较指定长度字符串)

strchr(p,c)在字符串中查找指定字符(第一次出现)

strrchr(最后一次出现)

strstr(p,p1)查找字符串

4.扩展用法2

#includ

总结题


一、一维数组

1.概念:

构造数据类型之一
-数组是具有一定顺序关系的若干个变量的集合,组成数组的各个变量称为数组的元素。
-数组中各个元素的数据类型要求相同,用数组名和下标确定。
-数组可以是一维的,也可以是多维的。

例int a[6];
数组名表示内存首地址,是地址常量sizeof(数组名)是数组占用的总内存空间
编译时分配连续内存,内存字节数 = 数组维数*sizeof(元素数据类)

2.引用

一维数组的引用
-数组必须先定义,后使用
-只能逐个引用数组元素,不能一次引用整个数组
-数组元素表示形式:数组名【下标】
其中:下标可以使常量或整形表达式

int a[10];
//printf("%d",a); (X)

for(i = 0; i<10; i++)
    printf("%d\t", a[j]); (√)

3.初始化

一维数组的初始化
-初始化方式:在定义数组时,为数组元素赋初值
int a[5]={1,2,3,4,5,};
说明
-数组不初始化,其元素值为随机数 auto类型
-对static数组元素不赋初值,系统会自动赋以0值
-只给部分分数组元素赋初值 

static int a[5];
等价于:a[0]=0; a[1]=0; a[2]=0; a[3]=0; a[4]=0;

int a[5]={6,2,3);
等价于:a[0]=6; a[1]=2;a[2]=3; a[3]=0; a[4]=0;

int a[3]={6,2,3,5,1};(×)

int a={1,2,3,4,5,6};//编译系统根据初值个数确定数组维数

注意

-C语言对数组不作越界检查,使用时要注意。ERROR:   int a[5];a[5]=10
-关于用变量定义数组维数。int i =15;int a[i]

二、二维数组

1.概念

数据类型 数组名【常量表达式(行)】【常量表达式(列)】
定义方式:申明时列数不能省略,行数可以
-例int a[3][4];
float b[2][5];
int c[2][3][4];
元素个数=行*列。

2.存放顺序

二维数组的存放顺序:

a[0][0] 1a[0][1] 2
a[1][0] 3a[1][1] 4
a[2][0] 5a[2][1] 6

-原因:内存是一维的
-二维数组:按行序优先

3.二维数组和一维数组的区别


(1)二维数组名本身存不存在地址?存在。

(2)对它求sizeof是不是整个数组的总空间?是的

(3)a++会报错,数组名不能做这样的处理。

(4)行名,或者叫一维数组名具不具备该特征?一样。例a[2][3] 中行名a[1]

4.引用和初始化

二维数组的引用
形式:数组名【下标】【下标】
二维数组元素的初始化
-分行初始化
-按元素排列顺序初始化

例:int a[][3]={{1},{4,5}};

100450
a[0][0]a[0][1]a[0][2]a[1][0]a[1][1]a[1][2]

5.多维数组

概念:具有两个或两个以上下标的数组称为多维数组。

例:打印杨辉三角的前十行

1 
1 1 
1 2 1 
1 3 3 1 
1 4 6 4 1 
1 5 10 10 5 1 
1 6 15 20 15 6 1 
1 7 21 35 35 21 7 1 
1 8 28 56 70 56 28 8 1 

int main()
{
        int i,j;
        int a[10][10]={{0}};

        for(i = 0; i< 10 ; i++)
        {
                for(j = 0;j<i;j++)
                {
                        a[i][j] = a[i-1][j-1] + a[i-1][j];

                }
                a[i][0]=1;
        }
        for(i = 0; i< 10 ; i++)
        {
                for(j = 0;j<i;j++)
                {
                        printf("%d ",a[i][j]);
                }
                putchar('\n');
        }

}
         1 
        1  1 
       1  2  1 
      1  3  3  1 
     1  4  6  4  1 
    1  5 10 10  5  1 
   1  6 15 20 15  6  1 
  1  7 21 35 35 21  7  1 
 1  8 28 56 70 56 28  8  1 
#include <stdio.h>
int main()
{
        int i,j,k;
        int a[10][10]={{0}};

        for(i = 0; i< 10 ; i++)
        {
                for(j = 0;j<i;j++)
                {
                        a[i][j] = a[i-1][j-1] + a[i-1][j];

                }
                a[i][0]=1;
        }
        for(i = 0; i< 10 ; i++)
        {
                for(k = 9;k>i;k--)
                {
                        printf(" ");
                }
                for(j = 0;j<i;j++)
                {
                        printf("%2d ",a[i][j]);
                }
                putchar('\n');
        }

}

思考

有一个3*4的矩阵,要求输出其中值最大的元素值,以及它的行号和列号

#include <stdio.h>
int main()
{
        int i,j;
        int max_i=0,max_j=0;
        int a[3][4]={
                {3,5,6,0},
                {10,4,11,8},
                {7,2,1,9}
        };

        for(i = 0; i< 3 ; i++)
        {
                for(j = 0;j<4;j++)
                {
                        if(a[i][j]>a[max_i][max_j]){

                                max_i = i;
                                max_j = j;
                        }
                }
        }
        printf("max = %d,max_i =%d,max_j = %d\n",a[max_i][max_j],max_i,max_j);
}

三、字符数组

1.概念

字符数组
字符数字是元素的数据类型为字符类型的数组
-char c[10],ch[3][4];
字符数组的初始化
-逐个字符赋值
-用字符串常量

2.初始化

字符数组的初始化
char ch[5]={'H','e','l','l','o'};
大括号也能省略
char ch[6]="hello";
char ch[6]={"hello}';
char ch[]="hello";

例 char ch[5] = {'B','o','y'};

Boy\0\0
ch[0]ch[1]ch[2]ch[3]ch[4]

0 和 '\0' 和NULL都是一个意思

char arr1[]={'a','b','c'};
char arr2[6]={'a','b','c'};
两个数组的区别:对于有了\0的arr2还是字符串,而arr1是字符数组

例题:输入一个字符串,然后将其逆序输出。

方法一、gets 和sizeof 确定个数

#include <stdio.h>

int main()
{
        char buf[50]={0};
        int i,n;

        printf("input words\n");
        gets(buf);

        n = sizeof(buf)/sizeof(char);
        for(i = n-1; i>=0; i--)
                putchar(buf[i]);
        putchar('\n');
        return 0;
}

方法二 、strlen 确定个数

#include <stdio.h>
#include <string.h>
int main()
{
        char buf[50]={0};
        int i,n;

        printf("input words\n");
        gets(buf);

        n = strlen(buf);
        for(i = n-1; i>=0; i--)
                putchar(buf[i]);
        putchar('\n');
        return 0;
}

方法三:定义2个下标,一个指向头,一个指向尾。如果头下标小于尾下标,交换数组元素的头和尾,都下标+1,尾下标-1,直到循环结束。

#include <stdio.h>
#include <string.h>
int main()
{
        char buf[50]={0},ch;
        int i,j,n;

        printf("input words\n");
        gets(buf);

        n = strlen(buf);
        i = 0;
        j = n -1;
        while(i < j){
                ch = buf[i];
                buf[i] = buf[j];
                buf[j] = ch;
                i++;
                j--;
        }
        for(i = 0; i<n ; i++)
                putchar(buf[i]);
        putchar('\n');
        return 0;
}

3.字符数组访问

#include <stdio.h>

int main()
{
        char arr1[]={'a','b','c'};
        char arr2[6] = {'a','b','c'};
        int i, n;

        n = sizeof(arr1)/sizeof(char);
        for(i = 0; i < n; i++)
                putchar(arr1[i]);
        putchar('\n');

        n = sizeof(arr2)/sizeof(char); 
        for(i = 0; i < n; i++)
                putchar(arr2[i]);
        putchar('\n');
        return 0;
}   

字符数组的个数可以用 n= sizeof(arr1) /sieseof (char);
putchar(arr[i]) 也可以用printf("%c,arr[i]);

如果使用printf和%s会出现的现象。主要没看到\0。并且地址是连续的


#include <stdio.h>

int main()
{
	char arr1[]={'a','b','c'};
	char arr2[6] = {'a','b','c'};
	int i, n;
	
	printf("arr1:%s\n",arr1);
	printf("arr2:%s\n",arr2);
	
}

arr1:abcabc
arr2:abc

4.二维字符数组初始化

char fruit[][6]={"Apple","Orange","Grape",''Pear",''Peach"};
char fruit[][6]={{'A','p','p','l','e'},{'O','r','a','n','g','e'},{'G','r','a','p','e'},{'P','e','a','r'},{'P','e','a','c','h'}};

fruit[0]Apple\0
fruit[1]Orange
fruit[2]Grape\0
fruit[3]Pear\0\0
fruit[4]Peach\0

打印二维字符数组思路 m行数等于整个字符地址大小,除以行字符地址空间大小
n列数等于行字符地址空间大小,除以字符类型大小。

#include <stdio.h>

int main()
{
        int i,j;
        int m,n;
        char fruit[][6]={"Apple","Orange","Grape","Pear","Peach"};
        m = sizeof(fruit)/sizeof(fruit[0]);
        n = sizeof(fruit[0])/sizeof(char);
        
        for(i = 0; i < m; i++){
                for(j = 0; j < n; j++){
                        printf("%c ",fruit[i][j]);
                }               
                putchar('\n');
        } 
}


A p p l e  
O r a n g e 
G r a p e  
P e a r   
P e a c h  

这个代码有点点多余,如果每行都有\0,其实不用一个个字符打印,可以打印字符串。

#include <stdio.h>

int main()
{
        int i,j;
        int m;
        char fruit[][7]={"Apple","Orange","Grape","Pear","Peach"};
        m = sizeof(fruit)/sizeof(fruit[0]);

        for(i = 0; i < m; i++){
                        printf("%s\n",fruit[i]);
        } 
}


Apple
Orange
Grape
Pear
Peach

四、字符串

1.概念

字符串
C语言中无字符串变量,用字符数组处理字符串,字符串结束标志:'\0'

2.函数用法

strlen

-格式:strlen(字符数组)
-功能:计算字符串长度
-返值:返回字符串时间长度,不含'\0'
-\xhh表示十六进制代表的符号
-\ddd表示8进制
例如:

#include <stdio.h>
#include <string.h>
int main()
{
        char a[10]={'a','\0','b','\0','D'};    
        printf("%d",strlen(a));    //1
        char b[]="\t\v\\\0will\n";
        printf("%d",strlen(b));    //3 遇到转译的时候斜杠不算在内
        char c[]="\x69\141\n";     //3 \xhh转移为16进制 i  \ddd代表8进制的字符  a
        printf("%d",strlen(c));
}

strcpy

-格式:strcpy(字符数组1,字符串2)
-功能:将字符串2,拷贝到字符数组1中去
-返值:返回字符数组1的首地址
-说明:
字符数组1必须足够大
拷贝时‘\0’一同拷贝

原理:

#include <stdio.h>
#include <string.h>
int main()
{
        char src[] = "hello world";
        char dest[100];
        int i ,n;
        i = 0;
        n  = strlen(src);
        while(i<=n){
                dest[i] = src[i];
                i++;
        }
        puts(src);
        puts(dest);
}

strcat

-格式:strcat(字符数组1,字符数组2)
-功能:把字符数组2连到字符数组1后面
-返值:返回字符数组1的首地址
-说明:
字符数组1必须足够大
连接前,两串均以'\0'结束;连接后串1的'\0'取消,新串最后加'\0'

#include <stdio.h>
#include <string.h>
int main()
{
        char str1[20] = "hello world";
        char str2[] = ".com.cn";

        strcat(str1,str2);

        puts(str1);
        puts(str2);
}

hello world.com.cn
.com.cn

如果不加\0

#include <stdio.h>
#include <string.h>
int main()
{
        char str1[] = {'a','b','c'};
        char str2[] = ".com.cn";

        strcat(str1,str2);

        puts(str1);
        puts(str2);
}
abc.com.cn.com.cn
.com.cn.com.cn

strcmp

-格式:strcmp(字符串1,字符串2)
-功能:比较两个字符串
-比较规则:对两串从左向右逐个字符比较(ACKII码),直到遇到不同字符或'\0'
-返值:返回int型整数
a.若字符串1<小于字符串2,返回负整数
b.若字符串1>大于字符串2,返回正整数
c.若字符串1==字符串2,返回0

3.扩展用法

strncpy(p,p1,n)复制指定长度字符串

#include <stdio.h>
#include <string.h>
int main()
{
        char src[] = "abcdefg";
        char dest[] = ".com.cn";

        strncpy(dest,src,4);

        puts(src);
        puts(dest);
}

abcdefg
abcd.cn

strncat(p,p1,n)附加指定长度字符串

#include <stdio.h>
#include <string.h>
int main()
{
        char src[] = "abcdefg";
        char dest[] = ".com.cn";

        strncat(dest,src,4);

        puts(src);
        puts(dest);
}

abcdefg
.com.cnabcd

strcasecmp忽略大小写比较字符串

#include <stdio.h>
#include <string.h>
int main()
{
        char src[] = "abcdefg";
        char dest[] = "ABCD";
        int n,m;
        n = strncmp(dest,src,4);
        m = strncasecmp(dest,src,4);
        printf("%d\n",n);
        printf("%d\n",m);
}


-1
0

strncmp(p,p1,n)比较指定长度字符串)

strchr(p,c)在字符串中查找指定字符(第一次出现)

#include <stdio.h>
#include <string.h>
int main()
{
        char src[] = "abcdefg";
        printf("%p %p \n",src, strchr(src,'d'));
}

0xbf911844 0xbf911847 


strrchr(最后一次出现)

-p代表字符串,c代表特点字符

#include <stdio.h>
#include <string.h>
int main()
{
        char src[] = "abcdefgd";
        printf("%p %p \n",src, strrchr(src,'d'));
}



0xbf8d7dc3 0xbf8d7dca 

strstr(p,p1)查找字符串

#include <stdio.h>
#include <string.h>
int main()
{
        char src[] = "abcdefgd";
        printf("%p %p %d\n",src, strstr(src,"bcd"),strstr(src,"bcd")-src);
}

0xbfc49343 0xbfc49344 1

4.扩展用法2

#includ<ctype.h>

man isalpha查看命令描述和返回值

NAME
       isalnum, isalpha, isascii, isblank, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit - character classification routines

SYNOPSIS
       #include <ctype.h>

       int isalnum(int c);
       int isalpha(int c);
       int isascii(int c);
       int isblank(int c);
       int iscntrl(int c);
       int isdigit(int c);
       int isgraph(int c);
       int islower(int c);
       int isprint(int c);
       int ispunct(int c);
       int isspace(int c);
       int isupper(int c);
       int isxdigit(int c);

RETURN VALUE
       The values returned are nonzero if the character c falls into the tested class, and a zero value if not.

isalpha()检查是否为字母字符

isupper()检查是否为大写字母字符

islower()检查是否为小写字母字符

isdigit()检查是否为数字

toupper()大写转换

tolower()小写转换

例:大写转小写,小写转大写

#include <stdio.h>
#include <ctype.h>

int main(int argc,char *argv[]){
    int ch;
    while((ch = getchar()) != EOF){
        if (isalpha(ch)){
            if (isupper(ch)) {
                ch = tolower(ch);
            }
            else {
                ch = toupper(ch);
            }
            printf("%c\n",ch);
         }
    }
    return 0;
}

总结题

从终端输入10个数字(乱序),利用简单选择排序法对这10个数字排序,结果从大到小排列。

冒泡排序和简单选择排序是两个不同的原理。如果不会,可以上网查阅资料

#include <stdio.h>
#include <ctype.h>
#define N 100

int main(int argc,char *argv[]){
    int buf[N]={0};
    int i,j,n,temp;
    printf("how many numbers? :\n");
    scanf("%d",&n); //输入数字的个数
    printf("please input:\n");
    for(i = 0; i < n; i++){
        scanf("%d",&buf[i]);   //循环接受数字
    }

    //冒泡算法
    for(i = 0; i < n; i++)
    {
        for(j = i+1;j < n; j++)
        {
                if(buf[j]>= buf[i]){
                        temp = buf[i];
                        buf[i] = buf[j];
                        buf[j] = temp;
                }
        }
    }
    //遍历打印
    for(i = 0 ; i<n; i++){

        printf("%d ",buf[i]);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

4IOT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值