計算機期末不知道如何複習?獻上一份複習總結:指標大全
指標被稱為是C語言的精華所在,真正理解和掌握指標是征服C語言的關鍵所在!在學習指標之前,我們先弄清楚一個概念:
地址
何謂地址?在記憶體(注意,我們這裡提到的記憶體並不是人們常說的計算機的實體記憶體,而是虛擬的邏輯記憶體空間)當中,簡單點說:地址就是可以唯一標識某一點的一個編號,即一個數字!我們都見過尺子,我們統一以毫米為單位,一把長1000毫米的尺子,其範圍區間為0~999,而我們可以準確的找到35毫米、256毫米處的位置。
同樣的道理,記憶體也如此,也是像尺子一樣線性排布,只不過這個範圍略大,在我們最廣泛使用的32位作業系統下,是從0~4,294,967,295之間,而地址就是這之中的的一個編號而已,習慣上,在計算機裡地址我們常常用其對應的十六進位制數來表示,比如0x12ff7c這樣。在我們的C程式中,每一個定義的變數,在記憶體中都佔有一個記憶體單元,比如int型別佔四個位元組,char型別佔一個位元組等等,每個位元組都在0~4,294,967,295之間都有一個對應的編號,C語言允許在程式中使用變數的地址,並可以通過地址運算子"&"得到變數的地址。
#include<stdio.h> int main() { int i; int a[10]={1,2,3,4,5,6,7,8,9,0}; char b[10]={'c','l','a','n','g','u','a','g','e'}; for(i=0;i<10;i++) { printf("int Address:0x%x,Value:%d\n",&a[i],a[i]); } printf("\n"); for(i=0;i<10;i++) { printf("char Address:0x%x,Value :%c\n",&b[i],b[i]); } return 0; }
在32位linux系統下執行參考結果:
int Address:0xbfb949c4,Value:1 int Address:0xbfb949c8,Value:2 int Address:0xbfb949cc,Value:3 int Address:0xbfb949d0,Value:4 int Address:0xbfb949d4,Value:5 int Address:0xbfb949d8,Value:6 int Address:0xbfb949dc,Value:7 int Address:0xbfb949e0,Value:8 int Address:0xbfb949e4,Value:9 int Address:0xbfb949e8,Value:0 char Address:0xbfb949f2,Value :c char Address:0xbfb949f3,Value :l char Address:0xbfb949f4,Value :a char Address:0xbfb949f5,Value :n char Address:0xbfb949f6,Value :g char Address:0xbfb949f7,Value :u char Address:0xbfb949f8,Value :a char Address:0xbfb949f9,Value :g char Address:0xbfb949fa,Value :e char Address:0xbfb949fb,Value :
指標的定義和使用
明白地址的概念之後,指標也就不奇怪了。簡單的講,地址就是邏輯記憶體上的編號,而指標雖然也表示一個編號,也是一個地址。但兩者性質卻不相同。一個代表了常量,另一個則是變數。就好比記憶體是一把尺子,而指標就是尺子上面的遊標,可以左右移動,他某一個時刻是指向一個地方的,這就是指標變數。
對指標變數定義的一般形式為:
型別說明符 *變數名;
其中,這裡的*與前面的型別說明符共同說明這是一個指標變數,型別說明符表示該指標變數所指向的變數為何種資料型別,變數名即為定義的指標變數名。除此之外,C還提供*運算子獲取地址上對應的值。
例如:
#include<stdio.h> int main() { int num=2014; int *p=# printf("num Address = 0x%x,num=%d\n",&num,num); printf("p = 0x%x,*p=%d\n",p,*p); printf("%d\n",*&num); return 0; }
請親自執行觀察結果並思考。
值得一提的是,由於指標存放的都是地址,在32位作業系統下都在0 ~ 4,294,967,295這個數區間內,所以:在32位作業系統下,任何型別的指標變數都佔四個位元組!
#include<stdio.h> struct INFO { int a; char b; double c; }; int main() { int *p; char *p1; float *p2; double *p3; struct INFO *p4; //struct INFO型別為結構體型別 我們將會在後面的章節中講解 void *p5; printf("int point size is :%d\n",sizeof(p)); printf("char point size is :%d\n",sizeof(p1)); printf("float point size is :%d\n",sizeof(p2)); printf("double point size is :%d\n",sizeof(p3)); printf("struct point size is :%d\n",sizeof(p4)); printf("void point size is :%d\n",sizeof(p5)); return 0; }
陣列與指標
前面我們已經知道,通過陣列下標可以確定陣列元素在陣列中的順序和儲存地址。
由於每個陣列元素相當於一個變數,因此指標變數可以指向陣列中的元素,也就是說可以用指標方式訪問陣列中的元素。
對一個指向陣列元素的指標變數的定義和賦值方法,與指標變數相同。例如:
int a[10]; /*定義 a 為包含 10 個整型資料的陣列*/ int *p; /*定義 p 為指向整型變數的指標*/ p=&a[0]; /*把 a[0]元素的地址賦給指標變數 p*/
C 語言規定,陣列名代表陣列的首地址,也就是第 0 號元素的地址。因此:
p=a; /*等價於 p=&a[0]; */ int *p=a; /*等價於 int *p=&a[0]; */
對於指向首地址的指標 p,p+i(或a+i)就是陣列元素 a[i]的地址,*(p+i)( 或*(a+i) )就是 a[i]的值。
如果指標變數 p 已指向陣列中的某一個元素,則 p+1 指向同一陣列中的下一個元素。
引入指標變數後,就可以用以下兩種方法來訪問陣列元素:
(1)下標法:即用 a[i]形式訪問陣列元素,在前面介紹陣列時都是採用這種方法。
(2)指標法:即採用*(a+i)或*(p+i)形式,用間接訪問的方法來訪問陣列元素,其中 a 是陣列名,p 是指向陣列的指標變數,其初值 p=a。
#include<stdio.h> int main() { int i; int a[10]={1,2,3,4,5,6,7,8,9,0}; int *p=a; for(i=0;i<10;i++) { printf("P Value:%d a Value :%d\n",*(p++),*(a+i)); } printf("\n"); return 0; }
注意輸出的兩種方式,指標可以通過++或--並修改自身值的方式移動,然而陣列名本身值不可以被更改。
字串與指標
前面我們已經討論過字元陣列與字串,字元指標也可以指向一個字串,可以用字串常量對字元指標進行初始化。例如:
char*str="www.dotcpp.com";
這是對字元指標進行初始化。此時,字元指標指向一個字串常量的首地址。
還可以用字元陣列來存放字串,例如:
char string[ ] = "Welcome to dotcpp.com"
在這個語句中,string 是陣列名,代表字元陣列的首地址。
因此可以通過陣列名 string 來訪問字串,字串指標和字串陣列兩種方式都可以訪問字串。
但它們有著本質的區別:字元指標str 是個變數,可以改變str 使它指向不同的字串, 但不能改變 str 所指向的字串常量的值。 而string 是一個數組,可以改變陣列中儲存的內容。應注意字串指標和字串陣列的區別。
#include<stdio.h> int main() { char *str = "www.dotcpp.com"; char string[]="Welcome to dotcpp.com"; str[0]='C'; //試圖修改str指向的常量區的字串內容 return 0; }
指標是C語言的精髓所在,需要深入理解的同時可以熟練運用指標在不同場合,當然離不開作業的練習,可以把之前的陣列相關的題庫用指標來實現。
期末了,為大家提供C語言基礎視訊資料,節約備考時間,不用去網上找資源,還有考試真題可以免費領取噢,需要的夥伴可以加群一起學習:1151395975