12

我刚刚参加了一个 C++ 测试,但我错误地回答了以下问题:

问:以下程序的输出是什么?

#include <iostream>
#include <stdint.h>

using namespace std;

int main() {
    int a = 0;
    for (int8_t i = 1; i > 0; i <<= 1)
        a++;
    cout << a;
    return 0;
}

有以下答案可供选择

  • 8
  • 7
  • 未定义的行为
  • 编译错误

正确”的答案是 7。如果答案中有“实现定义的行为”,我会选择那个,所以我选择了最接近的未定义行为。我知道在符号和幅度、1 的补码和 2 的补码中,答案将是 7。但是 C++ 标准理论上不允许任何其他数字表示吗?例如符号和大小,但 0 表示负数?

我是否正确,因为这个问题的真正正确答案应该是实施定义的行为,如果不是,您能否解释一下为什么答案是 7 而不管实施如何?

我阅读了对该问题的评论,最初的类型似乎a是 char,这显然引起了很多关于是否char已签名的投诉,因此测试集将其更改为 int8_t。作为一个额外的问题,是<stdint.h>C++ 的一部分吗?O_O

4

3 回答 3

18

由于不同的原因,我会说它是未定义的(而不是实现定义的)。

从 5.8:3

的值为E1 << E2E1 左移 E2 位位置;空出的位用零填充。如果 E1 具有无符号类型,则结果的值为 E1 × 2 E2 ,比结果类型中可表示的最大值多模一减少。否则,如果 E1 具有带符号类型和非负值,并且 E1 × 2 E2在结果类型中是可表示的,那么这就是结果值;否则,行为是 undefined

于 2013-03-24T10:28:51.687 回答
7

如果实现提供了 optional int8_t,那么答案应该是正确的,来自C++11 引用的关于 stdint的C99 草案;

7.18.1.1 精确宽度整数类型

typedef 名称 intN_t 指定宽度为 N、无填充位和二进制补码表示的有符号整数类型。因此,int8_t 表示宽度正好为 8 位的有符号整数类型。

于 2013-03-24T10:21:11.627 回答
3

既然直接的问题得到了回答,我将回答额外的问题:<stdint.h>是一个 C 头文件,它在 C++ 中可用。但是,请改用现代 C++ 标头<cstdint>

于 2013-03-24T11:34:14.117 回答