【问题标题】:C++ struct arraysC++ 结构数组
【发布时间】:2018-09-03 00:40:48
【问题描述】:

我最近不得不为学生使用一组结构(结构有 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 的引用。

【问题讨论】:

  • Array 存储这些特定结构的副本。这是没有意义的,因为这些结构是未初始化的。普通的旧Student sArr[5]; 会产生相同的效果(嗯,没有访问未初始化对象的未定义行为)。
  • sArr[0] 被初始化为s1 的内容。如果您编辑其中一个,则不会影响另一个,因为它们的信息不会存储在相同的地址中
  • 由于您没有展示任何关于 Student 的信息,我们不知道 sArr 中会包含什么。最坏的情况是内容不确定。如果Student 的默认构造提供了确定的数据,那就太好了(它可能,但我们不知道,因为你没有向我们展示任何有关它的信息)。根据您对“荒谬数字”内容的惊讶的声音,它可能不会,并且您的程序调用了 UB。如果是这样的话,你可能想解决这个问题。
  • 你一定在“Student sArr[5] = {s1, s2, s3, s4, s5};”之后做了什么在“cout
  • 如果您正在尝试学习具有 Java 背景的 C++,请帮自己一个忙,忘记所有关于 Java 的知识。对于具有 Java 背景的人来说,这种错误很常见。这种方法适用于 Java,但不适用于 C++。 C++ 的对象的工作方式与它们在 Java 中的工作方式完全不同。完全忘记你对 Java 的了解,从 C++ 书籍的第 1 页开始。

标签: c++ arrays struct


【解决方案1】:

与 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++ 引用不能重新赋值,也不能为空。

【讨论】:

    【解决方案2】:

    您得到了荒谬的答案,因为您将一个变量分配给实际上是另一个变量的数组元素,所以这就像将一个变量属性复制到另一个变量中。这并不意味着引用一个变量会导致我们修改成另一个变量。

    int a=10,c=12;
    int b[2]={a,b};
    

    在这种情况下,这并不意味着变量 a 的变化会导致我们 b[0] 的变化,反之亦然。 所以这样做的方法是创建指针数组,其每个元素都接受结构变量的地址,以便变量或数组元素的变化将改变的值反映到另一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多