0
#include<stdio.h>
int main(){
 int ret;
 printf("\n main() is called! \n");
 ret = func(1,2);
 printf("\n The ret value is : %d \n",ret);
 return 0;
}
int func(int x,int y){
  printf("\n func() is called! x: %d , y : %d \n",x,y);
  if(x == 1){
    return y+x;
  }
  else{
    return y-x;
  }
}

このプログラムには、main() 内に関数宣言がありません。このプログラムはコンパイル エラーを出していません。なんで ?

4

3 に答える 3

3

Cの昔は、それはやや普通でしたが、暗黙の宣言と呼ばれていました。アイデアは、コンパイラが最初の使用時に関数のプロトタイプを自動的に生成し、たまたま使用しているパラメーターの型を使用して を返すというものintです。

はい、それは聞こえるほど悪い考えです...そのため、最新のコンパイラはこのコードに対して警告を発行します。を使用する場合は、gccコンパイルし-Wallて通常の警告を確認してください。

PS: これがが単に ではなくとしてNULL定義されている理由の 1 つです。((void*)0)0foo(NULL)int foo(void*)int foo(int)

于 2013-06-06T10:20:52.413 に答える
2

関数の戻り値の型はint. まだ宣言されていない関数呼び出しがある場合、戻り値の型はデフォルトintで C 言語になります。あなたの場合、呼び出し func(1,2);、デフォルトはintであり、後で定義された関数も ですint。だからこそ争いがない。

戻り値の型を 以外に変更するintと、エラーが発生します。

たとえば、以下のコードではconflicting-typesエラーが発生します。関数呼び出しは暗黙的にint戻り関数を宣言し、後で元の関数定義の型はfloatです。

このコードは次のエラーを返します。

#include<stdio.h>
int main(){
 float ret;
 printf("\n main() is called! \n");
 ret = func(1,2);
 printf("\n The ret value is : %f \n",ret);
 return 0;
}
float func(int x,int y){
  printf("\n func() is called! x: %d , y : %d \n",x,y);
  if(x == 1){
    return x+y;
  }
  else{
    return y-x;
  }
}

編集:

C言語では、コンパイラの初期段階では、最初に関数呼び出しが見られると暗黙的に宣言され、後の段階で定義が検索されます。そのため、検索が失敗すると、未定義の関数エラーが発生しますが、宣言されていない関数は発生しません。しかし、定義はあるが、タイプが競合している場合、競合するタイプのエラーが発生します...しかし、あなたの場合、デフォルトの宣言と元の宣言が同じであるため、エラーは発生しませんでした。

また、関数が宣言を見ていないとすぐに関数が定義されている場合、コンパイルをすぐに中止する必要がないことに注意する必要があります。最初に宣言にフラグを立てるだけimplicitで、定義がまったくない場合はコードのどこにもありません。次に、をスローしundefined function errorます。

于 2013-06-06T10:21:33.963 に答える