C语言之结构体,位域,联合体

结构体

C语言中的一种自定义类型 需要程序员自己先把类型定义出来,再用该类型声明变量

定义结构

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

​```
struct tag {
    member-list
    member-list
    member-list 
    ...
} variable-list ;
​```

tag 是结构体标签。

member-list 是标准的变量定义,比如 int i; 或者 float f,或者其他有效的变量定义。

variable-list 结构变量,定义在结构的末尾,最后一个分号之前,您可以指定一个或多个结构变量。

结构体与数组:

​ 都是多个变量的混合体

​ 结构体的多个变量的类型可以不相同

​ 数组每个变量的类型都一样

1、定义结构类型 可以在函数外面 也可以在函数里面

struct Stu{
int id;//学号
char name[40];//名字
int age;//年龄
};
struct Stu 代表一种数组类型

2、声明结构体变量

​ struct Stu s;//s没有初始化 垃圾值

结构体一旦定义,再也不能用={}的形式赋值;

​ s={123,“马上”,20};//错误xxxxx

​ 就好比数组

​ int arr【5】;

​ arr【5】 = {1,2,3,4,5};//错误//可通过strcpy来完成给值。

​ 数组名之间不能相互赋值

struct Stu stu = {147,"马全",44};
s = stu;  结构体变量之间可以相互赋值

//struct stu是一个自定义的结构体类型

//id,name,age是struct Stu类型的成员变量 属性

//struct Stu s;//定义一个结构体变量 没有初始化

3、结构体变量的初始化

​ struct Stu s = {};//所有字段全部初始化为0
​ struct Stu s1 = {110,“马云”,45};
​ struct Stu s2 = {119,“马化腾”};//只有前面的有值 后面的自动补0
​ struct Stu s3 = {.name=“马伊莉”,.age=40};
​ .属性名=值 好比数组[下标]=值
​ struct Stu s4 = s1;//用另外的结构体变量来初始化

可以声明无名结构体
struct{int x;}a
struct{int x;}*p
4、访问成员变量运算符 .

.xxx

结构体变量.成员变量名

数组通过 数组名[ 下标]的形式 来访问数组中的元素

结构体通过 结构体名.属性名 的形式来 访问结构体中的成员

当结构体变量定义以后,要访问或者修改成员的值,都得通过

​ 结构体变量.成员变量 的形式来 访问 和 赋值

​ 如果成员变量是数组 , 不能直接用 = 的形式

在一般情况下,tag、member-list、variable-list 这 3 部分至少要出现 2 个。以下为实例:

//此声明声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c
//同时又声明了结构体变量s1
//这个结构体并没有标明其标签
struct
{
    int a;
    char b;
    double c;
} s1;
 
//此声明声明了拥有3个成员的结构体,分别为整型的a,字符型的b和双精度的c
//结构体的标签被命名为SIMPLE,没有声明变量
struct SIMPLE
{
    int a;
    char b;
    double c;
};
//用SIMPLE标签的结构体,另外声明了变量t1、t2、t3
struct SIMPLE t1, t2[20], *t3;
 
//也可以用typedef创建新类型
typedef struct
{
    int a;
    char b;
    double c;
} Simple2;
//现在可以用Simple2作为类型声明新的结构体变量
Simple2 u1, u2[20], *u3;
5、结构体指针变量访问成员运算符 ->

​ 结构体指针变量 访问 成员属性 时 直接 用->

struct	结构体类型名	*	指针变量;

struct	Book b=	{120,“红楼梦”,"曹雪芹",40.23};
struct 	Book *p;
p = &b;

(*p).no           p->no
(*p).name         p->name
(*p).author       p->author
(*p).price        p->price

用指针传递参数 效率高 节省内存

6、给类型重命名

typedef unsigned int size_t;
typedef struct Book Book;

typedef struct Book{
	
}Book;

struct Book{
	
}Book;
7、typedef 与 define
	typedef int * I;
	#defien T int*
	I a,b;
	T m,n;

8、结构体成员是数组与指针的区别
struct A{
	char name[40];
};
struct B{
	char *name;
};
9、结构体数组 以及 申请动态内存来保存结构体变量
结构体类型名 变量名[长度] = {};
结构体类型名 *变量名 = malloc/calloc
10、结构体内存大小 对齐 补齐的概念 (100%会考)

​ 对齐:
​ 结构体成员在存储时, 都是从距离结构体开始位置的自身成员长度的整数倍内存位置开始存储
​ 自身长度超过4按4对齐

补齐:
	结构体长度是成员最大长度的整数倍 超过4字节就4字节补齐
	
struct C{
	char c1;
	short s;
	char c2;
	int i;
};
//c-ssc---iiii

struct D{
	char c1;
	int i;
	char c2;
	double d;
};
//c---iiiic---dddddddd

位域(位段)

​ 位段的类型只能是整数类型 char short int

struct A{
	char i:3;//只占3个二进制位
	char :1;//空域
	char j:2;
	char k:2;
};
struct A a;
int x = 0x72;
memcpy(&a,&x,1);
0111 0010
a.i  =  010   %x   2 
a.j  =  11    %x   ffffffff
a.k  =  01    %x   1

struct A{
	char i:3;
	char j:6;
};
sizeof(struct A) == 2
struct B{
	int i:3;
	int j:2;
};
sizeof(struct B) == 4
struct C{
	char i:1;
	char j:2;
	char k:5;
	char c:1;
};
sizeof(struct C) == 2

联合 (共用体) union

多个变量共用一块内存

union	联合体名字{
	xxxx;
	yyyy;
}
sizeof(联合体)  == 最大长度的成员的字节数

共用体变量在初始化的时候不同给多个值  = {值}   只能给一值



int isBigSystem(){
	union A{
		int x;
		char c;
	};
	union A a;
	a.x = 1;
	if(a.c == 1){
		return 0;//小端系统 
	}else{
		return 1;//大端系统
	}
}

int isBigSystem(){
	int x = 1;
	char *p = (char *)&x;
	if(*p == 1){
		return 0;
	}else{
		return 1;
	}
}
大端系统:

多字节数据,低地址存储高字节的数据

小端系统:

​ 多字节数据,低地址存储低字节的数据

枚举 enum

​ 用特殊的标识符来表示一组特殊的值
​ enum Dir{Right,Left,Up,Down};
​ enum Col{Red,Green,Yellow,Pink,Black,Orange,…};
​ enum Week{Monday,Tuesday,Wendesday,Thirsday,Firday,Saturday,Sunday};

​ enum Dir是枚举类型 枚举值有:Right Left Down Up
​ 枚举值 本质 上是int类型
​ 可以把int类型数据赋值给枚举变量
​ 可以把枚举值赋值给整数变量

enum Dir d = 0;
d = Right;

int x = d;
x = Left;        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小城微雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值