C语言结构体

  C 数组允许定义可存储相同类型数据项的变量,结构是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。
  在实际的编程过程中,我们往往还需要一组类型不同的数据,例如对于学生信息登记表,姓名为字符串,学号为整数,因为数据类型不同,显然不能用一个数组来存放这些信息。这就需要使用到结构体来存储信息。

 


 
 
 

结构体

定义结构体

  为了定义结构,必须使用 struct 语句。struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式如下:

struct stu{
    char *name;  //姓名
    int num;  //学号
};

  stu是结构体名,它包含两个成员,分别是 name、num。结构体成员的定义方式与变量和数组的定义方式相同,但是结构体内部变量不能初始化
  注意大括号后面的分号“ ; ”不能少,这是一条完整的语句。
  结构体也是一种数据类型,只是它由程序员自己定义,可以包含多个其他类型的数据。包含的数据类型可以是任意一种C的数据类型,甚至可以是其他结构体!

 
 
 

定义结构体变量

既然结构体也是一种数据类型,那么我们就可以定义它:

struct stu stu1;

这样就定义了一个结构体变量stu1,为stu类型,具有两个成员组成。struct stu起到的作用相当于一般声明中的int或float。
例如,也可以定义两个struct stu类型的变量,或者是指向struct stu类型结构体的指针:

struct stu stu1, stu2, *stu3;

 
也可以在定义结构体的同时定义结构体变量(将变量名放在结构体定义的最后即可):

struct stu{
    char *name;  //姓名
    int num;  //学号
} stu1, stu2;

 
如果只需要 stu1、stu2 两个变量,后面不需要再使用结构体名定义其他变量,那么在定义时也可以不给出结构体名:

struct{  //没有写 stu
    char *name;  //姓名
    int num;  //学号
} stu1, stu2;

这样定义虽然省去了结构体名,但是若后序需要使用到结构体的话将无法定义。
结构体内存分配
  理论上讲结构体的各个成员在内存中是连续存储的,和数组非常类似的;但是在编译器的具体实现中,各个成员之间可能会存在缝隙,number和code[4]之间就可能存在缝隙。
 
 
 

结构体赋值与访问

初始化一个结构体变量与初始化数组的语法相似:

struct stu stu1 = {
	"qw",
	182061
};

使用一对花括号中括起来的初始化列表进行初始化,各初始化项用逗号分隔。

 
 
  使用结构体成员运算符——点( . )访问结构体中的成员。例如,stu1.num即访问stu1的num部分。可以想使用任何int类型变量那样使用stu1.num。本质上,.num的作用就相当于stu1结构体的下标。

stu1.name = "qw";
stu1.num = 182061;

 
 
  C99和C11为结构体提供了指定初始化器,其语法与数组的指定初始化器类似。但是,结构体的指定初始化器使用点运算符和成员名(而不是方括号和下标)标识特定的元素。

struct stu stu1 = { .num=182061 };
struct stu stu2 = { .num=182061,
					.name = "qw"
};

 
 

嵌套结构

#define LEN 20

struct names{				//第1个结构
	char first[LEN];
	char last[LEN];
};

struct guy{					//第2个结构
	struct names handle;	//嵌套结构
	char favfood[LEN];
	char job[LEN];
	float income;
};

 
 
 
 

结构体数组

  结构体数组,是指数组中的每个元素都是一个结构体。在实际应用中,结构体数组常被用来表示一个拥有相同数据结构的群体,比如一个班的学生、一个车间的职工等。

struct stu stu1[MAXBKS];

以上代码声明了一个内含MAXBKS各元素的数组,数组中的每个元素都是一个stu类型的结构体。因此,stu1[0]是第一个stu类型的结构体变量,stu1[1]是第二个stu类型的结构体变量,依次类推。
结构体数组结构
为了标识结构体数组中的成员,可以采用访问单独结构的规则:在结构名后面加一个点运算符,再在点运算符后面写上成员名。如下所示:

stu1[1].name
stu1[4].num

总结一下:

stu1				//一个stu结构的数组
stu1[0]				//一个数组元素,该元素是stu结构
stu1[0].num			//一个int类型变量(stu1[0]的num成员)
stu1[1].name[0]		//数组中stu1[1]元素的name成员的一个字符

 
 
 
 

结构体指针

声明和初始化结构体指针

声明结构体指针,与其他指针声明一样:

struct stu *stu1;

该声明并未创建一个新的结构体,但是指针stu1现在可以指向任意现有的stu类型的结构体。例如,stu2是一个stu类型的结构体变量、stu3是一个结构体数组,则可以这样写:

stu1 = &stu2;
stu1 = &stu3[0];

和数组不同的是,结构题变量并不是结构体的地址,因此要在结构体变量名前面加上&运算符。
 
 

使用指针访问成员

第1种方法(常用):使用 -> 运算符。该运算符由一个连接号(-)后跟一个大于号(>)组成。
  如果stu1 = &stu2,那么stu1->num即是stu2.num;
  如果stu1 = &stu2[0],那么stu1->num即是stu2[0].num
第2种方法:
  如果stu1 = &stu2[0],那么*stu1 = stu2[0],因为&和 *是一对互逆运算符。
  stu2[0].num = (*stu1).num必须使用圆括号,因为 .运算符比 * 运算符的优先级高。

stu2.num = (*stu1).num = stu1->num;

 
 
 
 

使用typedef

利用typedef可以为某一类型自定义名称。
使用关键字 typedef 可以为类型起一个新的别名,语法格式为:

typedef  oldName  newName;

oldName 是类型原来的名字,newName 是类型新的名字。

typedef struct stu{
    char *name;
    int num;
} STU,*STU1;

STU 是 struct stu 的别名,可以用 STU 定义结构体变量:

STU stu1,stu2;	//结构体变量
STU1 stu2;		//结构体指针

typedef与#define的不同点:

  1. 与#define不同,typedef创建的符号名只受限于类型,不能用于值。
  2. typedef由编译器解释,不是预处理器。
  3. 在其受限范围内,typedef比#define更灵活。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值