【问题标题】:How does assigning a string to int and passing that int to printf prints the string properly?将字符串分配给 int 并将该 int 传递给 printf 如何正确打印字符串?
【发布时间】:2016-12-19 10:47:44
【问题描述】:

为什么会这样? (即如何将int 传递给printf() 导致打印字符串)

#include<stdio.h>

int main() {
    int n="String";
    printf("%s",n);
    return 0;
}

警告:初始化从没有强制转换的指针生成整数[默认启用]
int n="字符串";
警告:格式“%s”需要“char *”类型的参数,但参数 2 的类型为“int”[-Wformat=]
printf("%s",n);

输出:字符串

编译器:gcc 4.8.5

【问题讨论】:

    标签: c string int printf


    【解决方案1】:

    使用 -Wall -Wextra -Werror -Wint-to-pointer-cast -pedantic (GCC) 之类的选项编译会很快告诉您不应依赖此行为。

    【讨论】:

      【解决方案2】:

      int 类型在当今大多数计算机上可以存储 4 个字节的数字(从 -2147483647 到 2147483647)

      这意味着它也“可以”存储一些地址,唯一的问题是当您的地址大于 2147483647 时会导致溢出并且您将无法获取地址,(这对您的程序非常不利显然)

      地址是指内存空间的数字, 指针用于存储地址,它们更大(64 位系统上为 8 个字节,32 位系统上为 4 个字节)并且它们也是无符号的(只有正数)

      这意味着,当您影响 int n="String"; 时,如果 "String" 的地址低于 2147483647,则不会导致问题,您的代码将运行(不要那样做)

      http://www.tutorialspoint.com/c_standard_library/limits_h.htm

      现在如果你想一想,你可以猜到为什么 32 位系统有 4GB 内存限制

      (对不起,可能出现的英文错误,我是法国人)

      【讨论】:

      • "在当今大多数系统上,int 类型可以存储 4 个字节的数字"。我不同意。如果您包括嵌入式系统,我相信 -32768 到 +32767 仍然是最常见的。
      【解决方案3】:

      在您的代码中,

        int n="String";  //conversion of pointer to integer
      

      高度依赖于实现note 1

       printf("%s",n);   //passing incompatible type of argument
      

      调用undefined behavior注意 2不要那样做

      故事的寓意:警告是有原因的,请注意它们。


      注 1:

      引用C11,第 6.3.2.3 章

      任何指针类型都可以转换为整数类型。除先前规定外, 结果是实现定义的。如果结果不能用整数类型表示, 行为未定义。 [....]

      注2:

      第 7.21.6.1 章

      [....] 如果有任何参数 不是相应转换规范的正确类型,行为是 未定义。

      对于%s 格式说明符和printf() 的参数类型

      s 如果不存在l 长度修饰符,则参数应为指向初始值的指针 字符类型数组的元素。 [...]

      【讨论】:

        【解决方案4】:

        您的程序的行为是未定义

        本质上,您将const char* 分配给int,然后printf 将其转换回来。但请务必将其视为完全巧合:您不能像这样强制转换不相关的类型。

        C 让你有能力射自己的脚。

        【讨论】:

        • 这让我想起了 Bjarne Stroustrup 所引用的一句话:C 让我很容易射中自己的脚。 C++ 让它变得更难,但当你这样做时,它会吹走你的整条腿。 :)
        猜你喜欢
        • 1970-01-01
        • 2018-10-08
        • 1970-01-01
        • 2020-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-12
        相关资源
        最近更新 更多