在C中,我可以在指针声明中初始化字符串,就像我可以在char数组声明中初始化字符串一样吗?

这两行代码是否实现了相同的结果? 如果我在函数中有这些行,那么在两种情况下字符串都存储在堆栈中吗? 除了不需要在第一行代码中声明空终止符之外,我是否应该使用一个而不是另一个?

char s[] = "string"; char* s = "string\0"; 

不,这两行没有达到相同的效果。

char s[] = "string"产生一个7个字节的可修改数组,最初填充内容's' 't' 'r' 'i' 'n' 'g' '\0' (全部复制过来)在运行时从字符串文字)。

char *s = "string"导致指向包含string-literal“string”的只读内存的指针。

如果你想修改你的字符串的内容,那么第一个是唯一的方法。 如果您只需要对字符串的只读访问权限,那么第二个将稍微更快,因为不必复制字符串。


在这两种情况下,都不需要在字符串文字中指定空终止符。 当遇到结束时,编译器将为您处理“。

这两者之间的区别:

 char a[] = "string"; char* b = "string"; 

是一个实际上是堆栈上的静态数组,而b是一个指向常量的指针。 您可以修改a的内容,但不能修改b的内容。

除了其他答案,我将尝试解释为什么你不能在程序流程后修改*s变量。

从概念上讲,当程序加载到内存中时,它有3个区域(段):

  • 代码段:程序的文本存储在这里(它是一个只读区域)
  • 数据段:包含具有预定义值且可以修改的任何全局或静态变量
  • stack segment:这里加载了调用它们的函数。 每个函数调用在堆栈上推送的值集(堆栈帧),其中包含函数和局部变量的返回地址。

在您的情况下, s[]变量是main()函数中的局部变量(数组),它使用值"string"初始化。 因此,它存储在堆栈中并且可以被修改。

*s变量是一个指向"string\0"地址的指针,这是一个位于代码段中的常量。 作为只读区域,您无法修改其内容。