87 votes

Alterner C syntaxe pour la déclaration de la fonction des cas d'utilisation

Donc je ne sais pas tout sur C. Ce qui est utile à propos de cette C de la syntaxe?

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

J'ai pu écrire cela dans visual studios 2010beta

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

Je ne comprends pas. Quel est le point de cette syntaxe? je peux écrire

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

La seule chose qu'il semble à spécifier est le nombre de paramètres qu'il utilise et le type de retour. Je suppose que params sans types est un peu fraîche mais pourquoi le permettent et que les int paranName après la touche func decl? Son bizarre.

Aussi est-ce toujours le standard C?

168voto

AndreyT Points 139512

La question que vous vous poser deux questions, pas un seul. La plupart des réponses à ce jour tenté de couvrir la totalité de la chose avec un générique de couverture "c'est K&R style" réponse, alors qu'en fait, seulement une petite partie de cela n'a rien à voir avec ce qui est connu comme le K&R de style (sauf si vous voyez l'ensemble du langage C "K&R-style" d'une manière ou d'une autre :)

La première partie est l'étrange syntaxe utilisée dans la fonction de définition de

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

Celui-ci est en fait un K&R-style de définition de la fonction. D'autres réponses ont couvert ce assez bien. Et il n'y a pas grand-chose, en fait. La syntaxe est obsolète, mais toujours intégralement pris en charge, même en C99 (sauf pour les "non implicite int" la règle en C99, ce qui signifie qu'en C99 vous ne pouvez pas omettre la déclaration d' p2).

La deuxième partie a peu à voir avec le K&R-style. Je me réfère au fait que la fonction peut être appelée avec "échangé" des arguments, c'est à dire pas de paramètre de type de vérification prend place dans un tel appel. Cela a très peu à voir avec le K&R-définition de style en soi, mais il a tout à voir avec votre fonction ayant pas de prototype. Vous voyez, C lorsque vous déclarez une fonction comme ceci

int foo();

il fait déclare une fonction foo qui prend un nombre quelconque de paramètres de type inconnu. Vous pouvez l'appeler comme

foo(2, 3);

et comme

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

sna ainsi de suite (vous voyez l'idée);

Seul l'appel avec les arguments appropriés va "travailler" (ce qui signifie que les autres produisent un comportement indéfini), mais il est entièrement à vous pour s'assurer de son exactitude. Le compilateur n'est pas nécessaire pour diagnostiquer le mauvais, même si celles-il en quelque sorte comme par magie sait le bon paramètre de types et de leur nombre total.

En fait, ce comportement est une fonction de C langue. Un dangereux, mais une caractéristique néanmoins. Il permet de faire quelque chose comme ceci

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]();
}

c'est à dire mélanger différents types de fonction dans un "polymorphe" tableau sans typecasts (variadic des types de fonction ne peut pas être utilisé ici). Encore une fois, dangers inhérents à cette technique sont tout à fait évident (je ne me souviens jamais de l'utiliser, mais je peux imaginer ce que ça peut être utile), mais que du C, après tout.

Enfin, le peu qui relie la deuxième partie de la réponse à la première. Lorsque vous effectuez un K&R-style de définition de la fonction, il n'est pas de présenter un prototype de la fonction. Aussi loin que le type de fonction est concerné, votre func définition déclare func comme

int func();

c'est à dire ni les types pas le nombre total de paramètres est déclarée. Dans votre message vous dites "... il semble à spécifier est le nombre de paramètres qu'il utilise ...". Formellement parlant, il n'est pas! Après vos deux paramètres K&R-style func définition, vous pouvez toujours appeler func comme

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

et il n'y aura pas de violation de contrainte en elle. (Normalement, une qualité compilateur va vous donner un avertissement).

Aussi, parfois négligé le fait est que

int f()
{
  return 0;
}

est également un K&R-style de définition de la fonction qui ne présentent pas un prototype. Pour faire "moderne" que vous auriez à mettre explicite void dans la liste des paramètres

int f(void)
{
  return 0;
}

Enfin, contrairement à une croyance populaire, les deux K&R-style des définitions de fonction et non un prototype de fonction déclarations sont entièrement pris en charge en C99. L'ancien a été abandonné depuis C89/90, si je me souviens bien. C99 exige la fonction doit être déclarée avant la première utilisation, mais la déclaration n'est pas nécessaire d'être un prototype. La confusion apparemment découle de la populaire terminologiques mix-up: beaucoup de gens appellent de toute déclaration de la fonction "prototype", alors qu'en fait, la fonction de "déclaration" n'est pas la même chose que le "prototype".

20voto

Dirk Points 17809

C'est assez vieux K&R C syntaxe (pré-dates de la norme ANSI/ISO C). Aujourd'hui, vous ne devriez pas utiliser plus (comme vous l'avez déjà remarqué son inconvénient majeur: le compilateur ne vérifie pas le type d'arguments pour vous). Le type d'argument fait par défaut est int dans votre exemple.

À l'époque, cette syntaxe est utilisée, on peut parfois trouver des fonctions comme

foo(p, q) 
{
    return q + p;
}

qui était en réalité une définition valable, que les types de foo, p, et q par défaut int.

6voto

unwind Points 181987

C'est tout simplement une ancienne syntaxe, qui date d'avant le "C ANSI" syntaxe peut-être plus familier avec. Il est appelé "K&R C", généralement.

Les compilateurs de soutien pour être complet, et pour être en mesure de gérer les anciennes bases de code, bien sûr.

3voto

Robert Gamble Points 41984

C'est l'original du K&R syntaxe avant de C a été normalisé en 1989. C89 présenté des prototypes de fonction, emprunté à partir de C++, et déconseillé le K&R de la syntaxe. Il n'y a pas de raison de l'utiliser (et beaucoup de raisons de ne pas le faire) dans le nouveau code.

0voto

C'est un style plus ancien des déclarations de fonctions. Veuillez consulter ce lien.

http://stackoverflow.com/questions/22500/what-are-the-major-differences-between-ansi-c-and-kr-c texte du lien

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X