2017-12-02 187 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); 

,因为当你在表达式中使用数组它衰减的指针的第一个元素。

好的,但为什么它工作呢?它可能工作在一些编译器上,因为它们只是在这两种情况下传递数组的地址,所以在堆栈上这两个东西都是相同的数字。

最后,在这个表达式语句中没有“分配”数组,因此事实上这个问题在第一个地方是没有意义的。或者更好的是,函数接收数组的地址并使用指向第一个元素的指针填充它。另一个有趣的是你不能有数组参数的函数。只有指针。

相关问题