No.23 經典筆試題:用宏來計算偏移量,判斷大小端(聯合體法,指針法)

  1. 寫一個宏,計算結構體中某變量相對於首地址的偏移,並給出說明
  2. 判斷大小端

代碼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是平臺無關的,默認是大端。在網絡上傳輸數據普遍採用的都是大端。(摘自百度百科)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章