2011-12-10 19 views
9
#include <stdio.h> 
void main() { 
    extern int fun(float); 
    int a=fun(3.5); 
    printf("%d",a); 
} 

int fun(aa) 
float aa; 
{ 
    return ((int)aa); 
} 

上記のコードブロックは、Visual Studio 8コンパイラで正常にコンパイルされますが、出力はジャンク値です。次の関数定義はどのように機能しますか?

prog.c:2: warning: return type of ‘main’ is not ‘int’
prog.c:8: error: conflicting types for ‘fun’
prog.c:3: error: previous declaration of ‘fun’ was here

それは、次のプロパティがある場合、それは動作します方法::

  1. は、変数の宣言の前にありますが、私はGCC-4.3.4で同じコードをコンパイルするときしかし、私は次のコンパイルエラーを得ました機能体の始まり。
  2. 関数定義に変数のパラメータ型がありません。
+0

これは、古いC関数宣言です。見てください:http://stackoverflow.com/questions/4581586/old-style-c-function-declaration – phoxis

+1

私はこのQの間違いはありません、なぜこれは閉鎖のために建設的でないと投票されていますか?あなたはQを理解していない場合、それは建設的でないかどうかを判断する能力がないので、そうすることを控える、OPに質問しているQに明確な物質があります。近くの票のどれもがそうであるとは言いません。 –

+1

ここでは@alsに同意しますが、妥当な質問のように思えます。 – Kev

答えて

8

この関数はK & Rスタイルで書かれています。プロトタイプは正しくありません。実際には、他の問題すぎて...

#include <stdio.h> 
void main() { 
    extern int fun(float); 
    int a=fun(3.5); 
    printf("%d",a); 
} 

int fun(aa) 
float aa; 
{ 
    return ((int)aa); 
} 

があるmain()の戻り値の型は、あなたのprint文は改行を含める必要があり、少なくとも標準Cでは、intあります。

機能fun()はプロトタイプで書かれていた場合はあなたのプロトタイプはOKのようになります。

int fun(float aa) { ... } 

しかし、関数はK & Rスタイルで書かれているので、機能がdoubleを渡されることを期待していることをfloatに変換されます:

int fun(double aa_arg) { float aa = aa_arg; ... } 

K & RCでは、すべてのfloat値はdoubleとして渡されました。これがごみを手に入れている理由です。あなたはあなたのコンパイラに(恐らく無意識に)嘘をついています。そしてあなたの上でGIGOを実行することによって、それ自体が戻ってきています。

FWIW:GCC 4.6.1は、コードをコンパイルするのを拒否します(警告設定なしでも)。それは文句:

f1.c: In function ‘main’: 
f1.c:2: warning: return type of ‘main’ is not ‘int’ 
f1.c: At top level: 
f1.c:9: error: conflicting types for ‘fun’ 
f1.c:3: error: previous declaration of ‘fun’ was here 

あなたはさまざまな方法でこの問題を解決することができます

#include <stdio.h> 
int main(void) 
{ 
    extern int fun(float); 
    int a = fun(3.5); 
    printf("%d\n", a); 
    return(0); 
} 

int fun(float aa) 
{ 
    return ((int)aa); 
} 

または:

#include <stdio.h> 
int main(void) 
{ 
    extern int fun(double); 
    int a = fun(3.5); 
    printf("%d\n", a); 
    return(0); 
} 

int fun(double aa) 
{ 
    return ((int)aa); 
} 

または:

#include <stdio.h> 
int main(void) 
{ 
    extern int fun(double); 
    int a = fun(3.5); 
    printf("%d\n", a); 
    return(0); 
} 

int fun(aa) 
double aa; 
{ 
    return ((int)aa); 
} 

または:

#include <stdio.h> 
int main(void) 
{ 
    extern int fun(double); 
    int a = fun(3.5); 
    printf("%d\n", a); 
    return(0); 
} 

int fun(aa) 
float aa; 
{ 
    return ((int)aa); 
} 

または:

#include <stdio.h> 
int main(void) 
{ 
    extern int fun(); 
    int a = fun(3.5); 
    printf("%d\n", a); 
    return(0); 
} 

int fun(aa) 
float aa; 
{ 
    return ((int)aa); 
} 

私はこれらがすべて正しいと(古いスタイル(K & R)関数定義などに文句を言うようにコンパイラを依頼しない限り)それらはすべて警告なしでコンパイルする必要があります信じています。むしろうるさいに設定GCCで

、私は警告を取得:

/usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f2.c -o f2 
f2.c:12: warning: no previous prototype for ‘fun’ 
/usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f3.c -o f3 
f3.c:12: warning: no previous prototype for ‘fun’ 
/usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f4.c -o f4 
f4.c:12: warning: function declaration isn’t a prototype 
f4.c: In function ‘fun’: 
f4.c:13: warning: old-style function definition 
/usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f5.c -o f5 
f5.c:12: warning: function declaration isn’t a prototype 
f5.c: In function ‘fun’: 
f5.c:13: warning: old-style function definition 
/usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f6.c -o f6 
f6.c: In function ‘main’: 
f6.c:5: warning: function declaration isn’t a prototype 
f6.c: At top level: 
f6.c:12: warning: function declaration isn’t a prototype 
f6.c: In function ‘fun’: 
f6.c:13: warning: old-style function definition 
+0

こんにちは、これは私が理解したものです - K&R C doubleとintに昇格されるときに浮動小数点データ型(またはshort、整数ファミリのchar)を受け取る関数を宣言することはできません。これを克服するために、floatをパラメータとして期待できるANSI C標準を使用しています。int fun(float aa私が間違っているなら私を修正してください。ありがとう – ZoomIn

+0

それは基本的に正しい、@Zoominです。 –

5

これは機能定義のK & R styleです。これは標準に準拠していないため、gcc(Ideoneが使用している)のコンパイラエラーです。

Visual Studioでは、デフォルトのコーディングスタイルを変更できるため、Visual Studioで機能します。

関連する問題