结构体类型同数组类型一样都是以一种结构化数据类型,只不过数组是用于封装同一种类型的数据的机制,而结构体是用于封装不同类型的数据的另一种机制。结构体类型由用户自定义,只不过定义完了后就和其它基本类型一样了,结构体类型、联合类型、指针类型都有别于基本类型,基本类型包括int、float、double、char、枚举等(要注意枚举类型属于基本类型,而不同于结构类类型)。
结构体类型定义(构造):
在函数外定义,定义结构体类型可以相当于是一条语句,所以一定要在末尾加上封号‘;’
struct stu{
int id ;
char name[20];
char number[12];
};
还可以用typedef为结构体类型取别名,但不允许定义别名的同时定义变量!因为若是不这样的话,每次使用结构体类型都要用struct XXX 太过麻烦了,所以用typedef取下别名就简单多了;
在结构体类型定义时成员用{ }包括起来,而且成员同C++中的类成员变量一样,不允许在结构体内进行初始化,这是不允许的,如:
在结构体类型定义时成员的排列顺序要注意,因为字节对齐的问题,结构体的大小不等同于各成员大小之和,而且成员排列顺序不同,结构体大小也不一定相同。
结构体变量定义:
可以是在编译时定义(相当于全局变量了):编译时定义分为两种,一种构造类型的同时定义变量,一种构造完类型后再单独进行第一变量;
也可以用别名来定义变量,但不允许定义别名的同时定义变量!如下面第三个:
也不允许成员中有自身结构体,只能包含自身结构体类型指针,但是可以有其它类型的结构体。
也可以在函数内定义(相当于局部变量):
结构体变量初始化:
因为结构体变量也是变量,所以也有默认初始化,全局的默认初始或为0(‘\0’、NULL),局部的成员默认初始化为随机值。
因为结构体和数组都是结构化数据类型,所以都允许部分初始化,不管是全局的还是局部的,部分初始化剩下的同数组一样都默认初始化为0(‘\0’、NULL)。
也可用另一个结构体变量来初始化,如struct stu s1 = s2,结构体间可以直接赋值但不能直接比较。
而成员中有结构体的话,则初始化要用{ {.. ,..} ,.. ,..}这样嵌套的方式初始化。
#include<stdio.h>
struct stu{
int id ;
char *p;
char name[20];
char number[12];
} s1 = {1,NULL,"lili","12345678901"},s5,s6={6}; //s5默认初始化,且全局的全部初始化为0('\0'、NULL);
//s6部分初始化,剩下同数组一样的默认为0('\0'、NULL);
typedef struct stu ss; //除了在构造结构体类型时,也可以单独进行typedef
int main(void)
{
char *p = "aabbccdd";
printf("p = %p\n",p);
struct stu s2 = {2,p,"wuhuan","23456789012"};
struct stu s3 = {3}; //可部分初始化,剩下的默认初始化为0('\0'、NULL) ,同数组一样
struct stu s4; //默认初始化为随机值
ss s7;
printf("s%d : id = %d\n p = %p\n name = %s\n number = %s\n",1,s1.id,s1.p,s1.name,s1.number);
printf("s%d : id = %d\n p = %p\n name = %s\n number = %s\n",2,s2.id,s2.p,s2.name,s2.number);
printf("s%d : id = %d\n p = %p\n name = %s\n number = %s\n",3,s3.id,s3.p,s3.name,s3.number);
printf("s%d : id = %d\n p = %p\n name = %s\n number = %s\n",4,s4.id,s4.p,s4.name,s4.number);
printf("s%d : id = %d\n p = %p\n name = %s\n number = %s\n",5,s5.id,s5.p,s5.name,s5.number);
printf("s%d : id = %d\n p = %p\n name = %s\n number = %s\n",6,s6.id,s6.p,s6.name,s6.number);
printf("s%d : id = %d\n p = %p\n name = %s\n number = %s\n",7,s7.id,s7.p,s7.name,s7.number);
return 0;
}
结果:
p = 0x8048780
s1 : id = 1
p = (nil)
name = lili
number = 12345678901
s2 : id = 2
p = 0x8048780
name = wuhuan
number = 23456789012
s3 : id = 3
p = (nil)
name =
number =
s4 : id = -1080755510
p = 0xc2
name =
number =
s5 : id = 0
p = (nil)
name =
number =
s6 : id = 6
p = (nil)
name =
number =
s7 : id = 134513261
p = 0x8049ff4
name = ц��
number = �/
结构体变量的赋值与比较:
赋值的时候表现的是变量的性质,可以直接用' = '来进行赋值; s1 = s2; OK !
而比较的时候表现的是结构化类型变量的性质,如同数组,不能直接比较,只能进行单个成员的比较。if(s1 == s2) 、 if(s1 != s2) 则是不行的;
结构体数组,与一般数组一样用,只不过数组元素是一个结构体变量而已。
结构体与数组与字符串与动态二维数组与malloc的关系:
==================================================================================================================
在函数外定义,结构体类型定义可以相当于是一条语句,所以一定要在末尾加上封号‘;’