首先明確指標是一種資料型別(分為int型指標,char型指標等等),除了本身的資料外,還定義一系列的操作。
關於對「指標是一種資料型別」的理解可以模擬int 資料型別,本身代表乙個整型資料,並定義了'+','-','*','/'等相關操作。
那麼問題來了,指標中的資料到底是什麼???
例如:
int a=5; //定義乙個int型資料
int *p=&a; //定義乙個int型指標指向int型資料a
首先這裡整型a中的資料為5,這裡假設整型a的記憶體位址為1024,那麼int型指標p中的資料也就是1024。這裡引入乙個關鍵的概念,指標的型別與指標所指向的資料型別,這是理解指標的重中之重。在這個例子中指標的型別為int型指標,指向的資料是int型資料。
強烈建議試試下段**,對理解指標有著相當大的作用:
int a=1;
int *p=&a;
printf(「%p」,&a); //①
printf(「%p」,p); //②
printf("%p",&p); //③
其中%p指的是記憶體位址型別(列印出的是16進製制資料)
③列印的資料是什麼?你們先自己思考 後面會講到。
算數運算(『+』&&『-』)首先明確千萬不要跟int型資料的『+』法搞混。指標的運算具體來講是這樣的,假設指標p指向的資料型別是datatype,即這裡p是乙個datatype型別的指標。指標的加減法實際上稱作「位移」更為合適。例如p+1指的就是將指標p位移乙個sizeof(datetype)單位,即指標p指向了位移後的記憶體位址。所以參於指標的運算不能是兩個指標。
舉個簡單的例子:
int a[10]=; //定義乙個整型陣列,這裡a實質上是乙個指向陣列中第乙個資料a[0]的指標
int *p=a;
printf(「%d」,*p);
printf("%d",*(p+1));
觀察輸出的值很容易的發現乙個規律就是,p+1指標的指向從a[0]跳到了a[1],同理可以改變上述程式的一些引數,並且試著定義其他資料型別的陣列,這裡強烈建議嘗試定義結構陣列,並進行訪問。
間接訪問運算(『*』)簡單明確的理解就是「訪問指標所指向資料的值」,注意與「指標的值」和「指標的位址」相互區分,搞懂這個概念,你對指標就有了乙個更清晰的理解。
這裡用舉乙個結構指標的例子;
struct node ; //定義結構型別node
int main(){
sturct node a;
struct node *p=&a; //實際上這裡是將結構體a的所占用記憶體的首位址付給了結構指標p
printf("%d",(*p).data); //這裡利用取位址符運算取出指標p所指向結構體a中的data值
}
注:(*p).data可以替換為p->data
指標的指標顧名思義,即指向指標這個資料型別的指標,還記得上面那個輸出③嗎,輸出的值就是指標p的位址,那麼這個時候我們完全可以再定義乙個指標變數,儲存該位址,指向指標的指標就應運而生了。
int **pp=&p; //將指標p的位址儲存到指標pp中,即指標pp指向指標p
printf("%p",*pp); //列印出的值與③相同,即指標p的位址
在二維陣列中的延伸前面我們應該已經知道在一維陣列中a中,a表示乙個指標,指向的陣列a中的首元素。
那麼在二維陣列中不過是對這個概念進行了擴充,例如a[5][4],這裡的a本質上是乙個陣列指標指向乙個容量為5的一維陣列而已。a[0],a[1]等如同一維陣列中a一樣指向他們所對應的一維陣列中首個量。
自己動手試試下面的實驗,幫助理解陣列,指標之間的關聯。
#includeint main(),};
printf("%pn",a); //輸出指標a資料,也就是指標a[0]的位址
printf("%pn",a+1); //輸出a+1的資料 ,也就是a[1]的位址
printf("%pn",&a[0]);
printf("%pn",&a[1]); //驗證上述
printf("%pn",(*a)+1); //輸出的是a[0][1]的位址
printf("%pn",&a[0][1]); //驗證
printf("%dn",*(a[0])); //輸出的是a[0]a[0]的值
printf("%dn",*(*(a+1)+1)); //輸出的是a[1][1]的值
}
陣列指標陣列兩個字放在前面表示什麼?沒錯,表示的是指標指向的資料型別。例如: int * [5] p ,定義乙個指向容量為5的一維陣列的指標p。事實上模擬二維陣列,這個指標p指向的是乙個指向某個容量為5的一維陣列第乙個資料的指標。
指標隨著指標型別的變化,它的運算方式『+』也發生了改變。(這裡有乙個問題,由於博主未接觸過指標的更底層的原始碼,我的猜想是這樣的:為了分辨指標的型別,指標的屬性中可能還有一些引數,用於辨別指標位移的大小,如同二維陣列中a的指標a,本身實際上是乙個指向整型指標的指標,但對a做『+』運算時位移的單位卻不是乙個sizeof(int),所以推斷a一定還有其他引數制約了該操作)
指標陣列字元陣列是什麼?儲存字元的陣列。那麼指標陣列是什麼,儲存指標的陣列!
沒問題,聰明的前輩們想到用陣列儲存一連串的指標,最常見的用法就是在定義多個字串的時候。
例:#includeint main();
char **pp=p;
printf("%s",p[1]);
}
在上列中定義了指標陣列p,並定義了指向指標的指標pp。
這裡結合上述的二級指標(指標的指標)給出適當的例子予以解釋
#include#include//尋找五環色,不適用二級指標
int main();
char str[20];
scanf("%s",str);
for(int i=0;i<5;i++)
} }
這裡注意的問題是,試圖訪問字串時,直接用指向字串的指標即可,不用使用*進行間接訪問。
#include#include//尋找五環色,使用二級指標
int main();
char str[20];
char **pp=color; //定義二級指標pp,明白color本質上是乙個二級指標
scanf("%s",str);
for(int i=0;i<5;i++)
} }
最後這裡留有一道題目:嘗試用指標陣列實現多個字串的動態輸入
指標作為函式的引數在c語言中,不同於c++,並無引用傳遞,而只能進行進行值傳遞。若需要呼叫函式來修改某些量時,就需要用到指標。通過將位址當做實參傳給函式中形參(即指標),完成賦值。
舉例氣泡排序法
#includevoid exchange(int *p,int *q)
int main();
for(int i=0;i<10;i++)
i++; }}
int main()
str[i]='0';
q=match(str,'a'); //呼叫match函式,尋找相同的值
printf("%s",q);
}
指向函式的指標在c語言中,函式名代表函式的入口位址。可以定義乙個指標變數,並接受函式的入口位址讓它指向函式,這就是指向函式的指標,也稱為函式指標。通過函式指標可以呼叫函式,它還可以作為函式的引數。
1.函式指標的定義
型別名*(函式名)(返回值型別)
int *(funptr)(int,int)
定義了乙個函式指標funptr,它可以指向有兩個整型引數且返回值型別為int的函式。
2.通過函式指標呼叫函式
使用前函式指標前,需要先對函式指標進行賦值,將乙個函式名賦給函式指標,但該函式必須已定義或者已宣告,且函式返回值型別與函式指標的型別要一致。
3.函式指標作為函式引數
c語言中,利用函式名作為實參,函式指標作為形參,完成傳遞傳遞函式。
例:利用函式指標實現
#includeint calc(int (*fun)(int),int a,int b)
int tun(int a)
int main()
(未完待續) 檔案指標偏移量
f.seek offset,whence offset代表檔案的指標的偏移量,單位是位元組bytes whence代表參考物,有三個取值 0 參照檔案的開頭 1 參照當前檔案指標所在位置 2 參照檔案末尾 ps 快速移動到檔案末尾f.seek 0,2 強調 其中whence 1和whence 2只能...
指標偏移量的理解
今天刷題的時候碰到如下的一道題 int main array 19 2019 unsigned long offset unsigned long short array 2019 unsigned long array unsigned char array 19 cout offset 以上程式...
c point偏移 c 偏移量分頁效果
分頁效果對程式設計師來所是常見的,但是在這裡我介紹的是乙個不一樣的分頁效果,也許你們也長用,偏移量的分頁效果,以前學的不精所以研究一好久覺得還是拿出來分享一下吧,同時也讓我記住。好了光說大家可定沒興趣,來個效果圖吧 這個效果想必大家不陌生吧。先介紹一下偏移量的思路吧,也方便我以後好記起,呵呵私心哈,...