【C语言】结构体、container_of获取结构体首地址、共用体、枚举

struct union enum
结构体

1、结构体或者类的自身对齐值是其成员中自身对齐值最大的那个值。(所以内存小的数据类型要放一起–先写后写都行就是要放一起)
2、若结构体中有另一个结构体,且另一个结构体中有更大对齐值的数据,这用该对齐值对齐
3、数组不能直接赋值给另一个数组,但将数组写入结构体之后可以实现
4、声明一个struct可以起一个别名:
typedef struct
{
}别名;
这样定义变量的时候就不用写struct了。
5、为什么要内存对齐?
因为cpu对内存的读取是对齐的,如果内存不对齐,cpu需要读取两次才能读取到(需要拼接)。
6、位域(为了节省空间所用,似乎不影响效率,编译有优化)
形式:typename member:位域个数(一个字节8位)可以没有变量名,但仅作填充作用,不可引用
如:

struct student
{
	int sex:1;
	int class:2;
	int :1;//无名位域,仅作填充
	int id:4;
};

看似占用空间8位(一字节),但是本质还是int形式,只能按int对齐故占用空间为sizeof(int)==4;(4字节,32位)
C99规定int、unsigned int和bool可以作为位域类型,但编译器几乎都对此作了扩展,允许其它类型类型的存在。

已知结构体成员的地址,求结构体的首地址(宏container_of)

1、可以先求偏移:

typedef struct
{
	int num;
	char name[12];
	float score;
}student;
student s1;
char* ptr=s1.name
//如果当前是name的话,求偏移量如下
int dx=(char*)(((student*)0x0)->name)-(char*)((student*)0x0);
//pstu即为首地址
student* pstu=(student*)(ptr-dx);

2、或者可以直接使用linux内核的container_of宏定义(头文件#include<stddef.h>)
宏定义如下:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) //计算偏移量
#define container_of(ptr, type, member) ({ \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})  //根据偏移量求得首地址
//使用方法:
//pstu即为结构体首地址
student* pstu=container_of(ptr,student,name);//当前指针,结构体数据类型、成员名字

typeof()获取变量的数据类型

enum(枚举) 和 union(共用体)
#include<stdio.h>
#include<stdbool.h>

int main(int argc,char* argv[])
{
	//不指定值的话默认从0开始,且后面的成员依次加1,后面成员也可以指定值,后续值根据指定值依次+1
	//但是指定值之后,若值不连续的话就不能遍历了
	enum Day
	{
			Sun,Mon,Tue,Wed,Thi,Fir,Sat
	};
	enum Day day;
	for(day=Sun;day<=Sat;day++)
			printf("today:%d\n",day);
	//枚举类型的空间大小为4,但它并不是int型
	printf("sizeof(enum Day day)=%d\n",sizeof(enum Day));

	//共用体
	union Year
	{
			int intYear;
			char charYear[5];
	};
	//共用体
	union Year year;
	year.intYear=2022;
	printf("this year is %d\n",year.intYear);

	year.charYear[0]='2';
	year.charYear[1]='0';
	year.charYear[2]='2';
	year.charYear[3]='2';
	year.charYear[4]='\0';
	printf("this year is %s\n",year.charYear);

	//共用体所有成员共用一个内存,每次只能赋值给一个成员,输出其他成员的值为乱码
	printf("sizeof(union Year year)=%d\n",sizeof(year));
	printf("this year is %d\n",year.intYear);

	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值