结构体位制详解 -- C

我基本总结下面4部分:

1、占位大小问题。

2、字节对齐问题。

3、特殊保留位0。

4、该结构体在内存中存放位置。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//基本概念
/*
struct _M
{
	(1)	类型 参数名 : 占位大小;
	(2)	类型 : 占位大小;
}

(1)
	类型 -- int,unsigned(32位),short,char。
	参数名 -- 同个结构体里面不能重名参数。
	占位大小 -- 不能大于类型最最大位数。

(2) 一般用于寄存器中保留位
*/

//占位大小问题:
/*
err -- int类型是32位,34大于32位,所以编译出错。
struct _A
{
	int x1:34;
};

err -- char类型是8位,9大于8位,所以编译出错。
struct _A1
{
	char x1:9;
};
*/

//字节对齐
/*
	偏移量 -- 类型和占位大小影响(与结构体字节对齐差不多意思)。
*/
struct B
{
	char x1:1;//1位,字节对齐占1字节,8位。
	char x2:8;
	char x3:1;
	char x4:8;
	char x5:1;
};

struct C
{
	char x1:4;
	char :1;
	char x2:3;
};

struct _C
{
	char x1:4;
	char :8;
	char x2:3;
};

//特殊保留位0
struct C1
{
	char x1:4;
	char :0;//这个0占了4个字节
	char x2:3;
};

struct _C1
{
	char x1:4;
	char :4;//这个0占了4个字节
	char x2:3;
};

//内存中存放顺序
struct D
{
	char x1:1;//最低位
	char x2:1;
	char x3:1;
	char x4:1;
	char x5:1;
	char x6:1;
	char x7:1;
	char x8:1;//最高位
};

int
main()
{
	//字节对齐
	B b;
	printf("sizeof(b) = %d\n", sizeof(b));

	C c;
	printf("sizeof(c) = %d\n", sizeof(c));

	_C _c;
	printf("sizeof(_c) = %d\n", sizeof(_c));

	//特殊保留位0
	C1 c1;
	printf("sizeof(c1) = %d\n", sizeof(c1));
	memset(&c1, 0, sizeof(c1) );
	c1.x1 = 0xf;
	c1.x2 = 0x7;
	printf("c1 = 0x%x\n", c1);

	_C1 _c1;
	printf("sizeof(_c1) = %d\n", sizeof(_c1));
	memset(&_c1, 0, sizeof(_c1) );
	_c1.x1 = 0xf;
	_c1.x2 = 0x7;
	printf("_c1 = 0x%x\n", _c1);

	//内存中存放顺序
	D d;
	memset(&d, 0, sizeof(d) );
	printf("d = 0x%08x\n", d);
	d.x1 = 1;
	printf("d = 0x%08x\n", d);

}

/*
[[email protected] test_class]# gcc quote.cpp ;./a.out
sizeof(b) = 5
sizeof(c) = 1
sizeof(c1) = 2
c1 = 0x70f
sizeof(c2) = 3
d = 0x00000000
d = 0x00000001
[[email protected] test_class]# gcc quote.cpp ;./a.out
sizeof(b) = 5
sizeof(c) = 1
sizeof(_c) = 3
sizeof(c1) = 2
c1 = 0x70f
sizeof(_c1) = 2
_c1 = 0x70f
d = 0x00000700
d = 0x00000701

*/

下面是别人的博客:

在使用结构体位制的时候有两点要特别注意:
1.//位段成员的类型仅能够为unsigned或者int
2.
unsigned b:4;
        unsigned :0;    //定义长度为0的位段时不能指定名字,否则编译不过
        unsigned d:1;   //定义了0字段后,紧接着的下一个成员从下一个存储单元开始存放;                                       //此例子中,d前面那个存储单元中的余下的27位中被0填充了

/*
        DATE : 2010.6.24
        关于C中的位端igned或者int
*/
#include <stdio.h>

typedef struct _A
{
        unsigned int a:4;//位段成员的类型仅能够为unsigned或者int
        unsigned b:4;
        unsigned c:2;
        unsigned d:6;
        unsigned E:1;
        unsigned D:2;
        unsigned T:3;
        unsigned A:9;
        unsigned h:4; //前面已经为31,故4+31>32已超过一个存储单元,所以4在一个新的存储单元存放
        unsigned y:29;//由于前面的4在一个新的存储单元的开头存放,且29+4>32, 故在另一个新的存储单元存放
}A;               //所以最后求出的A的大小是4 + 4 + 4 =12

/*对上面的具体解释: 一个位段必须存储在同一个存储单元中,不能跨两个单元.如果某存储单元空间中不能容纳
              下一个位段,则改空间不用,而从下一个存储单元起存放该位段. 结构体A中的h和y就是这种情况.
                                        在gcc环境下,测试后,一个存储单元为4个字节.
*/

typedef struct _S
{
        unsigned a:4;
        unsigned b:4;
        unsigned c:22;
        unsigned q:1;
        unsigned h:1;
        //unsigned i:33;  // 错误:‘i’ 的宽度超过它自身的类型
        //unsigned i:1;当多出此行时,该结构体大小由4变为8,因为此行之前正好为32位
} S;

typedef struct _T
{       //当没有占满一个存储单元时,结构体的大小对齐为一个存储单元的大小
        unsigned a:2;
        unsigned b:2;
        unsigned j:1;
        unsigned : 1;//可以定义无名位段,此例中该无名位段占用1位的空间,该空间将不被使用
} T;

typedef struct _V
{
        unsigned a:1;
        unsigned b:4;
        unsigned :0;    //定义长度为0的位段时不能指定名字,否则编译不过
        unsigned d:1;   //定义了0字段后,紧接着的下一个成员从下一个存储单元开始存放;
}V;                                     //此例子中,d前面那个存储单元中的余下的27位中被0填充了

int main()
{
        A a; S s; T t; V v;
        printf("sizeof(a)=%d\n", sizeof(a));
        printf("sizeof(s)=%u\nsizeof(t)=%u\n", sizeof(s), sizeof(t));
        printf("sizeof(v)=%d\n", sizeof(v));
        return 0;
}

结构体位制详解 -- C

时间: 2024-10-01 03:54:35

结构体位制详解 -- C的相关文章

Scala 深入浅出实战经典 第53讲:Scala中结构类型实战详解

王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 腾讯微云:http://url.cn/TnGbdC 360云盘:http://yunpan.cn/cQ4c2UALDjSKy 访问密码 45e2土豆:http://www.tudou.com/programs/view/pR_4sY0cJLs/优酷:http://v.youku.com/v_show/id_

结构体对齐详解【转】

 1 -- 结构体数据成员对齐的意义 许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的起始地址的值是某个数k的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus).这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度.比如这么一种处理器,它每次读写内存的时候都从某个8倍数的地址开始,一次读出或写入8个字节的数据,假如软件能保证double类型的数据都从8倍数地址开始,那么读或写一个

Java I/O : Java中的进制详解

作者:李强强 上一篇,泥瓦匠基础地讲了下Java I/O : Bit Operation 位运算.这一讲,泥瓦匠带你走进Java中的进制详解. 一.引子 在Java世界里,99%的工作都是处理这高层.那么二进制,字节码这些会在哪里用到呢? 自问自答:在跨平台的时候,就凸显神功了.比如说文件读写,数据通信,还有Java编译后的字节码文件.下面会有个数据通信的例子哦. Java对对象实现Serializablle接口,就可以将其转化为一系列字节,而在通信中,不必要关系数据如何在不同机器表示和字节的顺

07 redi sorder set结构及命令详解

zadd key score1 value1 score2 value2 .. 添加元素 redis 127.0.0.1:6379> zadd stu 18 lily 19 hmm 20 lilei 21 lilei (integer) 3 zrem key value1 value2 .. 作用: 删除集合中的元素 zremrangebyscore key min max 作用: 按照socre来删除元素,删除score在[min,max]之间的 redis 127.0.0.1:6379>

结构体位制 中存在 有符号 与 无符号 -- C

#include <stdio.h> #include <stdlib.h> #include <string.h> /* 有符号 结构体1 */ struct bits { int b1:5; /* 因为是int型,最大设置32位,由于int型是有符号整形, 所以这里5位为有符号类型. 11111 -1 10000 -16 01111 15 00000 0 */ int :2; int b2:2; /* 11 -1 10 -2 01 1 00 0 */ int b3:

go语言之行--结构体(struct)详解、链表

一.struct简介 go语言中没有像类的概念,但是可以通过结构体struct实现oop(面向对象编程).struct的成员(也叫属性或字段)可以是任何类型,如普通类型.复合类型.函数.map.interface.struct等,所以我们可以理解为go语言中的“类”. 二.struct详解 struct定义 在定义struct成员时候区分大小写,若首字母大写则该成员为公有成员(对外可见),否则是私有成员(对外不可见). type struct_variable_type struct { mem

(一)Python入门-4控制语句:02单分支选择结构-条件表达式详解

一:选择结构介绍 选择结构通过判断条件是否成立,来决定执行哪个分支.选择结构有多种形式,分为:单分 支.双分支.多分支.流程图如下: 二:单分支选择结构 if语句单分支结构的语法形式如下: if 条件表达式: 语句/语句块 其中:1条件表达式:可以是逻辑表达式.关系表达式.算术表达式等. 2语句/语句块:可以是一条语句,也可以是多条语句.多条语句,缩进必须对齐一致. 三:条件表达式详解 在选择和循环结构中,条件表达式的值为 False的情况如下: False.0.0.0.空值 None.空序列对

浅谈IP地址和子网掩码的对应关系,以及2进制和10进制详解!

大家好,我是带你们成长的凡凡- IP地址的结构:     #长度为 32 bit:先    #结构 - 网络位 + 主机位 子网掩码:      -作用           区分IP地址中的网络位与主机位          必须与IP地址,一一对应,成对出现:  -表示         纯2进制          点分十进制 (y.y.y.y) ->y的取值范围是 0 --255         /n (n表示的是子网掩码中有多少个1)      -功能实现         子网掩码中1所对应的

React在开发中的常用结构以及功能详解

一.React什么算法,什么虚拟DOM,什么核心内容网上一大堆,请自行google. 但是能把算法说清楚,虚拟DOM说清楚的聊聊无几.对开发又没卵用,还不如来点干货看看咋用. 二.结构如下: import reqwest from 'reqwest'; import React from 'react'; import ReactDOM from 'react-dom'; var Header = React.createClass({ handleClick:function(){ conso