【问题标题】:Can't print the sizeof a signed int type无法打印带符号的 int 类型的大小
【发布时间】:2014-04-16 21:28:05
【问题描述】:

为什么当我尝试这样做时:

#include <stdio.h>

int main()
{

    printf("Size of int: %d bytes\n",sizeof(int));

    return 0;
}

我知道了:

warning: format "%d" expects argmuments of int type, but the second argument is of type "long unsigned int..."

(?)

如果算的话,我的操作系统是 64 位版本 12.4 的 Ubuntu。 编译器是:GNU GCC Compiler,IDE 是 Code::Blocks。

出于好奇,我在另一台运行较差的 Win7 且结构也是 64 位的机器上运行相同的代码,我得到的结果是该 int 的大小,而不是像上面那样的警告。

【问题讨论】:

  • 我认为 Microsoft 不会尝试解析 printf 的格式来查看参数是否正常。

标签: c++ c


【解决方案1】:

这是正确的方法:

printf("Size of int: %zu bytes\n", sizeof(int));

sizeof 运算符产生size_t 类型的值,%zu 是打印size_t 类型值的正确转换规范。

如果你的编译器不支持 c99 或 c11,你可以这样做:

printf("Size of int: %lu bytes\n", (unsigned long) sizeof(int));

【讨论】:

    【解决方案2】:

    试试:

    printf("Size of int: %lu bytes\n", sizeof(int));
    

    【讨论】:

    • 这在 LLP64 系统(如 Windows)上是不正确的(实际上是不安全的),其中 long 仍然是 32 位。如果需要安全工作,您必须将 sizeof(int) 的结果转换为 unsigned long。
    【解决方案3】:
    printf("Size of int: %zd bytes\n",sizeof(int))
    

    【讨论】:

    • "zd" 不正确,因为它暗示了有符号类型。
    【解决方案4】:

    sizeof 返回一个size_t 类型,在某些情况下它会大于int。这会弄乱堆栈,因为printf 拉出了错误的大小参数。对于sizeof 之后打印的任何参数,您几乎肯定会看到不正确的结果。

    【讨论】:

    • 那么解决方案是什么?
    • @user2864740,请使用在此问题的其他答案中找到的正确格式代码。
    【解决方案5】:

    你可以转换值

    printf("Size of int: %d bytes\n", (int)sizeof (int));
    

    【讨论】:

      【解决方案6】:

      sizeof 产生size_t。使用格式说明符“%zu”应该提供正确的格式:

      printf("Size of int: "%zu bytes\n", sizeof(int));  
      

      此格式说明符符合 C99
      如果您没有符合 C99 的编译器,您可以将 sizeof 转换为 unsigned int 并使用 "%lu"

      printf("Size of int: "%lu bytes\n", (unsigned int)sizeof(int));    
      

      如果,根据 Microsoft 的说法,您使用的是 visual studios,这是正确的格式说明符size_t 是%Iu

      printf("Size of int: "%Iu bytes\n", sizeof(int));  
      

      【讨论】:

      • sizeof 不是宏,而是运算符。因为它不是一个函数,所以它不会返回。它产生的值的类型始终是size_t,而不是ssize_t
      • @ouah - 进行了编辑以消除这些问题。但是,我想听听您说什么来区分术语returnsyields。谢谢。
      • @rykker 我没有投反对票,但这仍然是错误的。 sizeof 不是宏。此外,不将sizeof 转换为unsigned long 可能会调用未定义的行为,因为在某些实现中size_t 可以是unsigned long long 的别名。
      猜你喜欢
      • 2011-08-24
      • 2018-08-14
      • 1970-01-01
      • 2011-08-22
      • 1970-01-01
      • 2010-12-06
      • 2013-06-23
      • 2023-03-06
      • 1970-01-01
      相关资源
      最近更新 更多