C C++位域Word文档下载推荐.docx
- 文档编号:19334519
- 上传时间:2023-01-05
- 格式:DOCX
- 页数:10
- 大小:18.71KB
C C++位域Word文档下载推荐.docx
《C C++位域Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《C C++位域Word文档下载推荐.docx(10页珍藏版)》请在冰豆网上搜索。
16.inet_ntoa(0x87654321);
17.}
//假设硬件平台是intelx86(littleendian)
typedefunsignedintuint32_t;
voidinet_ntoa(uint32_tin)
{
charb[18];
registerchar*p;
p=(char*)&
#defineUC(b)(((int)b)&
sprintf(b,"
printf(b);
}
intmain()
inet_ntoa(0x12345678);
inet_ntoa(0x87654321);
有点难度的一道题目,其实理解的也很简单。
位域(Bit-fields)分析
位域是c++和c里面都有的一个概念,但是位域有一点要注意的有很多问题我们一样样的看:
大端和小端字节序
这个很简单,就是起始点该怎么确定。
先看一个程序:
1.union{
2.struct
3.{
4.unsignedchara1:
2;
5.unsignedchara2:
3;
6.unsignedchara3:
7.}x;
8.unsignedcharb;
9.}d;
10.intmain(intargc,char*argv[])
11.{
12.d.b=100;
13.return0;
14.}
那么x的a1,a2,a3该怎么分配值,100的二进制是:
01100100,那么a1到a3是不是就是依次取值恩?
不是!
我们先看看100分配位的低端是左边的0还是右边的0?
很明显是右边的0,那么我们再看a1到a3的分配是从低端到高端的
那么,对应的应该是
<
--内存增大
a3a2a1
01100100
内存增大之所以这么写是因为,011是在高位!
而不是通常认为的的:
a1a2a3
还有一个情况多见就是一个二进制的数字转化为点分十进制数值,如何进行,这里涉及到大端还是小端的问题,上面没有涉及,主要是因为上面是一个字节,没有这个问题,多个字节就有大端和小端的问题了,或许我们应该记住这一点就是,在我们的计算机上面,大端和小端都是以字节为准的,当然严格来说更应该以位为准不是吗?
具体可以参考维基百科上面的一篇文章,他给出了一个以位为准的大小端序的图:
http:
//en.wikipedia.org/wiki/Endianess
下面研究字节为单位的大小端序,继续看代码吧,如下:
1.intmain(intargc,char*argv[])
2.{
3.inta=0x12345678;
4.char*p=(char*)&
a;
5.charstr[20];
6.sprintf(str,"
%d.%d.%d.%d"
p[0],p[1],p[2],p[3]);
7.printf(str);
8.return0;
9.}
这个程序假设是小端字节序,那么结果是什么?
我们看看应该怎么放置呢?
每个字节8位,0x12345678分成4个字节,就是从高位字节到低位字节:
12,34,56,78,那么这里该怎么放?
如下:
---->
>
内存增大
78563412
因为这个是小端,那么小内存对应低位字节,就是上面的结构。
接下来的问题又有点迷糊了,就是p怎么指向,是不是指向0x12345678的开头--12处?
12是我们所谓的开头,但是不是内存
的开始处,我们看看内存的分布,我们如果了解p[0]到p[1]的操作是&
p[0]+1,就知道了,p[1]地址比p[0]地址大,也就是说p的地址
也是随内存递增的!
12^p[3]
|
34|p[2]
56|p[1]
78|p[0]
内存随着箭头增大!
同时小端存储也是低位到高位在内存中的增加!
这样我们知道了内存怎么分布了
那么:
1.sprintf(str,"
str就是这个结果了:
120.86.52.18
那么反过来呢?
3.inta=0x87654321;
依旧是小端,8位是一个字节那么就是这样的啦:
87^p[3]
65|p[2]
43|p[1]
21|p[0]
结果是:
33.67.101.-121
为什么是负的?
因为系统默认的char是有符号的,本来是0x87也就是135,大于127因此就减去256得到-121
那么要正的该怎么的弄?
如下就是了:
4.unsignedchar*p=(unsignedchar*)&
用无符号的!
结果:
33.67.101.135
位域的符号(正负)
看完大端和小端以后,再看看位域的取值的问题,上面我们谈到了一些,首先就是位域是按照位来取值的跟我们的int是32位char是8
位一样,很简单,但是,要注意一点就是位域也有正负,指有符号属性的,就是最高位表示的,也会涉及到补码这个一般被认为非常
恶心的东西,看看程序吧:
1.#include<
stdio.h>
2.#include<
stdlib.h>
3.#include<
string.h>
4.intmain(intargc,char**argv)
5.{
6.union
7.{
8.struct
9.{
10.unsignedchara:
1;
11.unsignedcharb:
12.unsignedcharc:
13.}d;
14.unsignedchare;
15.}f;
16.f.e=1;
17.printf("
%d\n"
f.d.a);
18.return0;
19.}
小端>
那么输出是什么?
换一下:
10.chara:
11.charb:
12.charc:
14.chare;
输出又是什么?
小端的话,那么,再d.a上面分得1,而这个是无符号的char,那么前者输出是1,没有问题,第二个输出是-1,哈哈。
为什么?
第二个是无符号的,就一个位分得1,那么就是最高位分得1,就是负数,负数用的补码,实际的值是取反加1,就是0+1=1,再取符
号负数,就是-1.
整型提升
最后的打印是用的%d,那么就是对应的int的打印,这里的位域肯定要提升,这里有一点,不管是提升到有符号还是无符号,都是自
己的符号位来补充,而不改变值的大小(这里说的不改变值大小是用相同的符号属性来读取),负数前面都补充1,正数都是用0来补充
,而且也只有这样才能保证值不变,比如,char提升到int就是前面补充24个char的最高位,比如:
1.charc=0xf0;
2.intp=c;
3.printf("
%d%d\n"
c,p);
输出:
-16-16
p实际上就是0xfffffff0,是负数因此就是取反加1得到
c是一个负数那么转化到x的时候就是最高位都用1来代替,得到的数不会改变值大小的。
再看:
2.unsignedintx=c;
%u\n"
x);
得到的结果是4294967280,也就是0xfffffff0,记住,无符号用%u来打印。
地址不可取
最后说的一点就是位域是一个字节单元里面的一段,是没有地址的!
附录
最后附上《TheCBook》这本书的一段说法:
Whilewe'
reonthesubjectofstructures,wemightaswelllookatbitfields.Theycanonlybedeclaredinsidea
structureoraunion,andallowyoutospecifysomeverysmallobjectsofagivennumberofbitsinlength.Their
usefulnessislimitedandtheyaren'
tseeninmanyprograms,butwe'
lldealwiththemanyway.Thisexampleshould
helptomakethingsclear:
1.struct{
2./*field4bitswide*/
3.unsignedfield1:
4;
4./*
5.*unnamed3bitfield
6.*unnamedfieldsallowforpadding
7.*/
8.unsigned:
9./*
10.*one-bitfield
11.*canonlybe0or-1intwo'
scomplement!
12.*/
13.signedfield2:
14./*alignnextfieldonastorageunit*/
15.unsigned:
0;
16.unsignedfield3:
6;
17.}full_of_fields;
Eachfieldisaccessedandmanipulatedasifitwereanordinarymemberofastructure.Thekeywordssignedand
unsignedmeanwhatyouwouldexpect,exceptthatitisinterestingtonotethata1-bitsignedfieldonatwo'
s
complementmachinecanonlytakethevalues0or-1.Thedeclarationsarepermittedtoincludetheconstand
volatilequalifiers.
Themainuseofbitfieldsiseithertoallowtightpackingofdataortobeabletospecifythefieldswithinsome
externallyproduceddatafiles.Cgivesnoguaranteeoftheorderingoffieldswithinmachinewords,soifyoudo
usethemforthelatterreason,youprogramwillnotonlybenon-portable,itwillbecompiler-dependenttoo.The
Standardsaysthatfieldsarepackedinto‘storageunits’,whicharetypicallymachinewords.Thepackingorder,and
whetherornotabitfieldmaycrossastorageunitboundary,areimplementationdefined.Toforcealignmenttoa
storageunitboundary,azerowidthfieldisusedbeforetheonethatyouwanttohavealigned.
Becarefulusingthem.Itcanrequireasurprisingamountofrun-timecodetomanipulatethesethingsandyoucan
endupusingmorespacethantheysave.
Bitfieldsdonothaveaddresses—youcan'
thavepointerstothemorarraysofthem.
最后
了解了这些我想网宿的那道题目也很简单了。
希望大家指正。
本文来自CSDN博客,转载请标明出处:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+位域 C+