《指针的编程艺术(第二版)》一3.2 指针与二维数组

3.2 指针与二维数组

指针的编程艺术(第二版)
一维数组与指针的关系前面已经介绍过。一维数组的元素值,可使用[]或一个*得到,假设有一个数组如下:

int i[7] = {0, 1, 2, 3, 4, 5, 6};
int *ptr=i;

(i+2) 或i[2] 或(ptr+2) 或ptr[2],都表示数组某一个元素的值。而二维数组(two dimension array){XE "二維陣列(two dimension)"},则需要两个,或一个与一个[ ],或两个[ ],才能得到数组的元素值。其余的表示法,只能得到数组元素的地址。

假设一个二维数组的定义如下,

int j[2][3] = {0, 1, 2, 3, 4, 5};

其中j是此数组的名称,表示这个数组第1行第1列元素的地址,而j+1是第2行第1列元素的地址,除此之外

j[0]和j[1]等同于j和j+1,表示第1行第1个元素和第2行第1个元素的地址。j和j[0] 虽然表示同一元素的地址,但两者对于加1个单位的意思不同。

j+1表示第2行第1个元素的地址,也即是j+1==&j[1][0]。而j[0]+1是第1行第2个元素的地址,也就是j[0]+1==&j[0][1],如下图所示。

关于二维数组的每个元素所在内存的概念已在第1章讨论过,请参阅范例address2Array-5和address2Array-10。

接下来,请问j和(j+1)是某个元素的地址,还是某个元素的值呢?答案是某个元素的地址。j与j都表示第1行第1列元素的地址(&j[0][0])。而j+1与(j+1) 都表示第2行第1列元素的地址(&j[1][0]),如下图所示。

虽然j与*j表示相同的意思,但两者都加1,表示的意义是不相同的。j+1表示第2行第1列的地址,而 j+1表示第1行第2列元素的地址(&j[0][1])。同理,(j+1)+1是第2行第1列的元素地址(&j[1][1])。请参阅范例pointerArr2-5。

范例pointerArr2-5

/ pointerArr2-5.c /
#include <stdio.h>
#include <conio.h>
int main()
{
  int j[3][2] = {10, 20, 30, 40, 50, 60};
  int k;
  for(k=0; k<3; k++)
    printf("j[%d] = %p\n", k, j[k]);
  printf("\n");
  for(k=0; k<3; k++)
    printf("j+%d = %p\n", k, j+k );
  printf("\n");
  for(k=0; k<3; k++)
    printf("(j+%d) = %p\n", k, (j+k));
  getch();
  return 0;
}

输出结果

从输出结果可知,每列之间相距8个字节,因为每列有两个int的元素。

综上所述,如果有一个二维数组k,如下所示:

int k[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};

数组的示意图如下图所示。

如何得到元素值6(位于第2行第3个元素)的地址呢?答案如下:

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

从&k[1][2]可以很清楚地看出,它表示k[1][2]元素的地址。*(k+1)和k[1]都表示第2行第1个元素的地址,所以再加2,都可得到第2行第3个元素的地址。

当我们得到元素的地址后,再加上一个*就可以得到该元素的值,所以

 

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

都可以得到数组第2行第3列的值。由以上的语句,可以推导出以下的公式。

k[x][y] == (k[x]+y) == (*(k+x)+y)

这一公式很容易理解,因为*和[]是互通的。请参阅范例pointerArr2-10。

范例pointerArr2-10

/ pointerArr2-10.c /
#include <stdio.h>
#include <conio.h>
int main()
{
  int k[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
  printf("&k[1][2] = %p\n", &k[1][2]);
  printf("k[1][2] = %d\n", k[1][2]);
  printf("(k + 1) + 2 = %p\n", (k + 1) + 2);
  printf("((k + 1) + 2) = %d\n", ((k + 1) + 2));
  printf("k[1] + 2 = %p\n", k[1] + 2);
  printf("(k[1] + 2) = %d\n", (k[1] + 2));
  getch();
  return 0;
}

输出结果

范例程序使用3种方法,得到k[1][2] 的地址与数值。要得到k[1][2] 的值6,可以使用(k[1]+2)及((k+1)+2)。如果要得到k[1][2] 的地址,则可使用&k[1][2]、k[1]+2及(k+1)+2,此处以%p输出数组第2行第3个元素的地址是0022FF58。如果使用%x取代%p,则会省略前面的0。两者都可以用于输出内存地址。

时间: 2024-10-30 01:52:02

《指针的编程艺术(第二版)》一3.2 指针与二维数组的相关文章

《指针的编程艺术(第二版)》一3.4 为什么parr等同于 *parr?

3.4 为什么parr等同于 *parr? 指针的编程艺术(第二版) 因为一个指针相当于一维数组,所以可将上述的数组指针 char *parr[4] = {"Department", "of", "Information", "Management"}; 改为以二维数组的方法表示,如下语句所示. char parr[4][12] = {"Department", "of", "

《指针的编程艺术(第二版)》一3.5 指向数组的指针

3.5 指向数组的指针 指针的编程艺术(第二版)ptr[4] 和 (ptr)[4] 所表示的意义是不同的.ptr[4]已在前面讨论过了,而(*ptr)[4]是指向数组的指针(pointer to array){XE "指向陣列的指標(pointer to array)"},表示ptr是一指针,指向一个有4个元素的数组,其实它也可视为是一个二维数组ptr[][4],因为和[]是互通的,我们以范例pointerToArray-1来说明. 范例pointerToArray-1 / point

《指针的编程艺术(第二版)》一3.10 程序实战

3.10 程序实战 指针的编程艺术(第二版) 1.试以命令行参数,在命令行提示符的模式下,模拟两个整数的算术运算(加.减.乘.除)的功能,如下所示: calculate + 表示a加b的意思.而: calculate - 表示a减b的意思,其中a与b变量为已知.依此类推.

《指针的编程艺术(第二版)》一第三章 指针与数组3.1 指针与一维数组

第三章 指针与数组 指针的编程艺术(第二版) 3-1 指针与一维数组 3-2 指针与二维数组 3-3 数组指针 3-4 为什么parr等同于 *parr? 3-5 指向数组的指针 3-6 多重指针 3-7 命令行参数 3-8 改错题 3-9 练习 3-10 程序实战 指针其实就是一个地址.数组的名称,表示这个数组的第1个元素的地址,所以它也是指针.由此可知,指针与数组的关系是很密切的.为了与指针变量(pointer variable){XE "指標變數(pointer variable)&quo

《指针的编程艺术(第二版)》一第一篇 C语言篇

第一篇 C语言篇 指针的编程艺术(第二版)C语言最早是在AT&T(American Telephone and Telegraph,美国电话与电报公司)内部使用的语言,但为了发布UNIX操作系统,不得不公开这一程序语言.主导这语言的两个灵魂人物,分别是Dennis Ritchie与Brian Kernighan.ANSI C已于1989年公布.Dennis Ritchie生于1941年,哈佛大学数学博士,是C语言之父.Brian Kernighan目前在普林斯顿大学计算器科学系(Departme

《指针的编程艺术(第二版)》一2.4 练习

2.4 练习 指针的编程艺术(第二版)1.请问下面程序的输出结果是什么?并说明其含义. /* exercise2-1.c */ #include <stdio.h> #include <conio.h> int main() { char *diamond="拉钻石"; char *p1 = diamond; char **p2 = &p1; char ***p3 = &p2; printf("diamond=%p\n", d

《指针的编程艺术(第二版)》一3.6 多重指针

3.6 多重指针 指针的编程艺术(第二版)多重指针(multiple pointer){XE "多重指標(multiple pointer)"},指的是在一个语句中有2个或以上的*.我们以范例starstarPointer-3来说明. 范例starstarPointer-3 /* starstarPointer-3.c */ #include <stdio.h> #include <conio.h> int main() { int i[5]={10, 20,

《指针的编程艺术(第二版)》一第一章 内存的基本概念1.1 变量

第一章 内存的基本概念 指针的编程艺术(第二版)1-1 变量 1-2 一维数组 1-3 二维数组 1-4 结构 1-5 练习 当程序定义一个变量时,编译程序根据其数据类型分配适当大小的内存给它,以便存储数据.这就如同地址一般,邮差根据收件人的地址,将信件投入正确的信箱. 1.1 变量 指针的编程艺术(第二版)程序以变量名称代表某一事项,就好比每一个人都有姓名一般.如果有人喊"蔡明志",那我一定会说"到",因为这个名字就代表我的意思.我们就从变量开始谈起.请参阅范例a

《指针的编程艺术(第二版)》一第二章 指针与变量2.1 一颗星星:表示一把钥匙

第二章 指针与变量 指针的编程艺术(第二版)2-1 一颗星星:表示一把钥匙 2-2 两颗星星:表示两把钥匙 2-3 三颗星星:表示三把钥匙 2-4 练习 如果要间接访问某一变量值,我们可使用指针来完成. 2.1 一颗星星:表示一把钥匙 指针的编程艺术(第二版)本章将介绍指针变量(pointer variable)与一般变量的关系.首先介绍的是,如何定义一个指针变量,如下所示. int x=100; int *ptr = &x; 上述语句表示下列3种含义. 1.ptr是一个指针变量. 2.ptr变