我在ubuntu server 11.10上写了如下的代码:
// charc.c
#include <stdio.h>
int main(int argc,char** argv){
char* str="I am a student.";
printf("%s\n",str);
str[0]='i';
printf("%s\n,str);
return 0;
}
使用gcc编译:
gcc -o charc charc.c
当执行 str[0]='i' 时,报“Segmentation fault” 错误.
但如果将char* str="I am a student"换成str[]="I am a student";就没有错。
登录后可以发表评论,现在登录
在stackoverflow上找到答案,http://stackoverflow.com/questions/3862842/difference-between-char-str-string-and-char-str-string
char* str="STRING"中的str所指向的字符串是不能被修改的。
"字符串视作字符数组"->是不对的.
C语言中,指针与数组是不同的.任何一本稍有深度的c语言书都应该告诉你这点.
对char *str来说,str是一个4字节的内存,其内容是一个地址.
对char str[]来说,str是一个连续内存中的第一个地址,其内容是一个字符.
假设"hello"放在内存0-5,"world"放在6-11.不管数据段还是堆栈,都是内存.前面说过,char *ptr中的ptr有自己的一个四字节的内存,这里假设它是12-15.char *ptr="world"; 这一句,实际是往12-15号内存写入6这个数(它是内存地址),char string[]="hello";则是让string代表0号内存.ptr=string就是往12-15号内存写入0这个数(它是内存地址).
结合前面那本书的截图看.
char *str 字符指针,是变量。str[0]是否可改变取决于指向的是变量还是常量。
char str[] 字符数组,有一个拷贝的过程,str[0]可变, str不可变。
但我觉得没有必要区分,既然C语言中将字符串视作字符数组,而实际上char *str和char str[]在写法上是等价的,比如str[i] 可以写作 *(str+i) , 假设有一个函数
void change(char* str, int i, char ch){ str[i]=ch; }
不论你给一个函数传入字符数组还是字符串常量,在编译期是能通过的,但在运行时,对于传入的字符串常量就会报 ”段错误“。这就是C语言不好掌握的一个例证。为啥不能将char *str和 char str[]统一起来呢.
我还想说的是, 在C语言中,你 不能这么定义一个数组
char[] str = {'h','a', 'p','p','y'};
[]必须放在变量的右边
但是你却可以这样定义一个字符指针
char* str;
并且可以用sizeof (char *)得出字符指针类型的变量所占用字节数
由此可以看出,C语言没有字符数组类型一说,但却有字符指针类型,整型指针类型等各种指针类型。
而实际上,字符数组只是内存中的一片连续的物理地址空间,并通过一个字符指针变量(或叫数组名)进行随机访问. 因此对数组的访问可以归结为指针的操作,两者应该是统一的,但不知何故,C语言的作者要把它区分开来
#include <stdio.h> void change(char* str, int i, char ch){ str[i]=ch; } int main(void) { char str[] = "Hello!"; change(str, 0, 'h'); printf("%s\n", str); return 0; }用gcc -S x.c看中间汇编文件就明白了
char* p="xxx"; 这段xxx是在main上面的只读区的,编译的时候就已经生成了,运行的时候只是把p指针指向这段只读区
char p[]="xxx"; 这段是在main里面的
C和Java的字符串具有不变性 你不能在一段连续的空间上修改字符串的值 但是你可以修改引用的指向 完成你要的效果 这通常都是复制地址来完成的 比如我申请一个0X1065... =“hello world” 然后赋值hello peter 实际上编译器会复制一个指向0X1065的地址 也许是0X1022 然后赋值hello peter 最后 字符串和字符数组是不一样的 所以字符数组可以 字符串不可以
既然字符数组和指向字符的指针是有区别的,那为什么char *str 能指向一个数组的首地址呢?为什么数组的定义不能写成 char [] str="happy", char[] 才能突出字符数组类型