指向C中的const字符串的指针

Mih*_*csu 12 c arrays pointers const

char *p = "string"; //creates pointer to constant string

char p[] = "string"; //just an array with "string"
Run Code Online (Sandbox Code Playgroud)

我只是有点困惑为什么它在第一个例子中创建一个指向常量字符串的指针?它不应该仅仅是指向内存中带有"字符串"的地方的指针吗?

Bla*_*iev 22

在第一种情况下,"string"可以存储在进程的只读区域中,因此尝试修改指向的内存p将导致未定义的行为.

在第二种情况下,实际的存储器被分配并在运行时初始化栈上(或在该方法的程序启动时的适当部分,如果它不是一个局部变量),所以修改存储器是OK.

第一种情况可以这样说明:

+---+           +---+---+---+---+---+---+---+
|   |   ---->   | s | t | r | i | n | g | \0|
+---+           +---+---+---+---+---+---+---+
  p
Run Code Online (Sandbox Code Playgroud)

而第二种情况是:

+---+---+---+---+---+---+---+
| s | t | r | i | n | g | \0|
+---+---+---+---+---+---+---+
              p
Run Code Online (Sandbox Code Playgroud)

这两个声明有很大的不同,尽管您可能听说过低质量的C编程书籍它们是相同的.

第一个是类型的指针char *,而第二个是类型的数组char [].数组标识符在某些上下文中衰减为指针,但这不会使它们成为指针.

指针只是一个地址,数组是"整个" - 在第一种情况下sizeof(p)产生指针的大小(通常48取决于目标机器),在第二种情况下它产生7 * sizeof(char),实际字符串的长度.


Arm*_*yan 15

不幸的是,它在C语言中是合法的(在C++ 03中,为了兼容性).但是任何通过指针修改字符串文字的尝试都会导致未定义的行为.因此,最好总是将字符串文字分配给aconst char*

const char * cp = "Hello"; //OK
char* p = "Hello"; //OK in C and C++03 (unfortunately), Illegal in C++11
cp[0] = 'Y'; //Compile-time error, good
p[0] = 'Y'; //no compiler error, undefined behavior
Run Code Online (Sandbox Code Playgroud)