我在 C 中有一個結構如下:
typedef struct ENETPACKET_S {
unsigned n_rxcmd, n_txcmd;
uint64_t n_mac; // 8 bytes unsigned or 64 bit
unsigned n_rxmiss, n_rxerr, n_rxcrc, n_txcol;
} ENETPACKET;
在下面這個結構的變數中定義了一個指標:
static volatile ENETPACKET *const _net1 = ((ENETPACKET *)0x00500000);
我有兩個疑問:
我理解指向結構的指標,但在宣告中
_net1,定義了來自結構的變數/物件的指標。我不明白。我
((ENETPACKET *)0x00500000)對const指標的初始化感到困惑,我不明白這里正在初始化什么以及括號和*運算子。
uj5u.com熱心網友回復:
您似乎正在使用可能帶有微控制器的嵌入式設備。在這樣的系統中,可以通過設定一些暫存器來配置/使用一些外圍設備。這些暫存器可以直接讀取/寫入,因為它是您的 C 程式可用的記憶體。
舉一個小例子來說明它的樣子:
/* Control the PIN10 (input/output) */
/* The CONTROLLER of PIN10 is mapped at the address 0x00400000 */
static volatile uint8_t * const PIN10_CTRL = 0x00400000;
/* PIN10 control the output PIN of the MCU who is connected to a LED */
/* The STATUS of the PIN10 is mapped at the address 0x00400001 */
static volatile uint8_t * const PIN10 = 0x00400001;
*PIN10_CTRL = 0x1; /* Configure the PIN10 as a output PIN */
/* Blink the LED every second */
while (1)
{
*PIN10 = 1;
sleep(1);
*PIN10 = 0;
sleep(1);
}
如果我們現在考慮您的代碼:
static volatile ENETPACKET *const _net1 = ((ENETPACKET *)0x00500000);
它看起來像你的微控制器的網路介面是把一個結果ENETPACKET的地址0x00500000。這個地址是固定的,可以在微控制器的用戶手冊中找到。
該結構是可變的,以防止編譯器對他將生成的二進制代碼進行任何假設。如果省略了關鍵字volatile,您可能會對程式進行一些優化,并且資料會過時。
這個地址0x00500000可能是一組N x ENETPACKET資料包的地址。
uj5u.com熱心網友回復:
對于您的第一個問題(有點不清楚),也許考慮如何宣告和初始化指向簡單物件的指標:
int i; // declares "i" as an "int"
int* p; // declares "p" as a "pointer to an int"
int* pi = &i; // declares "pi" as a pointer-to-int and initializes with address of "i"
同樣,去掉各種限定符:
ENETPACKET str; // Declares "str" as an actual ENETPACKET structure
ENETPACKET *pstr = &str; // pstr is a pointer-to-structure set to address of "str"
現在,在(和名稱之前)之后的const限定符意味著您的代碼不能(絕不能)更改在其初始化中分配給變數的值(地址),但實際資料指向(即結構和它的值members)可以更改:指標是,而不是參考的資料;據推測,這是因為分配的值是硬體中的特定位置。*_net1const
對于您的第二點,(ENETPACKET*)前面的常量是強制轉換運算子;沒有它,您的編譯器會將0x00500000視為一個整數常量并生成如下所示的警告(來自 clang-cl):
警告:不兼容的整數到指標轉換初始化 'volatile ENETPACKET *const'(又名 'volatile struct ENETPACKET_S *const')使用型別為“int”的運算式 [-Wint-conversion]
添加顯式轉換會告訴編譯器:“是的,我知道型別不一樣,但我知道我在做什么,并且希望您將它們視為兼容的。” 謹慎使用石膏!
第二個(外部)括號實際上不是必需的,但作者為了清楚起見添加了(這是一件好事);如果使用的值從常量/文字(目前如此)更改為涉及指標算術的更復雜的運算式,或者在(可能更有可能)使用宏代替固定文字的情況下,它們可能變得很重要.
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/406175.html
標籤:
