c - printf() 函数如何知道其参数的类型

标签 c gcc printf

考虑以下程序,

#include <stdio.h>
int main()
{
    char a = 130;
    unsigned char b = 130;

    printf("a = %d\nb = %d\n",a,b);
    return 0;
}

该程序将显示以下输出。

a = -126
b = 130

我的问题是 printf() 函数如何知道 a 的类型已签名且 b 的类型未签名以显示结果像上面那样?

最佳答案

printf() 知道类型,这就是为什么您必须提供正确的格式字符串。 printf() 的原型(prototype)如下所示:

int printf(const char * restrict format, ...);

因此,唯一具有已知类型的参数是第一个,格式字符串。

这也意味着在此之后传递的任何参数都受制于默认参数提升——非常简化,将其理解为任何整数将被转换为至少 int——或者向 google 询问这个术语以了解每一个细节;)

在您的示例中,您有实现定义的行为:

char a = 130;

如果您的 char 可以表示 130,那么您将在 printf() 的输出中看到它。将值提升为 int 不会更改该值。您得到的是一个负数,这意味着 130 溢出了您的 char。在 C 中转换期间溢出有符号 整数类型的结果是实现定义,您获得的值可能意味着在您的机器上,char 有 8 位(因此最大值为 127)并且有符号整数溢出导致 环绕 到负值范围。你不能依赖这种行为!

简而言之,在这一行中创建了负数 -- 130int 类型,将其赋值给 char 并进行转换此转换溢出。

一旦您的 char 具有值 -126,将其传递给 printf() 只是将其转换为 int,不改变值(value)。

关于c - printf() 函数如何知道其参数的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51533340/

相关文章:

c - 忽略文件 lib.a,文件是为存档构建的,不是被链接的体系结构 (x86_64)

c++ 如果使用 sprintf 打印的字符多于 char 指针分配的字符,会发生什么情况?

c - 打印并保存.txt

c - C中最严格的类型是什么意思?

c - 从 C 函数返回 FILE 指针时的奇怪行为

c - fscanf 和动态数组分配

c - 如何将 ZeroMQ 套接字集成到 glib 主循环中?

c - 有没有办法从一个项目中获得两个二进制文件?

c++ - C++中sprintf函数的不同输出

gcc - CMake:如何显示编译器的标准输出