【问题标题】:Is &"string" the same address as "string"?&"string" 和 "string" 是同一个地址吗?
【发布时间】:2014-07-21 22:30:13
【问题描述】:

我有一些生成的 C 代码如下所示:

char *example[] = {&" ",&"\n", &"\t"};

如果我自己写这个,我会去掉与号 (&),因为字符串文字已经是 char * 类型。对我来说,看起来example 应该 已经生成并声明为char**[]

我可以确定指针是否与&s 相同?这是采用 C 中明确定义的地址的地址吗?

编辑:我正在调查当前处于生命周期中的某些软件的警告,该软件不接受任何更改。 printf("%p", &"hello world"); 是否始终与printf("%p", "hello world"); 相同,还是取决于编译器?

【问题讨论】:

  • 这在很多方面都非常令人困惑。字符串文字“根本不是char * 类型,在几个方面。获取字符串文字的地址不是一回事。
  • 我很确定字符串文字不是地址(类型char *),而是一个数组(类型char[] ) 或 数组初始值设定项(用于类型 char[])。当然,数组可以衰减为指针,但它没有到。
  • 如果你把额外的钱花在一个好的编译器上,你会得到有用的警告,这会节省你很多时间。
  • 你需要修复这段代码的“生成器”(或者插入你自己的预处理层来修复它)。
  • 我目前正在调查一个警告,看看它有多严重。我很乐意做以上所有的事情来修复它,但该软件目前处于不接受对编译器、软件等进行任何更改的生命周期中。

标签: c string memory-address c-strings


【解决方案1】:

&“string”和“string”是同一个地址吗?

不,它们的类型不同。

 "hello world"

对象的类型为char [12]。至于表达式上下文中的其他数组,则转换为char *

但是:

 &"hello world" 

类型为char (*)[12]

所以在你的例子中,这也意味着:

char *example[] = {&" ",&"\n", &"\t"};

是无效声明,因为初始化列表中的数组元素不是char * 类型。

这是正确的声明:

char *example[] = {" ", "\n", "\t"};

为了这个问题,如果你必须使用&,这里是正确的声明:

char (*example[3])[] = {&" ",&"\n", &"\t"};

【讨论】:

  • 所以正确的声明应该是char *example[][]printf("%p", &"hello world") 总是与printf("%p", "hello world") 相同,还是未定义?
  • 基本正确,但不清楚“表达式上下文”是什么意思,或者一元 & 的操作数如何不在这样的上下文中。数组到指针的转换发生除非数组表达式是(a)一元&的操作数; (b) sizeof 的操作数,或 (c) 用于初始化数组对象的初始化程序中的字符串字面量。
  • @Darthfett:不,正确的声明可能是char *example[] = {" ", "\n", "\t"};printf("%p", ...) 需要 void* 类型的参数。几乎可以肯定,您可以通过char* 逃脱,并且您可以可能 通过char(*)[12] 逃脱,但您应该转换为void* 以确保这一点。您对printf 的调用应该打印相同的内容如果 "hello world" 的两次出现在内存中合并;编译器可以这样做,但不是必须的。
  • @Darthfett 正确的声明应该是 char (*example[])[2] = {&" ",&"\n", &"\t"};,只要 example 中每个指向的字符串字面量都是 2 个字符长(一个字符加上空终止符),就像您的情况一样例子。
  • 肯定是同一个地址,虽然由于类型不同的指针/值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-14
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
  • 2019-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多