在C数组中是不可分配的,为什么这个程序工作?

时间:2017-12-02 21:26:38

标签: c

在C数组中不可分配,但在第36行(我也评论过的行)中,我为数组 name 分配了一个值而没有出现任何错误。为什么会这样?此外,除了这个令人困惑的事情,如果您检查我的 freeStudents 功能是否正常工作,我将非常感激。谢谢你的时间!

#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);
}

1 个答案:

答案 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)是什么类型的?表达式lst[i].name的类型为char[50](50个字符的数组),因此&(lst[i].name)是“50个字符的数组的地址”,在C中称为“指向一个50字符的数组“或C语法char(*)[50]。哪个不是char*。所以这是错误的或更好的未定义行为。

正确的版本应该是什么?好吧,这个:

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

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

好的,但为什么它还能运作? 可能在某些编译器上工作,因为它们只是在两种情况下都传递了数组的地址,因此在堆栈中两者都是相同的数字。

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