C语言基础(八)----结构体_编程开发

来源:微信公众号「编程学习基地」

结构体

结构体的作用

数组:具有相同类型的数据的集合

结构体:存储不同类型的数据项

单一的数据类型无法满足特定的需求,数据类型的集合体:结构体 出现了

结构体的定义和使用

结构体的定义方式

结构体是一种自定义数据类型 struct用来定义一个类型

  • 结构体的定义方式
struct 结构体名字
{
	//成员变量
}
  • 定义结构体后再定义变量
//例1:
struct stu
{
    int id			//学号
    char name[20];	//名字
};
struct stu stu1,*pStu,arr[10];	//定义变量
  • 在定义结构体的同时定义变量
//例2:
struct stu
{
	int id;			//学号
    char name[20];	//名字
}stu1,*pStu,arr[10];			//定义变量
引用结构体变量中的成员
  • 点运算符访问结构体的成员变量 .
//对例2的结构体变量进行访问
stu1.id=1001;
strcpy(stu1.name,"小明同学");

arr[1].id=1002;
strcpy(arr[1].name,"梦凡老师");
  • 箭头运算符访问结构体成员变量 ->
//对例2的结构体变量进行访问
pStu=(struct stu*)malloc(sizeof(struct stu));//分配内存
pStu->id=1001;
strcpy(pStu->name,"小明同学");

(arr+1)->id=1002;
strcpy((arr+1)->name,"梦凡老师");

typedef的定义和使用

作用 : 给类型取短一点的别名 方便阅读

_t结尾的类型 一般都是别名,例如size_t 就是 unsigned int

typedef的定义

  • 给基本数据类型取别名

typedef 数据类型 别名

typedef unsigned int size_t;    //给unsigned int 取别名 size_t
  • 给结构体变量取别名

typedef struct 结构体名字 结构体别名

typedef struct stu STU;			// STU 等价于 struct stu
STU stu1={1001,"小明同学"};		 // STU这个结构体类型就可以直接定义使用了
  • 定义结构体的时候给结构体取别名
//例3:  推荐这种写法
typedef struct stu	//定义结构体的时候取别名
{
    int id			//学号
    char name[20];	//名字
}STU;
STU stu1,*pStu,arr[10];	//定义变量

内存对齐

结构体变量大小 >= 结构体所有成员变量大小

结构体总大小为最大对齐数的整数倍
#include<stdio.h>
typedef struct test
{
    int x;
    char ch;
    int y;
    char c;
}TEST;
int main()
{
    printf("test的大小为:%d\n",sizeof(TEST));
    return 0;
}

输出结果:

test的大小为:16
Press any key to continue

上面的例子很简单,看的懂的话我变换一下再来看看

#include<stdio.h>
typedef struct test
{
    int x;
    char ch[10];	//数组看成单个元素
    int y;
    char c;
}TEST;
int main()
{
    printf("test的大小为:%d\n",sizeof(TEST));
    return 0;
}

输出结果:

test的大小为:24
Press any key to continue

为什么会是24,我们开头就说了:结构体总大小为最大对齐数的整数倍

该结构体最大对齐数为 int 也就是4个字节大小 ,结构体的大小就是4的整数倍

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U4yaxN0T-1577347105811)(D:\360MoveData\Users\邓志荣\Desktop\无标题.png)]

如果嵌套了结构体的情况,嵌套的结构体对齐到自己最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

为什么要有内存对齐

简单来说就是:浪费一点内存快速定位

专业点来说:

1.平台问题(移植问题):不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在某些地质处取某些特定类型的数据,否则跑出硬件异常。

2.性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要做两次内存访问,而对齐的内存只需要访问一次。

位域

在结构体定义时,我们可以指定某个成员变量所占用的二进制位数(Bit),这就是位域。

位域的定义:

struct Stu
{
    int a;		//成员 a 没有限制它占用 4 个字节的内存。
	int b:4;	//成员 b 被:后面的数字限制 占用 4 位的内存
};

注意:

  • 一个 字节 是 8 位
  • 位域的取值范围不能超过它所依附的数据类型的长度
4struct Stu
{
	int b:33;	// int 4 个字节,32位;33超过了int的数据长度,报错
};

  • 例4中sizeof(Stu)=4;原因还是内存对齐

枚举

关键字:enum

枚举类型的定义

enum game
{
	SPACE, WALL, SNAKE, FOOD, HEAD//空地  墙  蛇  食物
};

定义完之后 SPACE=0 ,WALL=1 ,后面依次类推

enum game
{
	SPACE, WALL=5, SNAKE, FOOD, HEAD//空地  墙  蛇  食物
};

SPACE=0, WALL=5, SNAKE=6,后面依次类推

enum和switch搭配,可以防止遗漏内容

在VS里面输入switch+tab键+枚举类型 可以迅速匹配枚举类型的所有成员

联合

关键字:union 共用一块内存

联合类型的定义

union 联合类型名
{
	//成员
};

联合和结构体的区别:

  • 结构体变量可以同时存放多个成员
  • 联合只能保证一个成员有效 (共同用一块内存)

联合在一般的编程中应用较少,在单片机中应用较多,只做了解就可以了。