结构体,结构体也是一种数据类型(数据类型如int/float等等),被叫做结构体类型。
结构体,说白了,就是把多种不同类型的数据捏到一起
目的:能够表达更丰富的信息,有点类似于很多高级语言中的“记录”
假设现在有这样两条学生信息:001 张三 男 18 xx地区;002 里斯 女 18 yy地区
我们就可以定义如下结构体:
struct student //定义一个结构体类型
{
int num;//学号
char name[100];//名字
int sex;//性别 0:女 1:男性
int age;
char address[100];//地址
};
根据上面定义的结构体类型,总结一下定义一个结构体类型的一般形式:
有点像这样的结构:
注意,如果将结构体定义在main中,那只能在main中引用
所以,我们一般将结构体定义在main之外
要定义一个结构体类型变量,我们把结构体名(前面要加struct)看成一个类型名就可以了:那么怎样用这个结构体类型呢? 有三种方法:
(1) struct 结构体名 变量名列表
struct student s1,s2;//定义两个结构体类型变量
(2)(少用)在定义结构体类型的时候,顺便定义了变量;变量位置位于} 之后 :之前,多个变量之间用,分隔;
一般形式: struct 结构体名{ }变量名列表;
(3)直接定义结构类型变量,连结构名都省了
(如上,如果用这个结构体只用s1和s2,那么student可以省略)
一般形式: struct{ }变量名列表;
说明:
(a)使用结构体,我们一般要先定义一个结构体类型,然后定义某些变量为该类型的变量,这是分两步走的。好处,可以反复利用结构体名,不断定义新的结构体类型变量
(b)结构体可以套结构
(c)结构体内成员(成员变量)名可以与程序中的变量名相同,彼此之间互不影响
(例如在main中定 义一个名字叫作num的普通变量)
(1)不能将结构体变量作为一个整体进行引用,如上面定义的s1、 s2,都是结构体变量,但不能拿来直接用。只能对结构体变量中的各个成 员分别引用。引用的方式为
比如 s1.num=101;//将101赋值给s1变量中的成员num
//其中 . 叫结构成员运算符,该运算符优先级非常高和()平级,所以可以把s1.num当成一个整体
(2)如果成员本身又属于一个结构体类型,则要用若干个结构体成员运算符,一级一级找到最低级成员,只能对最低级成员进行赋值或者存取操作。
s1.birthday.day=20;
(3)成员变量,就当成普通变量,可以象普通变量一样进行各种运算
(4)因为成员变量也相当于普通变量,所以它们也是有地址的。
s1.birthday++;//这是不可以的
.后面这个东西不能是一个结构;.后面是最简单最普通的变量
int *p=&s1.num;
printf ("%d",*p);
一段结构体变量定义时初始化的代码:
定义这个结构体数组(2种)
(a)单独写成一行来定义
(b)定义结构时顺便定义结构体数组。看如下代码的结构体末尾
(c)在定义结构体数组时,也可以顺便进行初始化:
定义时的初始化的一般形式为:
可以像使用普通结构体变量一样使用结构体数组
也就是结构体变量的指针,这个指针肯定是指向 结构体变量 所占据内存的起始地址
当然,结构体变量指针 也可以指向 结构体数组 中的元素。因为结构体数组中的每个元素就相当于一个结构体变量
上面这段代码中,ps指向了stu,stu里面的内容如果发生了改变,就等于ps所指向的内容发生了改变
Q:如何 通过结构体变量指针 来访问 结构体变量的成员呢?有两种方法:
(1)一种还是用结构体成员运算符“.”
(*ps).age=29;//*ps就相当于stu;()不能省略,因为.的优先级比*高
(2)另一种是用 指向结构体成员运算符 “->”
PS ->sex=1;//->优先级也是最高(和().同级)
如何 指向结构体数组 的指针 ?
比如有如下数组
struct student *ps;
ps= stuArr; 数组名代表数组的首地址 ,!! 数组中数组在内存中是紧挨着的
ps++;//相当于跳过一条记录,从张三跳跃到李四
// 跳过了 6*4+100*2=224字节
说明:
(1)(++ps)->num;//先加后用,所以应该是第1条(第二个)那条数据 1002
(ps++)->num;//先用后加,1001,指针指向李四
printf("%d",(++ps)->num)
(2)指针PS 指向的是结构体类型;不可以指向一个成员
不能让PS指向某一数组元素中的成员
ps=&stu[0];//可以
ps=&stu[0].num;//不可以;强制类型转换(没必要)
有这样一个函数
// 你两内存是同一个,会互相影响
-----------另一种:赋值完没用--------------------
拷贝:完整的结构体变量作为参数传递,相当于做了个内存内容的拷贝,
虽然合法,开销很大;费时费空间;而且,由于是两个占据的内存不是同一个,传回来没用呀
!!! 所以:能传递地址就传地址;或者用指针,能大大提高运行效率