愛伊米

C語言簡明教程(九)指標(二)

指標

(二)

實驗內容

在前面章節我們已經大量的使用了字串,如在  函式中輸入一個字串。我們本節將會詳細的介紹使用字串更加靈活的方法-透過指標引用字串。

實驗知識點

字串的引用方式

字元指標作函式引數

使用字元指標變數和字元陣列的比較

本次實驗作為上一章的延續,繼續講解指標,針對字串指標做深入學習。

字串的引用方式

在 C 程式中,字串是存放在字元陣列中的。想引用一個字串,可以使用下面兩種方式。

1。用字元陣列存放一個字串,可以透過陣列名和下標引用字串中一個字元,也可以透過陣列名和格式宣告 “%s” 輸出該字元。

例:定義一個字元陣列,在其中存放字串 “I love Shiyanlou!”,輸出該字串和第 10 個字元。

建立 11-1。c 檔案並輸入以下程式碼:

程式執行結果如下:

程式分析:

在定義字元陣列 string 時未指定長度,由於對它初始化,因此它的長度是確定的,長度應為 18,其中 17 個位元組存放 “I love Shiyanlou!” 這 17 個字元(包含空格和感嘆號),最後一個位元組存放字串 ,陣列名 string 代表字陣列首元素的地址。

2。用字元指標變數指向一個字串常量,透過字元指標變數引用字串常量。

要求透過字元指標變數輸出一個字串。

編寫源程式 11-2。c:

程式執行結果如下:

程式分析:

對字元指標變數 string 初始化,實際上是把字串第一個元素的地址賦給指標變數 string,使 string 指向字串的第一個字元。有人誤認為 string 是一個字串變數,以為在定義時把 “I love GMORAKEL!” 這幾個字元賦給該字串變數,這是不對的。在 C 語言中只有字元變數,沒有字串變數。

以下語句 中 %s 是輸出字串時所用的格式,在輸出項中給出字元指標變數名 string,則系統會輸出 string 所指向的字串第一個字元,然後自動使 string 加 1,使之指向下一個字元,再輸出該字元。。。如此直到遇到字串結束標誌 ,因此再輸出是能確定輸出的字元到何時結束。

將字串 a 複製為字串 b,然後輸出字串 b。

解題思路:

定義兩個字元陣列 a 和 b,用 “I am a programmer” 對 a 陣列進行初始化。將 a 陣列中的字元逐個複製到 b 陣列中。可以用不同的方法引用並輸出字元陣列元素,我們本例採用地址出各元素的值。透過改變指標變數的值使它指向字串中的不同字元。

編寫程式 11-3。c 用 i++ 來遍歷陣列,程式 11-4。c 用 p++ 遍歷陣列。

編寫源程式 11-3。c:

編寫源程式 11-4。c:

執行兩個程式,程式執行結果如下:

可以看出,結果是一樣的。

字元指標作函式引數

假如想把一個字串從一個函式“傳遞”到另一個函式,可以用地址傳遞的辦法,即用字元陣列名作引數,也可以用字元指標變數做引數。在被呼叫的函式中可以改變字串的內容,在主調函式中可以引用改變後的字串。在函式呼叫實現字串的複製。

解題思路:

定義一個函式  用來實現字串複製的功能,在主函式中呼叫此函式,函式的形參和實參可以分別用字元陣列名或字元指標變數。分別程式設計,以供分析比較。

編寫程式 11-5。c 用字元陣列名作為函式引數,程式 11-6。c 用字元型指標變數作實參,程式 11-7。c 用字元指標變數作形參和實參。

編寫源程式 11-5。c:

編寫源程式 11-6。c:

編寫源程式 11-7。c:

執行三個程式,程式執行結果如下:

C語言簡明教程(九)指標(二)

可以看出,結果是一樣的。

程式分析

程式 11-5。c。將陣列 a 複製到陣列 b 後,未能全部覆蓋 b 陣列原有內容。b 陣列最後 3 個元素仍保留原狀。在輸出 b 時由於按 %s 輸出,遇到  就會結束,因此第一個  後的字元不輸出。

C語言簡明教程(九)指標(二)

程式 11-6。c。 不變,在  函式中定義字元指標變數 from 和 to,分別指向兩個字元陣列 a 和 b。指標變數 from 的值是 a 陣列首元素的地址,指標變數 to 的值是 b 陣列首元素的地址。它們作為實參,把 a 陣列首元素的地址和 b 陣列首元素的地址傳遞給形引數組名 from 和 to(它們實質也是指標變數)。

程式 11-7。c。形參改用 char * 型變數(即字元指標變數)。在程式(1)和(2)中  函式的引數用字元陣列名,其實編譯系統是把字元陣列名按指標變數處理的,只是表示形式不同。

使用字元指標變數和字元陣列的比較

用字元陣列和字元指標變數都能實現字串的儲存和運算,但它們兩者之間是有區別的,主要為以下幾點:

字元陣列由若干元素組成,每個元素中放一個字元,而字元指標變數中存放的是地址(字串第 1 個字元的地址),絕不是將字串放到字元指標變數中。

賦值方式。可以對字元指標變數賦值,但不能對陣列名賦值。對字元指標變數賦值:

不能用以下辦法對字元陣列名賦值:

儲存單元的內容。編譯時為字元陣列分配若干儲存單元,以存放各元素的值,而對字元指標變數,只分配一個儲存單元。

由於指標這一章節介紹的內容偏多,概念和應用比較複雜,我們做一下總結,希望大家能夠理清思路。

首先要準確地弄清楚指標的含義。指標就是地址,凡是出現“指標”的地方,都可以用“地址”代替,例如,變數的指標就是變數的地址,指標變數就是地址變數。要區別指標和指標變數。指標就是地址本身,例如 2008 是某一變數的地址,2008 就是變數的指標。而指標變數是用來存放地址的變數。

什麼叫指向?地址就意味著指向,因為透過地址能找到具有該地址的物件。對於指標變數來說,把誰的地址存放在指標變數中,就說此指標變數指向誰。但應該注意:並不是任何型別的資料都可以存放在同一個指標變數中的。例如:

指標運算

指標變數加(減)一個整數。例如:p++,p- -,p+i,p-i,p-=i 等均是指標變數加減一個整數。將該指標變數的原值(地址)和它指向的變數所佔用的儲存單元的位元組數相加(減)。

指標變數賦值。將一個變數地址賦給一個指標變數。例如:

本 C 語言教程是入門教程,我們僅僅學習的指標的基本概念和初步應用,想要深入並熟練的掌握還需要更加深入的學習。使用指標有兩大優勢:

提高程式設計效率

在呼叫函式是當指標指向變數的值改變時,這些值能夠為主調函式使用,即可以從函式呼叫得到更多個可改變的值

指標使用十分靈活,對熟練的程式人員來說,可以利用它寫出質量很高的程式,實現許多其他高階語言難以實現的功能。但是也十分容易出錯,而且這種錯誤十分隱蔽,所以使用指標需要大家謹小慎微,多上機除錯。

課後練習

習題一

編寫一個程式,輸入月份號,輸出該月份號的英文名稱。例如輸入 8,則輸出 “August”,要求用指標陣列處理。

習題二

有 n 個人圍成一圈,順序排號。從第一個人開始報數(從 1 報到 3),凡是報到 3 的人退出圈子,問最後留下的是原來第幾號的那位。

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

參考答案

習題一

習題二