(1)賦值運算編程
指針變量能夠互相賦值,也能夠賦值某個變量的地址,或者賦值一個具體的地址小程序
(2)指針與整數的加減運算數組
指針變量的自增自減運算。指針加 1 或減 1 運算,表示指針向前或向後移動一個單元(不一樣類型的指針,單元長度不一樣)。這個在數組中很是經常使用。函數
指針變量加上或減去一個整形數。和第一條相似,具體加幾就是向前移動幾個單元,減幾就是向後移動幾個單元。學習
(3)關係運算spa
假設有指針變量 px、py。3d
px > py 表示 px 指向的存儲地址是否大於 py 指向的地址指針
px == py 表示 px 和 py 是否指向同一個存儲單元視頻
px == 0 和 px != 0 表示 px 是否爲空指針blog
以前咱們能夠經過下標訪問數組元素,學習了指針以後,咱們能夠經過指針訪問數組的元素。在數組中,數組名即爲該數組的首地址,結合上面指針和整數的加減,咱們就能夠實現指針訪問數組元素。
指向數組的指針
如如下語句:
上面語句定義了一個數組 nums,在定義時分配了 10 個連續的int 內存空間。而一個數組的首地址即爲數組名nums,或者第一個元素的首地址也是數組的首地址。那麼有兩種方式讓指針變量 p 指向數組 nums:
上面兩句是等價的。
以下幾個操做,用指針操做數組:
*p = 1,此操做爲賦值操做,即將指針指向的存儲空間賦值爲 1。此時 p 指向數組 nums 的第一個元素,則此操做將 nums 第一個元素賦值爲 0,即 nums[0] = 1。
p + 1,此操做爲指針加整數操做,即向前移動一個單元。此時 p + 1 指向 nums[0]的下一個元素,即 nums[1]。經過p + 整數能夠移動到想要操做的元素(此整數能夠爲負數)。
如上面,p(p + 0)指向 nums[0]、p + 1 指向 nums[1]、、、類推可得,p+i 指向 nums[i],由此能夠準確操做指定位置的元素。
在 p + 整數的操做要考慮邊界的問題,如一個數組長度爲 2,p+3 的意義對於數組操做來講沒有意義。
下面寫一段代碼,用指針訪問數組的元素:
注:數組名不等價於指針變量,指針變量能夠進行 p++和&操做,而這些操做對於數組名是非法的。數組名在編譯時是肯定的,在程序運行期間算一個常量。
字符指針與字符數組
在 C 語言中自己沒有提供字符串數據類型,可是能夠經過字符數組和字符指針的方式存儲字符串。
(1)字符數組方式
這個在前面應該學習過,這裏就不贅述了。
(2)字符指針方式
指針方式操做字符串和數組操做字符串相似,能夠把定義的指針看作是字符數組的數組名。在內存中存儲大體以下,這裏爲了方便換了個字符串:
注:字符指針方式區別於字符數組方式,字符數組不能經過數組名自增操做,可是字符指針是指針,能夠自增操做。自增自減小會實現什麼效果你們能夠本身嘗試運行一下
下面作個小練習,利用字符指針將字符數組 sentence 中的內容複製到字符數組 word 中:
注:指針變量必須初始化一個有效值才能使用
多級指針及指針數組
(1)多級指針
指針變量做爲一個變量也有本身的存儲地址,而指向指針變量的存儲地址就被稱爲指針的指針,即二級指針。依次疊加,就造成了多級指針。咱們先看看二級指針,它們關係以下:
其中 p 爲一級指針,pp 爲二級指針。二級指針定義形式以下:
和指針變量的定義相似,因爲*是右結合的,因此*pp 至關於*(*p)。在本次定義中,二級指針的變量名爲 pp,而不是**p。多級指針的定義就是定義時使用多個「*」號。下面用一個小程序給你們舉例:
注:在初始化二級指針 ppi 時,不能直接 ppi = &&i,由於&i 獲取的是一個具體的數值,而具體數字是沒有指針的。
(2)指針數組
指針變量和普通變量同樣,也能組成數組,指針數組的具體定義以下:
下面舉一個簡單的例子熟悉指針數組:
//定義一個數組intnums[5] = {2,3,4,5,2}, i;//定義一個指針數組int*p[5];//定義一個二級指針int**pp;//循環給指針數組賦值for(i =0; i <5; i++){ p[i] = &nums[i]; }//將指針數組的首地址賦值給 pp,數組 p 的數組名做爲 p 的首地址,也做爲 p 中第一個元素的地址。//數組存放的內容爲普通變量,則數組名爲變量的指針;數組存放的內容爲指針,則數組名爲指針的指針。pp = p;//利用二級指針 pp 輸出數組元素for(i =0; i <5; i++){//pp == &p[0] == &&nums[0],nums[0] == *p[0] == **ppprintf("%d", **pp);//指針變量+整數的操做,即移動指針至下一個單元pp++; }
指針與多維數組
講多維數組是個麻煩的事,由於多維數組和二維數組沒有本質的區別,可是複雜度卻是高了許多。這裏我主要仍是用二維數組來舉例,可是仍是會給你們分析多維數組和指針的關係。
(1)多維數組的地址
先用一個簡單的數組來舉例:
int nums[2][2] = {
{1, 2},
{2, 3}
};
咱們能夠從兩個維度來分析:
先是第一個維度,將數組當成一種數據類型 x,那麼二維數組就能夠當成一個元素爲 x 的一維數組。
如上面的例子,將數組當作數據類型 x,那麼 nums 就有兩個元素。nums[0]和 nums[1]。 咱們取 nums[0]分析。將 nums[0]看作一個總體,做爲一個名稱能夠用 x1 替換。則 x1[0]就是 nums[0][0],其值爲 1。
咱們知道數組名即爲數組首地址,上面的二維數組有兩個維度。首先咱們把按照上面 1 來理解,那麼 nums 就是一個數組,則nums 就做爲這個數組的首地址。第二個維度仍是取 nums[0],咱們把 nums[0]做爲一個名稱,其中有兩個元素。咱們能夠嘗試如下語句:
此語句的輸出結果爲一個指針,在實驗事後,發現就是 nums[0][0]的地址。即數組第一個元素的地址。
若是再多一個維度,咱們能夠把二維數組看作一種數據類型 y,而三維數組就是一個變量爲 y 的一維數組。而數組的地址咱們要先肯定是在哪一個維度,再將數組某些維度當作一個總體,做爲名稱,此名稱就是該維度的地址(這裏有些繞)。
例:
三維數組實際存儲形式以下:
實際存儲內容的爲最內層維度,且爲連續的。對於 a 來講,其個跨度爲 4 個單元;對 a[0]來講,其跨度爲 2 個單元;對 a[0][0]來講,跨度爲一個單元。有上面還能夠得出:
上面的等式只是數值上相等,性質不一樣。
(2)多維數組的指針
在學習指針與數組的時候,咱們能夠以下表示一個數組:
在前面講指針數組時,全部指針數組元素都指向一個數字,那麼咱們如今能夠嘗試用指針數組的每一個元素指向一個數組:
這裏可能不能理解爲何*p + 1 = &nums[0][1],而不是 nums[1]。*p 得到的是一個一維數組,而 int 數組 + 1 的跨度只有 4 個字節,也就是一個單元。前面 p 是一維數組的指針,其跨度爲一個數組。因此*p + 1 = &nums[0][1],而 p + 1 = nums[1]。
前面學習函數學到,函數參數能夠爲 int、char、float 等,可是在操做時,這些參數只做爲形參,全部操做都只在函數體內有效(除對指針的操做外),那麼今天來學習一下指針做爲函數參數。
函數參數爲指針
咱們直接作一個練習,定義一個函數,用來交換兩個變量的內容。
代碼很是簡單,我也就不細講了。這裏傳入的參數爲指針,因此調用 swap 方法後 x,y 的內容發生了交換。若是直接傳入 x,y,那麼交換隻在 swap 中有效,在 main 中並無交換。
函數的返回值爲指針
返回值爲指針的函數聲明以下:
在函數調用前要聲明須要對函數聲明(有點編譯器不須要)
除了上面的操做,更實用的是返回一個指向數組的指針,這樣就實現了返回值爲數組。
指向函數的指針
C 語言中,函數不能嵌套定義,也不能將函數做爲參數傳遞。可是函數有個特性,即函數名爲該函數的入口地址。咱們能夠定義一個指針指向該地址,將指針做爲參數傳遞。
函數指針定義以下:
函數指針在進行「*」操做時,能夠理解爲執行該函數。函數指針不一樣與數據指針,不能進行+整數操做。
下面舉個例子,來使用函數指針:
利用函數指針調用方法具體操做以下:
若是你想更好的提高你的編程能力,以便更好從事編程類工做的話!那麼你很幸運~分享(源碼、項目實戰視頻、項目筆記,基礎入門教程)
歡迎轉行和學習編程的夥伴,利用更多的資料學習成長比本身琢磨更快哦!