答案 0 :(得分:4)
答案是“遗产”(或“历史”)。在C90标准之前,没有函数原型,所有函数的所有参数都受默认促销规则的约束,因此char
自动传递为int
(short
被提升为{ {1}}也是int
到float
,对于无符号类型也是如此)。该标准无法破坏现有代码,因此它保留了这些函数的类型。它在实践中几乎没有什么区别。即使传递的值超出范围,您传递的值也将被视为字符类型。 double
的规范说:
fputc(int c, FILE *stream)
函数将fputc
指定的字符(转换为c
)写入unsigned char
指向的输出流...
§6.5.2.2函数调用
¶6如果表示被调用函数的表达式具有不包含a的类型 原型,对每个参数执行整数提升,并对其进行参数化 将float类型提升为double。这些被称为默认参数 促销。 ......
¶7...函数原型声明符中的省略号表示法导致 参数类型转换在最后声明的参数后停止。默认参数 促销是在尾随参数上进行的。
整数促销在§6.3.1
中定义¶2如果可以使用
stream
或int
,可以在表达式中使用以下内容:
- 具有整数类型(
unsigned int
或int
除外)的对象或表达式,其整数转换等级小于或等于unsigned int
和int
的等级。- 类型为
unsigned int
,_Bool
,int
或signed int
的位字段。如果
unsigned int
可以表示原始类型的所有值(由宽度限制,对于a 位字段),该值转换为int
;否则,它将转换为int
。这些被称为整数提升。 58)所有其他类型均未被 整数促销。¶3整数提升保留包括符号在内的值。如前所述,是否a 'plain'
unsigned int
被视为已签名的实现定义。58)整数促销仅适用于:通常算术转换的一部分,以确定 参数表达式,一元
char
,+
和-
运算符的操作数,以及两个操作数的操作数 移位运算符,由各自的子条款指定。
整数等级在10个项目符号中的部分的¶1中定义。
答案 1 :(得分: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
获取类型转换警告,如
char
(因为人们通常使用unsigned char进行类型转换以确保代码的可移植性,考虑到int
的签名未定义。)
所以唯一的选择就是notebook
。