字符串文字

时间:2009-04-05 06:40:37

标签: c++

我对c ++中的字符串文字几乎没有怀疑。

char *strPtr ="Hello" ;
char strArray[] ="Hello";

现在strPtr和strArray被认为是字符串文字。

根据我的理解,字符串文字存储在只读存储器中,因此我们无法修改它们的值。

我们做不到

strPtr[2] ='a';
and strArray[2]='a';

以上陈述都应该是非法的。 编译器应该在两种情况下抛出错误。

编译器将字符串文字保留在只读内存中,因此如果我们尝试修改它们,编译器会抛出错误。

此外,const数据也被视为只读。

是否同时处理字符串文字和const数据? 我可以使用const_cast从字符串文字中删除常量来改变它的值吗?

确切存储字符串文字的位置? (在节目的数据部分)

3 个答案:

答案 0 :(得分:16)

  

现在strPtr和strArray被认为是字符串文字。

不,他们不是。字符串文字是您在代码中看到的内容。例如,"Hello"strPtr是文字的指针(现在在可执行文件中编译)。请注意,它应该是const char *;根据C标准,您不能合法地删除const,并且在使用它时期望定义的行为。 strArray是一个包含文字副本的数组(在可执行文件中编译)。

  

以上陈述都应该是非法的。编译器应该在两种情况下抛出错误。

不,不应该。这两个陈述完全合法。由于情况,第一个是未定义的。如果它们是指向const char的指针,那将是一个错误。

据我所知,字符串文字的定义方式与其他文字和常量相同。但是,存在差异:

// These copy from ROM to RAM at run-time:
char myString[] = "hello";
const int myInt = 42;
float myFloats[] = { 3.1, 4.1, 5.9 };

// These copy a pointer to some data in ROM at run-time:
const char *myString2 = "hello";
const float *myFloats2 = { 3.1, 4.1, 5.9 };

char *myString3 = "hello";  // Legal, but...
myString3[0] = 'j';         // Undefined behavior!  (Most likely segfaults.)

我在这里使用ROM和RAM是一般的。如果平台仅是RAM(例如大多数Nintendo DS程序),那么const数据可以在RAM中。但是,写作仍未定义。对于普通的C ++程序员来说,const数据的位置无关紧要。

答案 1 :(得分:8)

char *strPtr ="Hello" ;

strPtr指向char的指针定义为字符串文字"Hello" - 此指针的有效类型为const char *。不允许通过strPtr对指针对象进行修改(如果您尝试这样做,则调用UB)。这是旧C代码的向后兼容功能。在C ++ 0x中不推荐使用此约定。见附件C:

  

更改:字符串文字使const   字符串文字的类型从“char of char”更改为“const char数组”。[...]

     

基本原理:这可以避免调用不合适的重载函数,该函数可能希望能够修改其参数。

     

对原始功能的影响:更改定义明确的功能的语义。转换难度:简单的句法转换,因为字符串文字可以转换为char *; (4.2)。最常见的情况由新的但已弃用的标准转换处理:

     

char* p = "abc"; // valid in C, deprecated in C++

     

char* q = expr ? "abc" : "de"; // valid in C, invalid in C++

     

使用范围广泛:有合理理由将字符串文字视为指向潜在可修改内存的指针的程序可能很少见。

char strArray[] ="Hello";

声明的strPtr类型是 - 它是一个未指定大小的字符数组,包含字符串Hello,包括空终止符,即6个字符。但是,初始化使它成为一个完整的类型,它的类型是6个字符的数组。通过strPtr进行修改是可以的。

  

确切存储字符串文字的位置?

实施定义。

答案 2 :(得分:1)

较旧的C和C ++编译器纯粹基于低级编码,其中没有更高标准的数据保护,甚至无法实施,通常在C和C ++中,您可以编写任何您想要的内容。

如果您知道如何使用地址,您甚至可以编写代码来访问和修改常量指针。

虽然C ++确实强制执行某些编译级保护,但运行时没有保护。您当然可以访问自己的堆栈,并使用其值来处理const指针中的任何数据。

这就是为什么发明C#的原因,因为无论你访问的是引用,它是一个固定的结构,它管理所有数据保护规则,它有隐藏的指针,无法访问和修改。< / p>

主要区别在于,C ++只能为您提供编译时保护,但C#甚至可以在运行时为您提供保护。