C++ 结构体数组

3

最近我需要使用一个学生结构体数组(结构体包含GPA、年龄、姓名和年级等级)。我首先创建了以下数组:

struct Student 
{
    //struct info 
} 


int main()
{
    Student s1, s2, s3, s4, s5;
    Student sArr[5] = {s1, s2, s3, s4, s5};
}

我继续使用循环来填写信息。但是,当我打印时,我使用了特定的结构名称。

cout << s1.age;

我得到了一个荒谬的数字。然后我通过删除s1到s5,简单地像这样打印出数组:

cout << sArr[0].age;

我原以为数组会存储特定的结构体,就像我声明的那些。但是我发现s1.age和sArr[0].age并不相同。这是为什么呢?我以为数组存储了结构体s1,而sArr[0]只是指向结构体s1的引用。


4
数组存储着那些特定结构体的拷贝,但这是毫无意义的,因为这些结构体在进入数组之前都未被初始化。使用简单的 Student sArr[5]; 就能达到同样的效果(除了访问未初始化对象的未定义行为)。 - Igor Tandetnik
2
sArr[0]被初始化为s1的内容。如果你编辑其中任意一个,它不会影响另一个,因为它们的信息没有存储在相同的地址上。 - absoluteAquarian
1
由于您没有展示关于“学生”的任何内容,我们不知道sArr中会有什么。最糟糕的情况是内容是不确定的。如果默认构造函数提供了确定的数据,那太棒了(它可能会,但我们不知道,因为您没有向我们展示任何内容)。从“荒谬的数字”内容的声音来看,它很可能没有,而且您的程序会调用UB。如果是这种情况,您可能需要修复它。 - WhozCraig
你的文章缺失了 "Student sArr[5] = {s1, s2, s3, s4, s5};" 和 "cout << s1.age; cout << sArr[0].age;" 之间的代码,也就是在这段代码中进行了操作。例如: "s1.age = 10;" 它不会改变sArr[0].age的值,因为sArr[0]是s1的一个拷贝(不是指向s1的指针)。 - milesma
1
如果你想从Java背景学习C++,请自己一个忙,忘掉所有关于Java的知识。这种错误在来自Java背景的人中很常见。这种方法在Java中可行,但在C++中不行。C++的对象与Java的完全不同。完全忘记你所知道的关于Java的一切,从C++书的第一页开始学起。 - Sam Varshavchik
显示剩余2条评论
2个回答

2
与Python、C#、Java和JavaScript不同,复制对象是按值而不是按引用进行的。对于没有指针或引用的简单对象,这意味着复制对象(如struct Student)是作为深层复制执行的。
C++编译器为struct Student生成一个复制构造函数,它从s1逐个字段地(递归地)复制到sArr[0]。您可以定义自己的复制构造函数,以定义对象的复制方式。在像您这样的代码中,复制的是对象,而不是引用。
如果您只想复制引用,则在您的示例中必须使用指针。Python、C#和Java引用是比C++指针稍微受限制的实体。这就是为什么在您的解决方案中需要使用指针的原因:
struct Student 
{ 
  //struct info 
};
int main()
{ 
   Student s1, s2, s3, s4, s5;
   Student *sArr[5] = {&s1, &s2, &s3, &s4, &s5}; 
}

当你拥有:

sArr[0]->age=10;

然后更新s1的年龄。


另一种选择是将对象放入数组中,并使用命名引用来访问它们:

struct Student 
{ 
  //struct info 
};
int main()
{ 
   Student sArr[5];
   Student &s1 = sArr[0];
   Student &s2 = sArr[1];
   Etc...
}

Python引用和C++引用的区别在于,C++引用不能被重新赋值,也不能为null。

1
由于您将变量分配到实际上是另一个变量的数组元素中,因此您会得到荒谬的答案,这就像将一个变量属性复制到另一个变量中。这并不意味着引用一个变量会导致我们修改另一个变量。
int a=10,c=12;
int b[2]={a,b};

在这种情况下,改变变量a并不意味着会导致b[0]的改变,反之亦然。因此,解决方法是创建指针数组,每个元素都被设置为接受结构体变量地址的方式,以便对变量或数组元素的更改会反映到另一个变量中。

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