小古銀的官方**(完整教程):
#include int main(void)
所有型別的指標都可以不需要轉換直接賦值到void *
型別的指標,像這樣:
int value = 100;
int *intpointer = &value;
void *pointer = intpointer;
但是當其他型別互轉或者void *
轉換其他型別時,就需要用到型別轉換:
int value = 100;
void *pointer = &value;
// 無型別指標轉換到其他指標用static_cast轉換, 不轉換而直接賦值將會編譯報錯
int *intpointer = static_cast(pointer);
// 其他型別指標互轉需要用reinterpret_cast轉換, 不轉換而直接賦值將會編譯報錯
long *longpointer = reinterpret_cast(&value);
我知道你的疑問並沒有得到解決:為什麼指標有用型別區分。
我們知道,記憶體是逐個位元組劃分的,然後為每個位元組的記憶體給乙個編號,就是記憶體位址。以int
為例,int
一般是4個位元組,那麼記憶體位址就是按順序連續的4個編號,這樣為每個位元組修改並不方便。為了更加方便地訪問記憶體,只需要指定指標的型別,並且給出記憶體第1個位元組的位址,編譯器就會知道你需要修改的是哪些位置的記憶體。同樣,你使用取位址符&
獲取到int
變數的位址,也是這個變數的第1個位元組的位址。(第1個位元組的位址下面將簡稱為首位址。)
#include int main(void)
輸出結果:
100
上面**中,先取出變數value
的位址&value
,然後在位址前面加上*
即*(&value)
,這樣就可以使用記憶體中的資料了,其中*(&value)
加()
是為了讓它先取位址。
#include int main(void)
輸出結果:
1024
由於編譯器知道*(&value)
和*pointer
表示的這份記憶體是int
型別(有4個位元組),所以它會將從首位址開始的4個位元組一起處理。所以如果你不指定位址和指標的型別,編譯器就不知道你要操作哪幾個位元組的記憶體。也就是使用void *
的話,編譯器就不知道這份記憶體有幾個位元組。
現在看看const
限制指標。
std::string text1 = "小古銀的c++教程";
std::string text2 = "c++的小古銀教程";
std::string * const pointer = &text1;
// pointer = &text2; // 去掉開頭注釋將會有編譯錯誤
如果想指標指向的記憶體中的資料不被改變,可以這樣寫:
std::string text1 = "小古銀的c++教程";
std::string text2 = "c++的小古銀教程";
const std::string *pointer = &text1;
pointer = &text2; // 可以改變pointer儲存的值
// *pointer = "小古銀是死肥宅"; // 去掉開頭注釋將會有編譯錯誤, 因為編譯器知道我不是死肥宅
std::string text1 = "小古銀的c++教程";
std::string text2 = "c++的小古銀教程";
const std::string * const pointer = &text1;
// pointer = &text2; // 去掉開頭注釋將會有編譯錯誤
// *pointer = "小古銀是死肥宅"; // 去掉開頭注釋將會有編譯錯誤
指標可以進行加減運算。和普通的數值運算不同,先看乙個例子就會明白了:
#include int main(void)
當你看到輸出結果的時候,你會發現兩個位址的差值是4個位元組。因為編譯器是根據指標的型別來進行加減運算,也因此void *
型別的指標是不能進行加減運算的。當然,你不應該對value
的下乙個位址表示的記憶體進行操作,因為你不知道這個記憶體裡到底儲存裡什麼,而且你連這個位址指向的地方有沒有記憶體你也不知道。
以int
舉例,指標的加減運算可以理解為:指標加1,就是下乙個int
型別變數的首位址;指標加2,就是下下乙個int
型別變數的首位址;指標減1,就是上乙個int
型別變數的首位址;指標減2,就是上上乙個int
型別變數的首位址;以此類推。
指標的運算只能是加法和減法,而且在加法中指標只能和整數相加;在減法中,指標只能減去乙個整數,或者兩個指標相減。
特殊地pointer = pointer + n;
(其中n
是乙個整數變數)可以簡寫成pointer += n;
,再特殊點,n
是1時,可以再簡寫成++pointer;
或者pointer++;
。減法同理,除了兩個指標相減。
還有乙個特殊的用法:*(pointer + n)
可以簡寫成pointer[n]
,這個在後面連續的記憶體裡經常用到。
C語言入門教程 4 9 指向指標的指標
指標變數可以指向另乙個指標變數,這種操作並不是將乙個指標變數所指向的記憶體位址傳遞給另乙個指標變數,而是定義一種指向指標型別的指標變數,可將其稱為雙重指標。雙重指標的定義形式為 資料型別 變數名 其中使用 2 個 間接運算子,如下例所示 int i,pi,dpi 宣告整型變數 i 整型指標變數 pi...
C語言入門教程 4 6 指標 和 陣列
陣列在記憶體中以順序的形式存放,陣列的第乙個儲存單元的位址即陣列的首位址。對一維陣列來說,直接引用陣列名就能獲得該陣列的首位址。指標變數可以存放於其內容相同的陣列首位址,也可以指向某一具體的陣列元素。通過這種方式,多維陣列也被看作一維陣列來操作,簡化了陣列的操作方式。4.6.1 指標 與 一維陣列 ...
C 入門教程(21) 型別推導和型別提取
寫c 時,經常遇到特別長的資料型別,由於這個原因,c 新增型別推導功能auto。用法 auto a 0 型別推導,就是由編譯器在編譯期推導出 右邊的資料型別,為 左邊的變數決定資料型別。例如上面例子,0預設是int型別,那麼變數a的資料型別就是int。有時候,不能使用型別推導但還是要用某個變數的型別...