另类(K&安培; R)的函数声明与原型C语法 [英] Alternative (K&R) C syntax for function declaration versus prototypes

查看:369
本文介绍了另类(K&安培; R)的函数声明与原型C语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是这个有用 C 语法 - 使用K&安培; R'?风格函数声明

What is useful about this C syntax — using 'K&R' style function declarations?

int func (p, p2)
    void *p;
    int  p2;
{
    return 0;
}

我能够在视觉工作室2010beta写这个

I was able to write this in Visual Studios 2010beta

//yes the params are flipped
void f()
{
    void *v=0;
    func(5,v);
}

我不明白。这是什么语法点?我可以这样写:

I don't understand. What's the point of this syntax? I can write:

int func (p, p2)
    int  p2;
{
    return 0;
}
//and write
int func (p, p2)
{
    return 0;
}

好像指定的唯一的事情就是有多少参数使用和返回类型。我想没有类型的参数是挺酷的,但为什么允许它与函数声明 INT paranName 后?这很奇怪。

也就是这仍然标准C?

推荐答案

你问这个问题实际上是两个问题,一个也没有。大多数答复到目前为止试图掩盖整个事情有一个通用的毯子这是K&安培; R风格的答案,而实际上只有一小部分有什么做什么被称为K&安培; R风格的(除非你看整个C语言K&安培; R风格,在这样或那样:)

The question you are asking is really two questions, not one. Most replies so far tried to cover the entire thing with a generic blanket "this is K&R style" answer, while in fact only a small part of it has anything to do with what is known as K&R style (unless you see the entire C language as "K&R-style" in one way or another :)

第一部分是在函数中使用奇怪的语法的定义

The first part is the strange syntax used in function definition

int func(p, p2)
void *p;
int  p2; /* <- optional in C89/90, but not in C99 */
{
  return 0;
}

这一块其实一个K&安培; R风格的函数定义。其他答案报道了这pretty好。而且也没有太多的话,其实。语法去precated,但仍完全C99甚至支持(除了C99不隐式int的规则,这意味着C99不能省略 P2 )。

This one is actually a K&R-style function definition. Other answer have covered this pretty well. And there's not much to it, actually. The syntax is deprecated, but still fully supported even in C99 (except for "no implicit int" rule in C99, meaning that in C99 you can't omit the declaration of p2).

第二部分有一点做与K&安培; R风格。我指的是事实,即功能可以与交换参数被调用,即没有参数类型检查发生在这样一个呼叫。这有很少做与K&安培; R风格的定义本身,而是它的一切做有没有原型的功能。你看,在C在声明这样的功能

The second part has little to do with K&R-style. I refer to the fact that the function can be called with "swapped" arguments, i.e. no parameter type checking takes place in such a call. This has very little to do with K&R-style definition per se, but it has everything to do with your function having no prototype. You see, in C when you declare a function like this

int foo();

它实际上声明了一个函数这需要的的未知类型参数的数目不详的。你可以把它作为

it actually declares a function foo that takes an unspecified number of parameters of unknown type. You can call it as

foo(2, 3);

j = foo(p, -3, "hello world");

ANS等(你的想法);

ans so on (you get the idea);

只有具备适当的参数调用会工作(意思是别人产生不确定的行为),但它完全是由你来确保其正确性。不需要编译器来诊断不正确的那些,即使它以某种方式神奇知道正确的参数类型和它们的总数量。

Only the call with proper arguments will "work" (meaning that the others produce undefined behavior), but it is entirely up to you to ensure its correctness. The compiler is not required to diagnose the incorrect ones even if it somehow magically knows the correct parameter types and their total number.

其实,这种行为是C语言的功能的。一个危险的,但尽管如此功能。它允许你做这样的事情。

Actually, this behavior is a feature of C language. A dangerous one, but a feature nevertheless. It allows you to do something like this

void foo(int i);
void bar(char *a, double b);
void baz(void);

int main()
{
  void (*fn[])() = { foo, bar, baz };
  fn[0](5);
  fn[1]("abc", 1.0);
  fn[2]();
}

即。在没有任何类型转换一个多态阵列混合使用不同的函数类型(可变参数函数类型不能这里虽然使用)。同样,这种技术的固有的危险是相当明显的(我不记得曾经使用它,但我可以想象它可以是有用的),但毕竟这是℃。

i.e. mix different function types in a "polymorphic" array without any typecasts (variadic function types can't be used here though). Again, inherent dangers of this technique are quite obvious (I don't remember ever using it, but I can imagine where it can be useful), but that's C after all.

最后,链接的答案为第一的第二部分的比特。当你犯了一个K&安培; R风格的函数定义,它不引入该功能的原型。至于功能类型而言,你的 FUNC 定义声明 FUNC

Finally, the bit that links the second part of the answer to the first. When you make a K&R-style function definition, it doesn't introduce a prototype for the function. As far as function type is concerned, your func definition declares func as

int func();

即。既不类型不是参数的总数被声明。在你原来的职位,你说:......这似乎是指定有多少PARAMS使用......。从形式上来讲,它不!之后你的两个参数K&安培; R风格的 FUNC 定义,你仍然可以调用 FUNC

i.e. neither the types not the total number of parameters is declared. In your original post you say "... it seems to specify is how many params it uses ...". Formally speaking, it doesn't! After your two-parameter K&R-style func definition you still can call func as

func(1, 2, 3, 4, "Hi!");

和不会有任何约束违反在它。 (正常情况下,优质的编译器会给你一个警告)。

and there won't be any constraint violation in it. (Normally, a quality compiler will give you a warning).

另外,有时会被忽略的事实是,

Also, a sometimes overlooked fact is that

int f()
{
  return 0;
}

也是K&安培; R风格的函数定义并不引入的原型。为了使现代你必须把明确的无效在参数列表

int f(void)
{
  return 0;
}

最后,相反到普遍的信仰,无论是K&安培; R风格定义和非原型函数声明完全支持C99。前者已自C89 / 90 pcated德$ P $,如果我没有记错。 C99需要在第一次使用前声明功能,而且是一个原型的声明不是必需的。混乱显然是从流行的术语混淆梗:很多人所说的任何函数声明原型,而实际上函数声明不是一回事原型

Finally, contrary to a popular belief, both K&R-style function definitions and non-prototyped function declarations are fully supported in C99. The former has been deprecated since C89/90, if I remember correctly. C99 requires the function to be declared before the first use, but the declaration is not required to be a prototype. The confusion apparently stems from the popular terminological mix-up: many people call any function declaration "a prototype", while in fact "function declaration" is not the same thing as "prototype".

这篇关于另类(K&安培; R)的函数声明与原型C语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆