6.4 指針與數(shù)組
變量在內(nèi)存存放是有地址的,數(shù)組在內(nèi)存存放也同樣具有地址。對數(shù)組來說,數(shù)組名就是數(shù)組在內(nèi)存安放的首地址。指針變量是用于存放變量的地址,可以指向變量,當然也可存放數(shù)組的首址或數(shù)組元素的地址,這就是說,指針變量可以指向數(shù)組或數(shù)組元素,對數(shù)組而言,數(shù)組和數(shù)組元素的引用,也同樣可以使用指針變量。下面就分別介紹指針與不同類型的數(shù)組。
6.4.1 指針與一維數(shù)組
假設(shè)我們定義一個一維數(shù)組,該數(shù)組在內(nèi)存會有系統(tǒng)分配的一個存儲空間,其數(shù)組的名字就是數(shù)組在內(nèi)存的首地址。若再定義一個指針變量,并將數(shù)組的首址傳給指針變量,則該指針就指向了這個一維數(shù)組。我們說數(shù)組名是數(shù)組的首地址,也就是數(shù)組的指針。而定義的指針變量就是指向該數(shù)組的指針變量。對一維數(shù)組的引用,既可以用傳統(tǒng)的數(shù)組元素的下標法,也可使用指針的表示方法。
int a[10] , *ptr; /* 定義數(shù)組與指針變量* /
做賦值操作:ptr=a; 或ptr = &a[0];
則ptr就得到了數(shù)組的首址。其中, a是數(shù)組的首地址, &a[0]是數(shù)組元素a[0]的地址,由于a[0]的地址就是數(shù)組的首地址,所以,兩條賦值操作效果完全相同。指針變量ptr就是指向數(shù)組a的指針變量。
若ptr指向了一維數(shù)組,現(xiàn)在看一下C規(guī)定指針對數(shù)組的表示方法:
1) ptr+n與a + n表示數(shù)組元素a[n]的地址,即&a[n] 。對整個a數(shù)組來說,共有10個元素, n的取值為0~9,則數(shù)組元素的地址就可以表示為ptr + 0~ptr + 9或a + 0~a + 9,與&a[0] ~&a[9]保持一致。
2) 知道了數(shù)組元素的地址表示方法, *(ptr + n)和*(a+n)就表示為數(shù)組的各元素即等效于a[n]。
3) 指向數(shù)組的指針變量也可用數(shù)組的下標形式表示為ptr[n],其效果相當于*(ptr + n)。
[例6-5] /*以下標法輸入輸出數(shù)組各元素。
下面從鍵盤輸入10個數(shù),以數(shù)組的不同引用形式輸出數(shù)組各元素的值。
# include
main( )
{
int n,a[10],*ptr=a;
for(n = 0; n<=9; n++)
scanf("%d" , &a[n]);
printf("1------output! \n");
for(n = 0; n<=9; n++)
printf("M", a[n]);
printf("\n");
}
運行程序:
1 2 3 4 5 6 7 8 9 0
1------output!
1 2 3 4 5 6 7 8 9 0
[例6-6] 采用指針變量表示的地址法輸入輸出數(shù)組各元素。
#include
main( )
{
int n,a[10],*ptr=a; / *定義時對指針變量初始化* /
for(n = 0; n<=9; n++)
scanf("%d", ptr + n);
printf("2------output! \n");
for(n=0; n<=9; n++)
printf("M", *(ptr+n));
printf("\n");
}
運行程序:
1 2 3 4 5 6 7 8 9 0
2------output!
1 2 3 4 5 6 7 8 9 0
[例6-7] 采用數(shù)組名表示的地址法輸入輸出數(shù)組各元素。
main( )
{
int n,a[10],*ptr=a;
for(n = 0; n < = 9; n ++)
scanf("%d", a+n);
printf("3------output! \n");
for(n = 0; n<=9; n++)
printf("M", *(a+n));
printf("\n");
}
運行程序:
1 2 3 4 5 6 7 8 9 0
3------output!
1 2 3 4 5 6 7 8 9 0
[例6-8] 用指針表示的下標法輸入輸出數(shù)組各元素。
main( )
{
int n,a[10],*ptr=a;
for(n = 0; n<=9; n++)
scanf("%d", &ptr[n]);
printf("4------output! \n");
for(n = 0; n<=9; n++)
printf("M", ptr[n]);
printf("\n");
}
運行程序:
1 2 3 4 5 6 7 8 9 0
4----output!
1 2 3 4 5 6 7 8 9 0
[例6-9] 利用指針法輸入輸出數(shù)組各元素
main( )
{
int n,a[10],*ptr=a;
for(n = 0; n<=9; n++)
scanf("%d", ptr++);
printf("5------output! \n");
ptr = a; / *指針變量重新指向數(shù)組首址* /
for(n = 0; n<=9; n++)
printf("M", *ptr++);
printf("\n");
}
運行程序:
1 2 3 4 5 6 7 8 9 0
5-----output!
1 2 3 4 5 6 7 8 9 0
在程序中要注意*ptr++所表示的含義。*ptr表示指針所指向的變量; ptr++表示指針所指向的變量地址加1個變量所占字節(jié)數(shù),具體地說,若指向整型變量,則指針值加2,若指向?qū)嵭?,則加4,依此類推。而printf(“M”, *ptr+ +)中,*ptr++所起作用為先輸出指針指向的變量的值,然后指針變量加1。循環(huán)結(jié)束后,指針變量指向如圖6 - 6所示:
指針變量的值在循環(huán)結(jié)束后,指向數(shù)組的尾部的后面。假設(shè)元素a[9]的地址為1000,整型占2字節(jié),則ptr的值就為100 2。請思考下面的程序段:
main( )
{
int n,a[10],*ptr=a;
for(n = 0; n<=9; n++)
scanf("%d", ptr++);
printf("4------output! \n");
for(n = 0; n<=9; n++)
printf("M", *ptr++);
printf("\n");
}
程序與例6 - 9相比,只少了賦值語句p t r = a;程序的運行結(jié)果還相同嗎?
6.4.2 指針與二維數(shù)組
定義一個二維數(shù)組:
int a[3][4];
表示二維數(shù)組有三行四列共1 2個元素,在內(nèi)存中按行存放,存放形式為圖6 - 7:
變量在內(nèi)存存放是有地址的,數(shù)組在內(nèi)存存放也同樣具有地址。對數(shù)組來說,數(shù)組名就是數(shù)組在內(nèi)存安放的首地址。指針變量是用于存放變量的地址,可以指向變量,當然也可存放數(shù)組的首址或數(shù)組元素的地址,這就是說,指針變量可以指向數(shù)組或數(shù)組元素,對數(shù)組而言,數(shù)組和數(shù)組元素的引用,也同樣可以使用指針變量。下面就分別介紹指針與不同類型的數(shù)組。
6.4.1 指針與一維數(shù)組
假設(shè)我們定義一個一維數(shù)組,該數(shù)組在內(nèi)存會有系統(tǒng)分配的一個存儲空間,其數(shù)組的名字就是數(shù)組在內(nèi)存的首地址。若再定義一個指針變量,并將數(shù)組的首址傳給指針變量,則該指針就指向了這個一維數(shù)組。我們說數(shù)組名是數(shù)組的首地址,也就是數(shù)組的指針。而定義的指針變量就是指向該數(shù)組的指針變量。對一維數(shù)組的引用,既可以用傳統(tǒng)的數(shù)組元素的下標法,也可使用指針的表示方法。
int a[10] , *ptr; /* 定義數(shù)組與指針變量* /
做賦值操作:ptr=a; 或ptr = &a[0];
則ptr就得到了數(shù)組的首址。其中, a是數(shù)組的首地址, &a[0]是數(shù)組元素a[0]的地址,由于a[0]的地址就是數(shù)組的首地址,所以,兩條賦值操作效果完全相同。指針變量ptr就是指向數(shù)組a的指針變量。
若ptr指向了一維數(shù)組,現(xiàn)在看一下C規(guī)定指針對數(shù)組的表示方法:
1) ptr+n與a + n表示數(shù)組元素a[n]的地址,即&a[n] 。對整個a數(shù)組來說,共有10個元素, n的取值為0~9,則數(shù)組元素的地址就可以表示為ptr + 0~ptr + 9或a + 0~a + 9,與&a[0] ~&a[9]保持一致。
2) 知道了數(shù)組元素的地址表示方法, *(ptr + n)和*(a+n)就表示為數(shù)組的各元素即等效于a[n]。
3) 指向數(shù)組的指針變量也可用數(shù)組的下標形式表示為ptr[n],其效果相當于*(ptr + n)。
[例6-5] /*以下標法輸入輸出數(shù)組各元素。
下面從鍵盤輸入10個數(shù),以數(shù)組的不同引用形式輸出數(shù)組各元素的值。
# include
main( )
{
int n,a[10],*ptr=a;
for(n = 0; n<=9; n++)
scanf("%d" , &a[n]);
printf("1------output! \n");
for(n = 0; n<=9; n++)
printf("M", a[n]);
printf("\n");
}
運行程序:
1 2 3 4 5 6 7 8 9 0
1------output!
1 2 3 4 5 6 7 8 9 0
[例6-6] 采用指針變量表示的地址法輸入輸出數(shù)組各元素。
#include
main( )
{
int n,a[10],*ptr=a; / *定義時對指針變量初始化* /
for(n = 0; n<=9; n++)
scanf("%d", ptr + n);
printf("2------output! \n");
for(n=0; n<=9; n++)
printf("M", *(ptr+n));
printf("\n");
}
運行程序:
1 2 3 4 5 6 7 8 9 0
2------output!
1 2 3 4 5 6 7 8 9 0
[例6-7] 采用數(shù)組名表示的地址法輸入輸出數(shù)組各元素。
main( )
{
int n,a[10],*ptr=a;
for(n = 0; n < = 9; n ++)
scanf("%d", a+n);
printf("3------output! \n");
for(n = 0; n<=9; n++)
printf("M", *(a+n));
printf("\n");
}
運行程序:
1 2 3 4 5 6 7 8 9 0
3------output!
1 2 3 4 5 6 7 8 9 0
[例6-8] 用指針表示的下標法輸入輸出數(shù)組各元素。
main( )
{
int n,a[10],*ptr=a;
for(n = 0; n<=9; n++)
scanf("%d", &ptr[n]);
printf("4------output! \n");
for(n = 0; n<=9; n++)
printf("M", ptr[n]);
printf("\n");
}
運行程序:
1 2 3 4 5 6 7 8 9 0
4----output!
1 2 3 4 5 6 7 8 9 0
[例6-9] 利用指針法輸入輸出數(shù)組各元素
main( )
{
int n,a[10],*ptr=a;
for(n = 0; n<=9; n++)
scanf("%d", ptr++);
printf("5------output! \n");
ptr = a; / *指針變量重新指向數(shù)組首址* /
for(n = 0; n<=9; n++)
printf("M", *ptr++);
printf("\n");
}
運行程序:
1 2 3 4 5 6 7 8 9 0
5-----output!
1 2 3 4 5 6 7 8 9 0
在程序中要注意*ptr++所表示的含義。*ptr表示指針所指向的變量; ptr++表示指針所指向的變量地址加1個變量所占字節(jié)數(shù),具體地說,若指向整型變量,則指針值加2,若指向?qū)嵭?,則加4,依此類推。而printf(“M”, *ptr+ +)中,*ptr++所起作用為先輸出指針指向的變量的值,然后指針變量加1。循環(huán)結(jié)束后,指針變量指向如圖6 - 6所示:
指針變量的值在循環(huán)結(jié)束后,指向數(shù)組的尾部的后面。假設(shè)元素a[9]的地址為1000,整型占2字節(jié),則ptr的值就為100 2。請思考下面的程序段:
main( )
{
int n,a[10],*ptr=a;
for(n = 0; n<=9; n++)
scanf("%d", ptr++);
printf("4------output! \n");
for(n = 0; n<=9; n++)
printf("M", *ptr++);
printf("\n");
}
程序與例6 - 9相比,只少了賦值語句p t r = a;程序的運行結(jié)果還相同嗎?
6.4.2 指針與二維數(shù)組
定義一個二維數(shù)組:
int a[3][4];
表示二維數(shù)組有三行四列共1 2個元素,在內(nèi)存中按行存放,存放形式為圖6 - 7:

