0. static修飾變量和函數
static修飾變量,1)限定作用域,本檔案内。全局變量(自定義起,本檔案前面要用需extern聲明),局部變量函數内;2)生命周期,程式運作期間一直儲存。
static修飾函數,限定作用域,本檔案内。
1. enum類型變量大小為4(sizeof),不論enum成員數量。
2. enum成員間用“,”分割,最後一個成員後可不加分隔号。
而struct、union成員間用“;”分割,最後一個成員後要加分隔号。而struct的成員初始化用“,”分割,最後成員後加不加“,”均可。
3. stu_pst為typedef的struct student的類型,const stu_pst stu3和stu_pst const stu4完全等價。資料類型可忽略。
4. {}作用就是打包。
5. const修飾的隻讀變量不能用來作為定義數組的維數,也不能放在case關鍵字後面。
一個參數既可以是const還可以是volatile嗎?解釋為什麼?
核心include/asm-generic/io.h:static inline u8 __raw_readb(const volatile void __iomem *addr)
可以的,例如隻讀的狀态寄存器。它是volatile因為它可能被意想不到地改變。它是const因為程式不應該試圖去修改它。
一個定義為volatile的變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去假設這個變量的值了。精确地說就是,優化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用儲存在寄存器裡的備份。volatile修飾符告訴complier變量值可以以任何不被程式明确指明的方式改變,最常見的例子就是外部端口的值,它的變化可以不用程式内的任何指派語句就有可能改變的,這種變量就可以用volatile來修飾,complier不會優化掉它。
const修飾的變量在程式裡面是不能改變的,但是可以被程式外的東西修改,就象上面說的外部端口的值,如果僅僅使用const,有可能complier會優化掉這些變量,加上volatile就萬無一失了。
6. p為typedef的struct student類型,p+0x1為&p + sizeof(struct student)*1。
7. c語言中,所有非數組形式的資料實參均以傳值形式調用。(對實參做一份拷貝并傳遞給被調用的函數,函數不能修改作為實參的實際變量的值,而隻能修改傳遞給它的那份拷貝)
c語言中,當一維數組作為函數參數的時候,編譯器總是把它解析成一個指向其首元素首位址的指針。
8. 記憶體可分為三個區:靜态區、棧、堆
靜态區:儲存自動全局變量和static變量(包括static全局和局部變量)。靜态區的内容在整個程式的生命周期内都存在,由編譯器在編譯的時候配置設定。
棧:儲存局部變量。棧上的内容隻在函數範圍記憶體在,當函數運作結束時,這些内容也會自動被銷毀。其特點就是效率高,但空間大小有限。
堆:由malloc系列函數或new操作符配置設定的記憶體。其生命周期由free或delete決定。在沒有釋放之前一直存在,直到程式結束。其特點是使用靈活,空間比較大,但容易出錯。
9. 指針一定要初始化為null,這樣才能用if(null != p)來判斷。
10. volatile用途:1)中斷服務程式中修改的供其它程式檢測的變量需要加volatile;2)多任務環境下各任務間共享的标志應該加volatile;3)存儲器映射的硬體寄存器通常也要加volatile說明,因為每次對它的讀寫都可能由不同意義;
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
volatile告訴編譯器不去優化,也就是說ptr指向的位址存的值可以在很短時間内變化,那麼你在計算乘法的過程中(想像成很多條編指令),改變了這個值,就得不到正确結果了。
static作用進一步說明:
在c語言中,static的字面意思很容易把我們導入歧途,其實它的作用有三條。
(1)先來介紹它的第一條也是最重要的一條:隐藏。
當我們同時編譯多個檔案時,所有未加static字首的全局變量和函數都具有全局可見性
(2)static的第二個作用是保持變量内容的持久。存儲在靜态資料區的變量會在程式剛開始運作時就完成初始化,也是唯一的一次初始化。共有兩種變量存儲在靜态存儲區:全局變量和static變量,隻不過和全局變量比起來,static可以控制變量的可見範圍,說到底static還是用來隐藏的。
(3)static的第三個作用是預設初始化為0。其實全局變量也具備這一屬性,因為全局變量也存儲在靜态資料區。在靜态資料區,記憶體中所有的位元組預設值都是0x00,某些時候這一特點可以減少程式員的工作量。比如初始化一個稀疏矩陣,我們可以一個一個地把所有元素都置0,然後把不是0的幾個元素指派。如果定義成靜态的,就省去了一開始置0的操作。再比如要把一個字元數組當字元串來用,但又覺得每次在字元數組末尾加’\0’太麻煩。如果把字元串定義成靜态的,就省去 了這個麻煩,因為那裡本來就是’\0’。