1、
①C語言中爲什麼指針那麼重要呢
指針怎麼用,指針和數組的關係,指針和指定地址調用某些地址寫入數據的方法(一般是單片機編程中使用較多)
指針中野指針和內存泄露
函數指針和指針函數,函數數組,中斷向量表正好就申請一個函數數組,之後調用中斷好來調用函數。
void rt_hw_trap_irq()
typedef void (*rt_isr_handler_t)(int vector);
{
unsigned long ir;
rt_isr_handler_t isr_func;
ir = AINTC->GPIR & 0x7f; 中斷服務地址表函數獲取
isr_func = isr_table[ir];
isr_func(ir); 中斷處理
AINTC->SICR = ir; 清
}
指針和數組的關係,指針對於數組的求地址取地址對應的變量(參考1-C語言深度解剖(131).pdf 第76頁)
. 和 ->的使用區別
typedef struct
{
HOSTPACKETDESC *mTailBD;
HOSTPACKETDESC *mHeadBD;
U32 *mRegion0DescriptorAddress;
USBINSTANCE mUsbInst;
} CPPI41DMAINFO;
static CPPI41DMAINFO CppiInfo;
USBINSTANCE *UsbInstance = &CppiInfo.mUsbInst;
static CPPI41DMAINFO CppiInfo; //CPPI info結構體
CppiInfo.mHeadBD = NULL; //初始化CppiInfo結構體
CppiInfo.mTailBD = NULL;
CppiInfo.mTxCompletionq[0] = TX_COMPQ24; //TX完成隊列
CppiInfo.mTxSubmitq[3][1] = TX_SUBMITQ23;
UsbInstance->mRxEndPoint[(EpInfo + EpNum)->mEndPoint].mChannel = (EpInfo + EpNum)->mEndPoint - 1;
UsbInstance->mRxEndPoint[(EpInfo + EpNum)->mEndPoint].mDmaMode = (EpInfo + EpNum)->mDmaMode;
C語言所有複雜的指針聲明,都是由各種聲明嵌套構成的。
要搞清一個指針需要搞清指針的四方面的內容:指針的類型,指針所指向的類型,指針的值或者叫指針所指向的內存區,還有指針本身所佔據的內區。
指針的類型
從語法的角度看,你只要把指針聲明語句裏的指針名字去掉,剩下的部分就是這個指針的類型。
這是指針本身所具有的類型。讓我們看看例一中各個指針的類型:
(1)int*ptr;//指針的類型是int*
(2)char*ptr;//指針的類型是char*
(3)int**ptr;//指針的類型是int**
(4)int(*ptr)[3];//指針的類型是int(*)[3]
(5)int*(*ptr)[4];//指針的類型是int*(*)[4]
指針所指向的類型
當你通過指針來訪問指針所指向的內存區時,指針所指向的類型決定了編譯器將把那片內存區裏的內容當做什麼來看待。
從語法上看,你只須把指針聲明語句中的指針名字和名字左邊的指針聲明符*去掉,剩下的就是指針所指向的類型。例如:
(1)int*ptr;//指針所指向的類型是int
(2)char*ptr;//指針所指向的的類型是char
(3)int**ptr;//指針所指向的的類型是int*
(4)int(*ptr)[3];//指針所指向的的類型是int()[3]
(5)int*(*ptr)[4];//指針所指向的的類型是int*()[4]
指針的值是指針本身存儲的數值,這個值將被編譯器當作一個地址,而不是一個一般的數值。
在32位程序裏,所有類型的指針的值都是一個32位整數,因爲32位程序裏內存地址全都是32位長。
還有一點,指針在聲明後其本身並不能表明是那種類型,因爲其所在內存中存儲的只是一個內存地址,
指針的加減運算都是編譯器完成的,這點很重要。
②預編譯宏使用#define #else #ifndef #endif
3.6,#pragma 預處理
在所有的預處理指令中,#pragma 指令可能是最複雜的了,它的作用是設定編譯器的
狀態或者是指示編譯器完成一些特定的動作。#pragma 指令對每個編譯器給出了一個方法,
在保持與C 和C ++語言完全兼容的情況下,給出主機或操作系統專有的特徵。依據定義,編譯
指示是機器或操作系統專有的,且對於每個編譯器都是不同的。
其格式一般爲:
#pragma para
其中para 爲參數,下面來看一些常用的參數(參考1-C語言深度解剖(131).pdf 第六十八頁)
③程序區域的知識,加載和運行域的概念
5.2,棧、堆和靜態區
對於程序員,一般來說,我們可以簡單的理解爲內存分爲三個部分:靜態區,棧,堆。
很多書沒有把把堆和棧解釋清楚,導致初學者總是分不清楚。其實堆棧就是棧,而不是堆。
堆的英文是heap;棧的英文是stack,也翻譯爲堆棧。堆和棧都有自己的特性,這裏先不做
討論。再打個比方:一層教學樓,可能有外語教室,允許外語系學生和老師進入;還可能
有數學教師,允許數學系學生和老師進入;還可能有校長辦公室,允許校長進入。同樣,
內存也是這樣,內存的三個部分,不是所有的東西都能存進去的。
靜態區:保存自動全局變量和static 變量(包括static 全局和局部變量)。靜態區的內容
在總個程序的生命週期內都存在,由編譯器在編譯的時候分配。
棧:保存局部變量。棧上的內容只在函數的範圍內存在,當函數運行結束,這些內容
也會自動被銷燬。其特點是效率高,但空間大小有限。
堆:由malloc 系列函數或new 操作符分配的內存。其生命週期由free 或delete 決定。
在沒有釋放之前一直存在,直到程序結束。其特點是使用靈活,空間比較大,但容易出錯。(參考1-C語言深度解剖(131).pdf 第109頁)
LR_IROM1 0xc0000000 0x1f400000 {
ER_IROM1 0xc0000000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$Sections)
.ANY (+RO)
}
RW_IRAM1 +0 { ; RW data
.ANY (+RW)
}
ER_ZI +0 { ; ZI data
.ANY (+ZI)
}
RW_RAM 0x80004000 0x0001c000 ; RAM段 (128-16)K
{
*(ram)
} 分散加載文件的使用
}
④變量函數相關
變量,全局和局部,外部和內部,static extern
結構體、枚舉變量的使用,
1.14,struct 關鍵字
struct 是個神奇的關鍵字,它將一些相關聯的數據打包成一個整體,方便使用。
在網絡協議、通信控制、嵌入式系統、驅動開發等地方,我們經常要傳送的不是簡單
的字節流(char 型數組),而是多種數據組合起來的一個整體,其表現形式是一個結構體。
經驗不足的開發人員往往將所有需要傳送的內容依順序保存在char 型數組中,通過指針偏
移的方法傳送網絡報文等信息。這樣做編程複雜,易出錯,而且一旦控制方式及通信協議
有所變化,程序就要進行非常細緻的修改,非常容易出錯。這個時候只需要一個結構體就
能搞定。平時我們要求函數的參數儘量不多於4 個,如果函數的參數多於4 個使用起來非
常容易出錯(包括每個參數的意義和順序都容易弄錯),效率也會降低(與具體CPU 有關,ARM
芯片對於超過4 個參數的處理就有講究,具體請參考相關資料)。這個時候,可以用結構體
壓縮參數個數。
⑤⑥⑦⑧⑨⑩ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ
2、
3、
4、
5、
6、
7、
8、
9、