初始化字符串数组时,编译器自动将字符串最后一个字符后面加上'\0',以表示字符串的结束。
如果数组的大小大于字符串的长度+1,那么把字符串结束后面的元素也都初始化为'\0';
看这段程序:
定义一个大小为12的字符串数组
char str1[12]="jiajia";
让一个char型的指针指向这个数组
char *p1=str1;
输出这个字符串
printf("%s\n\n",str1);
利用指针输出这个字符串数组中每个元素的字符、字符ascii值、字符存储地址
for(int i=0;i<12;i++)
{
printf("%c:%d:%p\n",*p1,*p1,p1);
p1++;
}
可以看出,数组元素的后几位都被初始化成了'\0';使用printf打印字符串数组时,程序遇到第一个'\0'就结束对字符串的读取。
如果数组的大小小于字符串的长度+1,程序在运行时可能要出现问题,所以应当确保数组的大小要大于字符串长度的大小+1;
这段程序的字符串长度+1小于数组的大小:
char str2[12]="hello jiajia";
char *p2=str2;
printf("\n\n\n%s\n\n",str2);
for(int i=0;i<28;i++)
{
printf("%c:%d:%p\n",*p2,*p2,p2);
p2++;
}
使用printf打印字符串,程序需要找到'\0'才能结束读取,结果找遍整个数组没有找到,只有继续顺着地址寻找,一直找到某个地址上的assii是0的,字符串才读取完毕。所以本段程序在读取完"hello jiajia"之后,后面可能还会有几个随机的字符,就是因为字符串终止于'\0'。
(2)char arr[]="Hello World!";
这种初始化方法不用担心数组大小过小的情况,数组的大小由编译器决定。
(3)char arr[]={'H','e','e','l','o',' ','W','o','r','l','d','\0'};
同第二种方法结果相同,但显然要麻烦许多。另外,' '代表空格,ascii值是32,'\0'代表字符串结束,ascii值是0;
(4)char *p="Hello World";
使用数组的方式初始化。同数组不同之处在于,p是一个变量,可以做递增、递减运算,而arr是数组的首地址,是一个地址常量,不能做递增、递减运算。
char *name="liujiajia";
name[0]='L';
printf("\n%s\n",name);
name[0]='L';这句代码在最新的c99标准中会引发程序异常。需要注意。
char *string="c programe";
char *string2;
string2=string; //将指针string的值赋给string2
printf("\nstring=%s,&string=%p,string=%p\n",string,&string,string);
printf("\nstring=%s,&string=%p,string=%p\n",string2,&string2,string2);
上面这段程序最后显示,指针string所指向的地址和指针string2所指向的地址相同,这就说明它们指向的是内存里面同一个字符串,也就是说字符串本身并没有复制,而是产生了一个指向同一个字符串的指针。这样程序的效率会更加的高。如果需要复制字符串可以使用 strcpy() 或 strncpy()。