为什么我不能只使用这个数组而不指定它的大小?

Why can't I just use this array without specifying its size?

int main()
{
    struct Student_struct {
        char name[40];
        int age;
        float grade;
    };

    struct Student_struct student;

    printf("---------------------Student-----------------------\n\n\n");
    student.name[] = "person";
    student.age = 20;
    student.grade = 7.5;
    
    return 0;
}

我收到以下错误:“]”之前的预期表达式

我知道我可以使用 strcpy(student.name, "person") 或 student.name[6] = "person",但为什么不能将其编码为 student.name[] =“人”?这背后的逻辑是什么?

数组大小已在结构声明中定义。在声明后使用方括号将访问数组中的元素,因此会出错。

尺寸不足不是问题。指定大小无济于事。

问题是您正在尝试分配给一个数组。那是不允许的。您需要使用 strcpy 等。

strcpy(student.name, "person");

在这种特殊情况下,您可以初始化数组而不是分配给它。

struct Student_struct student = {
   .name  = "person",
   .age   = 20,
   .grade = 7.5
};

在 C 中,您不能在 运行 时间内分配整个数组,没有合理的理由,语言就是这样设计的。您只能在初始化期间设置数组中的所有项目。同样,您不能 return 来自函数的数组。

在这种情况下,简单的修复是 strcpy(student.name, "person");

但是,虽然您不能在 运行 时间内分配整个数组,但您可以分配整个结构。这是一个可能的解决方法——通过创建一个临时的 复合文字 结构,我们可以这样做:

student = (struct Student_struct){ .name = "person", .age=20, .grade=7.5 };

我知道我可以使用 strcpy(student.name, "person") 或 student.name[6] = "person"

很好,但是你知道后者不会做你期望的吗?

数组不是 C 中的第一个 class 公民。句号。不能仅仅因为 C 语言不允许,就将数组作为赋值的左成员。

因此,当您使用 student.name[6] 时,这不是一个包含 6 个字符的数组,而只是第 7 个 th 个字符。语言允许的,因为字符是数字类型,指针可以转换为int。

因此 student.name[6] = "person" 首先获取指向垃圾字符串第一个元素的指针 "person" 将其转换 (*) 为整数值(如果指针大于整数,则可能已经实现定义) 然后尝试将其存储到单个 char 中,如果 char 未签名,则调用未定义的行为。 你真的知道吗?


(*) 实际上更糟,因为该语言需要显式转换才能将指针转换为算术值,因此这段代码至少应该发出警告,并且 警告不可忽略。因此,由于它违反了约束,因此代码无效 C。不过,如果要求将此警告视为错误,我所知道的所有常见实现要么停止,要么按照我上面描述的方式继续。

它不起作用仅仅是因为它是无效的语法。如果你想做一个初始化,你可以做这样的事情:

#include <stdio.h>

int
main(void)
{
        struct student {
                char name[40];
                int age;
                float grade;
        };

        struct student student = {
                "person",
                20,
                7.5
        };

        struct student student2 = {
                .name = "person",
                .age = 20,
                .grade = 7.5
        };

        printf("---------------------Student-----------------------\n\n\n");
        printf("%s\n", student.name);

        return 0;
}