今天重新溫習了一下C語言的指針部分,突然想到了經常會碰見的一種宏定義:#define PGAS (*((volatile unsinged long *)(x)))
在解析該宏定義前,先看看指針變量的聲明
聲明一個int類型的指針變量:int* p;
僅僅是這樣定義,這個指針是不能夠直接拿來使用的,還必須給它賦值(初始化),例如:
int a = 10;
int* p = &a;
或:
int a = 10;
int* p;
p = &a;
其中,&a表示變量a所代表的內存地址,所以指針變量p存儲的是一個內存地址(這個地址要和指針變量p自身的地址區分開),而*p是指針變量p所指內存地址中存儲的數據(上述代碼中既是變量a的值),經過初始化的指針我們是可以拿來使用的。
例如:給這個指針所指內存地址賦值:*p = 15;
讀取這個指針所指地址中存儲的數據的值 printf(“d\n”,*p);
運行下面的代碼,可以很清楚的了解指針變量的地址和指針變量所指的地址的關系:
void main() { int a = 10; int* p = &a; printf("變量 a 的值:%x\n",a); printf("變量 a 的地址:%x\n",&a); printf("指針變量 p 的值:%x\n",p); printf("指針變量 p 的地址:%x\n",&p); system("pause"); }
運行結果:
從圖中可以看出變量a的地址和指針變量p的值是一樣的:0x23febc
回歸正題:#define PGAS (*((volatile unsinged long *)(x)))
其中,x 是一個常量,代表內存地址值,(volatile unsinged long *)(x) 是把這個常量x強制轉換為一個unsigned int 指針,(*((volatile unsinged long *)(x)))表示的是地址x中的數據。
在上面的代碼中我們可以進行類似數學公式的帶入替換:
int a = 10;
int* p;
p = &a;
一般我們要對指針變量p所指地址賦值或要讀取指針變量p所指地址中的數據時,是這樣操作的:
int b = *p;
*p = 20;
等價於:
int b = *(&a);
*(&a) = 20;
上面說了&a表示的是變量a的地址,也就是一個無符號整型(unsigned int)常量。
再看一段代碼:
#include <stdio.h> #define A (*((volatile unsigned int*)(0x23febc))) void main() { A = 20; printf("%d\n",*((unsigned int*)(0x23febc))); printf("%d\n",A); system("pause"); }
記得剛接觸到這種宏定義時,查查資料當時可以弄懂,可是等到下次再遇見時,又不明白了,總之是時而明白,時而糊塗。
以文字的形式記錄下來,可以幫自己整理整理思路加深理解和記憶。