C 为什么可以将另一种类型的参数传递给函数?

C 为什么可以将另一种类型的参数传递给函数?,c,function,C,Function,考虑以下代码: void function (char arg) { // function's content } int main(void) { long double x = 1.23456; function(x); } 我给函数一个它不应该得到的参数。为什么它不会导致错误?在您的示例中,double类型被隐式转换为char类型被隐式转换 在赋值、参数传递、返回语句和其他一些语句的上下文中,如果目标类型也是算术类型,则任何算术类型的表达式都会隐式转换为目标

考虑以下代码:

void function (char arg)
{
    // function's content
}

int main(void)
{
    long double x = 1.23456;

    function(x);
}

我给函数一个它不应该得到的参数。为什么它不会导致错误?

在您的示例中,
double
类型被隐式转换为
char
类型被隐式转换

在赋值、参数传递、返回语句和其他一些语句的上下文中,如果目标类型也是算术类型,则任何算术类型的表达式都会隐式转换为目标类型。在本例中,
double
参数隐式转换为
char
。(这种特殊的转换很少有意义,但就语言而言是有效的。)

请注意,这种隐式转换不是针对可变参数(例如格式字符串后面的
print
)进行的,因为编译器不知道目标类型是什么
printf(“%d\n”,1.5)
不会将
1.5
double
转换为
int
;相反,它有未定义的行为

还有一些使用不同类型的运算符计算表达式的规则。我不会在这里详述所有细节,但举个例子:

int n = 42;
double x = 123.4;

如果您写入
n+x
n
的值将在执行加法之前从
int
提升(隐式转换)为
double

@shanereley您说的是“在您的示例中”。还有其他选择吗?有很多数据类型可以从一种类型隐式转换为另一种类型。例如,使用
函数(char*arg)
并试图向其传递
double
。编译器可能会发出警告,例如从'long double'转换为'char',可能会丢失数据。@WeatherVane如果没有,我尝试了两种不同的编译器。您可以(而且应该)使用增加警告级别,这是来自MSVC。在gcc
-Wall
中。您使用的编译器是什么?命令行上提供了哪些选项?@MichaelBurr一个来自repl.it IDE(我认为不可能在那里操作编译器),另一个是mingw-w64(所有参数默认设置)谢谢,然而,我已经听说过在处理不同类型的值时进行类型转换。还有一个问题,在不进行类型转换的情况下传递其他类型的参数是否安全/有资格,并将此工作转换为隐式转换?@EricPostFischil谢谢,修复了。@Kaiyaha为了澄清术语,C不使用“类型转换”这个词。转换采用某种类型的值并生成(不同)类型的值。强制转换是一种显式转换,由一个由括号中的类型名组成的强制转换运算符表示。有隐式转换。没有隐式强制转换。@Kaiyaha隐式完成的转换通常是相当安全的,只要源值可以在目标类型中表示。在某些情况下,您可能会失去精度或出现错误(根据类型,结果会有所不同)。例如,如果函数需要一个
int
参数,则传递它
6.02e23
将隐式转换为
int
,溢出将导致未定义的行为。(所以不要这么做。)我不得不说,在写了将近30年的C之后,我很少看到C语言中让我惊讶的东西;但这让我大吃一惊。我很惊讶,
gcc
通过了这个问题的构造,即使是
-Wall
。我需要明确地添加
-Wconversion
来检测它。我将来会这样做。太神了