c++的 union型別平時用的真心少 從來沒有認真研究過他
今天看了幾道c++的筆試題 有幾道 關於union的 題目 現在總結下
第一題:
union v x;
unsigned char c;
} v;
v.c = 100;
printf("%d", v.x.s3);
答案為 3 (s2 為 1 , s1為0)
網上的解釋
v是聯合體(共用體)變數,共有兩個元素x和c,都需要乙個位元組,它們分配於同乙個位址。
而x是結構體變數,共有三個元素s1、s2、s3,分別佔2位、3位、3位。分配記憶體時低位在前,最位在後。
當有v.c=100(其二進位制為01100100)時,各變數的關係及記憶體儲存情況見圖所示。
其中x的成員s3為二進位制的011,即十進位制的3,所以輸出結果為3。
同理的第二題:
#i nclude union
a;void main()
int 為 .. ... 0000 0001 0000 0010
學習中 看了些文章 有所收穫 下面轉兩篇文章
一篇是 union和struct的 大小問題
1,對於union,對齊的大小是最大的基本元素的對齊大小;物件的大小必須是該基本元素大小的整數倍;
2,對於struct,對齊的大小也是最大的基本元素的對齊大小,物件的大小需要考慮元素的對齊,並且需要是最大基本元素的整數倍;同時有#pragma pack修飾的情況,關於struct請詳細參考另外乙個帖子。
3,這裡所說的struct和union的對齊,是指其作為其他複雜物件中的元素的時候要求的對齊,對於本身大小的計算並沒有關係。本身的大小只和其所包含的基本元素的對齊有關係。
(copy 一段網上的對齊規則 1,資料成員對齊規則:結構的資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小的整數倍開始(比如int在32位機為4位元組,則要從4的整數倍位址開始儲存) 2,,結構體作為成員:如果乙個結構體裡有某些結構體成員,則結構體成員要從其內部最大元素大小的整數倍位址開始儲存(struct a裡存有 stuct b, b裡有char,int,double等元素,那麼b應該從8的整數倍開始儲存) 3,收尾工作:結構體的總大小,也就是sizeof的結果,必須是其內部最大成員的整數倍,不足的要補齊。)
例子一:
union u1
;所以該union的對齊大小是4個位元組;大小為大於等於max(9,4)=9並為4的整數倍,所以是12位元組。
例子二:
union u1_another
;所以該union的對齊大小是8個位元組,大小是大於等於9並為8的整數倍,即為16位元組;
例子三:
union u2
;所以該union的對齊大小是8個位元組,大小是16;
例子四:
struct s1
所以該結構體是8位元組對齊,大小為24個位元組;
另一篇是 union和大小端模式 :
一.union資料型別
union顧名思義,聯合體,float,int,char等等型別資料共用一塊記憶體空間。其大小為佔據記憶體空間最大的那個變數的空間大小。
eg:union
float a;
char b[2];
}u_test;
那麼union所佔的記憶體空間大小為float型別變數a所佔的記憶體大小,在常見32位計算機上為4位元組。
二.大小端對union的影響
一般x86體系的計算機採用的是小端模式:高高低低,高位元組資料存放在記憶體中的高位址處,低位元組資料存放在記憶體中的低位址處。
反之,大端模式就是高低高低了,高位元組資料存放在記憶體中的低位址處,低位元組資料存放在記憶體中的高位址處。
16bit寬的數0x1234在little-endian模式(以及big-endian模式)cpu記憶體中的存放方式(假設從位址0x4000開始存放)為:
記憶體位址
小端模式存放內容
大端模式存放內容
0x4000
0x34
0x12
0x4001
0x12
0x34
說明:記憶體中最小的單位為1位元組(8bit),上表中的0x4000正是這樣乙個位元組記憶體,顯然相對於0x4001而言,0x4000是低位址。低位元組資料
0x34
就存放於記憶體的低位址
0x4000
處,而高位元組資料
0x12
就存放於記憶體的高位址
0x4001處。
32bit寬的數0x12345678在little-endian模式以及big-endian模式)cpu記憶體中的存放方式(假設從位址0x4000開始存放)為:
記憶體位址
小端模式存放內容
大端模式存放內容
0x4000
0x78
0x12
0x4001
0x56
0x34
0x4002
0x34
0x56
0x4003
0x12
0x78
三.測試大小端對union的影響,假設union分配的記憶體位址首位址為0,
eg:union u_test
int a;
char b[2];
}mm;
寫乙個測試函式:
void test_union(void)
mm.a = 65*256 + 97;
printf("union's b[0] is: %c,b[1] is: %c\n",mm.b[0],mm.b[1]);
這個結構體的大小為int a的大小4位元組。假設在記憶體中是從位址0開始的連續4個單位。顯然這4個位元組的記憶體塊的存放著a的值。則按照高高低低的原則,低記憶體位址0應該存放的是低位元組資料97,依此往下存放,即記憶體位址為1的記憶體單元存放著十進位制數為65的資料,記憶體位址為2的記憶體單元存放著0,記憶體位址為3的記憶體單元存放著0。
記憶體位址
小端模式存放內容
存放著十進位制97
存放著十進位制65
所以上面的函式test_union執行的結果將會是列印小寫字母a(97)和大寫字母a(65).
那如果是大端模式將會是怎樣的結果呢?如下:
記憶體位址
大端模式存放內容
十進位制65
十進位制97
四.測試cpu是大端還是小端模式?
當然對於一般的cpu,我們已經了解到:
big endian : powerpc、ibm、sun
little endian : x86、dec
arm既可以工作在大端模式,也可以工作在小端模式。
如果不知平台到底執行於何種模式,也根據上面的這些特性可以自己測試出來?/*
** 函式名:checkcpu
** 輸 入:none
** 輸 出:0-
- 大端模式
** 1-
- 小端模式
** 功 能:檢測cpu的大小端模式*/
int checkcpu(void)
c;c.i = 1;
return (c.j =
= 1);}
如果為big為 00 00 00 01 然後j對齊低位址 為 00 所以c.j==0
或者:
bool isbigendian()
注: 轉換 也是從地位址開始處理 若為 little usdata 存為 22 11 pucdata從低位址開始獲取 則為 22
若為 big usdata存為 11 22 pucdata從低位址開始獲取 則為 11
今日學習總計
1.1 numpy numpy常用資料結構 numpy中常用的資料結構是ndarray格式 使用array函式建立,語法格式為array 列表或元組 可以使用其他函式例如arange linspace zeros等建立 numpy常用方法 ndim 返回int,表示ndarray的維度 shape ...
今日學習總計
有以下兩個重要的步驟來使系統的廣播意圖配合廣播接收器工作。建立廣播接收器 註冊廣播接收器 還有乙個附加的步驟,要實現自定義的意圖,你必須建立並廣播這些意圖。建立廣播接收器 廣播接收器需要實現為broadcastreceiver類的子類,並重寫onreceive 方法來接收以intent物件為引數的訊...
今日學習總計
bean 的裝配可以理解為依賴關係注入,bean 的裝配方式也就是 bean 的依賴注入方式。spring 容器支援多種形式的 bean 的裝配方式,如基於 xml 的 bean 裝配 基於 annotation 的 bean 裝配和自動裝配等。spring 基於 xml 的裝配通常採用兩種實現方式...