C语言中有两种方法可以存放字符串,但是它们却有区别。本文是看看书上以及网上的一些博客然后总结一下,一孔之见。
(1)分配内存位置的区别
char *p=“word”;//“word\0”被分配在字符串常量存储区存储区,所以如果对p[0]=‘x’是错误的。
char str[10]="word\n";//“word\0”被分配在栈空间中的,所以如果p[0]=‘x’是没有问题的。
注:在栈空间分配内存的变量,是不能用来做函数参数参数返回的。因为在函数调用结束后,函数中的变量(栈空间分配)都被销毁了,返回值是一个不确定的值。
(2)sizeof与strlen区别
例1:(字符指针没有隐含数组长度的概念)
char *p="wordlength";sizeof(p)=4,;//因为p只是一个字符指针,它所指的区域存储了字符串,但是编译器指示将其当作指针处理;
但是,如果strlen(p)=10;//strlen是一个函数操作,以'\0'为标准去计算字符串的长度,'\0'没有算进去
例2:(字符串隐含了一个字符串数组的长度概念)
char p[20]="wordlength";sizeof(p)=20*sizeof(char)=20,;//因为p是一个字符串,是一个数组,这是一个隐形长度的概念在里面,但是如果当作函数时又退化为指针。
char p[]="wordlength";sizeof(p)=11;//p是一个字符串,一个数组,虽然没有给出长度,编译器会自动算出长度,这里为什么是11,因为在字符串的结尾有一个额外的'\0'。
但是,如果strlen(p)=10;//strlen是一个函数操作,以'\0'为标准去计算字符串的长度,'\0'没有算进去。
sizeof(*p)=1;//*p是第一个字符串的第一个字母
(3)字符指针可以指向一个字符串
char *str=”china“;//C语言中对字符串常量按照字符数组处理的,在内存中开辟了一个字符数组来存放该字符串常量。对str的初始化,其实就是将把该内存中的第一个元素地址赋给了str。
上面的定义可以拆成下面两行:
char *str;
str = ”china“;//让str指向china这个存储空间
但是不能这样:
char *str;
*str=”china“;//str都没有指向任何空间,这样赋值显然是不对的。
(4)用scanf的时候注意
例1: char str[10];
scanf("%s",str);//这样输入时没有问题的,在编译的时候str已经分配了空间,其地址是确定的
例2: char *str;
scanf("%s",str);//这样是不对的,str没有指向确定的空间,这样是一个很危险的一个操作
(5)字符串的指针值是可以改变的
char *str="china";
str=str+1;//这是没有问题的
char c = *str ;//我们可以通过取地址操作获得字符串的某个字符
*str = ‘c’;//但是我不能修改str里面的内容,因为str指向的空间在字符串常量空间分配的,无法改变。
注:但是一般的数组名虽然代表地址,但它却是常量,它的值是不能改变的。
(6)char *str = “lsj”;//不需要释放内存
char *str = new char[strlen(1)+1];//需要释放内存