一、指標是什麼?
c語言裡,變數都是存放在記憶體裡,而記憶體其實就是一組有序位元組組成的陣列,每個位元組都有唯一的記憶體位址。cpu 通過記憶體定址對儲存在記憶體中的某個指定資料物件的位址進行定位。這裡,資料物件是指儲存在記憶體中的乙個指定資料型別的數值或字串,它們都有乙個自己的位址,而指標便是儲存這個位址的變數。也就是說:指標是一種儲存變數位址的變數。相當於指標是一種貨物標籤,或者目錄索引,只要根據指標我們就可以進行相應的操作,比直接操作內容更快捷。
上圖可見,0x00000000等就是指標。記憶體其實就是一組有序位元組組成的陣列,陣列中,每個位元組大大小固定,都是 8bit。對這些連續的位元組從 0 開始進行編號,每個位元組都有唯一的乙個編號。就是指標。
二、指標的三大用處
(一)複雜的資料結構往往需要使用指標來構建,如鍊表、二叉樹等;
(二)c語言是傳值呼叫,而有些操作傳值呼叫是無法完成的,如通過被調函式修改呼叫函式的物件,但是這種操作可以由指標來完成;
(三)指標的使用使得不同區域的**可以共享記憶體資料,訪問速度提公升了。
三、指標的使用
(一)建立指標
//1、 宣告乙個 int 型別的指標 p1,乙個char型別的指標p2
int *p1;
char p2;
和常規建立變數的唯一區別是加了號
//2、建立乙個指標陣列
int arr[10];
不難理解,就是建立乙個10個元素的陣列,每個元素都是乙個int指標,相當於陣列的每乙個資料均加個乙個指標
//3、建立乙個陣列指標
int (arr)[10];
這個可以理解為只有乙個指標,指向陣列,相當於在陣列第乙個資料位置加了標籤
//4、建立乙個指向指標的指標
int **p;
這個代表了在建立指標的時候,也可以把這個指標當做一種資料,再建立指向這個指標的乙個指標,有點像建立乙個目錄索引,索引的結構是找到另外乙個索引,可以理解為兩層巢狀的關係。
以上四種型別是行規形式,但基本涵蓋了最重要的幾種型別。
(二)使用指標
1、兩種賦值方式
當int a=10;
第一種:int p=&a;
第二種:int p;
p=&a;
這兩種的實現結果是一樣的。輸出的兩種結果
printf("%d\n", p);//輸出的p1的內容
printf("%#x\n", p);//輸出的p1的位址
2、設定空指標
null 的指標是乙個特殊的指標變數,表示不指向任何東西。可以通過給乙個指標賦乙個零值來生成乙個 null 指標。
示例:int *p = null;
printf(「p的位址為%d\n」,p);
這兩句輸出的為0.
(三)指標運算
示例1:
int a[10] = ;
int sub;
int *p1 = &a[2];
int *p2 = &a[8];
sub = p2-p1;
printf("%d\n",sub);
*這段的輸出結果是6,代表兩個指標之間的距離是6.
示例2:
當執行 p1++;後
再執行printf("%d\n",*p1);結果為4;
當再執行 p1++;後
再執行printf("%d\n",*p1);結果為5;
說明指標可以自動加1下移,當然也可以–上移。也可以+n,移動n個位置。
*(四)指標參與陣列操作
int x[10] = ;
int p = x;
printf(「x的位址為:%p\n」,x);
printf(「x[0]的位址為:%p\n」,&x[0]);//這個和上乙個顯示的都是位址一樣
printf(「p的值為:%d,x[0]的值為:%d\n」,p,x[0]); //這個都顯示1
p += 2;
printf("(p+2)的值為:%d\n",*p);//這個顯示3
(五)陣列指標操作
int arr[2][3] = ;
int (*p)[3];
p = arr;
for(int i=0; i<2;i++)
for(int j=0; j<3;j++)
printf("%d 「,arr[i][j]); //輸出的是1 2 3 4 5 6
printf(」\n");
printf("%d\n",(*p)[0]);//輸出1
printf("%d\n",(*p)[1]);//輸出2
printf("%d\n",(*p)[2]);//輸出3
p++;
printf("%d\n",(*p)[0]);//輸出4
printf("%d\n",(*p)[1]);//輸出5
printf("%d\n",(*p)[2]);//輸出6
(六)指標的指標
以下**在測試輸出時,可以看到顯示的內容都是一樣的。
int i = 10;
int *p = &i;
int **q = &p;
int ***r = &q;
printf(「i = %d\n」, i);
printf(「i = %d\n」, *p);
printf(「i = %d\n」, **q);
printf(「i = %d\n」, ***r);
通過以上**體會指標的指標,也就是將指標作為內容再巢狀指標,相當於一批貨物,每個貨物有乙個標籤,而倉庫管理員在標籤基礎上又做了一套查詢標籤的索引目錄。
當然,更上一層也可以根據現行的索引目錄再做一層索引目錄的索引,以此類推。但在實際應用中,一般用到指標的指標這第二個層級基本夠用了。
(七)指標用來操作結構體的方式
# include
# include
struct age
;struct selfmsg
;int
main
(void
)
以上這種方式,實際就是將指標和例項化結構體直接視為一類東西來使用。當然,c語言也提供了一種替代性方式來操作,即->,總的來說包括以下三 種形式是實現的相同功能:
結構體變數.成員名。
(*指標變數).成員名。
指標變數->成員名。
從實際操作來看,大部分程式設計師寫**,習慣使用方式1或3,個人推薦方式3。
(八)函式指標和指標函式
1、函式指標
# include
# include
intadd
(int x,
int y)
intsub
(int x,
int y)
//函式指標
int(
*fun)
(int x,
int y)
;int
main
(void
)
總體來看,這種模式我還沒覺得有太多用處,了解即可。
2、指標函式
#include
typedef
struct datadata;
//指標函式
data*f(
int a,
int b)
intmain()
指標函式實際上就是可以實現定義乙個函式,當需要在主程式操作時,通過指標形式加了乙個標籤,把函式通過指標進行操作更加便捷了。同時,在main中,將data結構體例項化,在使用時這種方式邏輯上相對複雜,需要大家慢慢悟,我也是在不斷學習中,環境一起交流。。。 C語言深入學習一
之前學過c語言不過比較淺顯,好多功能都不知道為什麼是這麼得到的,機緣巧合之下,找到了關於c語言深入學習的資源。很是開心。今天就分享給大家。希望大家能有所收穫。c語言中的資料型別 主要分為整形,浮點型,字元型。其對應為int等,float等,char等。typedef 是給某種功能另外叫乙個名字。可以...
C語言 陣列的深入學習
深入學習一下陣列 單元是依次相連線的。而且這多個變數必須單獨訪問,不可以一起訪問的。因為他們的位址彼此相連,所以使用指標 訪問這些變數就很容易了。這個位址在編譯器中決定具體數值,具體數值和變數名繫結,變數型別決定了這個位址的延續長度。3 陣列中幾個關鍵符號 a a 0 a a 0 的理解 1 a就是...
C語言中指標的深入學習之指標與陣列之間的恩怨
注意此處是建立在定義int a 5 的基礎上 此處的a不是字元 分析下邊 main int ptr int a 1 printf d,d n a 1 千萬別以為上邊 十分簡單,其實不然,最後終端上列印出來的值到底是多少那?對上題來說,a是乙個一維陣列,陣列中有五個元素 ptr是乙個int型別的指標,...