2013-12-19 199 views
4

我只是想了解這個C代碼(不是試圖通過該程序實現任何功能目標)。這個編譯使用gcc。 這是主要在 main(int a,char * argv []) 格式?是否允許在參數和函數體之間聲明任何內容(類似於char * a;這裏)?程序爲什麼編譯?

#include <stdio.h> 
main(u,_,a) 
    char 
    *a; 
{ 
    //printf("%s\n",_,a);//just to help debugging 
    //printf("%d\n",u); //just to help debugging 
} 
+1

看起來像一個預C89風格的函數。 – chux

+1

要添加一個不值得回答的有趣事實:在編寫16位可引導程序時,我不得不使用這種類型的函數聲明。 gcc不能編譯爲16位,所以我必須使用不支持ANSI的bcc(Bruce's C編譯器)。所以你可能會在一些領域碰到這種東西! – Guido

回答

4

這是編寫C函數的一個老的,過時的方式(在形式name=value字符串)。

在C的祖先的語言,沒有類型:所有變量包含在機器字。因此,在函數定義應該像這樣開頭:

main(u, _, a) { 
    /* ... some code ... */ 
} 

C as it used to be,被稱爲「K & RC」從seminal book about C(布賴恩Kernighan和丹尼斯·裏奇)加入,看起來像變量聲明表單類型的作家,和介於函數參數列表和函數代碼之間。

int main(u, _, a) 
    int u; 
    int _; 
    char *a; 
{ 
    /* ... some code ... */ 
} 

輸入K & R C,如果類型爲int,然後在很多地方它能夠被省略。對於函數參數,可以完全省略類型聲明行。

int main(u, _, a) 
    char *a; 
{ 
    /* ... some code ... */ 
} 

ANSI C被標準化於1989年,其主要創新之一是函數原型。在適當的ANSI C中,在使用之前聲明所有函數,並聲明所有參數的類型。

int main(int u, int _, char *a) 
{ 
    /* ... some code ... */ 
} 

C編譯器仍然支持傳統代碼的舊錶單。 (如果他們符合1989 C標準,他們必須)。20多年後遺留的代碼並不多,所以你不會經常找到這樣的代碼。

(請注意,這不是main正確的類型。我覺得GCC將警告你,但你可能要打開警告設置的。)

-1

這是main聲明的無效形式。這在C99/C11中是無效的,但在C90中也是無效的。 (有關C90中main函數的有效聲明,請參閱5.1.2.2.1)。

+0

因此,「爲什麼還要編譯」的答案是「因爲GCC過度寬容」。 – 2013-12-19 23:50:42

+0

@ H2CO3像往常一樣 – ouah

+0

雖然技術上是真的,但這是非常無益的,並沒有回答爲什麼編譯器會接受這種無效代碼的問題。 – Gilles

3

這是一個古老的聲明,沒人用了,除了混淆(參見:三合!)。我認爲在新的C標準下它是非法的,但gcc仍然支持它以實現向後兼容。

它的工作方式是類型作用下上市,並返回類型都不放過。沒有返回類型表示它默認爲int。典型的主要功能可以這樣寫:

main(argc, argv) 
    int argc; 
    char** argv; 
{ 
    printf("%d\n", argc); 
    return 0; 
} 

您不能在開始大括號之前聲明其他變量。嘗試添加int c;和得到這個錯誤:

參數列表和函數體之間
test.c:4: error: declaration for parameter ‘c’ but no such parameter 
4

聲明是所謂叫做K & R C(C的第一個版本)的一部分。所以是的,它們是有效的,如果你的編譯器能編譯K & R代碼。有

關於main()兩個以上的參數......是的,其實,主要最多可以有三個參數:

int main (int argc, char *argv[], char *envp[]); 

的第三個參數是指向字符串數組,包含它們中的每一個一環境變量定義