指標
(二)
實驗內容
在前面章節我們已經大量的使用了字串,如在 函式中輸入一個字串。我們本節將會詳細的介紹使用字串更加靈活的方法-透過指標引用字串。
實驗知識點
字串的引用方式
字元指標作函式引數
使用字元指標變數和字元陣列的比較
本次實驗作為上一章的延續,繼續講解指標,針對字串指標做深入學習。
字串的引用方式
在 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:
執行三個程式,程式執行結果如下:
可以看出,結果是一樣的。
程式分析
程式 11-5。c。將陣列 a 複製到陣列 b 後,未能全部覆蓋 b 陣列原有內容。b 陣列最後 3 個元素仍保留原狀。在輸出 b 時由於按 %s 輸出,遇到 就會結束,因此第一個 後的字元不輸出。
程式 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 的人退出圈子,問最後留下的是原來第幾號的那位。
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
參考答案
習題一
習題二