指針之 *((volatile unsigned long *)(x))解析


  今天重新溫習了一下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");
}

     記得剛接觸到這種宏定義時,查查資料當時可以弄懂,可是等到下次再遇見時,又不明白了,總之是時而明白,時而糊塗。

以文字的形式記錄下來,可以幫自己整理整理思路加深理解和記憶。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM