有谁知道为什么参数类型为putchar()
, fputc()
and putc()
is char
,但参数类型为putwchar()
, fputwc()
and putwc()
is wchar_t
?另请参见this和this。
2 回答
答案是“遗产”(或“历史”)。在 C90 标准之前,没有函数原型,所有函数的所有参数都受默认提升规则的约束,因此 achar
自动作为 an int
(short
也被提升为int
和float
to 传递double
,对于无符号类型也是如此)。该标准无法破坏现有代码,因此它为这些函数保留了该类型。它在实践中几乎没有什么区别。即使您传递的值超出范围,您传递的值也将被视为字符类型。的规格fputc(int c, FILE *stream)
说:
该
fputc
函数将c
(转换为unsigned char
)指定的字符写入...所指向的输出流中stream
</p>
默认促销规则
§6.5.2.2 函数调用
¶6 如果表示被调用函数的表达式具有不包含原型的类型,则对每个参数执行整数提升,并将浮点类型的参数提升为双精度。这些称为默认参数提升。…</p>
¶7 … 函数原型声明器中的省略号符号导致参数类型转换在最后一个声明的参数之后停止。默认参数提升是在尾随参数上执行的。
整数提升在 §6.3.1 中定义
¶2 可以在表达式中使用
int
或unsigned int
使用以下内容:
- 具有整数类型(除
int
or之外unsigned int
)的对象或表达式,其整数转换等级小于或等于int
and的等级unsigned int
。_Bool
,int
,signed int
或类型的位域unsigned int
。如果 an
int
可以表示原始类型的所有值(受宽度限制,对于位域),则该值将转换为int
; 否则,将其转换为unsigned int
. 这些被称为整数促销。58)整数提升不会改变所有其他类型。¶3整数促销保留价值,包括符号。如前所述,“普通”
char
是否被视为有符号是实现定义的。58)整数提升仅适用于:作为通常算术转换的一部分,适用于某些参数表达式,适用于一元
+
、、-
和~
运算符的操作数,以及移位运算符的两个操作数,由它们各自的子条款指定。
整数等级在 10 个要点的章节 ¶1 中定义。
我认为乔纳森的回答太简单了。事情稍微理性一些。我认为处理单个字符的库函数都不能与char
(仅与int
)一起使用,因为即使其中一些不使用,我们也无法在不收到类型转换警告的情况下EOF
使其类型char
void f(char c) { ...
...
char x = 't';
f((unsigned char)x);
...
warning: conversion to ‘char’ from ‘unsigned char’ may change the sign of the result
(因为人们通常将类型转换为 unsigned char 以确保代码的可移植性,考虑到 的签名是未定义的事实char
。)所以唯一的选择是 make it int
。