我是学习C编程语言的新手,这个问题让我感到困惑,因为我认为编译器会出错。
假设在定义/原型发生之前调用了一个函数,关于其参数,以下哪一个是假的?
一个。所有char类型都转换为int类型。
B中。所有短类型都转换为int类型。
℃。所有浮点类型都转换为double类型。
d。除char,short和float之外的所有类型都不会改变。
电子。每个参数都转换为其相应形式参数的类型。
答案 0 :(得分:4)
如果你在C89或C90中有一个函数调用(同样的东西;一个是ANSI C,另一个是ISO C),那么:
int
。char
(以及signed char
和unsigned char
)和short
(和unsigned short
)会转换为int
(或者,例外情况下, unsigned int
如果是unsigned short
和sizeof(unsigned short) == sizeof(unsigned int)
),则float
会转换为double
。printf()
或scanf()
。所以,答案是E。
标准(当前版本,ISO / IEC 9899:2011)说:
6.5.2.2函数调用
¶6如果表示被调用函数的表达式具有不包含a的类型 原型,对每个参数执行整数提升,并对其进行参数化 类型
float
被提升为双倍。这些被称为默认参数 促销活动。如果参数的数量不等于参数的数量,则 行为未定义。如果使用包含原型的类型定义函数,并且 原型以省略号(, ...
)或后面的参数类型结束 促销与参数类型不兼容,行为未定义。 如果使用不包含原型的类型定义函数,则使用类型 促销后的参数与之后的参数不兼容 促销,行为未定义,但以下情况除外:
一个提升类型是有符号整数类型,另一个提升类型是 相应的无符号整数类型,该值可在两种类型中表示;
这两种类型都是指向字符类型的限定或非限定版本的指针
void
。
请注意,将其“错误”导致未定义的行为,并且应该不惜一切代价避免未定义的行为。该程序可以执行任何操作 - 包括擦除计算机上的所有文件 - 并且根据标准可以接受。实际上,程序很少这样做(甚至更少导致'恶魔飞出你的鼻子',导致'鼻子恶魔'这个词(搜索它),但面对未定义的行为,这也是可以接受的)。
如果可能的话,你应该把它作为一个你永远不会在没有原型范围的情况下调用函数的策略。所有新代码都应符合该标准;如果你不幸不得不维护那些没有的古代代码,那么你可能不得不顺其自然,但我们的目标是通过-Wmissing-prototypes -Wstrict-prototypes -Wold-style-declaration -Wold-style-definition -Werror
等选项来编译所有代码。 。这些是GCC选项,报告函数原型和函数定义的问题。
答案 1 :(得分:0)
看看在
进行函数调用时会发生什么的 1。编译器在调用之前遇到了一个原型:
每个参数的值隐式转换为相应参数的类型,就像通过赋值一样。
的 2。编译器在调用之前没有遇到原型:
编译器将执行默认参数提升 :( 1)float
参数转换为double
。 (2)执行整体促销,导致char
和short
参数转换为int
(在C99中,执行整数提升)。
所以答案是
电子。每个参数都转换为其对应形式参数的类型。
但请记住依赖默认促销是危险的。考虑这个例子:
#include <stdio.h>
int main(void)
{
double x = 3.0;
printf("Square: %d\n", square(x));
return 0;
}
int square(int n)
{
return n*n;
}
在调用square
时,编译器还没有看到原型,因此它不知道square需要类型为int
的参数。相反,编译器在x
上执行默认参数提升,但不起作用。由于它期望类型为int
的参数但已被赋予double
值,因此调用square
的效果为未定义。
答案 2 :(得分:0)
谢谢大家! 我找到了答案。
+所有子整数(char和short)都转换为int或unsigned类型。
+所有类型的float都转换为double类型。
+所有其他类型都没有改变。
所以,答案是答案。
感谢道义上的支持!