2012-03-11 216 views
1

我想創建一個結構數組,其中的數組大小由程序中的用戶定義。例如。 P [0],P [1],P [2] .....動態分配結構數組

typedef struct 
{ 
int score; 
}player; 

void main() 
{ 
    int numPlayers; 

    printf ("\nEnter number of players (1 - 4)\n"); 
    scanf ("%d", &numPlayers); 

} 

我試着與兩個

player p[numPlayers]; 

player *p=malloc(numPlayers*sizeof(player)); 

但這樣做兩者都不會編譯。 任何人都可以看到這裏出了什麼問題嗎?

編輯:我正在使用VS2010。 我得到了第一個「表達式必須有一個常數值」,並且「void *」類型的值不能用於初始化第二個類型爲「player *」的實體。

+0

你得到了什麼編譯錯誤? – 2012-03-11 20:45:45

+0

什麼編譯器和編譯器錯誤是什麼? – hmjd 2012-03-11 20:45:51

回答

1

player p[numPlayers];方法調用「可變長度數組」。這是一項在GNU C方言中出現的功能,並且在1999年被採用到C語言中。爲了編譯,您需要一個編譯器,將其識別爲擴展或C99編譯器。可變長度數組有一個缺點:它們通常通過在堆棧上分配內存來實現。沒有辦法檢測是否有足夠的內存。

你有malloc的調用語法是罰款:

player *p=malloc(numPlayers*sizeof(player)); 

但是,如果你想要寫在你的函數這在任何地方,你需要使用一個C99編譯器,或者編譯器接受相互雜糅語句和聲明(比如GNU C在C99之前已經將它作爲C99的擴展並在默認情況下接受它)。在C90中,您必須在函數頂部的聲明塊或聲明中聲明指針: player *p = NULL;。然後,在玩家人數已知之後,分配給它​​。

你應該發佈不能編譯的實際程序。沒有這個,我們只是猜測!

此外,你有一些問題。首先,如果你想要調用malloc,你應該在頭文件<stdlib.h>中聲明malloc。

其次,main應返回類型int而不是void

另外,請檢查返回值scanfscanf功能對交互式輸入不利。例如,如果用戶點擊回車,scanf一直在等待輸入,尋找那些不友好的數字字符。scanf也沒有錯誤檢查%d。如果您輸入的數字不符合int類型,則該行爲僅爲未定義。這種類型的輸入處理僅適用於爲作者自己使用而編寫的快速而骯髒的「一次性」程序。

+0

「...在1991年」?真? 「1999」也許? – 2012-03-11 20:56:48

+0

感謝您的詳細回覆。我確實在scanf之後調用malloc。儘管它仍然無法正常工作,但即使改變了這些情況我將hmjd的代碼放在下面的空白項目中,我仍然遇到我提到的第二個錯誤。 – karoma 2012-03-11 21:29:27

+0

這可能是因爲你實際上是用C++編寫的。在C++中,你不能將'void *'類型的指針賦給'player *'。這不是一種類型安全的轉換。規則在C中放寬了(儘管'void'類型最初來自C++!)。在C++中,你需要像'player * p =(player *)malloc(...)'這樣的演員。你有沒有用'.cpp'後綴保存你的文件?無論如何,如果你在C++中工作,請爲你的問題標記C++。 – Kaz 2012-03-11 22:01:33

1

一種可能是你忘記了#include <stdlib.h>如果沒有它的原型,編譯器會假定malloc返回一個int,它不會轉換爲沒有轉換的指針(但不使用轉換 - 包含正確的頭文件,因此編譯器知道返回類型代替)

編輯:。這是不相關的,但FWIW,main應該返回int,不void

+1

如果碰巧是一個C++編譯器,它會拒絕該程序,因爲該函數未聲明。 – Kaz 2012-03-11 20:56:14

+0

'main'完全相關,因爲編譯器可以拒絕'void main'。你永遠不會知道;這位新手可能已經被老師告知要用'-Werror'來使用gcc。 :) – Kaz 2012-03-11 21:02:20

+1

@Kaz:理論上,是的。根據他的評論,不。 – 2012-03-11 21:04:48