您应该做的第一件事是阅读comp.lang.c FAQ的第 6 部分。
字符串字面"hello"量是一个类型的表达式char[6](“hello”为 5 个字符,结尾为 1 个字符'\0')。它指的是一个具有静态存储持续时间的匿名数组对象,在程序启动时初始化为包含这 6 个字符值。
在大多数情况下,数组类型的表达式被隐式转换为指向数组第一个元素的指针;例外情况是:
- 当它是
sizeof(的参数时,sizeof "hello"产生 6,而不是指针的大小);
- 当它是
_Alignof(C11 中的一个新特性)的论点时;
- 当它是一元的参数时
&(&arr产生整个数组的地址,而不是其第一个元素的地址;相同的内存位置,不同的类型);和
- 当它是用于初始化数组对象的初始化程序中的字符串文字时(
char s[6] = "hello";复制整个数组,而不仅仅是指针)。
这些例外都不适用于您的代码:
char *ptr;
ptr = "hello";
所以表达式"hello"被转换为(“衰减”到)指向'h'我上面提到的那个匿名数组对象的第一个元素()的指针。
因此*ptr == 'h',您可以ptr通过记忆前进以访问其他字符:'e'、'l'、'l'、'o'和'\0'。printf()当你给它一个"%s"格式时,这就是它的作用。
与字符串文字相关联的匿名数组对象是只读的,但不是const. 这意味着任何修改该数组或其任何元素的尝试都具有未定义的行为(因为标准明确说明了这一点)——但编译器不一定会警告您。(C++ 生成字符串文字const;在 C 中做同样的事情会破坏在添加到语言中之前编写的现有代码const。)所以不,你不能修改"hello"- 或者至少你不应该尝试的元素。为了让编译器在您尝试时发出警告,您应该将指针声明为const:
const char *ptr; /* pointer to const char, not const pointer to char */
ptr = "hello";
(gcc 有一个选项 ,-Wwrite-strings导致它将字符串文字视为const。这将导致它警告一些就标准而言是合法的 C 代码,但此类代码可能应该修改为使用const。)