【问题标题】:confused about value of strings (char *) in C [duplicate]对C中字符串(char *)的值感到困惑[重复]
【发布时间】:2021-01-27 15:54:21
【问题描述】:

正如我在 C 中所理解的,char *x 等于字符串 x 中第一个 char 的地址。 在下面的代码示例中,当我在调试器中运行程序时,l 和 m 的值始终是相同的地址并且条件语句为真:

int main(void)
{

    char *l = "hello";

    char *m = "hello";

    if (l == m)
        printf("true");
}

我不明白为什么两个变量总是具有相同的值(地址)

【问题讨论】:

  • 似乎是因为编译器认为相同的字符串只存储一次是合理的。
  • 可能有一个编译器选项来共享/不共享字符串文字定义。
  • 根据编译器的不同,许多人经常将重复的字符串文字折叠成只读数据段中的单个实例。这在 release 优化的构建中尤其经常启用。
  • tl;dr 相等的字符串文字可能有也可能没有相同的地址。
  • @anastaciu 已添加。

标签: c if-statement pointers c-strings string-literals


【解决方案1】:

来自 C 标准(6.4.5 字符串文字)

7 不确定这些数组是否不同,只要它们的 元素具有适当的值。 如果程序尝试 修改这样的数组,行为未定义。

因此编译器可以将相同的字符串文字存储为一个字符串文字或单独的字符串文字。通常编译器会提供一个选项,允许用户选择如何存储字符串文字。

您使用的编译器似乎默认将相同的字符串文字存储为一个字符串文字。你可以这样想象这种情况

char string_literal_hello[] = { 'h', 'e', 'l', 'l', 'o', '\0' };

int main(void)
{

    char *l = string_literal_hello;

    char *m = string_literal_hello;

    if (l == m)
        printf("true");
}

因此,lm 两个指针都指向编译器存储在字符串文字池中的字符数组 string_literal_hello 的同一个字符 'h'

【讨论】:

  • 学究式地,char string_literal_hello[] = "hello"; 不是字符串文字。 ;-)
  • @AndrewHenle 字符串文字是字符数组。
  • 是的,但您的示例是一个字符数组的示例,该数组已初始化为保存“hello”`字符串文字的值。如果您的系统将字符串文字放入只读内存,则您无法修改实际的字符串文字,但您可以修改 string_literal_hello 数组,因为它实际上不是字符串文字。根据the definition of a string literal字符串文字是用双引号括起来的零个或多个多字节字符序列,如“xyz”。这不是你的string_literal_hello
  • 正如我所说,“迂腐”。 ;-)
【解决方案2】:

您正在比较 l 和 m 中的地址值,并且对于像这样的常量,编译器选择了相同的地址,因为值相同。

把它改成这个,'l'和'm'将包含不同的地址,tru不会被打印出来。

char l[] = "hello";

char m[] = "hello";

【讨论】:

    猜你喜欢
    • 2018-01-23
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    • 2021-12-05
    • 1970-01-01
    相关资源
    最近更新 更多