二维数组和指针

二维数组和指针1、二维数组和数组元素的地址若有以下定义:int *p,

a[3][4];

1)二维数组a由若干个一维数组组成在C语言中定义的二维数组实际上是一个一维数组,这个一维数组的每一个成员又是一个一维数组。如以上定义的a数组,则可视a数组由a[0]、a[1]、a[2]等三个元素组成,而a[0]、a[1]、a[2]等每个元素又分别是由4个整型元素组成的一维数组。可用a[0][0]、a[0][1]等来引用a[0]中的每个元素,其它依次类推。在第二节中已解释过,C语言中,在函数体中或在函数外部定义的一维数组名是一个地址常量,其值为数组第一个元素的地址,此地址的基类型就是数组元素的类型。在以上二维数组中,a[0]、a[1]、a[2]都是一维数组名,同样也代表一个不可变的地址变量,其值依次为二维数组每行第一个元素的地址,其基类型就是数组元素的类型。因此,对于二维数组,象a[0]++这样的表达式是非法的。若有表达式a[0]+1,表达式中1的单位应当是2个字节。在以上定义中,指针变量p的基类型与a[i](0≤i<3)相同,因此,赋值语句p=a[i];是合法的。我们已知a[i]也可以写成:*(a+i),故以上赋值语句也可写成:p=*(a+i);。

2)二维数组名也是一个地址常量二维数组名同样也是一个存放地址常量的指针,其值为二维数组中第一个元素的地址。以上a数组,数组名a的值与a[0]的值相同,只是其基类型为具有4个整型元素的数组类型。即a+0的值与a[0]的值相同,a+1的值与a[1]的值相同,a+2的值与a[2]的值相同,它们分别表示a数组中第零、第一、第二行的首地址。二维数组名应理解为一个行指针。在表达式a+1中,数值1的单位应是4×2个字节,而不是2个字节。赋值语句p=a;是不合法的,因为p和a的基类型不同。同样,对于二维数组名a,也不可以进行a++,a=a+i等运算。

3)二维数组元素的地址二维数组元素的地址可以由表达式&a[i][j]求得;也可以通过每行的首地址来表示。以上二维数组a中,每个元素的地址可以通过每行的首地址:a[0]、a[1]、a[2]等来表示。如:地址&a[0][0]可以用a[0]+0来表示,地址&a[0][1]可以用a[0]+1表示;若0≤i<3、0≤j<4,则a[i][j]的地址可用以下五种表达式求得:(1)&a[i][j](2)a[i]+j(3)*(a+i)+j(4)&a[0][0]+4*i+j

(5)a[0]+ 4*i+j

在以上表达式中a[i]、&a[0][0]、a[0]的基类型都是int类型,系统将自动据此来确定表达式中常量1的单位是2个字节。但是不可以把求a[i][j]地址的表达式写成:a+4*i+j,因为a的基类型是4个整型元素的数组类型,系统将自动据此来确定常量1的单位是8个字节。

2、通过地址来引用二维数组元素若有以下定义:int

a[3][4],i,j;且当0≤i<3、0≤j<4,则a数组元素可用以下五种表达式来引用:(1)a[i][j](2)*(a[i]+j)(3)*(*(a+i)+j)(4)(*(a+i))[j](5)*(&a[0][0]+4*i+j)

在(2)中,表达式*(a[i]+j)中,因为a[i]的基类型为int,j的位移量为2×j字节。

在(3)中,表达式*(*(a+i)+j)中,a的基类型为4个元素的数组,i的位移量为4×2×i字节;而*(a+i)的基类型为int,j的位移量仍为2×j字节。

在(4)中,*(a+i)外的一对圆括号不可少,若写成:*(a+i)[j],因为运算符[]的优先级高于*号,表达式可转换成:*(*(a+i)+j)),即为:*(*(a+i+j)),这时i+j将使得位移量为4×2×(i+j)个字节,显示然这已不是元素a[i][j]的地址。*(*(a+i+j))等价于*(a[i+j])、等价于:a[i+j][0],引用的是数组元素a[i+j][0],而不是a[i][j],很可能早已超出数组定义的范围。

在(5)中,&a[0][0]+4*i+j代表了数组元素a[i][j]的地址,通过间址运算符*号,表达式*(&a[0][0]+4*i+j)代表了数组元素a[i][j]的存储单元。

3、通过建立一个指针数组来引用二维数组元素若有以下定义:int *p[3], a[3][2],

i,j

;在这里,说明符*p[3]中,也遵照运算符的优先级,一对[]的优先级高于*号,因此p首先与[]结合,构成p[3],说明了p是一个数组名,系统将为它开辟3个连续的存储单元;在它前面的*号则说明了数组p是指针类型,它的每个元素都是基类型为int的指针。若满足条件:0≤i<3,则p[i]和a[i]的基类型相同,p[i]=

a[i]是合法的赋值表达式。

若有以下循环:for(i=0; i<3; i++) p[i]=

a[i];在这里,赋值号右边的a[i]是常量,表示a数组每行的首地址,赋值号左边的p[i]是指针变量,循环执行的结果使p[0]、p[1]、p[2]分别指向a数组每行的开头。这时,数组p和数组a之间的关系如图9.6所示。

当p数组的每个元素已如图9.6所示指向a数组每行的开头时,则a数组元素a[i][j]的引用形式*(a[i]+

j)和*(p[i]+j)是完全等价的。由此可见,这时可以通过指针数组p来引用a数组元素,它们的等价形式如下:(1)*(p[i]+j)

(2)*(*(p+i)+j) (3)(*(p+i))[j] (4)p[i][j]

不同的是:p[i]中的值是可变的,而a[i]中的值是不可变的。

图9.64、通过建立一个行指针来引用二维数组元素若有以下定义:int a[3][2],

(*prt)[2];在这里,说明符(*prt)[2]中,由于一对圆括号的存在,所以*号首先与prt结合,说明prt是一个指针变量,然后再与说明符[2]结合,说明指针变量prt的基类型是一个包含有两个int元素的数组。在这里,prt的基类型与a的相同,因此prt=a;是合法的赋值语句。prt+1等价于a+1、等价于a[1]。当prt指向a数组的开头时,可以通过以下形式来引用a[i][j]:(1)

*(prt[i]+j) (2) *(*(prt+i)+j) (3)(*(prt+i))[j] (4) prt[i][j]

在这里,prt是个指针变量,它的值可变,而a是一个常量。

附:

#include "stdio.h"

void disp(int (*a)[3])

{

printf("%d",*(*(a+1)+1));

}

void main()

{

int

a[2][3];

a[0][0]=1;

a[0][1]=2;

a[0][2]=3;

a[1][0]=4;

a[1][1]=5;

a[1][2]=6;

disp(&a[0]);//也可以写作disp(a);

}

c语言二维指针类型转换,二维数组和指针(C语言)相关推荐

  1. 【学习笔记】C++语言程序设计(郑莉):数组、指针与字符串

    [学习笔记]C++语言程序设计(郑莉):数组.指针与字符串 1. 数组 1.1 数组的声明与使用 1.2 数组的存储与初始化 1.3 数组作为函数参数 1.4 对象数组 2. 指针 2.1 内存空间的 ...

  2. C++:C++语言入门级基础知识考察点回顾之数组、指针

    C++:C++语言入门级基础知识考察点回顾之数组.指针 目录 C++的数组.字符串 1.数组 1.1.声明数组 1.2.一维数组的应

  3. 什么是指针?什么是数组?指针和数组的关系?

    什么是指针?什么是数组?指针和数组的关系? 形象地讲,我们可以把计算机的内存看作一条长街上的一排房屋,每个房间都可以容纳数据并通过一个房号来表识.而表示每个房间房号的值我们可以称为地址.或许这样的比喻 ...

  4. 引用和指针的差别,数组和指针的差别

    一:引用和指针的差别 1:引用并不是对象,它仅仅是为一个已存在的对象所起的另外一个名字.必须初始化,并且无法改变它绑定的对象,之后每次使用这个引用都是訪问最初绑定的那个对象. 2:指针本身是对象,能够 ...

  5. C语言实现上三角蛇形矩阵不用数组,蛇形矩阵c语言实现

    [问题描述]蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形.如: 1 3 6 10 15 2 5 9 14 4 8 13 7 12 11 本题要求根据输入的行数要求,输出对应的一个蛇形上三角矩 ...

  6. C++,string类的指针,string类数组的指针 string *s

    可以这样: #include<iostream> #include<string> using namespace std;int main(void) {string s = ...

  7. c语言从文件中读取数据存入数组_在c语言中数组 a[i++] 和 a[++i]的 区别? 数组a[0]++又是什么意思?...

    在c语言中,数组 a[i++] 和数组 a[++i] 有区别吗? 首先我们先看下面的内容: b = a++; //先计算表达式的值,即先把a赋值给了b:然后a再自加1. b = ++a: //先a自加 ...

  8. c语言将水仙花数放入一维数组a中,C语言考试题库及答案(1)

    10.在考生文件夹下,要求程序PROG.C的功能是: 求[m,n]之间既不能被7整除也不能被5整除的整数之和,m和n的值由键盘输入. 例如,如果m和n的值分别为10和20,则计算结果为:106. #i ...

  9. 二维数组(解引用、指针数组、数组的指针)——C语言

    二维数组 在说二维数组前先来说下一维数组中的指针数组和和数组的指针 一.一维数组中指针数组和数组指针的区别 指针数组: 1 int *p[5]; []的优先级比*高,首先它是一个数组,它的大小是5,它 ...

  10. c语言字符二维数组传参,C语言函数传递二维数组

    C语言如果给函数传递二维数组作为参数 问题的产生 先看一个传递二维数组的例子: #include void foo(int a[][], int m, int n) { int i = 1; int ...

最新文章

  1. ISV页面中获取当前用户信息
  2. Nginx 安装配置教程
  3. spring-retry----线程内重试
  4. cf两边黑屏怎么解决win10_win10开机无限黑屏转圈重启解决方法
  5. sTC8G1K08+通过串口显示内部电压_基于51单片机的数字电流电压表
  6. Redis(案例五:Set数据)
  7. 年底了,按约定把2021 Go面试八股整理全了
  8. AppCan开发者资料分享(定期更新)
  9. Axure RP9 的元件库
  10. 【转】ubuntu12.04完美安装QQ2012、QQMusic、Foxmail等--wine
  11. VMware Workstation 不可恢复错误: (vcpu-0)解决方法
  12. 〖Python APP 自动化测试实战篇④〗- 通过 appium 驱动夜神模拟器完成第一个自动化脚本 - 查看通讯录
  13. linux中文显示为乱码
  14. php开源微博框架,记事狗微博开源代码学习笔记:微博话题列表
  15. linux系统与window区别,Linux和windows操作系统有哪些区别
  16. 临床执业助理医师(综合练习)题库【2】
  17. Dennard Scaling
  18. vCenter6.7 取消检查更新通知
  19. 中国十大金牌游戏策划
  20. 怎么在firefox 里面看维语,哈语等复杂字体的网页

热门文章

  1. shader之——shadowGun代码分析
  2. 后台权限管理系统设计(图文教程)
  3. 理光2014ad扫描服务器响应,理光mp2014ad扫描驱动和打印驱动
  4. SSH框架之文件上传
  5. java设置word审阅最终状态_如何使得打开word文件显示最终的修改状态
  6. 基于HTML+CSS+JavaScript仿华为手机电子商城
  7. 懒人精灵新版图色工具介绍
  8. TS:虚机ipv6网络不通问题-2022.5.16(已解决-博客分享)
  9. html5 中秋博饼游戏,微信通用功能模块 中秋博饼V4.1.5 开源版
  10. 汇编 DOS系统功能调用