1,、什么是指針
指針是一種數(shù)據(jù)類型,,與其它的數(shù)據(jù)類型不同的是指針是一種“用來存放地址值的”變量。舉一個簡單的例子:
如果定義了一個整型變量,,根據(jù)整型變量的特點,,它可以存放的數(shù)是整數(shù)。
如:int a; a=100; 這樣就把整型常量賦給了變量a,。但是如果寫成這樣:a=123.33;就會出問題,,最后輸出變量a的值結(jié)果是123。現(xiàn)在說到指針,,其實地址值也是一個整型數(shù),,如某某變量的地址值為36542,說明這個變量被分配在內(nèi)存地址值為36542的地方,。能不能這樣進(jìn)行推理,,既然地址值也是整型數(shù),整型變量正好可以用來存放整型數(shù),,那不是一個整型變量可以用來存放地址的值嗎,。程序?qū)懗上旅孢@樣:
int a,b;
a=&b;
很明顯,,這樣寫是錯誤的。原因在于不能簡單地把地址理解為整型數(shù),。
應(yīng)有這樣的對應(yīng)關(guān)系: 地址值<--->指針,; 整型數(shù)<--->int 型變量。
所以有這樣的說法:“指針就是地址”(指針就是存放地址值的一種數(shù)據(jù)類型)
下面是一段正確的程序:
int a,*p;
p=&a; /*把變量a的地址值賦給指針p*/
2,、什么是void指針
void的意思就是“無值”或“無類型”,。void指針一般稱為“通用指針”或“泛指針”。之所以有這樣的名字是因為使用void指針可以很容易地把void指針轉(zhuǎn)換成其它數(shù)據(jù)類型的指針,。例如在為一個指針分配內(nèi)存空間的時候:
int *p;
p=(int *)malloc(......); 本來函數(shù)malloc的返回值是void類型,,在這里通過在前面加上一個帶括號的int*就把void*類型轉(zhuǎn)換成了int*類型。
所以不能簡單的把void看成“無”的意思,。void數(shù)據(jù)類型是一種很重要的數(shù)據(jù)類型,。
3、指針可以相加減嗎
可以相互加減,。但是一定要作有意義的運算,。當(dāng)二個指針指向同一個數(shù)組的時候,它們相加減是有意義的,。如果二個指針分別指向二個不同的數(shù)組,,那么指針之間的相加減就沒有什么意義。指向同一個數(shù)組時,,其相加減的結(jié)果為二個指針之間的元素數(shù)目,。
4、什么是NULL指針
NULL指針是不指向任何一個地址的指針,。這樣的指針一般是允許的,。當(dāng)一個指針為NULL的時候,不要對它進(jìn)行存取,。
5,、什么是“野”指針
野指針是不由程序員或操作者所能控制的指針。當(dāng)在一個程序里面定義了一個指針而又沒有給這個指針一個具體地址指向的時候,,這個指針會隨意地指向一個地址,,這樣的指針就是一個野指針。如果這個地址后面的內(nèi)存空間沒有什么重要的數(shù)據(jù)則不會造成不好的后果,,但是一旦這里面存放了有用的數(shù)據(jù),,那么這些數(shù)據(jù)隨時都有被野指針存取的危險,如果這樣,,數(shù)據(jù)就會被破壞,,程序也會崩潰。所以在程序里面是一定要禁止任何野指針的存在。當(dāng)定義了一個指針的時候,,要馬上給這個指針分配一個內(nèi)存地址的指向,。這樣程序才不會因為指針而出現(xiàn)意外。
6,、NULL的值是什么
NULL不是被定義為0就是被定義成(void *)0,,這二種值基本上是一樣的。
如有這樣的語句: if(p==NULL) 或者寫成 if(p==0) 其作用是一樣,。
7,、什么是“內(nèi)存泄漏”
當(dāng)定義了一個指針的時候,立即要為這個指針分配一個內(nèi)存空間,。這只防止了野指針的產(chǎn)生,。當(dāng)一個指針使用完畢要立即釋放掉這個指針?biāo)加玫膬?nèi)存空間---這有二方面的意義: 1)避免了內(nèi)存空間的泿費; 2)防止了內(nèi)存泄漏,。為什么會產(chǎn)生內(nèi)存泄漏:如果沒有及時釋放掉指針?biāo)加玫膬?nèi)存空間,,而在下次使用這個指針時又給這個指針分配了內(nèi)存空間,這樣的次數(shù)一多,,內(nèi)存空間就慢慢被消耗掉了,。所以形象地稱這種現(xiàn)象為內(nèi)存泄漏。
如下面這樣一個程序:
void *p;
for(;;)
p=malloc(20); /*這20個字節(jié)的內(nèi)存空間是隨意指定的*/
這樣的一個小程序,,大家不要隨便運行它,。你可以在集成環(huán)境中單步調(diào)試運行,可以看一下每步運行后的結(jié)果,。可以看到,,每一次循環(huán)都會“吃掉”20個字節(jié)的內(nèi)存,,無數(shù)次之后,再多的內(nèi)存也慢慢地“泄漏”,,最后沒有內(nèi)存可用就死機(jī),。(與這個程序配合需要一段檢測整機(jī)總的內(nèi)存容量的程序,以觀察內(nèi)存總量的變化,。這里雖然沒有這一段程序,,但是看得到每次分配的內(nèi)存地址值是不相同的)
8、near指針和far指針
在DOS下(實模式)地址是分段的,,每一段的長度為64K字節(jié),,剛好是16位(二進(jìn)制的十六位)。
near指針的長度是16位的,,所以可指向的地址范圍是64K字節(jié),,通常說near指針的尋址范圍是64K。
far指針的長度是32位,含有一個16位的基地址和16位的偏移量,,將基地址乘以16后再與偏移量相加,,(所以實際上far指針是20位的長度。)即可得到far指針的1M字節(jié)的偏移量,。所以far指針的尋址范圍是1M字節(jié),,超過了一個段64K的容量。例如一個far指針的段地址為0x7000,,偏移量為0x1244,,則該指針指向地址0x71224.如果一個far指針的段地址是0x7122,偏移量為0x0004,,則該指針也指向地址0x71224,。
如果沒有指定一個指針是near或far,那么默認(rèn)是near,。所以far指針要顯式指定,。far指針工作起來要慢一些,因為每次訪問一個far指針時,,都要將數(shù)據(jù)段或程序段的數(shù)據(jù)交換出來,。另外,far指針的運算也比較反常,,例如上面講到的far指針指向同一個地址,,但是比較的結(jié)果卻不相同。
9,、什么時候使用far指針
當(dāng)使用小代碼或小數(shù)據(jù)存儲模式時,,不能編譯一個有很多代碼或數(shù)據(jù)的程序。因為在64K的一個段中,,不能放下所有的代碼與數(shù)據(jù),。為了解決這個問題,需要指定以far函數(shù)或far指針來使用這部分的空間(64K以外的空間),。許多庫函數(shù)就是顯式地指定為far函數(shù)的形式,。far指針通常和farmalloc()這樣的內(nèi)存分配函數(shù)一起使用?!?/SPAN> |