似曾相识 不过是个Bug...

大狗的窝~

C风格字符串

在C语言中,没有专门存放字符串的数据类型。

通常以以下三种方式表示:

(1)字符串字面值:

  "hello world" //静态存储区(文字常量区)中,不能被修改 纠正:字符常量在代码段!

 

(2)字符数组:(输出同上,注意最后的'\0')

  char str[] = {'h','e','l','l','o',' ','w','o','r','l','d','\0'}; 
  char str[] = "hello world"; //(不同于上述字符串字面值,这个存储在栈区,可以被修改)

 

(3)字符指针方式:(既可以指向字符串字面值,也可以指向字符数组)

  char* str = "hello world";

 或者

  char str1[] = {'h','e','l','l','o',' ','w','o','r','l','d','\0'};

  char* str2 = str1;

 在C语言中,所有字符串以一个称为空字符的字符结尾。空字符可以写成'\0'。

 

 上述三种字符串表示方法的区别:

(1)字符串字符值存储在程序的静态存储区纠正:代码区,其值不可被修改。

  char* str = "hello"; //字符串字面值,存储在静态区代码区
  str[1] = 'c'; //Error!
  strcpy(str, "world"); //Error!同上
  str = "abcde"; //OK!这只是把新的字符常量"abcde"的地址赋给str这个指针变量

其实这里我有点疑惑,我用VS编译通过,运行错误;

但是用gcc编译是可以通过的,运行输出是“hcllo”。导致这种结果,可能应该是实现的差异。

ANSI C说,修改字符串常量的行为是未定义的。

(今天又去Linux上的GCC编译了下,运行时是段错误!上面那个我是在Cygwin里的GCC编译的才能运行,我想应该是那个编译环境的问题,应该是报错的!)(又据说TC2.0编译也能成功运行...)

 

一个字符串字面值占据的存储空间,被用来代表不止一个字符串。换句话说,相同内容的2个字符串字面值可能占用同一个地址。

  char* str1 = "hello";
  char* str2 = "hello";
  puts(str2);      //输出"hello"
  str1[1]= 'c';     //修改是未可知的,假设按上述gcc编译通过且运行成功
  puts(str2);      //输出"hcllo"!!  

 

(2)字符数组存储在内存栈区,其值可以改变,但数组本身地址不可改变。

  char str1[] = "hello"; //存储在栈中,可以修改
  str1[1] = 'c';      //OK!
  str1 = "abcd";      //Error!数组名是常量
  char str2[] = "abcd";
  str1 = str2; //Error! 同上

这个简单木有问题,若需要修改字符串,建议请用字符数组方式。

 

(3)字符指针存储的是一个地址,既可以指向字符串字面值,也可以指向字符串数组。对于前者,字符串内容不能被修改;对于后者,则可以修改。

  char* str1 = "abcdefg";
  char str2[] = "hijklmn";
  char* str3 = str1;
  str3[1] = 'x';   //Error!
  str3 = str2;
  str3[1] = 'x';   //OK!

 

 关于其他一些疑惑:

1)在C++中,字符串字面值实际类型为 const char 数组。那为何 char *p = "ABCDEF"也是合法的?看起来一个pointer to const char指针被赋予了pointer to char指针。

因为字符串字面量在C++中存在两种转换,一种转换依据当前上下文环境,另一种遵循数组到指针的转换。

字符串字面量可以被转换为char*而不是const char*类型的指针,这个转换实际上是对旧有代码的兼容,是一个特例,而且被指定为deprecated的。

 虽然字符串字面量在C中类型为char[N],在C++中类型为const char[N],但并不说明C中的字符串字面量可以修改,C++的不可以。字符串字面量是否可以修改与实现数组的类型无关,C之所以没有规定为const char[N],还是出于对旧代码的兼容,而C++规定为const char[N]的原因之一是比C更严格的类型安全。无论CC++都规定对字符串字面量的修改是未定义的,编译器可以自行处理,也的确存在一些允许修改字符串字面量的编译器,例如老一代的编译器TC,编译器不管是否允许修改字符串字面量,都没有违反标准。

引用自http://blog.csdn.net/supermegaboy/article/details/4854987

 2)待补充。。。

 

posted on 2012-08-02 02:05  Mr.DejaVu  阅读(459)  评论(0编辑  收藏  举报

导航

for myself...