《C++新经典》第10章 结构体与共用体

92 篇文章 19 订阅
15 篇文章 2 订阅

10.1 结构体定义、引用与初始化

10.1.1 结构体简介

结构体将各种类型的数据(结构体成员)放在一起。

10.1.2 定义结构体类型变量的方法

  • 先定义结构体类型,后定义结构体类型变量
struct 结构体名 {
	成员列表
} ;
struct 结构体名 变量名列表;

struct student {
	int num;
	char name[100];
	int sex;
	int age;
	char address[100];
} ; //分号不能省略
struct student s1, s2;
  • 先定义结构体类型的同时定义结构体类型变量
struct 结构体名 {
	成员列表
} 变量名列表;

struct student {
	int num;
	char name[100];
	int sex;
	int age;
	char address[100];
} s1, s2; //分号不能省略
  • 直接定义结构体类型变量(省略结构体名)
struct {
	成员列表
} 变量名列表;

struct {
	int num;
	char name[100];
	int sex;
	int age;
	char address[100];
} s1, s2; //分号不能省略
  • 结构体内嵌结构体
struct date {
	int month;
	int day;
	int year;
};
struct student {
	int num;
	char name[100];
	int sex;
	int age;
	char address[100];
	struct date birthdar;
} ; //分号不能省略

10.1.3 结构体类型变量的引用

  1. 结构体变量不能整体引用,只能分别引用结构体变量中的各个成员。
结构体变量名.成员名

s1.num = 1001;
  1. 若成员属于结构体类型,则只能一级一级地找到最低级成员引用。
s1.birthday.month = 12;
  1. 结构体成员变量可以像普通变量一样进行各种运算。
s2.age = s1.age;
int age = s1.age + s2.age;
s1.age++;
  1. 成员变量也有地址
int *p = &s1.num;
printf("%d\n", p);

10.1.4 结构体变量初始化

struct student s = {100, "ww", 1, 16, "3d5l", 10, 14, 2018};
s.num = 1001;

10.2 结构体数组与结构体指针

10.2.1 结构体数组

struct student strArr[3]; //单独定义

//定义结构体时定义结构体数组
struct student {
	int num;
	//......
} strArr[3];

//定义结构体数组时初始化
struct student strArr[3] = {
	{1001, "zs", 1, 18, "sdf", 12, 30, 2000},
	{1001, "zs", 1, 18, "sdf", 12, 30, 2000},
	{1001, "zs", 1, 18, "sdf", 12, 30, 2000},
};

//结构体数组定义初始化一般形式
struct student strArr[ ] = { {}, {}, {} }; //自动推导大小

10.2.2 结构体指针

struct student strArr[] = {
	{1001, "zs", 1, 18, "sdf", 12, 30, 2000},
	{1001, "zs", 1, 18, "sdf", 12, 30, 2000},
	{1001, "zs", 1, 18, "sdf", 12, 30, 2000},
};

struct student *ps;
ps = stuArr;
for(int i=0; i<3; i++) {
	printf("name=%s\n", ps->name);
	printf("num=%d\n", (*ps).num);
	ps++;
}

10.2.3 结构体指针作为函数参数

void func(struct student *ps) {
	ps->age = 18;
}

//传递结构体变量合法,所有成员数据都要复制,开销大,费时费内存,影响程序运行效率。
void func(struct student s) {
	s.age = 18;
}

int main() {
	struct student strArr[] = {
		{1001, "zs", 1, 18, "sdf", 12, 30, 2000},
		{1001, "zs", 1, 18, "sdf", 12, 30, 2000},
		{1001, "zs", 1, 18, "sdf", 12, 30, 2000},
	};
	struct student *ps;
	ps = stuArr;
	
	func(ps);
	printf("age=%d\n", (*ps).age);
	return 0;
}

10.3 共用体、枚举类型与typedef

10.3.1 共用体

联合,几种不同类型(占据内存字节数可能不同)的变量存放在同一段内存单元(开始地址相同,互相覆盖)。

union 共用体名 {
	成员列表
} 变量列表;

union myuni {
	int carnum;
	char cartype;
	char cname[60];
} a, b, c;


union myuni {
	int carnum;
	char cartype;
	char cname[60];
};
union myuni a, b, c;

union {
	int carnum;
	char cartype;
	char cname[60];
} a, b, c;
  • 结构体内存大小是各个成员内存大小之和(存在字节对齐问题,基于硬件或效率)。
  • 共用体内存大小是最大成员内存大小。
  • 共用体变量引用同结构体,指明引用成员。
  • 共用体每个瞬间只有一个成员起作用。
union myuni a;
a.carnum = 1356;
strcpy(a.cname, "car"); //a.cname起作用,a.carnum无意义
  • 共用体变量地址和成员地址都相同,&a,&a.carnum,&a.cartype,&a.cname都相同。
  • 共用体变量不能定义时所有成员都初始化,允许初始化第一个成员。
union myuni a = {12, 'A', "car"}; //错误
union myuni a = {12}; //正确

10.3.2 枚举类型

枚举类型可以更直观、更容易让人看懂,见名知意。(实际上完全用整型变量也可以代替)

enum Color {
	Red,
	Green,
	Blue,
	Yellow,
};
enum Color color1, color2;
  • 枚举,就是将值一一例举出来。
color1 = Red;
  • 直接定义枚举类型变量

enum {Red,Green,Blue,Yellow} color1, color2;

  • 枚举常量(Red,Green等),用来给枚举变量赋值,从0开始。
sizeof(color1); //和sizeof(int)一致
sizeof(Red);	//和sizeof(int)一致
printf("Red=%d\n", Red);	//0
printf("Yellow=%d\n", Yellow);	//3
  • 改变枚举常量的默认值
enum Color {
	Red = 7,
	Green, //8
	Blue = 2,
	Yellow, //3
};
  • 枚举值,可理解为整数值,但不能将整数直接赋给枚举变量
color1 = 2; //错误
color1 = (enum Color) 1000;//类型转换,可以,枚举值和整型值互通使用
if(color1 == 1000)
	printf("color1 == 1000\n");
	
color1 = Blue;
if(color1 == Blue)
	printf("color1 == 1000\n");
  • 可将枚举值赋给整型变量
int abc = Green; //int abc = color1;
printf("%d\n", abs);

10.3.3 typedef定义类型

typedef定义新的类型名(不是定义变量)代替已有类型名。

typedef int INTEGER;
INTEGER a, b, c;

typedef struct date {
	int month;
	int day;
	int year;
} DATE;
DATE *p;

typedef int NUM[10];
NUM n; //int n[100];

typedef char * PSTRING;
PSTRING p, q; //char *p, *q;

typedef int (*POINTER)();
POINTER p1, p2;
  • typedef定义类型名常用大写,区别标准类型int,char等。
  • typedef重命名已有类型名(没创造新类型),非定义变量。
  • typedef编译时处理
  • typedef主要作用是提高程序通用性和可移植性,可以简化书写(简短类型名)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值