在C语言中初始化结构体数组

19
我在初始化结构体数组时遇到了问题。我不确定自己是否做得对,因为我收到了“从不兼容的指针类型进行初始化”和“从不兼容的指针类型进行赋值”的警告。我添加了代码,其中包含我收到这些警告的部分,当我尝试从结构体中打印数据时,我只会得到一些垃圾数据,例如@@###。
typedef struct
{
    char* firstName;
    char* lastName;
    int day;
    int month;
    int year;
} student;

// Initialize array

student** students = malloc(sizeof(student));
int x;
for(x = 0; x < numStudents; x++)
{
    // Here I get: "assignment from incompatible pointer type"
    students[x] = (struct student*)malloc(sizeof(student));
}

int arrayIndex = 0;

// Add struct

// Create student struct

// Here I get: "initialization from incompatible pointer type"
student* newStudent = {"john", "smith", 1, 12, 1983};

// Add it to the array
students[arrayIndex] = newStudent;
arrayIndex++;

2
你的代码似乎处于动态创建一个学生结构体数组和动态创建一个指向学生结构体的指针数组之间,然后动态创建每个指向的学生结构体。很难确定你想要做哪一个,这使得回答变得困难。 - Pete Kirkham
4个回答

31

这是不正确的:

student** students = malloc(sizeof(student));

您不需要一个 **。您需要一个 * 和足够的空间来容纳您需要的学生数量。

student *students = malloc(numStudents * sizeof *students); // or sizeof (student)
for (x = 0; x < numStudents; x++)
{
    students[x].firstName = "John"; /* or malloc and strcpy */
    students[x].lastName = "Smith"; /* or malloc and strcpy */
    students[x].day = 1;
    students[x].month = 12;
    students[x].year = 1983;
}

如果您仍然想在“//添加结构”部分中使用该代码,则需要更改以下行:
student* newStudent = {"john", "smith", 1, 12, 1983};

为了

student newStudent = {"john", "smith", 1, 12, 1983};

你之所以会得到“初始化与不兼容的指针类型”错误,是因为你试图用student类型的对象初始化一个指向student的指针。

1
你肯定是想说 student* students = malloc(numStudents * sizeof(student) ),对吧? - GnP
3
我更喜欢将对象本身用作 sizeof 运算符的参数。对于 struct something *ptr;,将运算符应用于(括号中的)类型 struct something 或对象 *ptr 将产生相同的值。sizeof *ptr == sizeof (struct something) - pmg
谢谢@prng。在意识到sizeof是C语言中的一元运算符而不是函数之前,我对语法感到困惑。 - GnP
为什么我无法使用“students[x]->firstName”访问我的成员变量? - xxks-kkk
@zack:因为“.”用于对象,“->”用于指针。在声明“student *students;”之后,对“students”的每个索引都会产生一个类型为“student”的对象。 - pmg

8

与编译器警告无关,但你最初的malloc是错误的;你需要:

malloc(sizeof(student *)* numStudents)

为了为 'numStudents' 个指向学生的指针分配空间。以下代码行:
students[x] = (struct student*)malloc(sizeof(student));

应该是:

students[x] = (student*)malloc(sizeof(student));

“struct student”并不存在。你已经声明了一个无名结构体,并将其typedef为“student”。与之对比:

struct student
{
    char* firstName;
    char* lastName;
    int day;
    int month;
    int year;

};

这会创建一个名为“struct student”的类型,但在C语言中,您需要明确引用“struct student”,而不仅仅是在其他地方使用“student”。但是,在C++中,这个规则已经改变了,所以您的编译器可能会有些模糊。

至于:

student* newStudent = {"john", "smith", 1, 12, 1983};

这应该是:

student newStudent = {"john", "smith", 1, 12, 1983};

作为花括号语法是直接字面量,而不是需要指向其他地方的东西。
编辑:经过反思,我认为aaa可能比我更全面地考虑了这个问题。你是否不小心在每个地方都使用了额外的指针解引用级别?所以你想要:
student* students = malloc(sizeof(student) * numStudents);

/* no need for this stuff: */
/*int x;
for(x = 0; x < numStudents; x++)
{
    //here I get: "assignment from incompatible pointer type" 
    students[x] = (struct student*)malloc(sizeof(student));
}*/

int arrayIndex = 0;

并且:

student newStudent = {"john", "smith", 1, 12, 1983};

//add it to the array
students[arrayIndex] = newStudent;
arrayIndex++;

如果不在newStudent的范围之外使用数组,则复制字符串指针是不正确的。


2
student* students = malloc(sizeof(student)*numStudents);
int x;
for(x = 0; x < numStudents; x++)
{
    student newStudent = {"john", "smith", 1, 12, 1983}; // string copy are wrong still
    students[x] = newStudent;
}

-1

初始化时,应该不是这样吗?

student** students = (struct student**)malloc(sizeof(student*)*numStudents);

然而,为什么要使用指向指针的指针呢?我认为只用一个指向结构体的指针就足够了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接