1. 程式人生 > >No.23 經典筆試題:用巨集來計算偏移量,判斷大小端(聯合體法,指標法)

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是平臺無關的,預設是大端。在網路上傳輸資料普遍採用的都是大端。(摘自百度百科)