指標系統學習1
1.地址和指標的概念:
記憶體區的每一個位元組有一個編號,這就是“地址” 。如果在程式中定義了一個變數,在對程式進行編譯時,系統就會給這個變數分配記憶體單元。
在C語言中,對變數的訪問有兩種方式,直接訪問和間接訪問。
打個比方,為了開一個A抽屜,有兩種辦法:
- 一種方法是:將A鑰匙帶在身上,需要時直接找出該鑰匙開啟抽屜:取出所需的東西。
- 為安全起見,將該A鑰匙放到另一抽屜B中鎖起來。如果需要開啟A抽屜,就需要先找出B鑰匙,開啟B抽屜,取出A鑰匙,再開啟A抽屜,取出A抽屜中之物。
2.關於直接訪問和間接訪問:
直接訪問如:a=5;
系統在編譯時,已經對變數分配了地址,例如,若變數a分配的地址是2000,則該語句的作用就是把常數5儲存到地址為2000的單元。
間接訪問如:scanf("%d",&a);
呼叫函式時,把變數a的地址傳遞給函式scanf,函式首先把該地址儲存到一個單元中,然後把從鍵盤接收的資料通過所儲存的地址儲存到a變數中。
3.初識指標:
在C語言中,指標是一種特殊的變數,它是存放地址的。假設我們定義了一個指標變數 int *i_pointer 用來存放整型變數 i 的地址。可以通過語句:i_pointer =&i;
將i的地址(2000)存放到i_pointer中。這時, i_pointer的值就是(2000) ,即變數i所佔用單元的起始地址。要存取變數i的值,可以採用間接方式:先找到存放“i的地址”的變數i_pointer ,從中取出i的地址(2000),然後取出i的值3。
*:這玩意叫做取值操作符 &:而這玩意叫做取址操作符 如:int i = 2000;int *pointer; pointer = &i; printf("%d\n", *pointer);
4.指標與指標變數:
知道了一個變數的地址,就可以通過這個地址來訪問這個變數,因此,又把變數的地址稱為該變數的“指標” 。
C語言中可以定義一類特殊的變數,這些變數專門用來存放變數的地址,稱為指標變數。
注意:指標變數的值(即指標變數中存放的值)是地址(即指標)。請區分“指標”和“指標變數”這兩個概念。
5.定義一個指標變數 "*":
下面都是合法的定義:
float *pointer_3; // pointer_3是指向float型變數的指標變數
char *pointer_4; // pointer_4是指向字元型變數的指標變數
6.在定義指標變數時要注意兩點:
一、指標變數前面的“*”,表示該變數的型別為指標型變數。其一般形式為:
型別說明符 *變數名;
其中,*表示這是一個指標變數,變數名即為定義的指標變數名,型別說明符表示本指標變數所指向的變數的資料型別。
例如: float *pointer_1;
指標變數名是pointer_1 ,而不是* pointer_1 。
二、在定義指標變數時必須指定基型別。
需要特別注意的是,只有整型變數的地址才能放到指向整型變數的指標變數中。下面的賦值是錯誤的∶
float a; int * pointer_1; pointer_1=&a; /*將float型變數的地址放到指向整型變數的指標變數中,錯誤 */
7.指標變數的引用 “&”
請牢記,指標變數中只能存放地址(指標),不要將一個整數(或任何其他非地址型別的資料)賦給一個指標變數,否則編譯器也會把該值當成一個地址來處理。
C語言中提供了地址運算子&來表示變數的地址。
其一般形式為: &變數名;
如&a表示變數a的地址,&b表示變數b的地址。當然,變數本身必須預先宣告。
/*例:通過指標變數訪問整型變數*/ void main() { int a,b; int *pointer_1, *pointer_2; a=100; b=10; pointer_1 = &a; pointer_2 = &b; printf("%d,%d\n",a,b); printf("%d,%d\n",*pointer_1, *pointer_2); }
8.對“&”和“*”運算子再做些說明:
如果已執行了語句 pointer_1=&a;
(1)&* pointer_1的含義是什麼?
“&”和“*”兩個運算子的優先級別相同,但按自右而左方向結合,因此先進行* pointer_1的運算,它就是變數a,再執行&運算。因此,&* pointer_1與&a相同,即變數a的地址。
如果有:pointer_2 =&* pointer_1;它的作用是將&a(a的地址)賦給pointer_2 ,如果 pointer_2 原來指向b,經過重新賦值後它已不再指向b了,而指向了a。
請看圖解!
(2) *&a的含義是什麼?
先進行&a運算,得a的地址,再進行*運算。即&a所指向的變數,也就是變數a。*&a和*pointer_1的作用是一樣的,它們都等價於變數a。即*&a與a等價。
(3) (*pointer_1)++相當於a++。
注意括號是必要的,如果沒有括號,就成為了*pointer_1++,從附錄可知:++和*為同一優先級別,而結合方向為自右而左,因此它相當於*(pointer_1++)。
由於++在pointer_1的右側,是“後加”,因此先對pointer_1的原值進行*運算,得到a的值,然後使pointer_1的值改變,這樣pointer_1不再指向a了。
9.例題:
題目:輸入a和b兩個整數,按先大後小的順序輸出a和b。
#include <stdio.h> void main() { int *p1, *p2, *p, a, b; scanf("%d %d", &a, &b); p1 = &a; p2 = &b; if( a < b) { p = p1; p1 = p2; p2 = p; } //此後,p1指向b, p2指向a ^_^ printf("a = %d, b = %d\n", a, b); printf("max = %d, min = %d\n", *p1, *p2); }
題目:對輸入的兩個整數按大小順序輸出!這次用函式實現交換功能!
#include <stdio.h> void swap(int *p1, int *p2); void main() { int a, b; int *pointer_1, *pointer_2; scanf("%d %d", &a, &b); pointer_1 = &a; pointer_2 = &b; if(a < b) { swap(pointer_1, pointer_2); //swap實現的是交換…… } printf("\n%d > %d\n", a, b); } void swap(int *p1, int *p2) { int temp; printf("I'm swapping……\n"); printf("Please wait^_^"); temp = *p1; //temp = a; *p1 = *p2; //a = b; *p2 = temp; //b = temp; }