结构体
struct student {
char name[64];
int height;
float weight;
long schols; //奖学金
};
//成员初始化
struct student jimmy = {"Jimmy", 173, 86.2};
结构体对象O中的成员m可以通过O.m来访问。
声明结构体所赋的初始值的形式是,将各个结构体成员的初始值一次排列在
{}
里面,并用逗号分隔。未赋初始值的成员被初始化为0.
结构体成员和->运算符
void height_fix(struct student *std)
{
if ((*std).height < 180) {
(*std).height = 180;
}
if ((*std).weight > 80) {
(*std).weight = 80;
}
}
在指针变量前加上指针运算符*
,就表示该指针指向的对象实体,即*std
是jimmy
的别名。所以,通过(*std).height
和(*std).weight
等表示可以表示std
指向的对象的别名。
->运算符(访问运算符 member-access operator) a -> b 用指针访问结构体a中的成员b
所以以上函数可以用另一种形式:
void height_fix(struct student *std)
{
if (std->height < 180) {
std->height = 180;
}
if (std->weight > 80) {
std->weight = 80;
}
}
结构体和typedef
有效利用typedef
声明,可以简化struct student
这种冗长的写法。
typedef struct student {
char name[64];
int height;
float weight;
long schols; //奖学金
} Student;
//成员初始化
Student jimmy = {"Jimmy", 173, 86.2};
上例中:结构体名是
student
,struct student
是类型名。
在类型名struct student
中,同义词Student
被作为typedef
名定义。因此,单独Student
也可以作为类型名发挥作用。
如果类型名使用Student
,不使用struct student
,可以将struct student
中的student
省略掉。
typedef struct {
char name[64];
int height;
float weight;
long schols; //奖学金
} Student;
聚合类型(aggregate type)
数组和结构体在处理多个对象的集合方面具有诸多相同点,他们统称为聚合类型。
但数组与结构体也有不同点⚠️:
元素类型
数组用于高效地操作"相同类型"数据的集合。
结构体用于高效低操作“不同类型”数据的集合(也可以处理相同的)。
可否赋值
int a[6], b[6];
a = b; //❌
struct student x, y;
x = y //👌
数组元素个数相同,不能相互赋值。
结构体类型相同可以相互赋值。
结构体可作为函数的返回值
因为结构体可以进行赋值,所以可用作函数的返回值类型。
Student student_sth(int height, float weight, long schols)
{
Student temp;
strcpy(temp.name, "James");
temp.height = height;
temp.weight = weight;
temp.schols = schols;
return temp;
}
命名空间(name space)
- 标签名(label name)
- 小标签名(tag name)
- 成员名
- 一般性标识符
int main(void)
{
struct x { //小标签名
int x; //成员名
int y;
} x;//变量名
x://标签名
x.x = 1;//变量名 . 成员名
x.y = 5;//变量名 . 成员名
}
只要不属于同一个命名空间,即使在同一有效范围内使用相同的名字,也不会产生任何问题。
结构体数组
Student stds[] = {
{"Allen", 178, 61.2, 80000},
{"Bob", 175, 62.5, 73000},
{"Dave", 173, 86.2, 0},
{"Mike", 165, 72.3, 70000},
{"Nova", 179, 77.5, 70000},
};