【问题标题】:Accessing chars from 'strings' that aren't declared in a variable (C)从未在变量中声明的“字符串”访问字符 (C)
【发布时间】:2012-04-25 03:30:13
【问题描述】:
char i;
for(i=0;i<16;i++)
    printf("%c","asdf"[i]);
i=1;
if("123"[i]==1)
    i=1;
if("456"[4]==1)
    i=1;
if("789"[1]==1)
    i=1;

输出是:

asdf 123 456

似乎大多数“字符串”在内存中是紧接在一起的。我不认为这是随机的,或者是吗? 此外,当我在 char-access-expression 中使用 int 变量而不是 i 时程序失败,这不是第一个(这里是 asdf[i])。例如if("123"[j]==1)

谁能给我解释一下?

【问题讨论】:

  • 编译器通常会将所有常量字符串收集到一个“字符串表”中。这样做时可能会删除重复的字符串;例如: "hello\0" 和 "lo\0" 可能最终在字符串表中折叠。
  • 但是为什么“789”不在这张桌子上呢?这取决于访问索引,还是看起来如此?
  • @user1329846:可能是编译器在编译时计算了"789"[1],但没有计算"456"[4]。字符串在内存中的位置不是由 C 标准定义的,所以这里没有任何保证,这就是为什么你应该避免你正在尝试做的事情。

标签: c arrays string memory char


【解决方案1】:

常量字符串通常与程序代码分开存储,它们在内存中紧密排列并不奇怪。但是你不应该依赖这个。

您的程序有未定义的行为,如果您尝试使用不同的编译器运行代码,可能会出现不同的情况。例如,当我使用 gcc 4.3.4 在 ideone 上运行您的代码时,它的输出与您得到的不同。

【讨论】:

  • 很抱歉,我很抱歉,但实际上我仍然想了解为什么不是我的示例中的所有字符串都直接紧随其后,这取决于访问索引(例如 i)。特别是:为什么程序在这个索引中使用 int 会失败?
  • @user1329846:关于未定义行为的一个很酷的事情是任何事情都可能发生,包括似乎没有任何明显逻辑解释的令人困惑的行为。与其尝试理解未定义的行为,不如尝试避免它。但是如果你真的想看懂,把生成的机器码反汇编一下,看看幕后是怎么回事。
  • 我也是这么想的,直到我得到了ninjalj的评论。当有理由收集字符串(以对它们进行重复数据删除)时,必须有理由不对每个字符串都这样做。我有点菜鸟,所以我想尽量避免拆卸......
  • @user1329846:编译器可以优化。在高优化级别,如果编译器只将"%c""asdf" 发送到字符串表,完全优化if 块,我不会感到惊讶。
  • Hrm..好的,对我来说已经足够回答了......谢谢你们!
猜你喜欢
  • 1970-01-01
  • 2023-03-23
  • 2021-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-28
  • 1970-01-01
  • 2011-04-19
相关资源
最近更新 更多