多维数组与指针

多维数组与指针

二维数组 a[3][4] , 可以看作是有三个以一维数组为元素的数组,这三个一维数组的数组名分别是 a[0], a[1] 和 a[2] 。 

    数组名 a ,为数组首地址,即其第一个元素(一维数组)的地址,指向第一个元素(一维数组), a+1 指向第二个元素(第二个一维数组), a+2 指向 a[2] 

又由于 a[0], a[1] 和 a[2] 为一 维数组,故它们也是数组的首地址。 a[0] 是第一个 一 维数组的数组名,即它是第 1 行第 1 个元素 a[0][0] 的地址,a[0]+1

指向 a[0][1], *(a[0]+1) 是 a[0][1] 的值。 也即,不管 二维数组还是 一维数组,它们的数组名都是数组的首地址,都指向数组的第一个元素,只不过,对二维数组

来说,数组名指向的是一个 一维数组(地址),而不是一具体数值;而对 一维数组来说,数组名指向的是一 具体数值,而不是一 个 地址。应特别注意的是 a,a[0]

都是地址,且数值是相同的,但 a 指向一维数组,而 a[0] 指向一个整型数值,它们的类型是不同的,所以 a+1 与 a[0]+1 的含义不但不同,数值也是不一样的。 

1. 多维数组的地址 

   通过上面的讨论,我们直接得到以下结论: 

   对 a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}} 

 

a[0] 

a[0]+1 

 

 

a,a+0 

a+1 

11 

13 

15 

a+2 

17 

19 

21 

23 

   是 二维数组的名字,是二维数组的首地址,即第 行的首地址 

   a+1 是数组 a 第 行首地址 

   a[0],a[1],a[2] 是二维数组中三个一维数组的名字(地址),是第 行第 个 ,第 行第 个 ,第 行第 个元素 的首地址。 

   a[i]+j 是第 行 列的地址 

   *(a[i]+j) 是该地址存储的值,即 a[i][j] 

   a+1 以行为单位移动,而 a[I]+1 在同一行以列(一个元素)为单位移动,所以 a+I 是行指针, a[I] 是列指针,a+1 是个指针,指向第一行的一维数组,那么

*(a+1) 就是个一维数组(的数组名),而第一行的一维数组的数组名是 a[1], 所以 *(a+1)=a[1], 也即 *(a+1) 指向了数组元素 a[1][0] ,变成了一个列指针,可

见对行指针进行 * 运算,就变成了列指针 

  同理 a[1] 是数组名, &a[1] 表示指向该数组的一个指针,即 a+1, 可见对列指针(数组名)取地址,就得到一个行指针,也即指向一个一维数组的指针。 

   大家思考一下 *(a+1)+1 和 *(*(a+1)+1) 的含义 

   大家再思考一下 &a[1][0] 和 &(&a[1][0]) 的含义

   可以得到一个结论,对行指针进行一次 * 运算,它将变成列指针,进行两次 * 运算,它将变成一个数值 

   同理,对数组元素进行一次 & 运算,它得到一个列指针,进行两次 & 运算,将得到一个行指针

  现在再来看以下式子的含义: 

   a, *a, **a 

   a+1, &a[1] 

   a[1], *(a+1) 

   a[1]+2, *(a+1)+2, &a[1][2] 

   *(a[1]+2), *(*(a+1)+2), a[1][2] 

  大家思考以下,下列式子值是否相同,含义是否也相同 

   a, *a, a[0], &a[0][0] 

   a+1, *(a+1), a[1], *(a[1]) 

   *(a[I]+j), *(*(a+I)+j), a[i][j] 

总结: 1. 二维数组名,指向一维数组的指针,行指针 三者等价 

2. 一维数组名,指向具体元素的指针,列指针 三者等价 

3. 行指针加 * ,变成列指针,行指针加 ** ,变成元素 

4. 列指针加 * ,变成列元素,列指针加 & , 变成行指针 

也即行指针、列指针、元素通过 [* , &] 两个运算符号,可以相互转化 

… 

… 

… 

1000 

A[0][0] 

1002 

A[0][1] 

1004 

A[0][2] 

1006 

 

1008 

A[1][0] 

1010 

11 

A[1][1] 

1012 

13 

 

1014 

15 

 

1016 

17 

A[2][0] 

1018 

17 

A[2][1] 

1020 

21 

 

1022 

23 

 

… 

… 

… 

  2. 指向一维数组的指针 

   定义格式: 类型说明符 (*变量名)[常量表达式] 

  如: int (*p)[4];   定义了一个指针变量,它指向一有 4 个整型元素的数组

例 ] 输出二维数组任一行任一列元素的值 。 


main( ) 

int a[3][4]={ {1,3,5,7}, {9,11,13,15}, 

{17,19,21,23} }; 

int (*p)[4], i, j ; 

p=a; 

scanf(“%d , %d”, &i,&j); 

printf(“a[%d][%d]=%d\n”,i,j,*(*(p+i)+j)); 

  3. 用指向数组的指针作函数参数 

  一维数组名可以作为函数参数传递,多维数组名也可作为函数参数传递,多维数组作为函数参数传递时,可有多种形式,只要它们的意思正确即可。

例 ] 三个学生及其每个学生四门课程的成绩已放在二维数 组 A[3][4]={{66,57,70,86},{58,67,90,45}, 

{98,67,87,95}} 中,从键盘输入一个学生的学号,输出该学生四门课程成绩的均分。 


/* 下面三个子函数功能相同,但形式不同 */ 

void aver1(int a[3][4],int n); 

void aver2(int *p); 

void aver3(int (*p)[]); 

main() 

int a[3][4]={{66,57,70,86},{58,67, 90, 

45},{98,67,87,95}} , n; 

clrscr(); 

printf(“please input n:”, n); 

scanf(“%d”, p); 

aver1(a,n); 

/* 上面一句与下面两句中的任意一句等价 

aver2(&a[n-1][0]); 

aver3(&a[n-1]); 

*/ 

getch(); 

void aver1(int a[3][4], int n) 

int s=0, I; 

float aver; 

for (I=0; I<4; I++) 

s=s+a[n-1][I]; 

aver=s/4.0; 

printf(“aver=%d\n”, aver); 

void aver2(int *p) 

int s=0, I; 

float aver; 

for (I=0; I<4; I++) 

s=s+p[I]; 

aver=s/4.0; 

printf(“aver=%d\n”, aver); 

void aver3(int (*p)[]) 

int s=0, I; 

float aver; 

for (I=0; I<4; I++) 

s=s+(*p)[I]; 

aver=s/4.0; 

printf(“aver=%d\n”, aver); 

§ 10.3 字符串与指针 

一、字符串的两种处理方式

  1. 字符数组方式 

   字符串的定义、输入、输出、和引用

例 1] 读下面的程序说出结果。 


main() 

char str1[80]={“How are you!”}; 

char str2[80]; 

clrscr(); 

printf(“please a String: ”); 

scanf(“%s”, str2); 

printf(“%s\n”, str1); 

printf(“%s\n”, str2); 

getch(); 

  2. 字符指针方式 

例 2] 读下面的程序说出结果。


main() 

char *p = “How are you!”; 

clrscr(); 

printf(“%s\n”,p); 

getch(); 

例 3] 读下面的程序。 


main() 

char str[80]; 

char *p; 

clrscr(); 

p=str 

printf(“please a String: ”); 

scanf(“%s”, p); 

printf(“%s\n”, p); 

getch(); 

例 4] 读下面的程序,判断有无错误。


main() 

char *p1=“How are you!”; 

char *p2; 

clrscr(); 

printf(“please a String: ”); 

scanf(“%s”, p2); 

printf(“%s\n”, str1); 

printf(“%s\n”, str2); 

getch(); 

  3. 总结和说明 

  ( 1 ) 正确理解 printf(“%s”, str) 的含义 

  ( 2 ) 正确理解下面几个式子 

   char str[80]= “ How are you” 

   char *p = “ How are you” // 让 p 指向字符 'H' 

   p= “How do you do ”; //p 为字符串的首地址 

   str= “How do you do ”; // 错误 

   请记住,数组名是地址常量,与指针变量是不一样的。

  ( 3 ) 指针定义时,若无初始化,则他指向的存储单元未知。 

  ( 4 ) 函数中出现字符串的地方,都可以用字符指针代替。 

  4. 关于几个函数的说明 

   printf(char *str, ...) 

   scanf(char *str, ...) 

   strlen(char *str) 

   strcpy(char *str) 

   strcat(char *str) 

例 5] 读下面的程序说出结果。 


main() 

char *p1, *p2;; 

int a, b; 

clrscr(); 

p1=”%d,%d”; 

p2=“a=%d b=%d\n”; 

printf(“please a , b: ”); 

scanf(p1, p2); 

printf(p2, a, b); 

getch(); 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值