在艰难的梳理完指针中的四个比较难区分的概念后,在今天开始了字符串的学习。
#include<stdio.h>
int main(){
int array[]={1,2,3,4,5};
char carray[]={'h','e','l','l','o'};
char carray2[]="world";//可以改变
char *parray="hello";//字符串常量,不能改变
/*char *p;//野指针,危险,但这里看不到段错误。
*p='a';
printf("%c",*p);
*/
printf("%s\n",carray2);
printf("%s",parray);
carray2[2]='l';//*parray='m';这个指令会造成段错误
putchar('\n');
puts(parray);
puts(carray2);
/*
for(int i=0;i<5;i++){
printf("%c",*parray++);
}
*/
return 0;
}
通过这段代码,可以了解到多种能够定义出一串字符串,虽然有些定义的方法看起来跟数组一样(有点low),但char string[ ]=" ";这种方法还是比较如人意的,既可以连贯的定义出字符串,后续也可以通过string[ ]= ;来对某一个字符进行更改。值得注意的是char *pstr=" ";的这种定义方法,定义出来的是字符串常量,后续不能改变。
#include<stdio.h>
int main(){
int array[]={1,2,3,4,5};
char carray[]={'h','e','l','l','o'};
char carray2[]="world";//字符串最后带有结束标志'\0'
int len;
len=sizeof(array)/sizeof(array[0]);
printf("%d\n",len);
len=sizeof(carray)/sizeof(carray[0]);
printf("%d\n",len);
len=sizeof(carray2)/sizeof(carray2[0]);
printf("%d\n",len);
return 0;
}
第二段代码主要是让我知道了字符串的最后带有结束标志'\0',通过用关键字sizeof来计算没有规定长度的字符串的长度可以看出,字符串的长度要比字母的个数长一个字节,而这个字节就是用来存放结束标志'\0'的。
#include <stdio.h>
#include <string.h>
void test()
{
}
int main(){
char cdata[666]="hello";
void (*ptest)();
ptest=test;
char *p="hello!";
printf("sizeof :%d\n",sizeof(cdata));
printf("strlen :%d\n",strlen(cdata));//strlen计算有效长度
printf("sizeof(ptest) :%d\n",sizeof(ptest));
printf("sizeof(p) :%d\n",sizeof(p));
printf("strlen(p) :%d\n",strlen(p));//计算p指向地址中的有效长度
printf("sizeof(char*) :%d\n",sizeof(char*));
printf("sizeof(int*) :%d\n",sizeof(int*));
printf("sizeof(char) :%d\n",sizeof(char));
printf("sizeof(int) :%d\n",sizeof(int));
return 0;
}
第三段代码用来区分sizeof和strlen。本质上来讲,两者大不相同:sizeof属于关键字,而strlen是一个函数。想要使用strlen函数必须包含头文件<string.h>。通过对代码中的cdata[666]="hello"分别使用sizeof和strlen可以看出strlen返回的是字符串的有效长度,原理就是检测字符串的结束标志'\0',而sizeof则计算出整个cdata的长度。在实际的应用中,我们需要根据不同的需求来使用两者。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char *p;
p=(char *)malloc(1);
*p='v';
free(p);
p=(char *)malloc(10);
if(p == NULL){
printf("malloc error\n");
exit(-1);
}
memset(p,'\0',10);
printf("扩容前的地址:%x\n",p);
int len =strlen("jhfdrufoiuykjkh");
int newLen=len - 10 + 1;
realloc(p,newLen);
printf("扩容后的地址:%x\n",p);
strcpy(p,"jhfdrufoiuykjkh");
puts(p);
puts("done");
return 0;
}
今天的最后一段代码,是学习malloc动态开辟内存空间留下的。虽然只有这一点点内容,但却是我今天花费时间最长的。先是以为对例子代码中的NULL不理解,查阅了本站几个关于malloc函数用法的文章,了解了NULL,弄懂了malloc的用法。但由于后续strcpy的使用中出现了对超出长度的字符串正常输出的情况,我就想了很多方法去找到不一样的原因,以及为什么会出现这种情况。比如我在strcpy前后分别用strlen计算p的长度,得到的结果分别是3和strcpy中字符串对应的长度。这令我很奇怪,为什么malloc分配的空间自动扩容了。于是我有用sizeof重复计算,结果都是8。现在冷静下来一想,这根本就是傻子行为。sizeof(p)计算的是计算机用来储存地址的空间大小,当然都是8个字节了。后来答疑助手告诉我这能运行是运气,这是在非法使用内存,只是因为被使用的内存我现在还用不上,所以一直能够正常运行。