一、字符数组的初始化

1、逐个字符来初始化字符数组

字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素。

char str[10]={ 'I',' ','a','m',' ',‘h’,'a','p','p','y'};

即把10个字符分别赋给str[0]到str[9]10个元素

注: 如果花括号中提供的字符个数大于数组长度,则按语法错误处理;若小于数组长度,则只将这些字符数组中前面那些元素,其余的元素自动定为空字符(即 '\0' );如果提供的初值个数和预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据数组个数确定数组长度。

2、字符串常量来初始化字符数组

在c语言中,将字符串作为字符数组来处理。

在实际应用中人们关心的是有效字符串的长度而不是字符数组的长度,例如,定义一个字符数组长度为100,而实际有效字符只有40个,为了测定字符串的实际长度,C语言规定了一个“字符串结束标志”,以字符'\0’代表。如果有一个字符串,其中第10个字符为'\0',则此字符串的有效字符为9个。也就是说,在遇到第一个字符'\0'时,表示字符串结束,由它前面的字符组成字符串。

系统对字符串常量也自动加一个'\0'作为结束符。例如"C Program”共有9个字符,但在内存中占10个字节,最后一个字节'\0'是系统自动加上的。(通过sizeof()函数可验证)

有了结束标志'\0'后,字符数组的长度就显得不那么重要了,在程序中往往依靠检测'\0'的位置来判定字符串是否结束,而不是根据数组的长度来决定字符串长度。当然,在定义字符数组时应估计实际字符串长度,保证数组长度始终大于字符串实际长度。(在实际字符串定义中,常常并不指定数组长度,如char str[ ])

说明:'\0’代表ASCII码为0的字符,从ASCII码表中可以查到ASCII码为0的字符不是一个可以显示的字符,而是一个“空操作符”,即它什么也不干。用它来作为字符串结束标志不会产生附加的操作或增加有效字符,只起一个供辨别的标志。

对C语言处理字符串的方法由以上的了解后,再对字符数组初始化的方法补充一种方法——即可以用字符串常量来初始化字符数组:

char str[ ]={"I am happy"};       可以省略花括号,如下所示

char str[ ]="I am happy";

注意:上述这种字符数组的整体赋值只能在字符数组初始化时使用,不能用于字符数组的赋值,字符数组的赋值只能对其元素一一赋值,下面的赋值方法是错误的

             char str[ ];

             str="I am happy";

不是用单个字符作为初值,而是用一个字符串(注意:字符串的两端是用双引号“”而不是单引号‘’括起来的)作为初值。显然,这种方法更直观方便。(注意:数组str的长度不是10,而是11,这点请务必记住,因为字符串常量"I am happy"的最后由系统自动加上一个'\0')

因此,上面的初始化与下面的初始化等价

char str[ ]={'I',' ','a','m',' ','h','a','p','p','y','\0'};

而不与下面的等价

char str[ ]={'I',' ','a','m',' ','h','a','p','p','y'};

前者的长度是11,后者的长度是10.

可见,用两种不同方法初始化字符数组后得到的数组长度是不同的。

例如:

1 #include <stdio.h>
 2 int main(void)
 3 {
 4 char c1[]={'I',' ','a','m',' ','h','a','p','p','y'};
 5 char c2[]="I am happy";
 6 int i1=sizeof(c1);
 7 int i2=sizeof(c2);
 8 printf("%d\n",i1);
 9 printf("%d\n",i2);
10 
11 }
12 
13 结果:10   11

注:每个char通常字节是1,int是4 。如int arr[] = { 1,2,3 }; 与 char  brr[] = { 1,2,3 };如果sizeof(arr)则结果是3*4=12;如果是sizeof(brr)则结果是3。

又e.g:

char a[]="hello"; 该数组长度为6;同char a[6]="hello"; 或者char a[6]={"hello"}; 显然直接写char a[]="hello"; 方便得多,免去了数字符个数的步骤。

又e.g:char a[5]="boy";则默认后面两位为\0

二、字符数组的输入输出

1.用 %c逐个字符I/O

1 #include <stdio.h> 
2 int main()
3 { char str[5];
4   int i; 
5   for(i=0;i<5;i++)
6      scanf(“%c”,&str[i]);
7   for(i=0;i<5;i++)
8      printf(“%c”,str[i]);

2.用%s整个字符串I/O:

1 #include <stdio.h> 
2 int main()
3 { char str[5];
4    scanf(“%s”,str);
5    printf(“%s”,str);
6 }

注:

关于字符串输入:在scanf中%s输入时因为%s会在后面自动加个\0字符,所以我们在scanf中%s输入时输入串长度<数组维数,至少要留一个位置给\0,且在遇空格或回车结束。特别注意的是,scanf函数中的输入项如果是字符数组名,不要再加地址符&,因为在C语言中数组名代表该数组第一个元素的地址(或者说该数组的起始地址)。如:scanf("%s",&str);这种写法是错的,str前面不应加&地址符。

字符串输出:printf("%s",c);实际上是这样执行的:按字符数组名c找到其数组起始地址,然后逐个往后面输出其中的字符,直到遇'\0'为止。

知识点1:%c和%s尽量不要混合使用。比如你是逐个赋的值,但是你输出却是直接用的字符串%s输出的话,如果不控制好字符长度啥的就容易出错.

例如:

字符数组字符串数组 javascript 字符数组总结_字符串

乱码的原因:越界。用%s输出的话是以\0为界限。你定义的字符数组维数为5,你scanf输入字符for(i=0;i<5;i++)也是5个,这样就没有给'\0'字符留位置,所以就发生了%s输出时找不到\0发生了越界。所以如果要用%s的话,我们在定义字符数组的时候要记得至少空闲一个位置留给\0一个位置。

知识点2:scanf中用字符串%s输入时,遇空格或回车结束

e.g1:

1 #include <stdio.h>
2 int main()
3 { char a[15],b[5],c[5];
4   scanf("%s%s%s",a,b,c);
5   printf("a=%s\nb=%s\nc=%s\n",a,b,c);
6   scanf("%s",a);
7   printf("a=%s\n",a);
8 }

运行情况: 输入:How are you? 输出:a=How b=are c=you? 输入:How are you? 输出:a=How

e.g2:

字符数组字符串数组 javascript 字符数组总结_字符数组_02

 

字符串输入原理:字符串是一行一行的输入,二维字符数组传参用的是一维字符数组的首地址,第一个维度存放的是一维数组的首地址。所以我们必须要指明地址,你直接写gets(text);系统是不知道的,即使能正常输入并运行结果。