c语言之自定义类型

什么是结构体?

结构体是一种自定义数据类型,结构体可以被声明为变量,指针数组,结构体里面的元素叫做结构体的成员。成员类型可以不同。

结构体的定义:


方式1:

struct contact{

成员列表;

}con1, con2;


方式2:

struct contact {

成员列表;

};

struct contact con1, con2;

//不能省略struct,想要省略struct可以在创建的时候再struct前面加上typedef

如下:

方式3:

typedef struct contact {

成员列表;

}CONTACT;

CONTACTcon1, con2;


结构体类型创建 :

struct contact con;

struct contact con[100];

struct contact * p_con;


结构体初始化

方式1:

struct contact con;

con.name = "tom";

...

方式2:

struct contact  *p_con;

con->name="tom";

...

方式3:

con = {"tom", ...};


结构体内存对齐 :

结构体内存对齐的原因?

首先看看不存在结构体对齐时:

struct con{

char c;

int num;

};

char在内存中占一个字节,所以num在内存的第二个字节到第6个字节处。

当需要读取num的时候,由于32位机器一次只能读取4个字节的数据,所以他会先读char后面的三个字节,然后读取剩下的一个字节。

所以读取num就需要两次访问内存。所以才需要结构体内存对齐来加快访问数据的速度,但是也造成了空间浪费。

结构体内存对齐的规则:

1,第一个成员在与结构体变量偏移量为0的地址处,

2,其他成员变量要对齐到某个对齐数的整数倍的地址处,

对齐数 = 编译器默认的一个对齐数与该成员大小的较小值,

VS中默认的值为8,linux中默认值为4;

3,结构体总大小为最大对齐数的整数倍。

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

所以上述结构体在内存中的实际大小为:8个字节。

位段:

位段和结构体很像,但是不存在内存对齐,和结构体不同的是,位段是为了节省空间而存在的。

struct contact {

int a:2;

int b:4;

int c:15;

int d:25;

}

在变量名称后面跟上:数字结构体就变成了位段,这个数字代表这个变量所占的比特位多少,例如a占2个bit位,b占4个bit位,这个位段一共占了46个bit位,

所以需要2个int来存,所以这个位段占了8个字节的空间。


枚举:

枚举的定义:

enum Color{

RED,GREEN,BLUE

}

枚举的使用:

Color.RED。其中RED,GREEN,和BLUE代表的值分别为0,1,2。

可以在创建的时候给枚举常量赋值;

enum Color{

RED=255;

GREEN=0;

BLUE=0;

}

枚举的作用和#define是一样的,但是枚举存在类型检查,但是#define就不存在类型检查。

使用枚举可以增加代码的可读性。

联合:

联合(union)又叫共用体,是在某些特殊情况下使用的。共用体顾名思义里面的变量共用同一块内存空间,

union contact{

int a;

char b;

double c;

这个联合的大小为8个字节,他们共用这8个字节的空间,当其中一个值变化了的时候,另一个也会发生变化。

联合的典型用法:

IP地址转化:

ip地址是一个由32个bit位组成的数字,IP地址在内存中的存储形式为132154564。要想把他转换成点分十进制的格式可以使用以下方法。

(注意大小端)

#include <stdio.h>
typedef union IP {
	unsigned long address;
	struct{
		unsigned char c1;
		unsigned char c2;
		unsigned char c3;
		unsigned char c4;
	}sIP;
}ip;

int main(int argc, char *argv[]) {
	ip ipAddr;
	ipAddr.address=7894756411;
	printf("%d.%d.%d.%d\n",ipAddr.sIP.c4, ipAddr.sIP.c3,ipAddr.sIP.c2,ipAddr.sIP.c1);
	return 0;
}

由于VS下数据是按小端存储的,所以打印的时候需要反过来打印,结果如下




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值