【问题标题】:What is the return value of &"suchString"?&“suchString”的返回值是多少?
【发布时间】:2017-10-21 19:08:09
【问题描述】:

这个sn-p代码的输出:

char* str1 = "suchString";
printf("%s %s\n", &"suchString", &str1);

是:

suchString �WO:+(或任何未知符号)

有什么区别,为什么输出不一样?

编辑 如果您尝试按如下方式消除 & 运算符:

char* str1 = "suchString";
printf("%s %s\n", "suchString", &str1);

输出与代码的第一个 sn-p 相同。 那么,"suchString" 和 &"suchString" 是一样的吗?

【问题讨论】:

  • 为什么要提供char**,指针的地址,作为%s 占位符的参数?老实说,我很惊讶第一个论点竟然奏效了。
  • 您应该使用所有警告和调试信息进行编译:gcc -Wall -Wextra -g with [GCC](htttp://gcc.gnu.org/)。你会收到警告
  • 这是一个测验,但我不知道为什么 &"suchString" 不打印 &str1 之类的地址
  • 因为字符串字面量是数组,而不是指针。
  • @tadman:你说得对,我没有仔细阅读。 printf 调用中的三个参数(包括格式字符串)的类型为 char*(在数组到指针衰减之后)、char(*)[11] 和 char**。第二个和第三个参数都需要是 char* 类型。

标签: c string pointers memory-address c-strings


【解决方案1】:

这个:

&"suchString"

获取字符串文字的地址。字符串文字是数组,而不是指针。

如果你在编译时启用了警告,你就已经知道了:

prog.c:5:14: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[11]' [-Wformat=]
     printf("%s %s\n", &"suchString", &str1);
             ~^        ~~~~~~~~~~~~~
prog.c:5:17: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'char **' [-Wformat=]
     printf("%s %s\n", &"suchString", &str1);
                ~^                    ~~~~~

第一个是char (*)[11]类型,而第二个是char **类型。

至于垃圾值,您提供了指向%s 格式的指针的地址,从而破坏了打印。如果你改用%p,你会看到一个地址被打印出来,例如“0x7ffe676f5588”。

尝试打印字符串文字的地址时也是如此,字符串说明符位于printf()。

此外,您应该转换为void*,如下所示:

printf("%p %p\n", (void*)"suchString", (void*)str1);

【讨论】:

  • 感谢您的回答,我试图消除 & 运算符,它是相同的 &"suchString" = "suchString".. 为什么?
  • @AhmedYasen:你说“它是一样的”。什么和什么一样?
  • %p 说明符需要void* 类型的参数。如果要打印不同类型指针的值,则应强制转换它。 (在大多数实现中,您可能无需演员就可以逃脱,但这是一种很好的做法。)
  • @AhmedYasen,在 C 中,对数组名称的引用会降级为数组的地址。注意:这个语句:&"suchString"实际上是错误的,因为它试图获取一个地址的地址。幸运的是,C 正确地返回了正确的(地址)值
【解决方案2】:
char* str1 = "suchString";
printf("%s %s\n", &"suchString", &str1);

%s 说明符需要char* 类型的参数,该参数必须是指向字符串的指针。您提供了 char (*)[11] 和 char** 类型的参数。您的代码具有未定义的行为,这意味着原则上它可以做任何事情。

字符串文字是一个数组。数组的地址指的是与数组第一个元素的地址相同的内存位置,但它的类型不同。仅传递 "suchString" 作为第二个参数是正确的,因为数组“衰减”为指向其第一个元素的指针。

在所有指针具有相同表示的实现中(这是典型的但不是必需的),将指针传递到相同的内存位置但类型错误可能会“工作”。 printf 的特殊之处在于它可以接受不同类型的参数,因此编译器不一定能诊断出类型错误。对于非可变函数,这样的错误可能会在编译时被拒绝。

str1 是一个指针,而不是一个数组。您已将其初始化为指向字符串文字的初始字符。您可以将str1 传递给printf,但&str1 是指针对象的地址,它不仅类型错误,而且根本不指向字符串。因此输出是垃圾。

如果要打印字符串值,可以这样做:

const char* str1 = "suchString";
printf("%s %s\n", "suchString", str1);

(我添加了const,因此如果您尝试修改字符串文字的内容,编译器会报错。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-06
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2020-12-13
    相关资源
    最近更新 更多