1.常用基本資料型別占用空間(64位機器為例):
char : 1個位元組 -- int :4個位元組 -- float:4個位元組 -- double:8個位元組
2.書寫型別:
A.整數: a. 默認為10進制 ,10 ,20. - b. 以0開頭為8進制,045,021. - c.以0b開頭為2進制,0b11101101. - . d.以0x開頭為16進制,0x21458adf.
B. 浮點:a. float 4 位元組 Byte - b.double 8 byte -c. long double 16 byte
C.字符型常量
char 用英文單引號括起來,只保存一個字符'a'、'b' 、'*' ,還有轉義字符 '\n' 、'\t',
D.字串常量
用英文的雙引號引起來 可以保存多個字符:"abc",
3.變數宣告
a、一種是需要建立存盤空間的,例如:int a 在宣告的時候就已經建立了存盤空間,
b、另一種是不需要建立存盤空間的,通過使用extern關鍵字宣告變數名而不定義它, 例如:extern int a 其中變數 a 可以在別的檔案中定義的,除非有extern關鍵字,否則都是變數的定義,
c. #define 是宏定義,它不能定義常量,但宏定義可以實作在字面意義上和其它定義常量相同的功能,本質的區別就在于 #define 不為宏名分配記憶體,而 const 也不為常量分配記憶體,怎么回事呢,其實 const 并不是去定義一個常量,而是去改變一個變數的存盤類,把該變數所占的記憶體變為只讀!
------------------------------------------------------------------------
sub:
其實 const 并不是去定義一個常量,而是去改變一個變數的存盤類,把該變數所占的記憶體變為只讀!所以這個變數不能改變值,編譯運行的時候起作用存在型別檢查,
define 定義的是不帶型別的常數,只進行簡單的字符替換,在預編譯的時候起作用,不存在型別檢查,
1、兩者的區別
(1) 編譯器處理方式不同
- #define 宏是在預處理階段展開,
- const 常量是編譯運行階段使用,
(2) 型別和安全檢查不同
- #define 宏沒有型別,不做任何型別檢查,僅僅是展開,
- const 常量有具體的型別,在編譯階段會執行型別檢查,
(3) 存盤方式不同
- #define宏僅僅是展開,有多少地方使用,就展開多少次,不會分配記憶體,(宏定義不分配記憶體,變數定義分配記憶體,)
- const常量會在記憶體中分配(可以是堆中也可以是堆疊中),
(4) const 可以節省空間,避免不必要的記憶體分配, 例如:
#define NUM 3.14159 //常量宏
const doulbe Num = 3.14159; //此時并未將Pi放入ROM中 ......
double i = Num; //此時為Pi分配記憶體,以后不再分配!
double I= NUM; //編譯期間進行宏替換,分配記憶體
double j = Num; //沒有記憶體分配
double J = NUM; //再進行宏替換,又一次分配記憶體!
const 定義常量從匯編的角度來看,只是給出了對應的記憶體地址,而不是象 #define 一樣給出的是立即數,所以,const 定義的常量在程式運行程序中只有一份拷貝(因為是全域的只讀變數,存在靜態區),而 #define 定義的常量在記憶體中有若干個拷貝,
(5) 提高了效率, 編譯器通常不為普通const常量分配存盤空間,而是將它們保存在符號表中,這使得它成為一個編譯期間的常量,沒有了存盤與讀記憶體的操作,使得它的效率也很高,
(6) 宏替換只作替換,不做計算,不做運算式求解;
宏預編譯時就替換了,程式運行時,并不分配記憶體,
----------------------------------
d.
define 注意“邊緣效應”,例:#define N 2+3, N 的值是 5,
int a = N/2
在編譯時我們預想 a=2.5,實際列印結果是 3.5 原因是在預處理階段,編譯器將 a=N/2 處理成 a=2+3/2,這就是 define 宏的邊緣效應,所以我們應該寫成 #define N (2+3),
4.儲存類(Storage Class):
auto 是區域變數的默認存盤類, 限定變數只能在函式內部使用;
register 代表了暫存器變數,不在記憶體中使用; sub: register用于定義存盤在暫存器中而不是 RAM 中的區域變數,這意味著變數的最大尺寸等于暫存器的大小(通常是一個詞),且不能對它應用一元的 '&' 運算子(因為它沒有記憶體位置),
static是全域變數的默認存盤類,表示變數在程式生命周期內可見; sub:
static 存盤類指示編譯器在程式的生命周期內保持區域變數的存在,而不需要在每次它進入和離開作用域時進行創建和銷毀,因此,使用 static 修飾區域變數可以在函式呼叫之間保持區域變數的值,
static 修飾符也可以應用于全域變數,當 static 修飾全域變數時,會使變數的作用域限制在宣告它的檔案內,
全域宣告的一個 static 變數或方法可以被任何函式或方法呼叫,只要這些方法出現在跟 static 變數或方法同一個檔案中,
extern 表示全域變數,即對程式內所有檔案可見,類似于Java中的public關鍵字
sub:
extern 存盤類用于提供一個全域變數的參考,全域變數對所有的程式檔案都是可見的,當您使用 extern 時,對于無法初始化的變數,會把變數名指向一個之前定義過的存盤位置,
當您有多個檔案且定義了一個可以在其他檔案中使用的全域變數或函式時,可以在其他檔案中使用 extern 來得到已定義的變數或函式的參考,可以這么理解,extern 是用來在另一個檔案中宣告一個全域變數或函式,
參考:1.菜鳥教程:https://www.runoob.com/cprogramming/c-storage-classes.html
2. 評論區筆記
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/65033.html
標籤:C
