C的聯合體(測試資料儲存的大小端模式) 位段(位段與位的對應關係)
/x86/Debian GNU/Linux/gcc
1 聯合體
(1)聯合體機制
聯合體的所有成員引用的是記憶體中的相同地址。訪問聯合的不同成員時,會根據此成員的型別去訪問對應的位元組,並根據此成員的型別去解釋這些位元組對應位的含義(表示int還是float)。
聯合體初始化時,初始化的是聯合的第一個成員(所以型別應該與聯合的第一個成員相同,否則會發生型別轉換),而且初始值必須位於一對大括號內。
(2)用聯合體測平臺數據儲存是大端還是小端
要想知道平臺採用的大端還是小端的方式儲存資料,可以看.c檔案對應的目標檔案或者可執行檔案。在知道系統採用的儲存方式後,可以反推記憶體地址採用的高地址還是低地址來表示。
//When this paltom uses litte address to be many bytes's address //Test platom is litte or bit endian void test_endian(void) { printf("\n--------------test_endian function------------------\n"); union one_test{ unsigned int i; unsigned char ch; }my_test={1}; printf("address of i = %p\naddress of ch = %p\n\n", &my_test.i, &my_test.ch); printf("ch = %d\nhex dump of ch = 0x%x\n", my_test.ch, my_test.ch); if(my_test.ch == 1){ printf("This platom uses litte endian\n"); }else{ printf("This platom uses big endian\n"); } }
聯合體my_test中的i和ch的記憶體地址相同。不同的是,訪問my_test.i時會讀sizeof(unsigned int)位元組內容並按照int型別解釋這些位;訪問my_test.ch時會讀一個位元組內容並按照char型別(實質是int)解釋這些位。
my_test經初始化後,my_test.ch與my_test.i的第一個位元組(表示整個變數的地址)內容相同。如果系統採用低地址來作為一個型別的地址(int佔4個位元組,用4個位元組中的最低地址表示int變數的地址),那麼以上程式就能夠測試出系統採用的大端還是小端方式儲存資料。如果my_test.ch值為1則表示系統採用小端方式儲存資料,否則為大端方式。如果系統採用高地址來作為一個型別的地址,那麼
將這段程式碼放在main函式中,某次執行的結果如下:
--------------test_endian function------------------ address of i = 0xbff03cdc address of ch = 0xbff03cdc ch = 1 hex dump of ch = 0x1 This platom uses litte endian |
已經在某.c檔案的目標檔案中得知/x86/Debian GNU/Linux平臺採用的小端方式儲存資料,故而得它用的低地址表示記憶體段地址。
2 位段
(1)結構體成員的儲存地址
陣列元素的地址按照下標連續遞增。結構體內的成員的地址雖不連續,但會按照成員的定義順序各成員的地址會由低到高。
(2)位段的儲存
//Test Bit-field's memory layout
void test_bit_field_layout(void)
{
printf("\n--------------test_bit_field_layout---------------\n");
union two_test{
struct bit_field{
unsigned int one :8;
unsigned int two :1;
unsigned int three :3;
unsigned int :4;
unsigned int four :1;
unsigned int five :8;
}my_bit_field;
unsigned char byte[4];
}my_test={{2, 1, 4, 1, 16}};
printf("value of byte:\nbyte[0] = %d\tbyte[1] = %d\tbyte[2] = %d\tbyte[3] = %d\n", \
my_test.byte[0], my_test.byte[1], my_test.byte[2], my_test.byte[3]);
printf("\nhex dump of byte:\nbyte[0] = 0x%x\tbyte[1] = 0x%x\tbyte[2] = 0x%x\tbyte[3] = 0x%x\n", \
my_test.byte[0], my_test.byte[1], my_test.byte[2], my_test.byte[3]);
}
將這個函式放在main函式中,某次執行得到的結果如下:
--------------test_bit_field_layout--------------- value of byte: byte[0] = 2byte[1] = 9byte[2] = 33byte[3] = 0 hex dump of byte: byte[0] = 0x2 byte[1] = 0x9 byte[2] = 0x21 byte[3] = 0x0 |
分析各位段儲存的資料(以小端的方式儲存):
如果將未命名的欄位unsignedint :4;遮蔽,則程式執行如下:
--------------test_bit_field_layout--------------- value of byte: byte[0] = 2byte[1] = 25byte[2] = 2byte[3] = 0 hex dump of byte: byte[0] = 0x2 byte[1] = 0x19 byte[2] = 0x2 byte[3] = 0x0 |
則各位段儲存的資料(以小端的方式儲存):
與一般結構體一樣,為了訪問的效率,編譯器可能會在兩個位段間及結構體末尾加入填充位。
關於如何排列Bit-field在C標準中沒有詳細的規定,這跟Byte Order、Bit Order、對齊等問題都有關,不同的平臺和編譯器可能會排列得很不一樣,要編寫可移植的程式碼就不能假定Bit-field是按某一種固定方式排列的。同時Bit-field在驅動程式中是很有用的,因為經常需要單獨操作裝置暫存器中的一個或幾個bit,但一定要小心使用,首先弄清楚每個Bit-field和實際bit的對應關係。
CNote Over.
相關推薦
C++檢視資料儲存大小端模式
所謂的大端模式,是指資料的低位儲存在記憶體的高地址中,而資料的高位,儲存在記憶體的低地址中; 所謂的小端模式,是指資料的低位儲存在記憶體的低地址中,而資料的高位儲存在記憶體的高地址中。 舉個例子,16bit的short型別整數0x1234,會佔用兩個大B(Byte位元組),即兩個記憶體單
C的聯合體(測試資料儲存的大小端模式) 位段(位段與位的對應關係)
/x86/Debian GNU/Linux/gcc 1 聯合體 (1)聯合體機制 聯合體的所有成員引用的是記憶體中的相同地址。訪問聯合的不同成員時,會根據此成員的型別去訪問對應的位元組,並根據此成員
程式設計測試計算機儲存的大小端模式
大端模式:低位位元組存在高地址上,高位位元組存在低地址上 小端模式:高位位元組存在高地址上,低位位元組存在低地址上 例如對於0x11223344儲存如下 用union來測試機器的大小端模式 #include <stdio.h> // 共用體中很重要的一點:a和b都是
SHA1--C語言實現--openssl-1.1.1改寫(自動匹配晶片大小端)
改寫自 openssl-1.1.1的SHA1的C語言實現,高效,自動匹配處理器大小端 # define SHA_LBLOCK 16 # define SHA_CBLOCK (SHA_LBLOCK*4)/* SHA treats input data as
C語言判斷資料儲存時大端模式還是小端模式
用C語言寫程式時需要知道是大端模式還是小端模式。所謂的大端模式,是指資料的低位儲存在記憶體的高地址中,而資料的高位,儲存在記憶體的低地址中;所謂的小端模式,是指資料的低位儲存在記憶體的低地址中,而資料的高位儲存在記憶體的高地址中。為什麼會有大小端模式之分呢?這是因為在計算機系
Android 資料持久化技術(即資料儲存方式)
在討論資料持久化技術之前我們先了解幾個概念? 什麼是瞬時資料:儲存在記憶體當中,有可能會因為程式的關閉或其他原因導致記憶體被收回而丟失的資料。 為什麼採用資料持久化技術:為了保證關鍵資料在程式退出時不被丟失。 什麼是資料持久化技術:將記憶體中的瞬時資料
現代C語言程式設計之資料儲存
C語言 2.1 計算機資訊資料儲存 2.1.1 計算機資訊資料儲存單位 在計算機最底層,資料都是以二進位制(01010)的方式儲存,而計算機中最小的儲存單位是位(bit),用來表示0或者1。計算機中最基本的儲存單位是位元組(Byte),1個位元組對應8個位(B
javaSE (三十四)File類和遞迴練習(統計資料夾大小、拷貝資料夾、層級列印資料夾、斐波拉契數列、獲取1000階乘全部0和尾部0數目、約瑟夫環)
1、統計資料夾大小: 思路: 套用之前已經做過的,鍵入一個路徑,若有效則封裝成File類 初始化計數器len, 若資料夾下是檔案,則記錄檔案.length() 若資料夾下是資料夾,遞迴 輸出len 注:遞迴也可以刪除資料夾,但是一定要先刪除裡
大小端模式(詳)
什麼是大小端模式 大端(儲存)模式:資料的低位儲存在記憶體的高地址中,資料的高位儲存在記憶體的低地址中; 小端(儲存)模式:資料的低位儲存在記憶體的低地址中,資料的高位儲存在記憶體的高地址中。 那麼如何來判斷自己的機器是哪種儲存模式呢? 程式碼一: #defin
Python 與下位機交流字串轉化方式(大小端模式)
1、說在前面的話 博主這個篇部落格想要說明的是,一個將整數型別轉化成一個可用於傳輸的16進位制字串流的形式 2、具體方法 方法一: 採用python中自帶的 hex() 函式,這個函式用於簡單的轉換可以,但是用用於轉換負數的時候,就不在是我們希望的能夠按照補
現代C語言程式設計之資料儲存(一)
2.1 計算機資訊儲存 2.1.1 計算機常用儲存單位 在計算機最底層,資料都是以二進位制(01010)的補碼方式儲存,而計算機中最小的儲存單位是位(bit),用來表示0或者1。 計算機中最基本的儲存單位是位元組(Byte),1個位元組對應8個位(Bit)。 而日常應用中常使用的
c++解析tcp頭部遇到的大小端轉換問題
首先要明白大端儲存和小端儲存的問題,windows系統使用小端儲存,而網路傳輸中的資料採用的是大端儲存。 關於大小端儲存 網上流傳的tcp頭部的結構體是這樣的 // TCP頭部(20位元組) typedef struct _tcp_header { unsigned short
C語言筆記之資料儲存型別
變數的儲存型別是指儲存變數值的記憶體型別。變數的儲存型別決定變數何時建立,何時銷燬以及他的值要儲存多久。 在任何程式碼塊之外申明的變數總是儲存與靜態記憶體中(不屬於堆疊的記憶體),這叫做靜態(static)變數。對於這種變數,你無法為他們指定其
hive安裝過程:metastore(元資料儲存)的三種方式之本地mysql方式
Hive版本:apache-hive-1.2.1 Hadoop版本:hadoop-2.5.1 Hive中metastore(元資料儲存)的三種方式: a)本地Derby方式 b)本地mysql方式 c)Remote方式 2、解壓
微控制器儲存中的大小端模式
請寫一個C函式,若處理器是Big_endian的,則返回0;若是Little_endian的,則返回1 解答: int checkCPU( ) { { union w {
MySQL遷移資料(切換資料儲存的資料夾)
備註:此流程是針對windows下相同版本(5.7.20)的(不同版本之間的遷移可參考,不一定成功,本人沒有測試) 1、首先做好資料備份,將原來的data資料夾(我的目錄D:\company\mysql-5.7.20-winx64\data)複製備份 2、停
C語言面試題——位域及大小端模式的理解
這裡涉及大小端的問題,我記為 “小高高,小弟弟(低低)”,就是: “小端模式,是指資料的高位儲存在記憶體的高地址中,資料的低位儲存在記憶體的低地址中” 這是記小端模式的,有點黃,不過好記!那麼大端模式就和這個相反嘍!!~~ 接下來就看一道面試題: #include<
webkitdirectory 實現資料夾上傳(包含資料夾大小和檔案個數的校驗)
由於工作中業務需要在介面提供使用者上傳資料夾的功能,平時上傳檔案做的還多一些,包括對上傳檔案也有許多外掛提供了良好的支援,比如fileinput.js,還有webupload.js。。。,但對上傳資料夾的支援就沒有,h5裡提供了webkitdirectory 來實現上傳資
判斷機器的大小端模式
大端 共用體 大小端模式:大端模式,是指數據的高字節保存在內存的低地址中,而數據的低字節保存在內存的高地址中,這樣的存儲模式有點兒類似於把數據當作字符串順序處理:地址由小向大增加,而數據從高位往低位放;這和我們的閱讀習慣一致。小端模式,是指數據的高字節保存在內存的高地址中,而數據的低字節保存在內存的低
大小端模式,內存地址高低位,寄存器高低位
.net ims family 個數 32位 指數 這樣的 空格 sun 原文鏈接:https://blog.csdn.net/Andyzzhz/article/details/40405451 CPU:大小端模式的區別: 大端模式(Big-endian),是指數