结构是一种复合数据类型,这意味着它是一个包含其他变量的变量。您熟悉 Objective C,因此您可能会认为它有点像“仅数据”类;也就是说,一个没有方法的类。这是一种将相关信息存储在一起的方法,您可以将这些信息作为一个单元传递。
Typedef 是一种让您将自己的数据类型命名为 C 中内置类型的同义词的方法。它使代码更具可读性并允许编译器捕获更多错误(您实际上是在向编译器教授更多关于程序意图的信息。 ) 经典的例子是
typedef int BOOL;
(旧的 ANSI C 中没有内置的 BOOL 类型。)
这意味着您现在可以执行以下操作:
BOOL state = 1;
并声明带BOOL
参数的函数,然后让编译器确保您传递BOOL
s,即使它们实际上只是int
s:
void flipSwitch(BOOL isOn); /* function declaration */
...
int value = 0;
BOOL boolValue = 1;
flipSwitch(value); /* Compiler will error here */
flipSwitch(boolValue); /* But this is OK */
因此,您上面的 typedef 正在为学生记录结构创建同义词,因此您可以传递学生记录,而不必struct StudentRecord
每次都调用它们。它使代码更清晰、更易读。除了这里还有更多,在你的例子中。我刚才描述的是:
typedef struct {
char * firstName;
char * lastName;
int id;
float mark;
} StudentRecord;
您现在可以执行以下操作:
StudentRecord aStudent = { "Angus\n", "Young\n", 1, 4.0 };
或者
void writeToParents(StudentRecord student) {
...
}
但是你有一个*
在 typedef 之后。那是因为您要对包含指向 StudentRecord 的指针的数据类型进行 typedef,而不是对 StudentRecord 本身进行 typedef。诶?继续阅读...
你需要这个指向 StudentRecord 的指针,因为如果你想传递 StudentRecords 并能够修改它们的成员变量,你需要传递指向它们的指针,而不是变量本身。typedef 对此非常有用,因为编译器可以再次捕获细微的错误。上面我们所做writeToParents
的只是读取 StudentRecord 的内容。假设我们想改变他们的成绩;我们无法使用简单的 StudentRecord 参数设置函数,因为我们无法直接更改成员。所以,我们需要一个指针:
void changeGrade(StudentRecord *student, float newGrade) {
student->mark = newGrade;
}
很容易看出您可能会错过 *,因此,改为 typedef 为 StudentRecord 的指针类型,编译器将提供帮助:
typedef struct { /* as above */ } *PStudentRecord;
现在:
void changeGrade(PStudentRecord student, float newGrade) {
student->mark = newGrade;
}
更常见的是同时声明两者:
typedef struct {
/* Members */
} StudentRecord, *PStudentRecord;
这也为您提供了普通的 struct typedef 和指针 typedef。
那么什么是指针呢?一个变量,它将地址保存在另一个变量的内存中。听起来很简单;从表面上看确实如此,但它变得非常微妙并且很快就被卷入其中。试试这个教程