C 二维数组与指针
http://c.biancheng.net/view/2022.html
1. 区分指针数组和数组指针
指针数组:存放指针的数组,如 int *pstr[5] = NULL; 数组中每个元素存放的是一个 int * 类型的指针
数组指针: 存放的是数组(数组名即为指针)如 int a[3][4] = {{0}}; int (*p) [4] =a; 括号中的*
表明 p 是一个指针,它指向一个数组,数组的类型为int [4]
,这正是 a 所包含的每个一维数组的类型。
C语言允许把一个二维数组分解成多个一维数组来处理。对于数组 a,它可以分解成三个一维数组,即 a[0]、a[1]、a[2]。每一个一维数组又包含了 4 个元素,例如 a[0] 包含 a[0][0]、a[0][1]、a[0][2]、a[0][3]。
对指针进行加法(减法)运算时,它前进(后退)的步长与它指向的数据类型有关,p 指向的数据类型是int [4]
,那么p+1
就前进 4×4 = 16 个字节,p-1
就后退 16 个字节,这正好是数组 a 所包含的每个一维数组的长度。也就是说,p+1
会使得指针指向二维数组的下一行,p-1
会使得指针指向数组的上一行
下面我们就来探索一下如何使用指针 p 来访问二维数组中的每个元素。按照上面的定义:
1) p
指向数组 a 的开头,也即第 0 行;p+1
前进一行,指向第 1 行。
2) *(p+1)
表示取地址上的数据,也就是整个第 1 行数据。注意是一行数据,是多个数据,不是第 1 行中的第 0 个元素,下面的运行结果有力地证明了这一点:
- #include <stdio.h>
- int main()
- {
- int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
- int (*p)[4] = a;
- printf("%d\n", sizeof(*(p+1)));
- return 0;
- }
- 运行结果:16
3) *(p+1)+1
表示第 1 行第 1 个元素的地址。如何理解呢?
*(p+1)
单独使用时表示的是第 1 行数据,放在表达式中会被转换为第 1 行数据的首地址,也就是第 1 行第 0 个元素的地址,因为使用整行数据没有实际的含义,编译器遇到这种情况都会转换为指向该行第 0 个元素的指针;就像一维数组的名字,在定义时或者和 sizeof、& 一起使用时才表示整个数组,出现在表达式中就会被转换为指向数组第 0 个元素的指针。
4) *(*(p+1)+1)
表示第 1 行第 1 个元素的值。很明显,增加一个 * 表示取地址上的数据。
根据上面的结论,可以很容易推出以下的等价关系:
a+i == p+i
a[i] == p[i] == *(a+i) == *(p+i)
a[i][j] == p[i][j] == *(a[i]+j) == *(p[i]+j) == *(*(a+i)+j) == *(*(p+i)+j)
【实例】使用指针遍历二维数组。
- #include <stdio.h>
- int main()
- {
- int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
- int(*p)[4];
- int i,j;
- p=a;
- for(i=0; i<3; i++){
- for(j=0; j<4; j++) printf("%2d ",*(*(p+i)+j));
- printf("\n");
- }
- return 0;
- }
运行结果:
- 0 1 2 3
- 4 5 6 7
- 8 9 10 11
指针数组和二维数组指针的区别
指针数组和二维数组指针在定义时非常相似,只是括号的位置不同:
- int *(p1[5]); //指针数组,可以去掉括号直接写作 int *p1[5];
- int (*p2)[5]; //二维数组指针,不能去掉括号
指针数组和二维数组指针有着本质上的区别:指针数组是一个数组,只是每个元素保存的都是指针,以上面的 p1 为例,在32位环境下它占用 4×5 = 20 个字节的内存。二维数组指针是一个指针,它指向一个二维数组,以上面的 p2 为例,它占用 4 个字节的内存
C 二维数组与指针的更多相关文章
- C语言教学--二维数组和指针的理解
对于初学者对二维数组和指针的理解很模糊, 或者感觉很难理解, 其实我们和生活联系起来, 这一切都会变得清晰透彻. 我们用理解一维数组的思想来理解二维数组, 对于一维数组,每个箱子里存放的是具体的苹果, ...
- 关于c语言二维数组与指针的个人理解及处理办法。
相信大家在学习C语言时,对一维数组和指针的理解应该是自信的,但是,我在学习过程中,看到网上一些博文,发现即便是参加工作的一些专业编程人员,突然碰到二维数组和指针的问题时,也可能会遇到难以处理的诡异问题 ...
- C指针 指针和数组 二维数组的指针 指针应用
直接到变量名标识的存储单元中读取变量的值--直接寻址 通过其他变量间接找到变量的地址读取变量的值--间接寻址 指针变量存放地址 显示变量的地址 指针变量使用前必须初始化,若不知指向哪,可先指向NULL ...
- C++笔记-数组指针/二维数组转换指针
参考资料: 1. 作者 BensonLaur :https://www.cnblogs.com/BensonLaur/p/6367077.html 2. https://blog.csdn.net/ ...
- C语言 二维数组(指针)动态分配和释放(转)
C 二维数组(指针)动态分配和释放 先明确下概念: 所谓32位处理器就是一次只能处理32位,也就是4个字节的数据,而64位处理器一次就能处理64位,即8个字节的数据.如果我们将总长128位的指令分别按 ...
- c语言编程-----指向二维数组的指针
c中如何返回一个指向二维数组的指针 #include <stdio.h> #include <stdlib.h> #define COUNT 3 typedef int (*M ...
- 二维数组和指针(C语言)
二维数组和指针 二维数组和指针1.二维数组和数组元素的地址若有以下定义:int *p, a[3][4]; 1)二维数组a由若干个一维数组组成在C语言中定义的二维数组实际上是一个一维数组,这个一维数组的 ...
- C/C++——二维数组与指针、指针数组、数组指针(行指针)、二级指针的用法
本文转载自:https://blog.csdn.net/qq_33573235/article/details/79530792 1. 二维数组和指针 要用指针处理二维数组,首先要解决从存储的角度对二 ...
- 对二维数组使用指针进行操作的探索(C语言)
/* Name: 对二维数组使用指针进行操作的探索 Copyright: Author: lingr7 Date: 01/12/18 11:55 Description: */ #include< ...
- 程序员之--C语言细节13(二维数组和指针,&*a[i][0]的理解,数组1[e]和e[1]非常可能你没见过)
主要内容:二维数组和指针.&*a[i][0]的理解.数组1[e]和e[1] #include <stdio.h> #define NUM_ROWS 10 #define NUM_C ...
随机推荐
- FreeBSD_11-系统管理——{Part_1-xfce 桌面}
一.首先安装 Xorg 安装 xorg pkg install xorg 清除旧文件(如果已前安装过 xorg) /etc/X11/xorg.conf /usr/local/etc/X11/xorg. ...
- 面向对象(五)——isinstance与issubclass、反射、内置方法
isinstance与issubclass.反射.内置方法 一.isinstance与issubclass方法 1.isinstance是用来判断对象是否是某个类 isinstance(obj,cla ...
- ajax 回传参数
JSONObject json = new JSONObject(); json.put("msg", msg); json.put("success", co ...
- Ubuntu12.04下删除文件夹内所有的.svn文件
前段时间在公司里遇到一个问题,从svn上下载下来的文件含有.svn文件,如何删除当前目录下的所有.svn文件呢? 一个个手动删除显然不可能,太多了.其实在Ubuntu12.04下延伸至其他所搜的Lin ...
- 牛客OI月赛12-提高组题解
牛客OI月赛12-提高组 当天晚上被\(loli\)要求去打了某高端oj部分原创的模拟赛,第二天看了牛客的题觉得非常清真,于是就去写了 不难发现现场写出\(260\text{pts}\)并不需要动脑子 ...
- to meet you Java多线程与并发
2: hotspot中对象在内存的布局是分3部分 对象头 实例数据 对其填充 这里主要讲对象头:一般而言synchronized使用的锁对象是存储在对象头里的,对象头是由Mark Word和Class ...
- [转] js对键盘输入事件绑定到特定按钮。
<script type="text/javascript" language="javascript"> document.onkeyup = f ...
- 2018-6-17-win10-UWP-全屏
title author date CreateTime categories win10 UWP 全屏 lindexi 2018-06-17 17:51:19 +0800 2018-2-13 17: ...
- 解决 Onenote 默认全角输入的一种解决办法(输入法已经设置为默认半角)
环境说明:Windows 7 x64 Ultimate SP1, QQ 拼音输入法 6.1(5306),Onenote 2016 x64 问题描述:每次打开Onenote,在输入法已经设置为默认半角的 ...
- Spring Boot 自定义注解,AOP 切面统一打印出入参请求日志
其实,小哈在之前就出过一篇关于如何使用 AOP 切面统一打印请求日志的文章,那为什么还要再出一篇呢?没东西写了? 哈哈,当然不是!原因是当时的实现方案还是存在缺陷的,原因如下: 不够灵活,由于是以所有 ...