2012-09-09 44 views
2

我對C編程非常陌生,我仍然試圖理解使用指針和使用typedef結構的概念。關於C中的結構,下面的代碼是什麼意思?

我有下面這段代碼片斷,我需要在程序中使用:

typedef struct 
{ 
    char* firstName; 
    char* lastName; 
    int id; 
    float mark; 
}* pStudentRecord; 

我不能完全肯定這是什麼一樣 - 對我來說,似乎在Objective-C使用界面相似,但我不認爲是這樣。

後來才知​​道有這條線

pStudentRecord* g_ppRecords; 

基本上,我需要一些基於大量增加pStudentRecordg_ppRecords。我知道如何爲pStudentRecord類型的對象創建和分配內存,但我不確定如何實際添加多個對象到g_ppRecords

+0

如果是功課,請您可以添加標籤'家庭作業'?它不貶義。謝謝 –

+0

我沒有時間給出完整的答案,但是你說你知道Obj-C?結構就像一個Obj-C類定義,除了它只包含數據 - 從來沒有任何方法。它更像是一個NSDictionary而不是Object。 –

+2

typedef所做的一件事是使它更難以處理該類型的對象(因爲結構類型本身沒有名稱 - 只有指向結構的指針)。因此,這種結構類型的局部變量很難,你只能通過使用指針解引用表達式來獲得結構的大小:'pStudentRecord p = malloc(sizeof(* p));'' –

回答

1

結構是一個複合數據類型,這意味着它是一個包含其他變量的變量。你熟悉Objective C,所以你可能認爲它有點像'僅數據'類;也就是沒有方法的類。這是將相關信息存儲在一起的一種方式,您可以將它們作爲一個單元傳遞出去。

Typedef是一種讓您將自己的數據類型命名爲C中內置類型的同義詞的方法。它使代碼更具可讀性並允許編譯器捕獲更多錯誤(您正在有效地教導編譯器更多地瞭解你的程序的意圖。)典型的例子是

typedef int BOOL; 

(有沒有內置BOOL型老年ANSI C.)

這意味着你現在可以做的事情一樣:

BOOL state = 1; 

,並聲明函數採取BOOL參數,然後讓編譯器確保你通過BOOL s,即使他們真的只是int s:

void flipSwitch(BOOL isOn); /* function declaration */ 
... 
int value = 0; 
BOOL boolValue = 1; 
flipSwitch(value); /* Compiler will error here */ 
flipSwitch(boolValue); /* But this is OK */ 

因此,您的typedef正在爲學生記錄結構創建一個同義詞,因此您可以傳遞學生記錄而不必每次都調用它們struct StudentRecord。它使得代碼更清晰,更易讀。除此之外,在這裏還有更多,在你的例子。我剛纔描述的是:

typedef struct { 
    char * firstName; 
    char * lastName; 
    int id; 
    float mark; 
} StudentRecord; 

你現在可以做的事情一樣:

StudentRecord aStudent = { "Angus\n", "Young\n", 1, 4.0 }; 

void writeToParents(StudentRecord student) { 
    ... 
} 

但你已經得到了的typedef後*。這是因爲你想輸入一個數據類型來保存指向StudentRecord的指針,而不是typedef StudentRecord本身。嗯?繼續閱讀...

您需要將此指針指向StudentRecord,因爲如果您想要傳遞StudentRecords並能夠修改其成員變量,則需要傳遞指向它們的指針,而不是變量本身。 typedefs對此很好,因爲再一次,編譯器可以捕獲細微的錯誤。上面我們製作了writeToParents,它只讀取了StudentRecord的內容。說我們想改變他們的成績;我們不能用簡單的StudentRecord參數設置函數,因爲我們不能直接更改成員。因此,我們需要一個指針:

void changeGrade(StudentRecord *student, float newGrade) { 
    student->mark = newGrade; 
} 

不難發現,你可能會錯過*,所以反而,類型定義一個指針類型StudentRecord和編譯器會有所幫助:

typedef struct { /* as above */ } *PStudentRecord; 

現在:

void changeGrade(PStudentRecord student, float newGrade) { 
    student->mark = newGrade; 
} 

這是比較常見的,同時申報兩個:

typedef struct { 
    /* Members */ 
} StudentRecord, *PStudentRecord; 

這給出了普通的struct typedef和一個指針typedef。

什麼是指針?一個變量,用於保存另一個變量的內存中的地址。聽起來很簡單;它的表面,但它變得非常微妙,並且非常迅速地涉及。嘗試this tutorial

+0

哇!這是非常徹底的,謝謝!我仍然很難理解如何添加到* g_ppRecords的「指針數組」。我基本上有一個int值,它需要反映* g_ppRecords中的pStudentRecords的數量。然後我需要添加一個基於當前值的pStudentRecord,就像我在for循環中一樣。我想我知道如何分配足夠的內存,我相信它就像這樣g_ppRecords [num * sizeof(pStudentRecord *)],但是我不知道下一步。 – user1186173

+0

不客氣@ user1186173。至於陣列,這是另一個問題。你想開始閱讀關於在C中的動態數組。你也可以在這裏,也爲類似的問題:http://stackoverflow.com/questions/2024448/c-dynamic-array-of-pointers-to-array -of結構 –

0

這定義了指向結構的指針的名稱,但不是結構本身的名稱。 嘗試改用:

typedef struct 
{ 
    char* firstName; 
    char* lastName; 
    int id; 
    float mark; 
} StudentRecord; 

StudentRecord foo; 
StudentRecord *pfoo = &foo; 
+0

我不允許更改此部分中的原始代碼。所以我不確定我是否可以使用你的建議。 – user1186173

2

限定的指針捲曲護腕內所描述的結構,在這裏是一個簡單的例子

typedef struct { 
    int x; 
    int y; 
}Point,* pPoint; 

int main(void) { 
    Point point = {4,5}; 
    pPoint point_ptr = &point; 
    printf("%d - %d\n",point.x,point_ptr->x); 

    pPoint second_point_ptr = malloc(sizeof(Point)); 
    second_point_ptr->x = 5; 
    free(second_point_ptr); 
} 
2

第一聲明未命名的結構,和一個型pStudentRecord這是一個指向它的指針。第二個聲明g_ppRecords是指向pStudentRecord的指針。換句話說,指向指向結構的指針

將第二個想象成「指針數組」可能更容易。因此,g_ppRecords[0]可能會指向另一個pStudentRecordg_ppRecords[1]。 (這又指向一個記錄結構。)

爲了增加它,你將需要知道它是如何存儲指針的,也就是說如何告訴它有多少指針存儲在它中。其中任一位置都有大小,對於大小N,意味着至少分配了N * sizeof(pStudentRecord*)的內存,並且g_ppRecords[0]g_ppRecords[N-1]包含N項。或者說,它是NULL終止,尺寸爲N,是指內存至少爲(N+1) * sizeof(pStudentRecord*)分配和g_ppRecords[0]通過g_ppRecords[N-1]保持N項目,g_ppRecords[N]持有NULL,標誌着字符串的結尾。

在此之後,創建或添加到g_ppRecords應該很簡單。

相關問題