陣列與指標

2021-04-06 16:00:59 字數 4329 閱讀 3562

10.3.1 通過指標引用一維陣列中的元素

在c語言中,指標和陣列有著緊密的聯絡,其原因在於凡是由陣列下標完成的操作皆可用指標來實現。在陣列中我們已經知道,可以通過陣列的下標唯一確定了某個陣列元素在陣列中的順序和儲存位址,這種訪問方式也稱為"下標方式"。例如:

int a[5] = , x, y;

x=a[2]; /* 通過下標將陣列a下標為2的第3個元素的值賦給x,x=3 */

y=a[4]; /* 通過下標將陣列a下標為4的第5個元素的值賦給y,y=5 */

由於每個陣列元素相當於乙個變數,因此指標變數既然可以指向一般的變數,同樣也可以指向陣列中的元素,也就是可以用"指標方式"訪問陣列中的元素。

例10-6:分析程式的執行過程和結果。

#include

main ( )

;int x, y, *p;       /* 指標變數p */

p = &a[0]; /* 指標p指向陣列a的元素a[0],等價於p=a */

x = *(p+2); /* 取指標p+2所指的內容,等價於x=a[2] */

y = *(p+4); /* 取指標p+4所指的內容,等價於y=a[4] */

printf ("*p=%d, x=%d, y=%d/n", *p, x, y);}

語句"p=&a[0]"表示將陣列a中元素a[0]的位址賦給指標變數p,則p就是指向陣列首元素a[0]的指標變數,"&a[0]"是取陣列首元素的位址。

c語言中規定,陣列第1個(下標為0)元素的位址就是陣列的首位址,同時c中還規定,陣列名代表的就是陣列的首位址,所以,該語句等價於"p=a;"。注意,陣列名代表的乙個位址常量,是陣列的首位址,它不同於指標變數。

對於指向陣列首位址的指標p,p+i(或a+i)是陣列元素a[i]的位址,*(p+i)(或*(a+i))就是a[i]的值,其關係如圖10-5所示。

圖10-5 指標操作與陣列元素的關係

對陣列元素的訪問,下標方式和指標方式是等價的,但從c語言系統內部處理機制上講,指標方式效率高。需要注意的是:指標方式不如下標方式直觀。下標方式可以直截了當地看出要訪問的是陣列中的哪個元素;而對於指向陣列的指標變數,進行運算以後,指標變數的值改變了,其當前指向的是哪乙個陣列元素不再是一目了然。

例10-7:分析程式。

main( )

;int *p;

p = a;   /* 指標p為陣列的首位址 */

printf("%d", *p);

printf(" %d/n", *(++p));   /* 以下兩個語句等價 */

printf("%d", *++p);

printf(" %d/n", *(p--)); /* *(p--)等價於*p-- */

p += 3;

printf("%d %d/n", *p, *(a+3));

}執行結果:

1 23 3

5 4

此例中指向陣列a與指標變數p的指向變化情況見圖10-6。

注意,第2個printf語句中的"*(++p)",是先使指標p自增加1,再取指標p值作"*"運算,它的含義等價於第3個printf語句中的"*++p"。而"*(p--)"是先取指標p值作"*" 運算,再使指標p自減減1。

用指標方式實現對陣列的訪問是很方便的,可以使源程式更緊湊、更清晰。

10.3.2 指標基本運算

對於指標的運算有三種:指標與正整數的加減運算、兩個指標的關係運算,以及兩個指標的減法運算。

1. 指標與正整數的加減運算

當指標p指向陣列中的元素時,n為乙個正整數,則表示式:

p+n表示:指標p所指向當前元素之後的第n個元素。而表示式:

p-n表示:指標p所指向當前元素之前的第n個元素。

最常見的指標加減運算為p++的含義是:指標加1,指向陣列中的下乙個元素;p--的含義是:指標減1,指向陣列中的前乙個元素。

指標與整數進行加減運算後,它們的相對關係如圖10-7所示。

由於指標p所指的具體物件不同,所以對指標與整數進行加減運算時,c語言會根據所指的不同物件計算出不同的放大因子,以保證正確操作實際的運算物件。對於字元型,放大因子為1;對於整型,放大因子為2;對於長整型,放大因子為4;對於雙精度浮點型,放大因子為8。不同資料型別的放大因子等於乙個該資料型別的變數所占用的記憶體單元數。

例10-8:程式設計將str1複製到str2中。

#include

#include

main( )

/* 指標p1和p2分別向後移動1個字元 */

printf("string 2:");

puts(str2);}

程式中的關鍵是while語句,"(*p2=*p1)!='/0'"的含義是:先將指標p1的內容送到指標p2的內容中,即進行兩個指標內容的賦值,然後再判斷所賦值的字元是否是串結束標記'/0',如果不是串結束標記,則執行迴圈繼續進行字元複製;如果是串結束標記,則退出迴圈,完成串複製。

對於上面程式中的while迴圈,是可以進行優化的。優化後的迴圈可以如下:

優化一:

while ( *p2 = *p1 )

優化二:

while ( *p2++ = *p1++ ) ; /* 迴圈體為空 */

2. 兩個指標的關係運算

只有當兩個指標指向同乙個陣列中的元素時,才能進行關係運算。

當指標p和指標q指向同一陣列中的元素時,

則:pq 當p所指的元素在q所指的元素之後時,表示式的值為1;反之為0。

p==q 當p和q指向同一元素時,表示式的值為1;反之為0。

p!=q 當p和q不指向同一元素時,表示式的值為1;反之為0。

任何指標p與null進行"p==null"或"p!=null"運算均有意義,"p==null"的含義是當指標p為空時成立,"p!=null"的含義是當p不為空時成立。

不允許兩個指向不同陣列的指標進行比較,因為這樣的判斷沒有任何實際的意義。

例10-9:編寫程式將乙個字串反向。

#include

main( )

10.3.3 通過指標引用二維陣列中的元素

在c語言中,二維陣列是按行優先的規律轉換為一維線性存放在記憶體中的,因此,可以通過指標訪問二維陣列中的元素。

如果有:int a[m][n];

則將二維陣列中的元素a[i][j]轉換為一維線性位址的一般公式是:

線性位址=a+i×m+j

其中:a為陣列的首位址, m和n分別為二維陣列行和列的元素個數。

若有:int a[4][3], *p;

p = &a[0][0];

則二維陣列a的資料元素在記憶體中儲存順序及位址關係如圖10-8所示。

這裡,a表示二維陣列的首位址;a[0]表示0行元素的起始位址,a[1]表示1行元素的起始位址,a[2]和a[3]分別表示2行和3行元素的起始位址。

陣列元素a[i][j]的儲存位址是:&a[0][0]+i*n+j。

我們可以說:a和a[0]是陣列元素a[0][0]的位址,也是0行的首位址。a+1和a[1]是陣列元素a[1][0]的位址,也是1行的首位址。

由於a 是二維陣列,經過兩次下標運算[ ]之後才能訪問到陣列元素。所以根據c語言的位址計算方法,a要經過兩次*操作後才能訪問到陣列元素。這樣就有:*a是a[0]的內容,即陣列元素a[0][0]的位址。**a是陣列元素a[0][0]。a[0]是陣列元素a[0][0]的位址,*a[0]是素組元素a[0][0]。

例10-11:給定某年某月某日,將其轉換成這一年的第幾天並輸出。

此題的演算法很簡單,若給定的月是i,則將1、2、3、……、i-1月的各月天數累加,再加上指定的日。但對於閏年,二月的天數29天,因此還要判定給定的年是否為閏年。為實現這一演算法,需設定一張每月天數列表,給出每個月的天數,考慮閏年非閏年的情況,此表可設定成乙個2行13列的二維陣列,其中第1行對應的每列(設1~12列有效)元素是平年各月的天數,第2行對應的是閏年每月的天數。程式中使用指標作為函式day_of_year的形式引數。

#include

main( )

, };

int y, m, d;

scanf("%d%d%d", &y, &m, &d);

printf("%d/n", day_of_year(day_tab,y,m,d) ); /* 實參為二維陣列名 */

}day_of_year(day_tab,year,month,day)

int *day_tab; /* 形式引數為指標 */

int year, month, day;

{ int i, j;

i = (year%4==0&&year%100!=0) || year%400==0;

for ( j=1; j

由於c語言對於二維陣列中的元素在記憶體中是按行存放的,所以在函式day_of_year 中要使用公式"day_tab+i*13+j"計算main函式的day_tab中元素對應的位址。

指標與陣列,指標陣列 陣列指標

int a 10 print n a p,a p a,a print n a 1 p,a 1 p a 1,a 1 a做乙個指標,步長為4,指向乙個元素,a做乙個指標,步長為40,指向乙個維陣列 int b 3 4 print n b p,b p,b p b,b,b print n b 1 p,b 1...

指標陣列與陣列指標

1.指標陣列 指標陣列中每乙個元素都是乙個指標,也既是存放字串的首位址。所以指標陣列適合處理若干個長度不等的字串。定義的一般形式為 型別說明符 指標陣列名 陣列長度 例如 int p 3 宣告乙個陣列,指標陣列p,由3個int型別指標變數元素組成 從運算子的優先順序分析,由於 的優先順序大於 所以p...

指標陣列與陣列指標

呵呵,實在是厭倦了繞口的解釋。指標陣列,故名思義,就是指標的陣列,陣列的元素是指標 陣列指標,同樣,就是直想陣列的指標。簡單舉例說明 int p 2 首先宣告了乙個陣列,陣列的元素是int型的指標。int p 2 宣告了乙個指標,指向了乙個有兩個int元素的陣列。其實這兩種寫法主要是因為運算子的優先...