指针和二维数组

指针和二维数组

首先定义一个数组:

1 int a[5][3] = { {1,6,11},
2                 {2,7,12},
3                 { 3,8,13 },
4                 { 4,9,14 },
5                 { 5,10,15 }
6     };

随便定义的一个二维数组i = 5, j = 3

然后看下面3种方式:

1 int *b = a[0];
2 int *c = *a;
3 int &d = **a;

其实上面的三种方式的效果是一样的,大牛一看就知道,这不是废话么。我们还是输出下

 1 //value
 2 std::cout << *b << endl;
 3 std::cout << *c << endl;
 4 std::cout << d << endl;
 5 std::cout << *a[0] << endl;
 6 std::cout << a[0][0] << endl;
 7 //address
 8 std::cout << b << endl;
 9 std::cout << c << endl;
10 std::cout << &d << endl;
11 std::cout << &a[0] << endl;
12 std::cout << &a[0][0] << endl;

输出如下:

这里a[0],a,*a,&a[0][0]存放的地址如下图可以看出来

虽然值是一样的,但是类型不一样,同时所表示的含义也是不一样的

a[0] 存放的是第一行的首元素地址,*a 同样。

&a[0][0]存放的是着整个数组的首元素的地址。

a 则是存放着整个数组的首元素地址。

但是这里需要注意的是 a[5][3] 不等于 int **,而是等于(*)[3]。

其实很容易记混淆,我也是老忘记,记得以前面试的时候老会遇到这样的考数组和指针关系的。

<c++实践之路>中有一句话:不要在可以使用索引的地方使用指针。

那么也就是说了解这些关系一点用就没有么?不是,虽然数组名不等于指针,但是,理清这些关系,对把数组作为参数传递的时候,有很大帮助。(以后写关于数组当函数参数的随笔)

接下来,我们来看指针实现下标索引的方法:

先看这个,如果我们这样定义:int *b = a[0]; //定义一个指针b指向数组a第一行的首元素地址

那么,如果我们要找到a[0][2]的地址应该如何表示呢?那就是,b + 2,那么值就是*(b + 2);

那么,如果我们要找到a[1][0]的地址呢?那就是,b + 3 * 1 + 0,那么值就是*(b + 3 *1 + 0 ),为什么要这样写呢,等下解释

同样如果是a[2][3]?那就是,b + 3 * 2 + 3 ,这下看出规律了吧。 对于数组a[][n],如果定义 int *b = a[0],那么对于a[i][j] ,用b来表示 就是  b + n * i + j

因为数组的地址是连续的,比如a数组首元素的起始地址也就a[0][0]的地址是10CF9E4(十进制为 17627620),那么a[1][0]的地址   17627620 + sizeof(int)*3,也就是10CF9F0(十进制为 17627632)

对于int *c = *a; 同样可以得出。

如果要用a来表示a[2][3]的地址呢,由上面很容易就知道是*a + 2 * 3 + 3。

在面试的时候,自己被问道了很多基础的东西,我每每都是说自己记忆力不好,记不住来搪塞,可是,自己仔细想想,很多东西只是自己没有去了解。之前的遇到问题的思路都是: 遇到问题——百度谷歌——查找相关问题——找出适合自己的问题的解决方法——解决。

然而,这样对自己的提升真的不大,就长远发展来看,属于自己的东西真的很少。

也许该随笔还有很多错误的地方,谢谢包容提出。

共勉!

时间: 2024-08-23 13:10:55

指针和二维数组的相关文章

二级指针与二维数组

最近看<Linux C程序设计大全>这本书,虽然书中有一些错误,但整体来说,书写得还算可以. 当看到网络编程[第23.2.4小节 获得主机信息]时,遇到了一段代码,原文如下: “一台主机有许多和网络相关的信息,例如,主机名称.IP地址.主机提供的服务等.这些信息一般都保存在系统中的某个文件里(例如/etc/hosts等),用户程序可以通过系统提供的函数读取这些文件上的内容.Linux环境下使用gethostent函数读取和主机有关的信息,该函数的原型如下: 1 #include <net

指针与二维数组间的关系

1.四种表示a[i][j]的形式是等价的: a[i][j]==*(a[i]+j)==*(*(a+i)+j)==(*(a+i))[j] 2.通过行指针p引用二维数组a的元素a[i][j]的方法可用以下4种等价形式: p[i][j]==*(p[i]+j)==*(*(p+i)+j)==(*(p+i))[j] 3.对指向二维数组的行指针p进行初始化的方法: p=a 或p=&a[0] 4.对指向二维数组的列指针进行初始化的方法(以下三种方法等价): p=a[0] 或 p=*a 或 p=&a[0][0

例看二维数组,指针,二维数组指针

例程: /****************************************************** * * 文件名:例程 * * 文件描述:例看二维数组,指针,二维数组指针 * * 创建人:Jesse * * 版本号: * * 修改记录: * ******************************************************/ #include <stdio.h> #define ROW 3 #define LINE 3 void main(voi

数组指针与二维数组的寻址

引例:已知如下程序 1 #include <stdio.h> 2 main() 3 { 4 int x[3][4] = {1,3,5,7,9,11,2,4,6,8,10,12} ; 5 int (*p)[4] = x, k = 1, m, n = 0; 6 for(m=0; m < 2; m++) 7 n += *(*(p+m)+k); 8 printf("%d\n",n); 9 } 试写出程序的输出值.(虽然我很讨厌做这种笔头功夫的题,我也坚信编程语言是在实践中练出

c语言指针与二维数组

1 指针数组 例子: int i,j; int x[2][3]={{1,2,3},{4,5,6}}; int *p[2]={x[0],x[1]};//声明一个含有2个元素的一维int指针数组p for(i=0;i<2;i++) { for(j=0;j<3;j++) { cout<<*(p[i]+j)<<endl; } } 输出语句为cout<<p[i][j]<<endl;也是可以的. int i,j; int x[2][3]={{1,2,3},{

指针和二维数组的关系

指针引用多维数组 int a[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}};                    二维数组 a[0]  == 1 2 5 7 a[1]  == 9 11 13 15 a[2]  == 17 19 21 23 OK,二维数组在我们眼中,相当于三个一维数组组成:a代表着 二维数组的首地址. 而在二维数组中需要我们特别注意的是 a+1 指向其实是a[1]的地址. 我们在例子中设置的是 “INT” 类型的,在32位 vs中

指针与数组--指针与二维数组2

指向一维数组的指针   char (*p)[10] ;指向一维数组的指针类型 typedef  char(*TYPE_P2ARRAY)[10]  ;   该指针可以指向数组 ,且使用起来效果节本相同,但指针与数组并不等价.{sizeof结果不同  , 且该指针还可以指向除此之外其他类型的数据. } #include <stdio.h> typedef int (*TP_PARRY1)[3] ; #define Uart_Printf printf void f1(void) { int a[2

指针与二维数组

二维数组的本质: int matrix[3][4]; int matrix[3][4]; ==> int [4] matrix[3];     令type为int[4]; type int[3]; 说明matrix是一个数组,有3个元素:每一个元素是int [4]类型的: 实质上int[4]就是一个拥有4个int元素的一维数组. 事实上,二维数组名称的本质是:二维数组的首地址常量(指针常量): 指针加1移动的是该指针的指类长度. 例:double *p; p+1  就是移动8字节的长度. mat

C语言数组篇(五)多级指针和二维数组指针的区别

多级指针 以二级指针为例 二级指针的由来是 指针数组 的指针形式. int *p[10] 读取的顺序是 p[10] --> 10个空间的数组 * p[10] --> 这10个空间的数组里面存放的数据都是 指针型的数据 int *p[10] --> 数组里面每个指针指向的空间存放的是int型的数据 int *p[10] --> int **p; p: 指针数组的数组名,也是数组的首地址. *p 数组里面存放的指针 **p 数组里面存放的指针 指向的空间 的内容 二维数组指针: 二维数