二维数组与二级指针是好兄弟吗_第1页
二维数组与二级指针是好兄弟吗_第2页
二维数组与二级指针是好兄弟吗_第3页
二维数组与二级指针是好兄弟吗_第4页
二维数组与二级指针是好兄弟吗_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

抛出问题最近碰到一个问题点,这里跟大家分享一下。有一个二维数组,我想把它传给一个函数。于是我把函数接口定义出来了,如下:int

array[2][3]

=

{1,2,3,4,5,6};

void

fun(int

**array)

{

array[0][0]

=

5;

}当我试图直接把数组名传给函数时候,fun(array)编译会报错,大概意思就是类型不匹配。既然类型不匹配,那我就直接强转成你所需要的类型,于是我又做了调整,fun((int**)array),这下确实不报错了。但是此时我还没意识到问题的严重性。不出意外的情况下意外还是发生了,只要进入到这个函数后,程序就挂了。那你知道是什么原因吗?如果不清楚就往下看吧...指针先从指针说起,指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容:指针的类型、

指针所指向的类型

指针的值或者叫指针所指向的内存区、

指针本身所占据的内存区。指针的类型只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。例如:int*ptr;

//指针的类型是

int*

char*ptr;

//指针的类型是

char*

int**ptr;

//指针的类型是

int**

int(*ptr)[3];

//指针的类型是

int(*)[3]指针所指向的类型只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。例如:int*ptr;

//指针所指向的类型是

int

char*ptr;

//指针所指向的的类型是

char

int**ptr;

//指针所指向的的类型是

int*

int(*ptr)[3];

//指针所指向的的类型是

int()[3]指针的值在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。指针本身所占用的内存大小意思是指针本身占了多大的内存,在32位平台里,指针本身占据了4个字节的长度。可以使用sizeof(指针的类型)测试。一维数组对于一个一维数组intarray[10],数组名代表一个常量地址,该地址指向第一个元素。以下两种情况数组名不能当指针使用。&对数组名取址,int(*p_array)[10]=&array,&这个运算符也很有讲究的,暂时不多说了。sizeofsizeof(array)计算的是整个数组在内存中所占用的空间。二维数组二维数组本质上是以数组作为数组元素的数组,即“数组的数组”。假设我们定义了一个二维数组intarray[2][3]={1,2,3,4,5,6}。网上有很多地方都再说数组名array和array[0]、&array[0]以及&array[0][0]是等效的。那我们代码测试一下。printf("%#x,%#x,%#x,%#x\r\n",array,array[0],&array[0],&array[0][0]);

Terminal:

0x404008,0x404008,0x404008,0x404008因为这几种写法输出地址都是相同的,所以有的同学自然就认为这几种写法就是一样的。虽然地址相同,但是实际意义是有区别的,我们继续看下面的代码。//这里重新定义了指针变量,能够方便的知道右值得类型

int

*p_array1

=

array[0];

int

*p_array2

=

&array[0][0];

int

(*p_array3)[3]

=

&array[0];

int

(*p_array4)[3]

=

array;

printf("%#X,%#X,%#X,%#X,%#X\r\n",array,++p_array1,

++p_array2,

++p_array3,

++p_array4);

Terminal:

0X404008,0X40400C,0X40400C,0X404014,0X404014根据以上实验分析能够看出:array[0]与&array[0][0]指针类型相同,都是int*,地址存放的是int数据,当指针自增1时地址都偏移了一个int类型的大小。&array[0]与array指针类型相同,都是int(*)[3],首先它是一个数组指针,这个指针指向一个数组,数组中数据的类型为int型。当指针自增1时地址都偏移了一个数组的长度(即3个int数据的大小)。所以说array只和&array[0]真正意义等效。那怎么去理解这几种表达呢?表示含义array是一个数组指针,类型为int(*)[3]。指向二维数组中第一个元素(元素是一维数组),指针所指向的内存大小为一维数组的长度array[0]是一个指针,类型为int*。就相当于一个一维数组名,指向一维数组中第一个元素的地址,指针所指向的内存大小为一个数据长度&array[0]是一个数组指针,类型为int(*)[3]。相当于对一维数组取地址。指针所指向的内存大小为一维数组的长度&array[0][0]是一个指针,类型为int*,是对二维数组中第一个数据取地址,注意是数据不是元素,指针所指向的内存大小为一个数据长度如以上能够理解清楚,那么文中的问题应该就能够自己分析清楚了。二级指针先定义一个二级指针int**p,首先p是一个指针,在这个地址中存放的数据是指向一个整形数据的地址。问题解答接着看文章中的问题,把一个二维数组强转成二级指针传给了函数。注意二维数组名的类型是一个数组指针和二级指针完全不是一个东西。那么会出现什么问题呢?int

array[2][3]

=

{1,2,3,4,5,6};

int

main(int

argc

,char

**argv)

{

int

**p_data

=

(int

**)array;

printf("%#x,

%d\r\n",

p_data,

*p_data);

}

Terminal:

0x404008,

1地址数据0x40400810x40400C20x40401030x40401440x40401850x40401C6看上面的例子,array的地址为0x404008,当把一个二维数组强转成二级指针的时候。p_data地址中存放的数据为1,因为二维数据中第一个数据就是1。根据二级指针的定义,这个数据1又会当成一个地址,该地址指向的内存才是最终的数据。但是呢,这个地址1其实是个数据,并不是真正的地址。如果访问地址1中的数据,就属于非法访问地址了,可能会进入异常。二维数据当函数入参通过以上学习我们已经知道二维数组名就是一个数组指针,我们函数就可以像下面这样声明。void

fun(int

array[][3],

int

row);

void

fun(int

(*p_array)[3],

int

row);

void

fun(int

row,

int

column,

int

array[row][column]);实参与入参最后在看下,应该如何定义与实参相对应的形参的数据类型。含义实参形参二维数组

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论