[Powered by Google Translate] 让我们来谈谈结构。 结构为我们提供了一组变量的一种方式进行分组 一个漂亮的包装。 这也可能是最容易看到的一个例子, 所以我们说结构, 然后打开大括号, 此结构中,我们将有一个int的年龄, 一个char *的名字, 就是这样。 它可能看起来怪异的一个大括号后的分号, 但它其实是必要的​​结构。 任何有效的数据类型可以在struct定义。 在这里,我们使用了一个int和一个char *, 但你也可以使用一个数组的说,100个元素 另一个结构。 当你在C的结构, 你创建新的类型 的集合其他类型的。 在这里,我们正在做一个新的类型 从一个整数和一个char *。 正如我们将在后面看到,一个结构类型 是在相当于你使用的任何其他类型的方式有很多。 通常情况下,我会比较结构类型, 是类似于一个整数类型。 虽然我们写的代码是有效的C, 这是非常有用的, 和铛会给我们一个警告。 请记住结构和其相似? 好了,我们基本上只是说: INT, 这是不是一个非常有帮助的行。 因此,让我们声明该类型的变量 给它起名字前的分号。 我们将调用该变量的学生。 现在,我们已经声明了一个变量所谓的学生 由结构所给出的类​​型。 我们怎样才能得到里面的结构变量? 从技术上讲,这些变量的名称为 的成员。 要访问任何特定成员的学生结构, 你追加一个点的变量名, 其次是你想要的成员的名称。 所以在这里,唯一有效的可能性 是student.age student.name。 我们可以做这样的事情 student.age = 12 和student.name学生。 现在,如果我们想进行第二次的学生吗? 你可能会认为复制和粘贴这些行 改变学生到学生2或东西, 将工作, 但在技术上,与学生,学生2 不具有相同的类型。 你看,你将无法将其分配给另一个。 这是因为,到目前为止, 你的结构是匿名的。 我们需要给它一个名字。 要做到这一点,我们插入了名的结构 后字结构。 学生, 其次由定义。 我们仍然可以立即声明一个变量的类型 结构的学生,就像我们之前。 我们把它叫做S1 通过结构的名称, 现在,我们可以使用struct学生 在几乎相同的方式,我们将使用int。 因此,我们可以声明一个变量的类型结构学生, 喜欢 结构学生S2。 像数组,结构提供了一个快捷的初始化语法, 所以我们可以说,结构学生S2 等于 左花括号3,S2。 在这里,S2.age将是3, 和S2.name将指向S2。 把所有的事情你可以做一个int类型的 他们的大多数你可以做与结构学生类型。 作为函数参数的类型,我们可以使用一个struct学生。 我们可以使用一个新的结构的内部结构学生。 我们可以有一个指针,指向一个结构的学生。 我们可以做的结构尺寸学生。 结构学生是一种 就像是int类型。 我们也可以指定S1到S2 因为两者都是相同的类型的,所以我们可以做 S1 = S2。 如果我们这样做,会发生什么事 S1.age = 10? 是否S2的变化呢? 同样,认为就像常规整数的结构。 如果我们给一些int X的一些诠释y, 如X = Y 然后改变X, 作为在X + +中, Ÿ改变呢? Y不改变这里,也没有S2以上。 S2.age仍然是3。 但是请注意,分配一个struct时, 所有的指针指向了同样的事情, 因为他们只是复制。 如果你不想共享的指针, 你需要手动处理, 也许通过一个块内存malicking其中一个指针以指向 以及将数据复制过来。 这可能是恼人的学生到处写结构。 使用类型定义,我们可以做的 类型定义 结构 我们会打电话给学生。 现在,我们可以使用学生无处不在 我们使用使用struct的学生。 这种类型高清的匿名结构 并调用它的学生。 但是,如果我们也能保持学生的标识符 旁边的字结构,typedef结构的学生, 我们可以同时使用的结构学生和学生互换。 他们甚至不必须具有相同的名称。 我们可以鲍勃类型定义结构学生 然后STRUCT学生和Bob 将互换的类型。 不管类型高清 我们需要的标识下,以结构 如果定义的结构 是递归的。 例如, 类型定义结构节点 它被定义为一个int VAL 将有一个指针,指向另一个结构节点。 中节点*下。 然后,我们把它叫做节点。 这个结构是递归的, 自定义的结构节点包含在这 指针的struct节点。 请注意,我们不得不说结构节点下 内的struct节点的定义, 因为类型定义尚未完成,使我们能够简化这一 只是节点。 您将了解更多关于结构与此类似 在处理链表和树。 什么结构的功能呢? 这也是完全有效的。 我们可以有 丧失功能 作为参数, 学生小号 并与学生做一些事情。 然后,我们可以通过它为学生结构像这样。 功能从之前的S1。 该结构的行为 正是因为整数时传递给函数。 功能的S1收到一份 所以不能修改S1; 相反,只有副本中存储的S. 如果你想要的功能可以修改S1, 功能将需要采取一个学生* S, 你必须通过S1的地址,像这样。 学生* S,功能和S1。 还有另外一个原因,通过地址在这里。 如果我们的结构中包含100个字段? 每一次我们给函数传递一个学生, 我们的程序需要所有这100场复制到函数的参数s, 即使它从来没有使用他们的绝大多数。 因此,即使功能并不打算修改学生, 如果仍然是有价值的,通过地址。 好吧,如果我们想创建一个指向结构的指针? 我们可以做这样的事情 学生* S 平等的malloc 大小的学生。 请注意,在这里仍然起作用的大小。 所以,我们现在怎么办访问岁成员 的块的S点到? 首先,你可能会觉得这样做 * S.age = 4, 但是这将不是那么回事。 因为这真的会被解释为 *括号中S.age = 4, 甚至不能编译, 因为S是不是一个结构,或者是一个指向结构的指针, 点不会在这里工作。 我们可以做 (* S)= 4岁。 但括号可以得到恼人的和混乱的。 值得庆幸的是,我们有一个特殊的箭头操作符 看起来像 S-> = 4岁。 这2种方法的引用年龄 是等价的 和我们真的没有以往任何时候都需要的箭头操作符, 但它使事情看起来更漂亮。 由于S是一个指向一些内存块,它包含结构, 你能想到的S>年龄为指针箭头 并抓住时代成员。 那么,为什么我们应该使用结构? 这是绝对有可能只用原始的整数, 字符,指针和等 我们已经习惯了; 代替S1和S2之前, 我们可以有AGE1,平方,NAME1,NAME2 在单独的变量。 这是只有2名学生, 但是,如果我们有10个,其​​中? 什么,如果不是只有2个字段, 学生结构有100个字段? GPA,课程,发色,性别,等等。 10结构,而是我们需要1,000个独立的变量。 另外,还要考虑功能 100个字段,它唯一的参数,采用该结构 并打印出所有的领域。 如果我们不使用结构, 我们每一次调用该函数, 我们需要通过在所有100个变量, 如果我们的学生有100个变量, 学生2 100个变量, 我们需要确保我们不小心从学生的一些变量1 学生和一些变量。 这是不可能犯类似的错误使用结构, 因为所有的100个变量都包含在一个单一封装。 只是一对夫妇的最后的注意事项: 如果你什么都明白了这一点,伟大的。 其余的视频仅仅是为了完整起见。 由于结构可以持有任何类型的指针, 他们还可以保存函数指针。 如果你熟悉面向对象编程, 这提供了一种方法,使用结构程序在一个面向对象的风格。 在其他时间的函数指针。 此外,有时你可能有2结构 其定义依赖于另一个。 例如, 我们可以有结构A, 它被定义为 指针到一个struct B, B * X, 现在,我们可以有一个struct乙 它被定义为一个指针 一个结构A, A * Y. 但是,这不能编译, 因为结构B不存在在结构A正在编制。 如果我们交换结构A和结构B, 然后我们就只是留下了同样的问题; 这个时候,结构中有一个不存在的。 为了解决这个问题,我们可以这样写 结构B; 之前定义的结构A. 这就是所谓的前瞻性声明。 这只是让编译器知道 结构B是一个有效的类型,将完全定义或其他地方。 我的名字是罗布·波顿,这是CS50。 [CS50.TV]