直观理解C语言中指向一位数组与二维数组的指针_C 语言

一维数组和指针:
对于一位数组和指针是很好理解的:
一维数组名:
对于这样的一维数组:int a[5];  a作为数组名就是我们数组的首地址, a是一个地址常量 .
首先说说常量和变量的关系, 对于变量来说, 用箱子去比喻再好不过了, 声明一个变量就声明一个箱子,比如我们开辟出一个苹果类型的箱子, 给这个变量赋值就是把盛放苹果的箱子中放入一个实实在在的苹果, 这就是变量的赋值. 
而对于数组来说, 就是一组类型相同的箱子中,一组苹果箱子, 可以放入不同的苹果.
一维数组空间:
变量被声明后, 我们操作编译器, 对我们的C源文件进行编译, C在编译的时候 就会给我们的变量开辟相应的空间, 而对于数组而言, 开辟的空间是连续的.   我们把每个空间叫做存储单元, 每个空间都是有自己的编号, 就像我们现实生活中每户人家都有自己的一个门牌号一样, 系统数组空间地址是相连的, 并且我们的数组名就是一维数组首地址, 是一个地址常量.
指针:
既然数组的是占用连续的存储单元, 并且数组的首地址就是数组名, 我们可以通过指针变量来取出相应的地址.
指针变量, 就是这个箱子是专门存放其他箱子地址的. 我们可以把数组首地址给我们的指针变量. int a[7],*p; p=a;

二维数组和指针的理解:

对于初学者对二维数组和指针的理解很模糊, 或者感觉很难理解, 其实我们和生活联系起来, 这一切都会变得清晰透彻.
我们用理解一维数组的思想来理解二维数组, 对于一维数组,每个箱子里存放的是具体的苹果, 二维数组,就是把一维数组中的内容中又存放了一系列的箱子, 这样就构成了二维数组.
这就像一辆火车, 火车有很多节火车厢, 每个火车厢里面有一趟座位, 那我们火车厢的编号和每个火车座位的编号就不同了.  例如int  a[3][4] ; 3节火车厢, 每个火车厢中有四个挨着的座位.  实际的座位的编号和我们的火车厢的编号这是我们要区分开的,  我们的火车厢编号就是a[0],a[1],a[2](从座位的角度上来看)
从外面看, 我们每节火车厢的地址, a+0,a+1,a+2, a就相当于一个行地址, 火车厢为单位的地址, a+1是跳到下一个车厢的首地址,  而a[0]就相当于是座位的首地址, a[0]+0就会跳到第0节车厢的第0个座位, a[0]+1就会跳到第0节车厢的第1一个座位.

指针数组指向二维地址(座位的地址,实际地址):
建立一个指针数组来引用二维数组中的元素:int *p[3], a[3][2],i,j; 从各种可以看到p是一个数组名, 在定义时系统给他开辟3个连续的存储单元; 在这个前面加上*号表示, 数组的基本类型为int的指针类型. 我们可以通过for循环让这个数组里面的指针指向每排"座位"的首地址:

这个数组可以理解为是"座位"地址类型数组.
而下面我们定义的这个数组: int a[3][2], (*prt)[2] 为行指针数组(火车车厢数组). 这样我们可以把每节"车厢的地址"放入到我们的行指针数组变量中了.
这样我们可以把a这个行地址常量赋值给行地址变量 p=a. p+1等价于a+1,等价于a[1] 当p指向数组的首地址时, 可以通过以下形式来引用p[i][j]:
(1) *(p[i]+j)
(2)*(*(p+i) +j ))
(3)(*(p+i))[j]
(4)p[i][j]
p是一个行指针变量, 而二维数组名a是一个行地址变量.
以上就是对二维数组和指针的理解.
        

时间: 2024-09-23 01:53:19

直观理解C语言中指向一位数组与二维数组的指针_C 语言的相关文章

详解C++中的一维数组和二维数组_C 语言

C++一维数组 定义一维数组 定义一维数组的一般格式为:     类型标识符  数组名[常量表达式]; 例如: int a[10]; 它表示数组名为a,此数组为整型,有10个元素. 关于一维数组的几点说明: 1) 数组名定名规则和变量名相同,遵循标识符定名规则. 2) 用方括号括起来的常量表达式表示下标值,如下面的写法是合法的: int a[10]; int a[2*5]; int a[n*2]; //假设前面已定义了n为常变量 3) 常量表达式的值表示元素的个数,即数组长度.例如,在"int

在java中一维数组和二维数组有什么区别吗?

问题描述 在java中一维数组和二维数组有什么区别吗? 求大神指点java中一维数组和二维数组的区别,为什么一位数组是一行 二维数组可以定义多行 解决方案 如图黑色的是一维数组红色的是二维数组一维数组用来存数据二维数组用来存一维数组 解决方案二: JAVA中一维数组和二维数组的定义一维数组及二维数组的用法java中arraylist和一维数组二维数组的转换 解决方案三: 一楼正解,一维和二维的区别就是线和面的区别,一维的数组你就可以通过一个下标来准确定位,而二维的就需要有两个就像坐标系一样,一维

link中如何颠倒一个二维数组?二维数组不支持revses吧?

问题描述 link中如何颠倒一个二维数组?二维数组不支持revses吧? link中如何颠倒一个二维数组?二维数组不支持revses吧? 解决方案 可以用select Enumerable.Range(0 arr.GetLength(1)).Select(x => Enumerable.Range(0 arr.GetLength(1)).Select(y => arr[x y]).Reverse().ToArray()).Reverse().ToArray(); 解决方案二: 长方形的矩阵有上

c语言-C语言使用随机分布函数rand()%100;但是二维数组a[0][0]的值大于100,其他正常

问题描述 C语言使用随机分布函数rand()%100;但是二维数组a[0][0]的值大于100,其他正常 #include #include #define M 5 #define N 4 void china(int a[][N],int b[M]);/*给二维数组随机分配数值,并求二维数组每行数值之和*/ void orange(int a[][N],int b[M]);/*将付好值得数组和求和打印出来*/ void main() {int a[M][N],b[N]; china(a,b);

Java中增强for循环在一维数组和二维数组中的使用方法_java

一维数组: int[] a={1,2,3}; for(int i:a) { System.out.print(i+" "); } 输出:1 2 3 二维数组: import java.util.Scanner; public class tet { public static void main(String[] args) { //int[][] b={{1,2,3},{4,5,6}};行 int[][] a=new int[5][];//必须明确行数 for(int i=0;i&l

C语言中初始、增加和删除进程信号的操作方法简介_C 语言

C语言sigemptyset()函数:初始化信号集头文件: #include <signal.h> 定义函数: int sigemptyset(sigset_t *set); 函数说明:sigemptyset()用来将参数set 信号集初始化并清空. 返回值:执行成功则返回0, 如果有错误则返回-1. 错误代码:EFAULT 参数set 指针地址无法存取. C语言sigaddset()函数:增加一个信号至信号集头文件: #include <signal.h> 定义函数: int s

如何将表中记录构建成需要的二维数组方式!

问题描述 后台表存储格式--第一行是表栏位名称:emloyeescoresubject00197Chinese001100Mathematics00189Other00287Chinese00296Mathematics00278Other一实现:如何在C#中用Gridviw绑定出以下格式ChineseMathematicsOther0019710089002879678二实现求每位的平均分(用二维数组求)~~~~以上,在线等.虚心学习中!!! 解决方案 解决方案二:你搜索一下SQL行列转换就解

《C语言及程序设计》实践参考——折腾二维数组

返回:贺老师课程教学链接  [项目1-折腾二维数组]创建一个5行4列的二维整型数组,通过初始化,为数组中的前两列的10个元素赋初值,然后: 通过键盘输入,使后两列的10个元素获得值: 按行序优先输出数组元素: 将所有元素值乘以3后保存在数组中: 按列序优先输出(输出的第一行是数组中的第一列--,其实输出的就是"转置"): 将数组"倒"着输出(即最后一行最后一列的最先输出,第0行第0列的最后输出): 输出数组中的所有偶数: 输出所有行列下标之和为3的倍数的元素值. #

C语言中函数的声明、定义及使用的入门教程_C 语言

对函数的"定义"和"声明"不是一回事.函数的定义是指对函数功能的确立,包括指定函数名,函数值类型.形参及其类型以及函数体等,它是一个完整的.独立的函数单位.而函数的声明的作用则是把函数的名字,函数类型以及形参的类型.个数和顺序通知编译系统,以便在调用该函数时进行对照检查(例如,函数名是否正确,实参与形参的类型和个数是否一致),它不包括函数体.--谭浩强 ,<C程序设计>(第四版),清华大学出版社,2010年6月,p182 这段论述包含了许多概念性错误,这