1.字符串初始化
字符串初始化的三种方法:显然第二三种更方便
char cdata1[]={'h','e','l','l','o'};
char cdata2[]="hello";
char *pchar ="hello";
注意第二种和第三种的区别:
1.第二种是字符串"变量",可以修改
2.第三种是字符串"常量",不可修改(但在数组中是可以修改的)
3.注意指针的操作:可以保存地址,修改指向字符串常量的地址空间;但是对野指针的内存空间无法操作
#include <stdio.h>
int main(){
int data[]={1,2,3,4,5};
//字符串初始化的三种方法:
char c='c';
char cdata1[]={'h','e','l','l','o'};
char cdata2[]="hello";
char *pchar ="hello";
printf("%s\n",cdata2);
putchar('\n');
puts(cdata2);
for(int i=0;i<5;i++){
printf("%c",*(pchar+i));
}
}
注意格式控制符为c%
char *p='a'; 野指针,并没有明确的内存指向,这种操作非常危险,容易和对其他程序造成影响
2.单双引号的区别
3.字符串的内存存放方式及结束标志
#include <stdio.h>
int main(){
char cdata1[]={'h','e','l','l','o'};
char cdata2[]="hello";
printf("cdata1的长度为%d\n",sizeof(cdata1)/sizeof(cdata1[0]));
printf("cdata2的长度为%d\n",sizeof(cdata2)/sizeof(cdata2[0]));
}
cdata1的长度为5
这种建立字符串数组的方式,末尾不会补充“/0”,因此长度为5
cdata2的长度为6
这种方式,在末尾会自动添加一个“/0”,因此长度为5+1=6
4.sizeof与strlen的区别
#include <stdio.h>
#include <string.h>
int main(){
char cdata1[]={'h','e','l','l','o'};
char cdata2[]="hello";
char cdata3[128]={'h','e','l','l','o'};
printf("cdata1的长度为%d\n",sizeof(cdata1)/sizeof(cdata1[0]));
printf("cdata2的长度为%d\n",sizeof(cdata2)/sizeof(cdata2[0]));
printf("sizeof:%d\n",sizeof(cdata2));
printf("strlen:%d\n",strlen(cdata2));
printf("sizeof:%d\n",sizeof(cdata3));
printf("strlen:%d\n",strlen(cdata3));
}
sizeof:6
strlen:5
sizeof:128
strlen:5
两者大小不同的原因是:strlen函数会丢弃字符“/0”,而sizeof函数不会
在char cdata3[128]={'h','e','l','l','o'};中,字符串的长度已经确定为128,
因此sizeof计算结果为128;
但由于初始化时只确定了前5个字符,所以后面的字符均被初始化为‘/0’,
又因为strlen函数主动忽略'/0',所以计算时只考虑前5个有效字符,结果为5
顺带提一句,当不确定变量类型的时候,sizeof(cdata1)/sizeof(cdata1[0]) 来计算元素个数是非常好的解决方式。
void test(){
}
int main(){
char data[128]="hello";
void (*ptest)();
ptest=test;
char *p="hello";
printf("sizeof:data %d\n",sizeof(data));//字符串长度
printf("sizeof:p %d\n",sizeof(p));//指针
printf("sizeof:char* %d\n",sizeof(char *));//char指针
printf("sizeof:int* %d\n",sizeof(int *));//int指针
printf("sizeof:char %d\n",sizeof(char));//一个char型变量
printf("sizeof:ptest %d\n",sizeof(ptest));//函数指针
}
sizeof:data 128
sizeof:p 8
sizeof:char* 8
sizeof:int* 8
sizeof:char 1
sizeof:ptest 8
由上述结果可以发现,无论是什么类型的指针变量(int指针、char指针、数组指针、函数指针等),其大小均为8个字节,因为指针变量存放的内容本质是一个地址,而地址的长度是由计算机自身决定的。
5.malloc动态开辟内存空间(防止悬挂指针/野指针)
1.动态内存的开辟与分配
char *p;//野指针
*p='c';
printf("%c\n",*p);
puts("end");
p=(char *)malloc(1); 此时p有了具体的内存指向,在此基础上,让p去承接‘c’
char *p;
p=(char *)malloc(1);
*p='c';
printf("%c\n",*p);
puts("end");
2.动态内存的释放
char *p;
p=(char *)malloc(1);
*p='c';
free(p);
p=(char *)malloc(5);
printf("重新分配后的地址为:%p\n",p);
strcpy(p,"hello world");
int len=strlen("hello world");
int newlen=len-5+1;
realloc(p,newlen);//扩容函数
printf("扩容后的地址为:%p\n",p);
strcpy(p,"hello world");
puts(p);//打印字符串
puts("end");
重新分配后的地址为:00000000001E23E0
扩容后的地址为:00000000001E23E0
hello world
end
free(p)释放空间
(char *)malloc(1)分配空间
(int *)malloc(12)
realloc(p,newlength)扩容空间,扩容之后,地址不变,第二个参数为扩容长度
puts(p)打印字符串