当前位置:  开发笔记 > 编程语言 > 正文

C函数调用中的默认参数提升

如何解决《C函数调用中的默认参数提升》经验,为你挑选了3个好方法。

Upvoted AProgrammer的答案 - 那些是真货.

对于那些想知道为什么会这样的人:在1988年之前的黑暗时代,经典的"K&R"C中没有函数原型这样的东西,并且默认的论证促销是因为(a)基本上存在的"自由",因为它的成本没有更多的把一个字节在寄存器中,而不是把一个字在寄存器中,和(b)以减少在参数传递的潜在错误.第二个原因从未完全消除它,这就是为什么在ANSI C中引入函数原型是C语言中有史以来最重要的变化.

至于何时启动默认促销:默认参数促销参数的预期类型未知时使用,也就是说当没有原型或参数是可变参数时.



1> AProgrammer..:

具有原型的函数的(非可变参数)参数被转换为相应的类型,可以是char,short,float.

没有原型和可变参数的函数的参数受默认参数提升的约束.

如果使用原型定义函数并在没有原型的情况下使用它,反之亦然,并且它具有char,short或float类型的参数,那么在运行时可能会出现问题.如果提升的类型与读取参数列表时使用的类型不匹配,则可变函数会遇到相同类型的问题.

示例1:使用原型定义函数并在没有原型的情况下使用它时出现问题.

definition.c

void f(char c)
{
   printf("%c", c);
}

use.c

void f();

int main()
{
   f('x');
}

可能会失败,因为将传递一个int并且函数需要一个char.

示例2:定义没有原型的函数并将其与一个原型一起使用时出现问题.

definition.c

void f(c)
   char c;
{
   printf("%c", c);
}

(这种定义很老式)

use.c

void f(char c);

int main()
{
   f('x');
}

可能会失败,因为期望int,但会传递一个char.

注意:您将注意到标准库中的所有功能都具有默认促销产生的类型.因此,在添加原型的过渡期间,它们不会引起问题.



2> Norman Ramse..:

Upvoted AProgrammer的答案 - 那些是真货.

对于那些想知道为什么会这样的人:在1988年之前的黑暗时代,经典的"K&R"C中没有函数原型这样的东西,并且默认的论证促销是因为(a)基本上存在的"自由",因为它的成本没有更多的把一个字节在寄存器中,而不是把一个字在寄存器中,和(b)以减少在参数传递的潜在错误.第二个原因从未完全消除它,这就是为什么在ANSI C中引入函数原型是C语言中有史以来最重要的变化.

至于何时启动默认促销:默认参数促销参数的预期类型未知时使用,也就是说当没有原型或参数是可变参数时.


谢谢你的澄清.回答"为什么"真的有助于我解决这个问题.

3> caf..:

您的困惑源于对术语的轻微误解 - 声明和定义都可以包括原型(或不包括原型):

void func(int a, char b, float c);

这是一个包含原型的函数声明.

void func(int a, char b, float c) { /* ... */ }

这是一个包含原型的函数定义.

"Prototyped"和"non-prototyped"只是函数类型的属性,声明和定义都引入了函数的类型.

所以你可以有一个没有原型的声明:

void func();

或者你可以有一个没有原型的定义(K&R C风格):

void func(a, b, c)
    int a;
    char b;
    float c;
{ /* ... */ }

推荐阅读
小白也坚强_177
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有