2017-12-02 164 views
-2

在C數組中不可分配,但在第36行(我也註釋過的行)中,我給數組分配了一個值,名稱爲,但沒有得到任何錯誤。這是爲什麼發生?此外,除了這個莫名其妙的事情,如果您檢查我的freeStudents功能是否正常工作,我將非常感激。謝謝你的時間傢伙!在C數組中不可賦值,爲什麼這個程序工作?

#include <stdio.h> 
#include <stdlib.h> 
#define MAX_NAME 50 

struct students 
{ 
    char name[MAX_NAME]; 
    float average; 
}; 

void storeStudents(struct students *lst, int n); 
void printStudents(struct students *lst, int n); 
void freeStudents(struct students *lst); 

int main(void) 
{ 
    int n; 
    printf("How many students you wanna store? "); 
    scanf("%d", &n); 
    struct students *list; 
    list = (struct students *)malloc(n*sizeof(struct students)); 

    storeStudents(list,n); 
    printStudents(list,n); 
    freeStudents(list); 

    return 0; 
} 

void storeStudents(struct students *lst, int n) 
{ 
    int i; 
    for(i=0;i<n;i++) 
    { 
     printf("Name of student: "); 
     scanf("%s", &(lst[i].name)); //In C arrays are not assignable, so why is this line working? 
     printf("Average of student: "); 
     scanf("%f", &(lst[i].average)); 
    } 
    printf("\n"); 
} 

void printStudents(struct students *lst, int n) 
{ 
    int i; 
    for(i=0;i<n;i++) 
    { 
     printf("Name: %s\tAverage: %.2f", lst[i].name, lst[i].average); 
     printf("\n"); 
    } 
} 

void freeStudents(struct students *lst) 
{ 
    free(lst); 
} 
+2

如果啓用編譯器警告,您將看到實際發生了什麼:https://ideone.com/7JPJFH –

+0

Oliver Charlesworth代碼塊編譯器不會給我提供任何警告/錯誤.. –

+0

這是什麼意思?數組不可分配「?數組包含的內容顯然是可變的,因此您可以爲它的一個元素指定一個新值。你在哪裏讀過「數組不可分配」? –

回答

2

在C中,您不能將數組賦值給另一個數組,因爲數組不能在賦值的左側。所以如下:

char a[5] = { 1, 2, 3, 4, 5 }; 
char b[5]; 
b = a; 

是不正確的。但是,當然,這是正確的:

b[0] = a[0]; 
b[1] = a[1]; 
b[2] = a[2]; 
b[3] = a[3]; 
b[4] = a[4]; 

因爲b[0](這是*(b+0))不數組,但一個char

現在到了。在第36行,你做的事:

scanf("%s", &(lst[i].name)); 

解剖,再發表評論:不要使用scanf()用戶輸入。

無論如何,函數是一個變量參數函數,意味着它會高興地接受任何你傳遞的作爲第二個參數。但是你應該傳遞的是一個char*(一個指向char的指針)。爲什麼?因爲設計函數的人決定如此:當格式字符串有%s時,你需要一個char*參數。

什麼類型是&(lst[i].name)?表達式的類型爲char[50](50個字符的數組),所以&(lst[i].name)是「50個字符數組的地址」,其在C中被稱爲「指向50個字符的數組的指針」或C語法char(*)[50]。這不是char*。所以這是錯誤的或更好的未定義的行爲。

正確的版本應該是什麼?那麼,這樣的:

scanf("%s", lst[i].name); 

,因爲當你在表達式中使用數組它衰減的指針的第一個元素。

好的,但爲什麼它工作呢?它可能工作在一些編譯器上,因爲它們只是在這兩種情況下傳遞數組的地址,所以在堆棧上這兩個東西都是相同的數字。

最後,在這個表達式語句中沒有「分配」數組,因此事實上這個問題在第一個地方是沒有意義的。或者更好的是,函數接收數組的地址並使用指向第一個元素的指針填充它。另一個有趣的是你不能有數組參數的函數。只有指針。

相關問題