Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中的无符号int的行为为负_C_Printf_Undefined Behavior - Fatal编程技术网

C中的无符号int的行为为负

C中的无符号int的行为为负,c,printf,undefined-behavior,C,Printf,Undefined Behavior,我不明白为什么对于下面的代码,无符号int的输出是负数。 就像一个带符号的int uint32_t yyy=1<<31; printf("%d\n",yyy); uint32\u t yyy=1这是因为printf参数%d隐式地将数字转换为整数 改用%u。使用%u输出无符号数字: printf("%u\n", yyy); 您需要使用无符号int格式说明符: printf("%u\n",yyy); ^^ 为printf使用错误的格式说明符是未定义的行为,C

我不明白为什么对于下面的代码,无符号int的输出是负数。 就像一个带符号的int

  uint32_t yyy=1<<31;
  printf("%d\n",yyy);

uint32\u t yyy=1这是因为printf参数%d隐式地将数字转换为整数


改用%u。

使用
%u
输出无符号数字:

printf("%u\n", yyy);

您需要使用
无符号int
格式说明符:

printf("%u\n",yyy);
        ^^
printf
使用错误的格式说明符是未定义的行为,C99标准草案部分
7.19.6.1
涵盖了这一点。fprintf函数也涵盖了格式说明符方面的
printf

如果转换规范无效,则行为无效 未定义。248)如果任何参数的类型不正确 对应的转换规范,行为未定义


printf
的页面有一个很好的表格,指定可用的格式说明符。

%d
的格式说明符要求的是
int
,而不是
无符号int
,因此代码具有未定义的行为。根据C99标准第7.19.6.1节的fprintf功能:

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

对无符号整数使用
%u

uint32_t yyy=1u<<31;
printf("%u\n",yyy);

uint32\u t yyy=1u因为您正在将其作为签名打印。使用
%u

正如许多人所说,使用
%u
标识符

原因是,
printf
无法判断任何额外参数的类型(它们作为
va_列表
给出),因此程序员必须使用格式字符串提供该信息。然后,当您提供
%d
时,
printf
将调用:

int val;
val = va_arg(va_list, int);

并隐式地将unsigned int转换为signed。

printf
接受数量可变的参数。当您调用它时,编译器会尽职尽责地将它们全部放在堆栈上。因为它是C,所以没有反射-
printf
无法推断它收到的东西的类型。在位级别上,您无法初步区分有符号整数、无符号整数或浮点、适当小的结构、较大结构的一部分等

这就是为什么还必须提供格式字符串。它告诉
printf
从堆栈中读取的类型以及顺序。它完全依赖于该格式字符串,无法验证它

因此,根据已经发布的单行答案,如果您告诉它将字段解释为有符号的数量,那么它将被打印为有符号的数量。

整数以格式存储。这意味着仅仅通过查看值无法判断数字是有符号的还是无符号的。您必须告诉机器您希望它使用的表示形式,并自己跟踪它


在您的示例中,您告诉机器,
jjj
未签名(用于类型检查),然后要求
printf()
将其视为已签名,方法是在格式字符串中使用
%d
(无法获取类型信息)。如果要打印未签名的int,请改用
%u

尝试
printf(“%u\n”,yyy)
即使在调用
printf
之前,如果
int
在您的C实现中有32位,则此代码具有未定义的行为。
1I的值见。感谢您的回答~出于可移植性考虑,您可以使用以下内容打印uint32_t(可能比未签名的更大):'printf(“%”PRIu32“\n”,yyy);'
int val;
val = va_arg(va_list, int);