1. 程式人生 > 資訊 >8K 紀錄片《千年陝菜》第二季啟動,共分 8 集

8K 紀錄片《千年陝菜》第二季啟動,共分 8 集

網路資料
讓你不再害怕指標
前言:複雜型別說明
要了解指標,多多少少會出現一些比較複雜的型別,所以我先介紹一下如何完全理解一個複雜型別,要理解複雜型別其實很簡單,一個型別裡會出現很多運算子,他們也像普通的表示式一樣,有優先順序,其優先順序和運算優先順序一樣,所以我總結了一下其原則:
 
從變數名處起,根據運算子優先順序結合,一步一步分析.
下面讓我們先從簡單的型別開始慢慢分析吧:
int p;
//這是一個普通的整型變數
int *p;
//首先從P 處開始,先與*結合,所以說明P 是一個指標,然後再與int 結合,說明指標所指向的內容的型別為int 型.所以P 是一個返回整型資料的指標
int p[3]; //首先從P 處開始,先與[]結合,說明P 是一個數組,然後與int 結合,說明數組裡的元素是整型的,所以P 是一個由整型資料組成的陣列
int *p[3];
 //首先從P 處開始,先與[]結合,因為其優先順序比*高,所以P 是一個數組,然後再與*結合,說明數組裡的元素是指標型別,然後再與int 結合,說明指標所指向的內容的型別是整型的,所以P 是一個由返回整型資料的指標所組成的陣列

 
3.指標的值----或者叫指標所指向的記憶體區或地址
指標的值是指標本身儲存的數值,這個值將被編譯器當作一個地址,而不是一個一般的數值。在32 位程式裡,所有型別的指標的值都是一個32 位整數,因為32 位程式裡記憶體地址全都是32 位長。指標所指向的記憶體區就是從指標的值所代表的那個記憶體地址開始,長度為si zeof(指標所指向的型別)的一片記憶體區。以後,我們說一個指標的值是XX,就相當於說該指標指向了以XX 為首地址的一片記憶體區域;我們說一個指標指向了某塊記憶體區域,就相當於說該指標的值是這塊記憶體區域的首地址。
 
指標所指向的記憶體區和指標所指向的型別是兩個完全不同的概念。在例一中,指標所指向的型別已經有了,但由於指標還未初始化,所以它所指向的記憶體區是不存在的,或者說是無意義的。
以後,每遇到一個指標,都應該問問:這個指標的型別是什麼?指標指
的型別是什麼?該指標指向了哪裡?(重點注意)

 
int (*p)[3];
//首先從P 處開始,先與*結合,說明P 是一個指標然後再與[]結合(與"()"這步可以忽略,只是為了改變優先順序),說明指標所指向的內容是一個數組,然後再與int 結合,說明數組裡的元素是整型的.所以P 是一個指向由整型資料組成的陣列的指標
 
int **p;
 //首先從P 開始,先與*結合,說是P 是一個指標,然後再與*結合,說明指標所指向的元素是指標,然後再與int 結合,說明該指標所指向的元素是整型資料.由於二級指標以及更高階的指標極少用在複雜的型別中,所以後面更復雜的型別我們就不考慮多級指標了,最多隻考慮一級指標.
 
int p(int);
//從P 處起,先與()結合,說明P 是一個函式,然後進入()裡分析,說明該函式有一個整型變數的引數然後再與外面的int 結合,說明函式的返回值是一個整型資料
 
Int (*p)(int);
//從P 處開始,先與指標結合,說明P 是一個指標,然後與()結合,說明指標指向的是一個函式,然後再與()裡的int 結合,說明函式有一個int 型的引數,再與最外層的int 結合,說明函式的返回型別是整型,所以P 是一個指向有一個整型引數且返回型別為整型的函式的指標
 
int *(*p(int))[3];
//可以先跳過,不看這個型別,過於複雜從P 開始,先與()結合,說明P 是一個函式,然後進入()裡面,與int 結合,說明函式有一個整型變數引數,然後再與外面的*結合,說明函式返回的是一個指標,,然後到最外面一層,先與[]結合,說明返回的指標指向的是一個數組,然後再與*結合,說明數組裡的元素是指標,然後再與int 結合,說明指標指向的內容是整型資料.所以P 是一個引數為一個整資料且返回一個指向由整型指標變數組成的陣列的指標變數的函式.


先宣告幾個指標放著做例子:
///////////////////// 例一 //////////////////////////
(1)int*ptr;
(2)char*ptr;
(3)int**ptr;
(4)int(*ptr)[3];
(5)int*(*ptr)[4];
 
1.指標的型別
從語法的角度看,你只要把指標宣告語句裡的指標名字去掉,剩下的部分就是這個指標的型別。這是指標本身所具有的型別。讓我們看看例一中各個指標的型別:
(1)int*ptr;//指標的型別是int*
(2)char*ptr;//指標的型別是char*
(3)int**ptr;//指標的型別是int**
(4)int(*ptr)[3];//指標的型別是int(*)[3]
(5)int*(*ptr)[4];//指標的型別是int*(*)[4]
怎麼樣?找出指標的型別的方法是不是很簡單?

 
2.指標所指向的型別
當你通過指標來訪問指標所指向的記憶體區時,指標所指向的型別決定了編譯器將把那片記憶體區裡的內容當做什麼來看待。從語法上看,你只須把指標宣告語句中的指標名字和名字左邊的指標宣告符*去掉,剩下的就是指標所指向的型別。
 
例如:
(1)int*ptr; //指標所指向的型別是int
(2)char*ptr; //指標所指向的的型別是char
(3)int**ptr; //指標所指向的的型別是int*
(4)int(*ptr)[3]; //指標所指向的的型別是int()[3]
(5)int*(*ptr)[4]; //指標所指向的的型別是int*()[4]
在指標的算術運算中,指標所指向的型別有很大的作用。指標的型別(即指標本身的型別)和指標所指向的型別是兩個概念。當你對C 越來越熟悉時,你會發現,把與指標攪和在一起的"型別"這個概念分成"指標的型別"和"指標所指向的型別"兩個概念,是精通指標的關鍵點之一。
我看了不少書,發現有些寫得差的書中,就把指標的這兩個概念攪在一起了,
所以看起書來前後矛盾,越看越糊塗。