首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >K&R中的C函数声明

K&R中的C函数声明
EN

Stack Overflow用户
提问于 2013-08-24 18:23:50
回答 4查看 4.8K关注 0票数 12

我不熟悉K&R风格的函数声明。

下面是带有警告的编译(仅与使用-Wall的main的返回值有关),但是使用的变量的数据类型是什么?

代码语言:javascript
运行
复制
main(a, b, c, d){
    printf("%d", d);
}

foo(a, b){
     a = 2; 
     b = 'z';
}

如果这是一个询问之前,请提供在评论部分的链接。我找不到类似的东西。

编辑

我刚看到一个模糊的C代码,它使用这些。

但我可以向您保证,我不会在C编程中使用这种语法。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-08-24 19:36:53

"K&R C“是指1978年Kernighan &Ritchie的著作”C编程语言“第一版所定义的语言。

在K&R (即前ANSI) C中,实体通常可以在没有显式类型的情况下声明,并且默认为int类型。这可以追溯到C的祖先语言B和BCPL。

代码语言:javascript
运行
复制
main(a,b,c,d){
    printf("%d", d);
}

这几乎相当于:

代码语言:javascript
运行
复制
int main(int a, int b, int c, int d) {
    printf("%d", d);
}

在ANSI C (1989)和ISO C (1990)中,旧语法仍然合法,但过时了,但1999年ISO C标准放弃了“隐式int”规则(同时保留了旧的声明和定义语法)。

请注意,我说过它几乎是等价的。当被看作定义时,本质上是相同的,但作为声明,它不提供参数类型信息。使用旧式定义,不需要诊断带有错误数量或类型的参数的调用;它只是未定义的行为。对于可见的原型,不匹配的参数触发编译时诊断--如果可能,参数被隐式转换为参数类型。

因为这是main的定义,所以还有另一个问题。标准只为main指定两种形式(一种没有参数,另一种有两个参数,argcargv)。实现可能支持其他形式,但是有四个int参数的实现不太可能是其中之一。因此,程序的行为是未定义的。实际上,d很可能在最初的调用中有一些垃圾值。(是的,C中允许递归调用main,但这绝不是一个好主意。)

代码语言:javascript
运行
复制
foo(a,b){
    a = 2;
    b = 'z';
}

这几乎相当于:

代码语言:javascript
运行
复制
int foo(int a, int b) {
    a = 2;
    b = 'z';
}

(请注意,'z'int类型,而不是char类型。)

同样,旧表单不提供参数类型检查,因此调用如下:

代码语言:javascript
运行
复制
foo("wrong type and number of arguments", 1.5, &foo);

不需要被诊断。

底线:很好地知道K&R风格的函数声明和定义是如何工作的。仍然有旧代码使用它们,即使在C2011中(尽管没有“隐式int”规则),它们仍然是合法的(但已经过时了)。但是,编写使用它们的代码几乎没有很好的理由(除非您只能使用一个非常老的编译器,但这很少见,而且越来越少见)。

但我可以向您保证,我不会在C编程中使用这种语法。

太棒了!

票数 21
EN

Stack Overflow用户

发布于 2013-08-25 01:49:21

在K&R风格的函数定义中,参数的类型由函数“签名”本身和实际函数体之间的一组专用声明指定。例如,这个函数定义

代码语言:javascript
运行
复制
void foo(a, b, c)
double a;
char b;
{
  ...
}

使用doublecharint类型的参数。这实际上是“隐式int”规则起作用的位置和方式:由于上面的声明列表没有提到参数c,所以假定它具有int类型。

注意重要的细节,我认为其他答案没有足够清楚地说明这一点:参数c的类型int不是因为函数参数列表中缺少类型,而是因为它没有在函数“签名”之后的声明符序列中提及(在函数主体之前)。在K&R风格的声明中,函数参数列表中总是缺少类型(这是K&R声明的定义特性),但这并不意味着所有参数都被假定为int类型。

请注意,C99仍然支持K&R样式声明,但是由于C99宣布“隐式int”规则为非法,它要求您在函数“签名”之后提及声明列表中的所有函数参数。由于这个原因,上面的示例不会在C99中编译。必须将int c添加到声明列表中。

票数 7
EN

Stack Overflow用户

发布于 2013-08-24 18:27:03

在C89中,默认变量类型是int:它被定义为隐式int。此规则在C99中已被撤销。

在您的示例中,它被编译为:

代码语言:javascript
运行
复制
main(int a,int b,int c,int d){printf("%d", d);}

foo(int a,int b){a=2; b='z';}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18421735

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档