c語言程式設計(5)指標

2021-10-19 14:03:23 字數 4690 閱讀 8521

指標是 c 語言中乙個重要的概念,也是 c 語言最精彩的部分。正確而靈活的運用它,可以是程式簡潔、緊湊、高效。

指標變數是一種特殊的變數,它存放的不是資料,而是另一種變數的位址。這個存放資料的變數被稱為指標變數所指向的目標變數。由於通過指標變數中的位址可以直接訪問它指向的目標變數,常把指標變數簡稱為指標。

1:指標變數的命名,與一般變數命名相同,遵循 c 語言的命名規則。

2:指標變數的型別,是指標變數所指向的變數的型別,而不是自身的型別。

定義指標變數

定義指標變數的一般形式為:

型別名 * 指標變數名

int* point_1,

* point_2;

上面定義的基型別為 int 的指標變數 point_1 和 point_2 只能用來指向整型的變數。

引用指標變數

給指標變數賦值。如:

p=

&a;//把 a 的位址賦給指標變數 p

引用指標變數指向的變數

printf

("%d"

,*p)

;

表示將整數 1 賦給 p 當前所指向的變數,如果 p 指向變數 a,則相當於把 1 賦給 a,即 a=1;。

引用指標變數的值。如:

printf

("%o"

,p);

作用是以八進位制數形式輸出指標變數 p 的值,如果 p 指向了 a,就是輸出了 a 的位址,即 &a。

**練習

輸入兩個整數,按先大後小的順序輸出 a 和 b。

#include

intmain()

// 如果 a < b,通過結果可以觀測到 p1 指向 b,p2 指向 a

printf

("a=%d,b=%d\n"

,a,b)

;printf

("max=%d,min=%d\n"

,*p1,

*p2)

;return0;

}

輸入22 和 42,由於 aa 和 b 的值並未交換,他們仍然保持原值,但 p1 和 p2 的值改變了。p1 的值原來為 &a,後來變為 &b。這樣輸出 *p1 和 *p2 時,實際上輸出變數 b 和 a 的值,所以先輸出 42,然後輸出 22。

程式中 p=p1;p1=p2;p2=p; 這個語句是我們之前使用過的方法,兩個變數的值交換要利用第三個變數。實際上學到指標我們可以用更加簡潔的方法把 p=p1;p1=p2;p2=p; 改為 p1=&b,p2=&a,這樣就不需要定義中間變數 p,使得程式更加簡潔。

可以用乙個指標變數指向乙個陣列元素。例如:

int a[10]

=;int*p;

p =&a[0]

;

以上是使指標變數 p 指向 a 陣列的第 0 號元素。

在 c 語言中,陣列名(不包括形參陣列名,形引數組並不佔據實際的記憶體單元)代表陣列中首元素(即序號為 0 的元素)的位址。因此,下面兩個語句等價:

p =

&a[0];

//p 的值是 a[0] 的位址

p = a;

//p 的值是陣列 a 首元素(即 a[0])的位址

注意陣列名不代表整個陣列,只代表陣列首元素的位址。上述 p=a; 的作用是「把 a 陣列的首元素的位址賦給指標變數 p」,而不是「把陣列 a 各元素的值賦給 p」。

在指標指向陣列元素時,可以對指標進行以下運算:

加減乙個整數,如 p+1; 或者 p-1;

自加運算,如 p++ 或者 ++p

自減運算,如 p–或者 --p

說明:

如果指標變數 p 已指向陣列中的乙個元素,則 p+1 指向同一陣列中的下乙個元素,p-1 指向同一陣列中的上乙個元素。注意:執行 p+1 時並不是將 p 的值(位址)簡單地加 1,而是加上乙個陣列元素所占用的位元組數。例如,陣列元素是 float 型,每個元素佔 4 個位元組,則 p+1 意味著使 p 的值加 4 個位元組,以使它指向下乙個元素。p+1 所代表的位址實際上是 p+1*d,d 是乙個陣列元素所佔的位元組數。若 p 的值是 2000,則 p+1 的值不是 2001 而是 2004。

如果 p 的初值為 &a[0],則 p+i 和 a+i 就是陣列元素 a[i] 的位址,或者說,他們指向 a 陣列序號為 i 的元素,見下圖,這裡注意的是 a 代表陣列首元素的位址,a+1 也是位址,它的計算方法同 p+1,即它的實際位址為 a+1*d。例如,p+9 和 a+9 的值是 &a[9],它指向 a[9]。

*(p+i)和 *(a+i) 是 p+i 或 a+i 所指向的元素,即 a[i]。例如 *(p+5) 和 *(a+5) 就是 a[5],三者等價。

**練習有乙個整型陣列 a,有 10 個元素,要求輸出陣列中的全部元素。

#include

intmain()

程式中的 scanf("%d",&a[i]); 可以修改為 scanf("%d",a+i);。用指標變數表示當前的位址。

在使用指標變數指向陣列元素時,有一些問題需要注意可以通過改變指標變數的值指向不同的元素。例如:上述第 3 種方法是用指標變數 p 來指向元素,用 p++ 使 p 的值不斷改變從而指向不同的元素。

歸納分析引用乙個陣列元素,可以用下面兩種方法

下標法,如 a[i],p[i] 的形式;直觀,不易出錯。

指標法,如 *(a+1) 或 *(p+i)。其中 a 是陣列名,p 是指向陣列元素的指標變數,其初值 p=a。

遍歷陣列的成員可用:

下標法,如 a[2];

通過陣列名計算陣列元素位址,找出元素的值

用指標變數指向陣列元素。

int

main()

void

fun(

int arr,

int n)

array 是實參陣列名,arr 為形參陣列名。從前兩節我們應該知道,當用陣列名作為引數時,如果形引數組中各元素的值發生變化,實參陣列元素的值隨之變化。

程式分析

先看陣列元素為實參時的情況。如果已經定義乙個函式,其原型為void swap(int x,int y);,假設函式的作用是將兩個形參 (x,y) 的值交換,現有以下的函式呼叫swap(a[1],a[2]);。用陣列元素 a[1] 和 a[2] 作為實參的情況,與用變數作實參時一樣,是「值傳遞」的方式,將 a[1] 和 a[2] 的值單向傳遞給 x 和 y。當 x 和 y 的值改變時 a[1] 和 a[2] 的值並沒有改變。

我們再來看陣列名作為函式引數的情況,實參陣列名代表該陣列首元素的位址,而形參是用來接收從實參傳遞過來的陣列首元素位址的。因此,形參應該是乙個指標變數。實際上 c 編譯系統是將形參陣列名作為指標變數來處理的。

如果有乙個實參陣列,要想在函式中改變陣列中的元素的值,實參和形參的對應關係有以下 4 種情況。

形參和實參都用陣列名,例如:

int

main()

intf

(int x,

int n)

由於形參陣列名 x 接收了實參陣列首元素 a[0] 的位址,因此可以認為在函式呼叫期間,形引數組與實參陣列共用一段記憶體單元,這種形式比較好理解。

實參用陣列名,形參用指標變數。例如:

int

main()

voidf(

int*x,

int n)

實參 a 為陣列名,形參 x 為 int * 型的指標變數,呼叫函式開始後,形參 x 指向 a[0],即 x=&a[0],通過 x 的值的改變,可以指向 a 陣列的任一元素。例 11-2.c 就屬於此類。

實參形參都用指標變數。例如:

int

main()

voidf(

int*x,

int n)

實參 p 和形參 x 都是 int * 型的指標變數。先使實參指標變數 p 指向陣列 a[0],p 的值是 &a[0]。然後將 p 的值傳給形參指標變數 x,x 的初始值也是 &a[0],通過 x 的值的改變可以使 x 指向陣列 a 的任意元素。

實參為指標變數,形參為陣列名。例如:

int main()

voidf(

int x,

int n)

實參 p 為指標變數,它指向 a[0]。形參為陣列名 x,編譯系統把 x 作為指標變數處理,今將 a[0] 的位址傳給形參 x,使 x 也指向 a[0]。也可以理解為形引數組 x 和 a 陣列共用同一段記憶體單元。在執行過程中可以使 x[i] 的值變化,而 x[i] 就是 a[i]。這樣,main 函式可以使用變化了的陣列元素的值。

以上 4 種方法,實質上都是位址的傳遞其中 3 和 4 兩種只是形式上不同,實際上形參都是使用指標變數。

C語言基礎 C語言指標 5 指標和陣列

上一節,我們補充了一點關於指標的小知識,這次我們來講講指標和陣列 首先,我們來看乙個小例子 include int main int p p ages 0 printf p d n p return 0 輸出的結果 有些人看到後,知道是可以這樣子傳值,但如果我們把整個陣列的所有元素列印出來呢?我們應...

c語言010 指標

include int main 注意 p前面的型別決定了取位址的能力。如果是int型別的,就說明在32平台下可以取址能力是4個位元組。2 指標的本質就是儲存乙個位址,在32位的系統上,所有程式的記憶體位址都用4個位元組表示,所以不管是什麼型別的指標。指標大小都佔4個位元組。稱之為間接引用,表示根據...

2018 5 1指標c語言

是人類的,人類 肯定是給我隨便用,不然 抽他。include include pragma pack push,1 struct s1 a char ch pragma pack pop static void alloc void static void fill void p static vo...