?? 41.htm
字號:
即為a[i]。
<BR> (3). 指向數組元素的指針, 也可以表示成數組的形式,
也就是說, 它允許
<BR>指針變量帶下標, 如p[i]與*(p+i)等價。
<BR> 假若: p=a+5;
<BR>則p[2]就相當于*(p+2), 由于p指向a[5], 所以p[2]就相當于a[7]。而p[-3]就相
<BR>當于*(p-3), 它表示a[2]。
<P> 2.2. 指向二維數組的指針
<BR> 2.2.1. 二維數組元素的地址
<BR> 為了說明問題, 我們定義以下二維數組:
<BR> int a[3][4]={{0,1,2,3}, {4,5,6,7}, {8,9,10,11}};
<BR>a為二維數組名, 此數組有3行4列, 共12個元素。但也可這樣來理解, 數組a由三
<BR>個元素組成: a[0], a[1], a[2]。而它勻中每個元素又是一個一維數組, 且都含
<BR>有4個元素 (相當于4列), 例如, a[0]所代表的一維數組所包含的 4 個元素為
<BR>a[0][0], a[0][1], a[0][2], a[0][3]。如圖5.所示:
<BR> ┏━━━━┓
┏━┳━┳━┳━┓
<BR> a─→ ┃ a[0] ┃─→┃0 ┃1 ┃2 ┃3 ┃
<BR> ┣━━━━┫
┣━╋━╋━╋━┫
<BR> ┃ a[1] ┃─→┃4
┃5 ┃6 ┃7 ┃
<BR> ┣━━━━┫
┣━╋━╋━╋━┫
<BR> ┃ a[2] ┃─→┃8
┃9 ┃10┃11┃
<BR> ┗━━━━┛
┗━┻━┻━┻━┛
<BR>
圖5.
<BR> 但從二維數組的角度來看, a代表二維數組的首地址,
當然也可看成是二維
<BR>數組第0行的首地址。a+1就代表第1行的首地址, a+2就代表第2行的首地址。
如
<BR>果此二維數組的首地址為1000, 由于第0行有4個整型元素, 所以a+1為1008,
a+2
<BR>也就為1016。如圖6.所示
<BR>
a[3][4]
<BR>
a ┏━┳━┳━┳━┓
<BR>
(1000)─→┃0 ┃1 ┃2 ┃3 ┃
<BR>
a+1 ┣━╋━╋━╋━┫
<BR>
(1008)─→┃4 ┃5 ┃6 ┃7 ┃
<BR>
a+2 ┣━╋━╋━╋━┫
<BR>
(1016)─→┃8 ┃9 ┃10┃11┃
<BR>
┗━┻━┻━┻━┛
<BR>
圖6.
<BR> 既然我們把a[0], a[1], a[2]看成是一維數組名, 可以認為它們分別代表它
<BR>們所對應的數組的首地址, 也就是講, a[0]代表第 0 行中第 0 列元素的地址,
<BR>即&a[0][0], a[1]是第1行中第0列元素的地址, 即&a[1][0], 根據地址運算規則,
<BR>a[0]+1即代表第0行第1列元素的地址, 即&a[0][1], 一般而言, a[i]+j即代表第
<BR>i行第j列元素的地址, 即&a[i][j]。
<BR> 另外, 在二維數組中, 我們還可用指針的形式來表示各元素的地址。如前所
<BR>述, a[0]與*(a+0)等價, a[1]與*(a+1)等價, 因此a[i]+j就與*(a+i)+j等價,
它
<BR>表示數組元素a[i][j]的地址。
<BR> 因此, 二維數組元素a[i][j]可表示成*(a[i]+j)或*(*(a+i)+j),
它們都與
<BR>a[i][j]等價, 或者還可寫成(*(a+i))[j]。
<BR> 另外, 要補充說明一下, 如果你編寫一個程序輸出打印a和*a,
你可發現它
<BR>們的值是相同的, 這是為什么呢? 我們可這樣來理解: 首先, 為了說明問題,
我
<BR>們把二維數組人為地看成由三個數組元素a[0], a[1], a[2]組成, 將a[0], a[1],
<BR>a[2]看成是數組名它們又分別是由4個元素組成的一維數組。因此, a表示數組第
<BR>0行的地址, 而*a即為a[0], 它是數組名, 當然還是地址, 它就是數組第0 行第0
<BR>列元素的地址。
<P> 2.2.2 指向一個由n個元素所組成的數組指針
<BR> 在Turbo C中, 可定義如下的指針變量:
<BR> int (*p)[3];
<BR> 指針p為指向一個由3個元素所組成的整型數組指針。在定義中,
圓括號是不
<BR>能少的, 否則它是指針數組, 這將在后面介紹。這種數組的指針不同于前面介紹
<BR>的整型指針, 當整型指針指向一個整型數組的元素時, 進行指針(地址)加1運算,
<BR>表示指向數組的下一個元素, 此時地址值增加了2(因為放大因子為2), 而如上所
<BR>定義的指向一個由3個元素組成的數組指針, 進行地址加1運算時, 其地址值增加
<BR>了6(放大因子為2x3=6), 這種數組指針在Turbo C中用得較少, 但在處理二維數
<BR>組時, 還是很方便的。例如:
<BR> int a[3][4],
(*p)[4];
<BR> p=a;
<BR> 開始時p指向二維數組第0行, 當進行p+1運算時, 根據地址運算規則,
此時
<BR>放大因子為4x2=8, 所以此時正好指向二維數組的第1行。和二維數組元素地址計
<BR>算的規則一樣, *p+1指向a[0][1], *(p+i)+j則指向數組元素a[i][j]。
<BR> 例1
<BR> int a[3] [4]={
<BR> {1,3,5,7},
<BR> {9,11,13,15},
<BR> {17,19,21,23}
<BR> };
<BR> main()
<BR> {
<BR> int i,(*b)[4];
<BR> b=a+1;
/* b指向二維數組的第1行, 此時*b[0]或
<BR>
**b是a[1][0] */
<BR> for(i=1;i<=4;b=b[0]+2,i++)/*
修改b的指向, 每次增加2 */
<BR> printf("%d\t",*b[0]);
<BR> printf("\n");
<BR> for (i=0; i<2;
i++) {
<BR> b=a+i;
/* 修改b的指向, 每次跳過二維數組的
<BR>
一行 */
<BR> printf("%d\t",*(b[i]+1));
<BR> }
<BR> printf ("\n");
<BR> }
<BR> 程序運行結果如下:
<BR> 9 13 17
21
<BR> 3 11 19
<P> 3. 字符指針
<BR> 我們已經知道, 字符串常量是由雙引號括起來的字符序列,
例如:
<BR> "a string"
<BR>就是一個字符串常量, 該字符串中因為字符a后面還有一個空格字符, 所以它由8
<BR>個字符序列組成。在程序中如出現字符串常量C 編譯程序就給字符串常量按排一
<BR>存貯區域, 這個區域是靜態的, 在整個程序運行的過程中始終占用, 平時所講的
<BR>字符串常量的長度是指該字符串的字符個數, 但在按排存貯區域時, C 編譯程序
<BR>還自動給該字符串序列的末尾加上一個空字符'\0', 用來標志字符串的結束,
因
<BR>此一個字符串常量所占的存貯區域的字節數總比它的字符個數多一個字節。
<BR> Turbo C中操作一個字符串常量的方法有:
<BR> (1). 把字符串常量存放在一個字符數組之中, 例如:
<BR> char s[]="a
string";
<BR>數組s共有9個元素所組成, 其中s[8]中的內容是'\0'。實際上, 在字符數組定義
<BR>的過程中, 編譯程序直接把字符串復寫到數組中, 即對數組s初始化。
<BR> (2). 用字符指針指向字符串, 然后通過字符指針來訪問字符串存貯區域。
<BR>當字符串常量在表達式中出現時, 根據數組的類型轉換規則, 它被轉換成字符指
<BR>針。因此, 若我們定義了一字符指針cp:
<BR> char *cp;
<BR>于是可用:
<BR> cp="a string";
<BR>使cp指向字符串常量中的第0號字符a, 如圖7.所示。
<BR>
cp
<BR> ┏━━━┓
┏━┳━┳━┳━┳━┳━┳━┳━┳━┓
<BR> ┃ ─╂─→
┃a ┃ ┃s ┃t ┃r ┃i ┃n ┃g ┃\0┃
<BR> ┗━━━┛
┗━┻━┻━┻━┻━┻━┻━┻━┻━┛
<BR>
圖7.
<BR>以后我們可通過cp來訪問這一存貯區域, 如*cp或cp[0]就是字符a, 而cp[i]或
<BR>*(cp+i)就相當于字符串的第i號字符, 但企圖通過指針來修改字符串常量的行為
<BR>是沒有意義的。
<P> 4. 指針數組
<BR> 因為指針是變量, 因此可設想用指向同一數據類型的指針來構成一個數組,
<BR>這就是指針數組。數組中的每個元素都是指針變量, 根據數組的定義, 指針數組
<BR>中每個元素都為指向同一數據類型的指針。指針數組的定義格式為:
<BR> 類型標識 *數組名[整型常量表達式];
<BR> 例如:
<BR> int *a[10];
<BR>定義了一個指針數組, 數組中的每個元素都是指向整型量的指針, 該數組由10個
<BR>元素組成, 即a[0], a[1], a[2], ..., a[9], 它們均為指針變量。a為該指針數
<BR>組名, 和數組一樣, a是常量, 不能對它進行增量運算。a為指針數組元素a[0]的
<BR>地址, a+i為a[i]的地址, *a就是a[0], *(a+i)就是a[i]。
<BR> 為什么要定義和使用指針數組呢? 主要是由于指針數組對處理字符串提供了
<BR>更大的方便和靈活, 使用二維數組對處理長度不等的正文效率低, 而指針數組由
<BR>于其中每個元素都為指針變量, 因此通過地址運算來操作正文行是十分方便的。
<BR> 指針數組和一般數組一樣, 允許指針數組在定義時初始化,
但由于指針數組
<BR>的每個元素是指針變量, 它只能存放地址, 所以對指向字符串的指針數組在說明
<BR>賦初值時, 是把存放字符串的首地址賦給指針數組的對應元素, 例如下面是一個
<BR>書寫函數month_name(n), 此函數返回一個指向包含第n月名字的字符指針( 關于
<BR>函數, 第6節將專門介紹)。
<BR> 例2: 打印1月至12月的月名:
<BR> char *month_name(int n)
<BR> {
<BR> static char
*name[]={
<BR>
"Illegal month",
<BR>
"January",
<BR>
"February",
<BR>
"March",
<BR>
"April",
<BR>
"May",
<BR>
"June",
<BR>
"July",
<BR>
"August",
<BR>
"September",
<BR>
"October",
<BR>
"November",
<BR>
"December"
<BR> };
<BR> return((n<1||n>12)?name[0]:name[n]);
<BR> }
<BR> main()
<BR> {
<BR> int i;
<BR> for(i=0; i<13;
i++)
<BR>
printf("%s\n", month_name(i));
<BR>
<P>
<A HREF="index.html">返回目錄</A>
<BR> }
<BR>
<P>
</BODY>
</HTML>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -