先來一個觀點.你們先看看對不對
按:在CSDN論壇上,有位壇友提到這個問題:
====================================
先看一段代碼:
#include<stdio.h>
void main()
{
int*p=10;
printf("%d",p);
}
看 看上述代碼有什麼問題沒有?相信清楚指針概念的各位知道,int*p其實劃分來看是(int*)p,他實際上是一個指針,那麼int*p=10;等價於 int*p;p=10;,你們都知道,指針就是地址,前面語句的意思是,把常量10的值賦給指針p,按照定義來講,這是不合法的,由於常量不能直接賦值給 指針,好比int a=10;int*p=&a;這纔是合法的。可是我經過VC6.0編譯器編譯一下,文件名爲al.C(注意了,非CPP後綴),結果編譯器絕不報 錯;輸出結果爲10。
====================================
看了這位壇友的帖子,實在使人擔心呀……
首先,您(稱呼這位壇友)說「按照定義來講,這是不合法的,由於常量不能直接賦值給指針」。
哪裏有這個「定義」呀?
我慢慢說……到後來,您就會知道,您的這種「定義」是毫無心義的。
先說啥是指針。
您說「你們都知道,指針就是地址」。這種說法是錯誤的(且害人的)。用這種思路去理解指針,那說明您尚未體會到,關於指針的許多真實狀況。
「地址」這個觀念,是爲了讓那些須要向存儲器中的某個或某些存儲單元進行數據存取的主體(好比處理器)可以找到這些存儲單元,而引入的。
顯然地,在這些主體看來,那些存儲單元的位置(即地址),也是數據。那麼,這後一種數據,也要在存儲器中被存儲、被讀寫。(從C語言編程語境來看, 這後一種數據的符號,就是指針變量或指針常量的符號。)
而「指針」這個觀念的引入,與「地址」的比起來,要複雜一些,或者說,前者的用途與意義更具多樣性:
(1)指針變量或指針常量的值,每每能夠由一個取地址符(&)做用在一個變量或常量的符號上而得到。
若是您要說「指針的值,不能取常量的地址」的話,那您又錯了。以下寫法,就能夠令指針取到常量的地址:
int const a=12345;
int const *pa=&a;
或
int const a=12345;
int const *pa;
pa=&a;
從這個角度看來,指針的用途和意義在於:獲取程序中變量或常量符號實際對應於存儲器的數據的位置。
那麼,對於同一個指針量,能夠隨程序員的意願,在任什麼時候候,獲取任何既有的符號所對應的數據的位置,做爲它的值 —— 不過,這裏有一個極不可忽略的條件,下面會講。
地址,則沒有上述的意義和用途。一個符號所對應的數據,在存儲器中的位置,在符號被聲明的當初,就職由老Boss來分配。這個分配過程,對於程序員來講,是透明的 —— 這是高級語言與低級語言之間的一個顯著區分。但因爲C語言裏存在着「指針」這個機制,就使得它「高級得不那麼完全」 —— 由於,程序員能夠透過指針,來窺探到老Boss和他的存儲器情人是怎麼約會的。
(2)指針量的值,除了由上面第(1)點中所說的方式得到以外,還能夠由第(1)點中的方式所得到的量,再加加減減,即進行所謂「指針運算」來被賦予。讓函數返回一個「實用的」存儲器中的位置值,一般就是屬於這一類。
(3)在第(1)點的例子裏,咱們已經看到:在聲明指針量符號的時候,必須必須同時給出某種數據類型。這個數據類型必須必須,跟這個指針未來要指向的符號在被聲明時所設置的數據類型,徹底一致!
若是差那麼一點兒,但尚在老Boss的理解範圍以內的話,那麼,老Boss會罵一句(吐出一個Warning),而後他會心不服但手服地,爲指針量賦值等號右邊的東西,作一些強制的轉換。
可是若是差得比較離譜了,老Boss就索性罷工了。
在這位壇友的例子中:
int*p=10;
就是屬於前一種的「差那麼一點兒」的狀況。這時候,雖然老Boss沒有罷工(沒有編譯error),可是您不知道,他已經有一些怨氣地在暗地裏,爲您作了一些事情。若是您打開Warning選項,就能聽到他的罵聲。(千萬不要覺得「編譯經過,程序就是寫得100%合乎標準的」!)
若是您把上面的代碼,改寫成這樣:
int *p=(int *)10;
那麼,保證老Boss不會罵您、更不會罷工。
上面這樣寫是什麼意思呢?原來您的寫法,是把一個整數10賦予了指針量p。咱們姑且認爲這個10就是整數常量。其實,無論這個10是個啥量啥類型,只要前面頂上一個「(int *)」,它就會被老Boss強制轉換爲:符號p在聲明時所設置的那個類型(即指向整數類型變量的指針)。
我爲何說「無論這個10是個啥量啥類型」呢?
您看:
int *p=(int *)'a';
就是如此,老Boss也不會罵人或罷工。程序員
致謝原文:http://www.douban.com/group/topic/30597081/編程