关于K&R C第二版42页函数参数类型声明规则的疑问咨询
问题解答
首先明确:K&R原文的结论有一个核心前提——不存在函数原型,这个结论是针对C语言早期的K&R C标准的,C89之后引入函数原型的规范后,直接声明return_type func(char, float);是完全合法的。
1. 无函数原型场景下为什么不能直接声明char/float形参?
K&R C标准中没有函数原型的概念,声明函数时仅需要指定返回值类型,不需要写参数类型,比如示例的lower函数当时的声明就是int lower();。这种场景下调用函数时,编译器会自动执行「默认参数升级规则」:
- 所有整型小类型(char、short)自动升级为int
- 所有单精度浮点类型float自动升级为double
调用方传入的参数实际已经是int/double类型,如果函数定义时把形参写为char/float,就会出现实参、形参类型不匹配的问题,直接触发未定义行为;就算编译器做兼容处理,也需要额外做一次类型截断转换,反而增加了不必要的开销。
2. 效率猜测是否正确?
默认参数升级规则本质是C语言早期的兼容性设计,不是为了效率专门设计的,但在绝大多数处理器架构下,这种设计确实能提升运行效率:
- 处理器的通用寄存器通常和int的字长对齐,char/short类型的值存入寄存器时,本身就需要做符号扩展或零扩展到int长度,直接按int类型传递参数,不需要额外做截断操作,反而减少了类型转换的开销。
- 不存在「参数传递完还要转回char/float」的额外开销:如果形参声明为int,函数逻辑中直接用int类型运算即可,不需要主动转成更小的类型,只有你显式把值赋值给char/float类型变量时,才会做截断操作。
另外补充示例中lower函数用int做形参的另一个重要原因:这类字符处理函数需要兼容EOF输入,EOF是标准库定义的int类型负值,若形参声明为char,当系统的char是无符号类型时,EOF传入后会被截断为255这类正值,永远无法匹配EOF的判断逻辑,会导致功能异常。
内容的提问来源于stack exchange,提问作者Gie dunn
相关产品推荐
相关产品推荐

