C语言中的二级指针和二维数组问题
关于二级指针和二维数组两者差别很大,不可以直接用二级指针传递二维数组
首先来看看二维数组在内存中是如何组织的呢?
一维数组 T arr1 = new T[9] 二维数组T arr2 = new T[3][3]
实际上,不管是一维还是多维数组,都是内存中一块线性连续空间,因此在内存级别上,其实都只是一维。但是不同的定义使得表现形式不一样,从而有多维数组的概念。访问数组元素其实非常简单,原因就在于元素在内存中的线性排列,这样对一维数组的访问只需要arr1[index] = *(arr1+index*sizeof(T));对二维数组的访问
arr2[i][j]=*(arr2+(i*col+j)*sizeof(T)),因此连续线性的数组访问效率很高。多维类似。
下面一个程序测试:
#include<cstdio>
/************************************************************************/
/* 数组和指针参数是如何被编译器修改的?
“数组名被改写成一个指针参数”规则并不是递归定义的。数组的数组会被改写成“数组的指针”,而不是“指针的指针”:
实参 所匹配的形参
数组的数组 char c[8][10]; char (*c)[10]; 数组指针
指针数组 char *c[10]; char **c; 指针的指针
数组指针(行指针) char (*c)[10]; char (*c)[10]; 不改变
指针的指针 char **c; char **c; 不改变 */
/************************************************************************/
/*二级指针**作为形参,可以接受二级指针**p、指针数组*p[]作为实参的参数,从而传递二维数组*/
void print(int **p, int row, int col)
{
int i=0,j=0;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
printf("%d\t",p[i][j]);
}
}
printf("\n");
}
/*数组指针(*)[]作为形参,可以接受数组指针(*p)[3]作为实参的参数,从而传递二维数组*/
void print(int (*p)[3], int row, int col)
{
int i=0,j=0;
for(i=0;i<row;i++)
{
for(j=0;j<3;j++)
{
printf("%d\t",p[i][j]);
}
}
printf("\n");
}
/*function 'void __cdecl print(int ** ,int,int)' already has a body Error executing cl.exe.
/*同二级指针*/
/*
void print(int *p[], int row, int col)
{
int i=0,j=0;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
printf("%d\t",p[i][j]);
}
}
printf("\n");
}
*/
/******以上两个函数无法重载overload,说明编译器把*p[]和**p 都当成一种类型******************************************/
int main()
{
int i = 0;
int **pointer_to_pointer;
//printf("%X\n",*pointer_to_pointer);//会错误,因为pointer_to_pointer 还未初始化,是野二级指针
int *pointer = new int[9];
int *pointer_array[3]; //指针数组,即是一个存放指针元素的数组,定义后即会有含有三个指针元素的数组,但是每个指针元素并没有初始化
printf("%X\t%X\t%X\n",pointer_array,pointer_array+1,pointer_array+2);
printf("%X\t%X\t%X\n",pointer_array[0],pointer_array[1],pointer_array[2]);
int bi_array[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
int (*array_pointer)[3] = bi_array;//数组指针,指向数组的指针,可用于函数传递二维数组
int single_array[3] = {1,2,3};
//pointer_to_pointer = bi_array; //!!! 错误,二级指针和二维数组首地址(实际内存空间不管是N维数组,都是一片连续的线性空间,二维数组元素访问a[i][j]是a+sizeof(type)*(C*i+j),因此a可以看成是一个指针而已)不是一个东西,二者不能相互赋值
//cannot convert from 'int [3][3]' to 'int ** '
//pointer_to_pointer = (int**)bi_array; // !!!慎用,因为虽然没有语法错误,但是会出现内存访问错误;
//pointer_array = bi_array;//错误cannot convert from 'int [3][3]' to 'int *[3]'
//pointer_to_pointer = bi_array+1;//错误cannot convert from 'int (*)[3]' to 'int ** '
/*******************以上说明二维数组和二维指针不是等价的,不能相互赋值*************************************************/
pointer_to_pointer = pointer_array;
/*******以上这句说明指针数组*[] 可以转换为二级指针** 他们相互等价*****************************************************/
//pointer = bi_array;//错误cannot convert from 'int [3][3]' to 'int *'
pointer = (int *)bi_array;
for(i=0;i<9;i++)
{
printf("%d\t",pointer[i]);
}
printf("\n");
//pointer = array_pointer;//错误cannot convert from 'int (*)[3]' to 'int *'
pointer = (int *)array_pointer;
for(i=0;i<9;i++)
{
printf("%d\t",pointer[i]);
}
printf("\n");
for(i=0;i<9;i++){pointer[i] = 9;} //此时指向bi_array的array_pointer的元素被pointer修改为9
array_pointer = (int(*)[3])pointer;
print(array_pointer,3,3);
/********以上说明二维数组名和数组指针虽然是一个指针,但编译器并不理解,对他来说是数组类型的指针,但可以类型强制转换*****/
for(i=0;i<3;i++)
{
pointer_array[i] = bi_array[i];
}
printf("\n");
print((int(*)[3])pointer,3,3);
print(pointer_to_pointer, 3 ,3);
print(pointer_array, 3, 3);
return 0;
}
对二维数组做如下总结:
1.二维数组和二维指针不是等价的,不能相互赋值
2.指针数组*[] 可以转换为二级指针** 他们相互等价
3.二维数组名和数组指针虽然是一个指针,但编译器并不理解,对他来说是数组类型的指针,但可以类型强制转换
pointer = (int *)array_pointer; array_pointer = (int(*)[3])pointer; pointer = (int *)bi_array;
4.如果想用函数传递二维数组,一般形参用二级指针**p或指针数组*[],可以支持二级指针和指针数组的实参传递,特殊的还可以用(*p)[N]
------------------------------分割线------------------------------
C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码 http://www.linuxidc.com/Linux/2014-05/101227.htm
读C++ Primer 之构造函数陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm
读C++ Primer 之智能指针 http://www.linuxidc.com/Linux/2011-08/40177.htm
读C++ Primer 之句柄类 http://www.linuxidc.com/Linux/2011-08/40175.htm
将C语言梳理一下,分布在以下10个章节中:
- Linux-C成长之路(一):Linux下C编程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
- Linux-C成长之路(二):基本数据类型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
- Linux-C成长之路(三):基本IO函数操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
- Linux-C成长之路(四):运算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
- Linux-C成长之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
- Linux-C成长之路(六):函数要义 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
- Linux-C成长之路(七):数组与指针 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
- Linux-C成长之路(八):存储类,动态内存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
- Linux-C成长之路(九):复合数据类型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
- Linux-C成长之路(十):其他高级议题
本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-03/115055.htm
C语言中的二级指针和二维数组问题相关推荐
- 二级(多级)指针,二级指针和二维数组的避坑,指针面试考题
1.二级指针的的认识 2.二级指针的实战 想获得二维数组的某个人的位置,采用的是return的方式 如果把第三行的int * 换成void ,把ppos换成传参的方式做. 结果崩溃了 原因是 是个野指 ...
- 指针:C语言二级指针与二维数组
前言 最近用C语言写LeetCode 有的题目给的函数把二维数组用二级指针传进来 并传入行数和列数 引起一些疑惑 本来以为C语言学得海星,查了一些资料后,觉得自己还是个弟弟 : ( 按一维数组 ...
- c语言二级指针与二维数组
一.二维数组的地址不能赋给二级指针的原因 int arr[][3] = { { 1,2,3 },{ 4,5,6 },{ 7,8,9 } }; int** p = arr; 二.指针遍历二维数组 int ...
- C语言学习之利用指针输出二维数组任一行任一列元素的值
利用指针输出二维数组任一行任一列元素的值. int main(){int a[3][4];int i,j,x,y;int (*p)[4];//指针变量p指向包含4个整型元素的一维数组printf(&q ...
- java把二维转换为一维_在R语言中什么函数可以将二维数组转换成一维数组
满意答案 vi31892i 2013.09.11 采纳率:44% 等级:11 已帮助:6956人 这好象是汇编语言的问题吧 举个例子吧 #include "iostream.h&quo ...
- c语言中怎么用scanf给二维数组赋值,关于VC++6.0无法用scanf()输入浮点值赋给二维数组的问题...
VC++6.0在编译时为了节省资源的占用,如果检测到你的整个代码里面没有需要用到浮点数据时,就不会加入浮点链接库,所以在遇到复杂的结构如 二维数组的输入中,就会出现错误: VC++6.0只能向一维数组 ...
- 指针数组,数组指针与二维数组剖析
int *p[3]与int (*p)[3]的区别 *p[3]这个是一个指针数组,它所代表的意思是数组中的每一个元素都是一个指针变量,而(*p)[3],p是一个指针变量,表示指向一个含有3个整型元素的一 ...
- C语言指针和二维数组
二维数组在概念上是二维的,有行和列,但在内存中所有的数组元素都是连续排列的,它们之间没有"缝隙".以下面的二维数组 a 为例: int a[3][4] = { {0, 1, 2, ...
- Algorithm:C++语言实现之概率算法相关问题(计算机中的概率事件、C语言中的随机事件、产生二维随机数、圆内均匀取点)
Algorithm:C++语言实现之概率算法相关问题(计算机中的概率事件.C语言中的随机事件.产生二维随机数.圆内均匀取点) 目录 一.概率 1.计算机中的概率事件 1.1.C语言中的随机事件 1.2 ...
最新文章
- Appium官网Introduction
- Oracle EBS:Package被锁,执行时卡住的解决办法
- Windows下Mex程序的调试
- 1052 Linked List Sorting (25 分)【难度: 一般 / 知识点: 链表】
- WebSocket客户端连接成功后,返回的socket里有用的字段
- 日常电脑小工具编程_如何使编程成为日常习惯
- HttpModule的认识
- python查找文件内容_python实现搜索文本文件内容脚本
- linux的文件存取权限,linux文件的存取权限
- matlab怎么创建数组对象,数组 – matlab初始化对象数组
- 减少计算机硬盘,电脑磁盘分区会降低性能?
- 小米手表如何优雅听歌?
- Win10 系统设置共享文件
- 公钥密码学中的三大难解数学问题
- Python基础语法 - 第3关 霍格沃茨来信 input()函数
- 分布式优化算法学习(一)
- 关于 字号、PX像素、PT点数、em、CM厘米、MM毫米之间的换算
- Android dex修复工具,安卓热修复----手动加载dex文件到设备并执行
- Unity3D通过代码修改RGB值来控制UI与物体的Color颜色
- 数据治理第1享:数据资产目录