No.23 經典筆試題:用巨集來計算偏移量,判斷大小端(聯合體法,指標法)
阿新 • • 發佈:2018-12-20
- 寫一個巨集,計算結構體中某變數相對於首地址的偏移,並給出說明
- 判斷大小端
程式碼1:
//寫一個巨集,計算結構體中某變數相對於首地址的偏移,並給出說明
//定義的這個巨集將結構體裡邊的變數的地址取出後再強轉成char型,然後進行相減。
//注意:&s == &s.num (進行驗證:請看程式碼2)
#define OFFSET(a, b) ((char*)(&b) - (char*)(&a))
#include <stdio.h>
typedef struct S{
double num ;
char ch ;
}S;
int main()
{
S s ;
printf("此結構體第二個變數相對於首地址的偏移為: %d\n", OFFSET(s, s.ch)) ;
return 0 ;
}
執行結果:
程式碼2:測試程式
//測試程式:驗證&member 是否與 &member.sch_num 相等
#include <stdio.h>
typedef struct Node{
int sch_num ;
char add[20] ;
}Node ;
int main()
{
Node member = {10101, "beijing"} ; //定義結構體成員
printf("結構體地址為: %p\n", & member) ;
printf("結構體成員第一個變數首地址為: %p\n", &member.sch_num) ;
return 0 ;
}
執行結果:
程式碼3.1:聯合體法判斷大小端
//聯合體判斷大小端
#include <stdio.h>
union Un
{
int a ;
char i ;
};
int main()
{
union Un u ;
u.a = 0x12345678 ;
//在int的四個位元組裡,i佔一個位元組。通過列印i空間裡的值,看看i所佔的空間裡值是多少
//若值為12,則表示大端儲存;若為78,則表示小端儲存。
printf ("聯合體判斷大小端:\n") ;
printf("u.i = %x\n", u.i) ;
return 0 ;
}
執行結果:
程式碼3.2:指標法判斷大小端
//指標法判斷大小端
#include <stdio.h>
int main()
{
int a = 0x12345678 ;
char* p = (char*)&a ;
//定義一個char型別的指標,將a進行&a並進行強轉,打印出p所指的記憶體裡的值
//若值為12,則表示大端儲存;若為78,則表示小端儲存。
printf("指標法判斷大小端:\n") ;
printf("%x\n", *p) ;
return 0 ;
}
執行結果:
附加: 目前Intel的80x86系列晶片是唯一還在堅持使用小端的晶片,ARM晶片預設採用小端,但可以切換為大端;而MIPS等晶片要麼採用全部大端的方式儲存,要麼提供選項支援大端——可以在大小端之間切換。另外,對於大小端的處理也和編譯器的實現有關,在C語言中,預設是小端(但在一些對於微控制器的實現中卻是基於大端,比如Keil 51C),Java是平臺無關的,預設是大端。在網路上傳輸資料普遍採用的都是大端。(摘自百度百科)