2010-10-12 64 views
2
#include <stdio.h> 

int *top; 
int a=1; 
top=&a; 

void main() 
{ 
    printf("%d\n",*top); 
} 
 
error C2440: 'initializing' : cannot convert from 'int *' to 'int' 

UPDATE爲什麼下面這段代碼失敗

我知道如何使它工作,但我問爲什麼這是行不通的。

+1

除非你實現定義'main'爲返回'void'的一個擴展標準,可以調用未定義行爲與此程序。任何事情都可能發生:快樂的代碼失敗,你必須問這個:) – pmg 2010-10-12 17:09:52

回答

6

實際上,你正在跳過編譯器對古代C語法的支持。原始的C編譯器允許沒有類型的聲明,默認爲int。因此,任何功能之外,

foo; 

將宣佈一個全局變量int稱爲foo。所以,當你說

top = &a; 

它聲明瞭一個全局int變量稱爲top,並試圖用a地址進行初始化。這給你兩個你看到的錯誤 - 兩個衝突的聲明top和無法將int *轉換爲int。當然,那些相同的古代C編譯器不會給你第二個錯誤,愉快地將地址轉換爲int而不會抱怨。

這也告訴你爲什麼int i; i = 100;作品---它的兩個聲明爲i作爲全球int變量這是確定的(這是確定的,因爲它們是同一類型),第二個它初始化100(只有一個聲明有一個初始化)

有很多有趣的東西,在丹尼斯·裏奇的The Development of the C Language

+0

Chris Dodd有什麼好的時機。 :) – birryree 2010-10-12 03:41:22

1

這工作:

#include <stdio.h> 

int *top; 
int a=1; 
int main() 
{ 
    top=&a; 
    printf("%d\n",*top); 
} 

您需要確保不會做這樣的全球分配。你只能做初始化,沒有別的全局變量。

您也沒有提及其他錯誤,請提及所有錯誤,有時一個錯誤是基於另一錯誤,當一個錯誤被修復時,其他錯誤得到修復。在這種情況下,它是:

'頂部'的衝突類型。

4

我對你得到的確切的錯誤信息有點驚訝,但問題(或者至少有一個明顯的問題)是在函數之外,你可以定義和初始化變量,但你是而不是允許做一個正常的分配 - 這必須作爲執行功能的一部分來完成。因此,您的top=&a;是不允許的。

另一個問題是,你有main返回void,它應該返回int(雖然大多數編譯器會接受,甚至沒有警告,更不用說錯誤消息)。

+0

+1,編譯器肯定有一些相當古怪的錯誤。 'clang'和'gcc'不會給這個問題提供非常準確的錯誤。 – birryree 2010-10-12 03:11:36

+0

爲什麼不能'top =&a; '被視爲初始化'頂部'? – justnobody 2010-10-12 03:16:45

+0

爲什麼這樣工作:'int i; i = 100;''main'外'' – justnobody 2010-10-12 03:18:11

0

老實說,我不知道爲什麼失敗了,但這個工程:

#include <stdio.h> 

int a = 1; 
int* top = &a; 

void main() 
{ 
    printf("%d\n", *top); 
} 

請記住:總是初始化POINTERS! 如果你不打算立即指派他們,至少做這樣的事情:

int* top = 0; 
0

另一種選擇:

#include <stdio.h> 

int a=1; 
int *top=&a; 

void main() 
{ 
    printf("%d\n",*top); 
} 
3

其實,從您的原始代碼:

int *top; 
int a=1; 
top=&a; 

正如其他人所說 - 在全球空間中,您可以聲明或聲明並初始化。你不能做任務。

top = &a;這一行實際發生的是您實際上重新聲明瞭名爲top的變量,並且它默認爲int類型。編譯器應該實際發出警告,要創建一個名稱爲top的新變量,該變量與以前聲明的變量具有相同的名稱,並生成一個額外的警告,表明您正在創建一個默認類型變量int

在C中,聲明爲不帶類型的變量默認爲int,並且會產生您看到的錯誤。

錯誤C2440:初始化:不能從「詮釋*」轉換爲「廉政」

什麼,這是真正的抱怨是,top = &a;在你的代碼實際上看起來像int top = &a;編譯器,所以你試圖綁定一個int*int