C語言基礎

#define GPIO_BASE 0x40020000u
volatile uint32_t *const odr =
    (volatile uint32_t *)(GPIO_BASE + 0x14);
*odr |= 1u << 5;

微控制器的輸出暫存器以上方的方式宣告並使用。關於這個宣告的說明,下列何者正確?

  1. A*odr 的值不能改寫,而 odr 本身可能因中斷而改變,因此每次使用時都會重新讀取
  2. B因為加上了 volatile,*odr |= 1u << 5 的讀取、修改、寫入會成為不會被中斷打斷的一連串操作
  3. Codr 所指向的位址不能改變,透過 odr 的讀寫不會被省略,會依撰寫的次數實際執行
查看答案與解析

正確答案:C. odr 所指向的位址不能改變,透過 odr 的讀寫不會被省略,會依撰寫的次數實際執行

const 在 * 的右邊,表示 odr 這個指標本身不能改變,永遠指向同一個暫存器的位址。所指向的 uint32_t 加上了 volatile,因此編譯器不會省略或合併對 *odr 的讀寫,會依撰寫的次數實際存取。不過 volatile 不會讓操作不可分割,因此在 *odr |= … 的讀取與寫入之間仍可能發生中斷。若中斷處理常式也操作同一個暫存器,應在那段期間禁止中斷,或使用專門用來設定位元的暫存器。

  • A. 這是把 const 與 volatile 的對象讀反的說明。const 加在指標本身,volatile 加在所指向的內容。
  • B. volatile 只讓存取不被省略,不會讓從讀取到寫入的過程不可分割。
  • C. 正確。指標本身是 const,所指向的暫存器是 volatile。
練習這個領域 前往領域頁面

C語言基礎的其他題目

  1. 關於C語言標準所說的未定義行為,下列說明何者正確?
  2. int 與 unsigned int 為32位元。下列何者依C語言的標準屬於未定義行為?
  3. 以 gcc 啟用最佳化來編譯上方的函式時,if (p == NULL) 的判斷可能被刪除。其理由為下列何者?
  4. C語言的標準中,關於 int 型別的大小有何規定?下列何者正確?
  5. 在嵌入式程式中,存放32位元周邊暫存器值的變數,常以 stdint.h 的 uint32_t 宣告,而不是 unsigned int。主要理由為下列何者?