1. 程式人生 > 其它 >(*(volatile unsigned int *)0x0000FFF0)

(*(volatile unsigned int *)0x0000FFF0)

(*(volatile unsigned int *)0x0000FFF0)

在MCU的底層驅動中經常看到這樣的對暫存器地址操作的C語言寫法,下面來一一分析下這個

為了簡化對該表示式的理解可以分兩步走

對上面表示式進行簡化如下:

(*(volatile unsigned int *)(x)) 注意這裡將上面常量用一個變數替換是便於下面分析

再簡化

p=(volatile unsigned int *)(x)

(*p)

再簡化我們拿掉看不懂的volatile

1) p=( unsigned int *)(x)

2) (*p)

現在就很清楚了,第一個表示式將變數x轉換為指標,該指標我們給它取名為p,原先x本來是存資料的,現在無非是拿來存地址了,就是這樣。

第二個表示式就更簡單了就是取該指標裡的值

現在我們變換一下,將x變數換成常量,這裡先給個值吧,比如就是標題的0x0000FFF0

還是一樣分兩步走

1) p=( unsigned int *)(0x0000FFF0)

2) (*p)

第一個表示式將常量轉換為指標,第二個表示式就是取該指標所存取地址的值,現在問題來了那常數是不可以存地址的,所以很明顯了這裡常數就是該地址值,所以就可以概括了,就是0x0000FFF0地址的值

還有最後一個問題要解決了,就是這個型別轉換前面的volatile

這個其實就是告訴編譯器對該變數不要進行優化,每次都是從該地址讀取資料,這樣是為了防止一些錯誤。

還是舉個例子來說好了

Int *a,int b;

b=(*a) *(*a);

單單看第二個表示式,可以知道需要在a所指向的地址連續取兩次值,而計算機中一般取的值肯定是存在某一個儲存空間上的,計算機在編譯這段程式碼時會考慮到讀取效率的問題,就會將讀取兩次值改為一次,怎麼改呢,那就是先將a所指向的地址取一次值,然後儲存起來,以後用到的話,就直接用儲存起來的那個值就好了。

計算機優化後的程式碼可能長成這樣:

Int *a,int b;

c= *a;

b=c*c;

但是若是在*a前面加了volatile情況就會像我們所想那樣工作,而不會被編譯器優化了,其實這個主要的好處還是為了減少錯誤,試著想一下,當將一個地址拿來的東西存到一個地方,萬一那個地方出了問題,資料丟失了就糟糕了,當然這只是萬一。

綜合分析來看,為了提高程式碼執行效率,就不加volatile,有利於程式碼優化,提升計算機執行效率,但為了防止關鍵資料丟失或減少不確定性,就加volatile,減少錯誤發生。

最後要記住volatile:中文意思為易變的