基礎(chǔ)知識(shí)不夠清楚,學(xué)習(xí)自《C和指針》& 《C Primer Plus》
基本數(shù)據(jù)類型
- 整形
提示:
如果一個(gè)值被當(dāng)作字符使用,那么把這個(gè)值表示為字符常量可以使這個(gè)值的意思更為清晰。
value = value - 48;
value = value - '0';
兩條語句的含義完全一樣,但最后一條語句的含義更為清晰,不論使用何種字符集,使用字符常量總是產(chǎn)生正確的值,可以提高程序的可移植性。
字符串就是一串以NUL結(jié)尾的零或多個(gè)字符,以下摘自 C語言中NULL和NUL的區(qū)別
NULL是一個(gè)宏,它在幾個(gè)標(biāo)準(zhǔn)頭文件中定義,0是一個(gè)整型常量,'\0'是一個(gè)字符常量,而NUL是一個(gè)字符常量的名字。這幾個(gè)術(shù)語都不可互換。
1、NULL用于表示什么也不指向,也就是空指針((void *)0)
2、0可以被用于任何地方,它是表示各種類型零值的符號(hào)并且編譯器會(huì)挑出它
3、'\0'應(yīng)該只被用于結(jié)束字符串
4、NUL沒有被定義于C和C++,它不應(yīng)該被使用除非你自己定義它,像:#define nul '\0'
- 浮點(diǎn)型
- 指針型
要理解指針,關(guān)鍵在于明白*是間接訪問(或者說是簡潔尋址)操作符,所有語句char *message表示表達(dá)式*message產(chǎn)生的結(jié)果類型是char
由于C語言的形式自由,容易誘使把星號(hào)寫在靠近類型的一側(cè),如下所示:int* a, b, ca被聲明為int類型的指針,但是b和c是整形 - 聚合類型(數(shù)組和結(jié)構(gòu)等)
typedef
使用 typedef來聲明類型,而不是 define 因?yàn)楹笳邿o法正確地使用指針類型
#define d_ptr_to_char char*
d_ptr_to_char a, b;
由于 define 只是替換了文本,a 是一個(gè)指向 char的指針,但是 b 被聲明為一個(gè)字符
常量
聲明
int const a;
const int a;
兩種方式一樣,a 的值無法修改,要讓它一開始就擁有一個(gè)值
- 聲明時(shí)初始化
int const a = 1; - 在函數(shù)中聲明為
const的形參在函數(shù)被調(diào)用的時(shí)候會(huì)獲得實(shí)參的值
指針相關(guān)
有兩樣?xùn)|西有可能成為常量——指針變量和它指向的實(shí)體,示例(這里是《C和指針》里的實(shí)例,變量名取得非常有意義)
//pi是一個(gè)普通的指向整型的指針
int *pi;
/*
** pci 是一個(gè)指向整型常量的指針
** 怎樣理解?
** 理解為對(duì)pci進(jìn)行間接訪問操作后得到的是一個(gè)整型常量
** 是不是超簡單
** 可以修改指針的值,但是不能修改它指向的整型數(shù)
*/
int const *pci;
/*
** 指向整型的常量指針
** 指針是常量,無法修改,但是可以修改它指向的值
** 理解為對(duì)某個(gè)常量進(jìn)行間接訪問得到的是一個(gè)整型
** 而這個(gè)常量是一個(gè)指向整型的指針
*/
int * const cpi;
/*
** 指針本身和它指向的變量都不允許修改
*/
int const * const cpci;
主要是看 const 右邊是什么
兩種創(chuàng)建名字常量方法的比較
(終于搞清楚了開心)
#define 指令也可以創(chuàng)建名字常量,如下
#define MAX_ELEMENTS 50
int const max_elements = 50;
在這種情況下,使用 #define 比 const 要好。因?yàn)橹灰试S使用字面值常量的地方都可以使用前者(編譯時(shí)代入),比如聲明數(shù)組的長度。 const字面常量只能用于允許使用變量的地方。
查閱《C Primer Plus》后覺得 const 定義的 max_elements也應(yīng)該大寫,畢竟也是常量。
作用域 (scope)
標(biāo)識(shí)符的作用域就是標(biāo)識(shí)符在程序中可以被使用的區(qū)域
- 代碼塊作用域 (block scope)
- 文件作用域 (file scope)
- 原型作用域
- 函數(shù)作用域
linkage 鏈接屬性
- external
- internal
- none
注意??
-
static只對(duì)缺省鏈接屬性為 external 的聲明才有改變鏈接屬性的效果,如果對(duì)一個(gè)鏈接屬性為 none,即函數(shù)中聲明的變量,是無效的 -
extern關(guān)鍵字并不能修改變量第一次聲明時(shí)的鏈接屬性
static int i;
int func()
{
int j;
extern int i; // 不能修改鏈接屬性
}
存儲(chǔ)類型 (storage class)
缺省存儲(chǔ)類型取決其聲明位置
- 靜態(tài)的(static),代碼塊之外聲明的變量,存儲(chǔ)于靜態(tài)內(nèi)存,無法指定為其他存儲(chǔ)類型
- 自動(dòng)的(auto),運(yùn)行時(shí)堆棧可以加上關(guān)鍵字
static,可以改變存儲(chǔ)類型,但不改變作用域(所以其實(shí)好像并沒有用)函數(shù)的形參不能聲明為靜態(tài),實(shí)參總是在堆棧中傳遞給函數(shù),用于支持遞歸。 - register
static
在上文的鏈接屬性和存儲(chǔ)類型都出現(xiàn)了static,當(dāng)其處在不同的上下文環(huán)境時(shí),其作用也不一樣:
- 用于函數(shù)定義和代碼塊之外的變量聲明時(shí),
static關(guān)鍵字用于修改標(biāo)識(shí)符的鏈接屬性,從 external 改為 internal,但標(biāo)識(shí)符的作用域和存儲(chǔ)類型不變 - 用于代碼塊內(nèi)的變量聲明時(shí),
static關(guān)鍵字用于修改變量的存儲(chǔ)類型,但是變量的鏈接屬性和作用域不變。用這種方法聲明的變量在程序執(zhí)行之前創(chuàng)建,程序的整個(gè)執(zhí)行期間一直存在,而不是每次在代碼塊開始執(zhí)行時(shí)創(chuàng)建,在代碼塊執(zhí)行完畢之后銷毀。
注意??
- 當(dāng)局部變量與全局變量同名時(shí),在局部變量的作用域內(nèi),靜態(tài)變量被屏蔽