1.int x=3;
int *p= &x;
(1)這一段**中int* p結合順序為(int*)p,改為int(*p)則無法通過編譯。
(2)此處p代表乙個首位址,而下面的使用中p則代表定位到這個首位址,而int和char之類的之前的型別,則起到了確定該指標指向的變數的具體長度,譬如int為4個位元組,short為兩個位元組。同時p+1,會根據p指向的資料的型別來計算,而非真的+1,比如int型+4,short型+2。
(3)因為p實際代表的是乙個位址,則在賦值時必須賦予其乙個位址。這時候我們就會提出疑問,如果自己定義乙個int型別變數當做位址賦予p可不可以。譬如int * p=0xcccccccc,這樣是無法通過編譯的。
(5)* 的作用:*代表將乙個指標指向變數的值取出,即定位到p指向的位址,並取出相應的長度的資料。譬如int取4個位元組,short取2個位元組。*p = *p+1
,代表將p所指向的int型別資料值加一。
2.int x[10]
(1)此處定義了乙個名為x的int型陣列,陣列名x在絕大多數情況下代表了該陣列的首位址,例外情況暫時不提及。
(2)而在使用時x[2]代表了訪問陣列的第3個元素,x[4]代表訪問陣列的第5個元素。那麼有沒考慮過x[-1]到底訪問了什麼。
譬如:int x[10];
int y=4;
printf("%d\n",x[-1]);
輸出結果竟然是4,也就是y的值。
其實在訪問x[i]時,會通過x+i*(x的型別長度)的方式來訪問。
此外,其實只要前為乙個位址的值就可以進行類似陣列的訪問。
譬如:int x;
int y=4;
printf("%d\n",(&x)[-1]);
輸出結果依然為4。
我們會發現,這種x[i]的方式與*(x+i)的方式結果是一樣的。
其實不光結果一樣,我們看一下兩份**的彙編**。
其中lea指令代表把x對應首位址的值載入到eax暫存器中。而在下面的訪問則是一模一樣的。這也就證明了x的訪問其實和直接用指標訪問是沒啥區別的。
3.int ** x;
4.int y=4;
int & x=y;
上次看到有人函式裡用int * &x 型別傳指標,結果和int * x的結果一模一樣,我感到無比震驚。結果鼓搗了一下午,看完了彙編,弄懂了之後,查了一下,發現原來這是引用變數,&在這裡並不指位址操作符。
於是最後再說一下引用型別的原理。
引用型別是相當於為變數y起了乙個別名叫x。修改其中任意乙個值,另乙個都會相應的改變。譬如x=3;則y的值也會變成,反之依然成立。
乍看起來覺得很神奇,其實看一眼彙編:
解釋一下,首先把3放進了x對應的記憶體位址內,然後
int & y=x就是把x的位址放進了y對應的位址單元內,
而y=4則是首先取出其中的x的位址,然後以此為指標,去訪問到對應的x單元。
感謝**,如有錯誤和不足望指正。
Cpp學習筆記(1)
1 記憶體申請 如果要申請20個結構體complex,那麼可以這樣寫 c的記憶體申請 complex arr complex malloc 20 sizeof complex c 釋放 complex arr new complex 20 delete arr申請時自動出構造,釋放時自動出析構。釋放...
CPP學習備忘 1 基本程式設計語句
switch括號中的表示式只能是整型 字元型或列舉型表示式。case後面的常量表示式之型別必須與其匹配。流iostream主管資料型別的識別工作和溝通作業系統,全權負責把流中的資料送到對應的裝置上。流的格式操作亦可直接以輸出流的方式操作。常用的流狀態 showpos 在正數 包括0 之前顯示 號 l...
指標學習(1)
指標是c和c 中和重要的組成部分,怎麼理解指標呢?首先來看一下記憶體 指標和變數的關係。記憶體可以比作是很多很多已經編號了的小球,你想用記憶體的時候就要知道小球的編號。比如說int i,這是乙個整型變數,占用4個位元組。如果每乙個小球就是乙個位元組的話,那麼就需要使用四個小球。變數連續的儲存在記憶體...