【问题标题】:Integer types in C and C++, and their interpretation by printfC 和 C++ 中的整数类型,以及它们的 printf 解释
【发布时间】:2014-02-08 10:02:58
【问题描述】:

我最近回答了一个关于 SO 的问题,在此过程中发现自己对一些事实有点不确定,所以我想对这些事实进行第二次断言:

  1. C 和 C++ 中的整数类型:

    • char:1字节大小的整数值。

    • short:2字节大小的整数值。

    • long:4字节大小的整数值。

    • long long:8字节大小的整数值。

    shortlonglong long 类型后面通常跟int

    但这不是必须的,我们可以在没有int 的情况下使用它们。

    或者,我们可以只声明int,但不同的编译器可能会有不同的解释。

    总结一下:

    • shortshort int 相同,但不一定与int 相同。

    • longlong int 相同,但不一定与int 相同。

    • long longlong long int 相同,但不一定与int 相同。

    • 在给定的编译器上,intshort intlong intlong long int

  2. 使用printf打印一个整数:

    -printf("%d"...) 从堆栈中读取一个int 值。

    -printf("%ld"...) 从堆栈中读取long int 值。

    -printf("%lld"...) 从堆栈中读取一个long long int 值。

    所以:

    -printf("%ld"...) 将在任何给定平台上读取 4 个字节。

    -printf("%lld"...) 将在任何给定平台上读取 8 个字节。

    -printf("%d"...) 将读取 2 个字节或 4 个字节或 8 个字节,具体取决于给定平台上int 的定义。

上面的描述有空洞吗?

谢谢

【问题讨论】:

  • "通常后跟int" - 不是大多数现代编码风格。
  • int 的大小不需要与任何其他整数类型相同。
  • short、long、long long类型后面通常跟int。
  • @ta.speot.is:这个评论不是很有帮助。具体说法有误吗?如果是,它有什么问题?请阅读其后的两个陈述。
  • 为什么不,嗯,阅读标准?

标签: c++ c integer printf


【解决方案1】:

有几个相当大的漏洞。

char 总是占用 1 个字节。这是 only 类型,但可以保证其大小。所有其他的基本上都是 1 个或更多字节,并且足够大以容纳指定范围的值(shortint 为 16 位,long 为 32 位,long long 为 64 位)。

换句话说,您给出的尺寸很常见,但不能保证。

printf:

  • “%d”指定int
  • “%ld”指定long int
  • “%lld”指定long long int

如上所述,每个都有指定的最小范围,但不是必需的大小。

同样,该标准实际上并没有指定机器有一个堆栈(还有一些,例如 IBM 大型机和旧的 Crays,没有),但如果您只考虑抽象的行为需求,那么您得到的是当然是 LIFO(类似堆栈)的要求。

【讨论】:

  • 虽然 sizeof(char) == 1 的定义是 CHAR_BIT == 16 而不是 8,特别是在 DSP 世界中。
  • 是的,从技术上讲,在这样的系统上,一个字节是 16 位。
【解决方案2】:

如果不咨询limits.h 和可能的stdint.h,您无法肯定地说任何整数类型对于给定平台的大小是多少。但是,您可以确定 printf 格式字符串将正确的模式与在给定实现的堆栈上传递的正确大小的整数相关联。

【讨论】:

    【解决方案3】:

    您的某些断言不正确,因为它们因平台而异。要确定您的类型的宽度,请打开您的 limits.hfloat.h 文件。您也可以使用sizeof 运算符。

    请记住,char 始终是一个字节,无论它有多少位。也就是说,在某些机器上 char 是 8 位,而在另一台机器上 char 是 16 位。在每种情况下,它都被认为是一个字节。其他类型是char的倍数。

    【讨论】:

    • 谢谢,但我没有问如何计算给定变量的大小。
    • @barakmanos 你没有直接,但你假设某些类型是某些大小(short 总是两个字节)是不正确的。
    【解决方案4】:

    很多问题....
    很多答案....

    OP:long:一个大小为 4 字节的整数值。
    A:long 是一个整数,最小范围为 -2147483647 到 +2147483647,因此它至少需要 32 位。

    OP:long long:一个8字节大小的整数值。
    答:long long 是一个整数,最小范围为 -9223372036854775807 到 +9223372036854775807,因此它至少需要 64 位。

    OP:shortlonglong long 类型通常后跟 int
    答:我看到shortlonglong long 的频率更高,然后是int,除非它是像C 规范这样的迂腐用法。
    A:进一步(不是我的意见):short int ishort i 相同。 long int ilong i 相同。 long int ilong i 相同。
    答:进一步:short signed int ishort i 相同。 shortsignedint 可以以任何顺序出现,结果相同。

    OP:但这不是必须的,我们可以在没有int 的情况下使用它们。
    答:是的。往上看。

    OP:或者,我们可以只声明 int,但这可能会被不同的编译器以不同的方式解释。
    A: 大小/范围可能会改变,但shortsigned short 相同signed short intsigned int 相同。这适用于“long”和“long long”,但不适用于“char”。

    OP:shortshort int 相同,但不一定与 int 相同。
    答:是的。

    OP:longlong int 相同,但不一定与int 相同。
    答:是的。

    OP:long long 与 long long int 相同,但不一定与 int 相同。
    答:是的。

    OP:在给定的编译器上,intshort intlong intlong long int
    答:不。所有 4 种可能是不同的大小/范围。

    OP:-printf("%d"...) 从堆栈中读取 int 值。
    OP:-printf("%ld"...) 从堆栈中读取 long int 值。
    OP:-printf("%lld"...) 从堆栈中读取 long long int 值。
    答:是的——存在“堆栈”以外的其他机制。最好将 int 想象成来自可变参数。

    OP:-printf("%ld"...) 将在任何给定平台上读取 4 个字节。
    OP:-printf("%lld"...) 将在任何给定平台上读取 8 个字节。
    OP:-printf("%d"...) 将读取 2 个字节或 4 个字节或 8 个字节,具体取决于给定平台上的 int 定义。
    答:不会。long 的大小至少与int 一样大。 long long 的大小至少与 long 一样大。读取的字节数取决于平台。

    C 中“字节”的定义是“数据存储的可寻址单元,大到足以容纳执行环境的基本字符集的任何成员”。所以sizeof(char) --> 1 或C 的说法是 1 字节,无论是 8、9、32 还是任何位大小。

    在更大的世界中,许多人认为“字节”是 8 位。这两个“字节”的定义很容易混淆。在谈论C 时,我更喜欢说“短的大小是4”,意思是sizeof(int) --> 4 或char 的两倍,而不使用“字节”这个词。

    【讨论】:

    • 上述答案的一些问题: 1.我没有提到signed/unsigned是有原因的。它对问题没有任何“影响”。 2. 你在“IMO 你的建议是错误的”之后所做的每一个陈述都在问题中指定,那么这些陈述是对还是错? 3. 你是否暗示int 可能不是short intlong intlong long int
    • 是的,int 可能与 short、long 和 long long 不同。
    • @barak manos 1) 我也没有提到unsignedsignedint 一样被提及,等等。它是可选的,无需更改类型。 2)编辑更清楚。 3) 是的,所有 4 个都可能不同。
    • 您可以拥有例如 16 位 short、32 位 int、64 位 long、128 位 long long 和 256 位 intmax_t。我不知道有什么系统可以做到这一点,但这远非不可能。
    猜你喜欢
    • 1970-01-01
    • 2021-11-13
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    相关资源
    最近更新 更多