C 二维数组,以及自定义二维数组

我们通常情况下是这样定义一个二维数组的:

int a[10][15];

我们分别查看一下 a,a[0],*a

都是一样的值吧

我们可以这么理解: a是一个数组的数组

a是数组首元素的地址,a的首元素是一个15个元素的数组,a[0]和a[0]的首元素(a[0][0])的地址是同一个地址

所以有人可能会想int **pa 是不是 跟a同一个类型的

我们可以尝试下面的代码:

int a[4][2]=0x1234;
int **ppa=a;
//尝试写入数据
**ppa=1;

我们发现段错误,说明出错了,而且ppa并不能代表a

我们把a,*a,**a,ppa,* ppa打印出来

a和ppa的值相同没问题,因为是指向同一个地址,*a仍然是a的首地址,*ppa直接解引用了

所以**ppa相当于向0x1234写入数据所以发生了段错误!

如果想理解好这个我们先看一下c语言多维数组的内存是什么样的:

实际上,在内存中,多维数组也是像一维数组一样是连续的,只不过我们把这个数组抽象了一下,

我们让这个数组的首地址赋值给一个int**指针,那么这个指针会认为是一个int*数组的地址

(就是一个数组里面保存的都是指针),所以这样解引用会发生错误

解决方法:

使用指向多维数组的指针:

int (*pa)[2];//注意和int *pa[2] 区别,后者是一个保存int*的数组

比如我们在函数传参的时候

这样会导致后面的2是固定的,编程的时候会受到一些限制

int func(int (*pa)[2],int l);

int (*p)[2]的理解:

int a[4][2];
int (*pa)[2]= a;
printf("%p\n",(char*)&pa[1]-(char*)pa);

自增一次多走了sizeof第二个维度的长度

如果是函数定义的话,也可以:

int func(int a[][2],int l)这样a第一个维度可以不是固定的,第二维度是固定的,也不是很方便,我们如果定义动态二维数组的话一般不适用多维数组,适用数组的数组

数组的数组(自定义二维数组):

就是用一个int**ppa来指向一个区域,这个区域内每一个元素都是一个指针,每一个指针都指向一个数组

const int col = 5;
const int row = 5;
int **t = (int **)malloc(col*sizeof(int*));
for(int i = 0;i<col;i++)
t[i]=(int*)malloc(row*sizeof(int));

当然,我们也可以把这些不连续的小空间放在一起申请

int **t = (int **)malloc(col*sizeof(int*));
int *p = (int*)malloc(col*row*sizeof(int));
for(int i = 0;i < col;i++)
t[i]=p+col*i;

C 二维数组,以及自定义二维数组的更多相关文章

  1. Android生成自定义二维码

    前面说过两种二维码扫描方式,现在说如何生成自定义酷炫二维码.二维码生成需要使用Google开源库Zxing,Zxing的项目地址:https://github.com/ZBar/ZBar,我们只需要里 ...

  2. PHP如何判断一个数组是一维数组或者是二维数组?用什么函数?

    如题:如何判断一个数组是一维数组或者是二维数组?用什么函数? 判断数量即可 <?php if (count($array) == count($array, 1)) { echo '是一维数组' ...

  3. C语言数组:C语言数组定义、二维数组、动态数组、字符串数组

    1.C语言数组的概念 在<更加优美的C语言输出>一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下: #include <stdio.h> #include &l ...

  4. [zt]C++二维数组讲解、二维数组的声明和初始化

    定义: int *pia = new int[10]; // array of 10 uninitialized ints 此 new 表达式分配了一个含有 10 个 int 型元素的数组,并返回指向 ...

  5. C++二维数组、指针、对象数组、对象指针

    项目中用到,随手记一下: 1.二维数组.与指针 创建二维数组指针的方式: a.已知一维的大小 1 int **array=new int *[rows]; 2 (for int i=0;i<ro ...

  6. 《剑指Offer》第1题(Java实现):在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

    一.题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该 ...

  7. 剑指Offer 1. 二维数组中的查找 (数组)

    题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...

  8. 06-01 Java 二维数组格式、二维数组内存图解、二维数组操作

    二维数组格式1 /* 二维数组:就是元素为一维数组的一个数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的 ...

  9. C/C++——二维数组与指针、指针数组、数组指针(行指针)、二级指针的用法

    本文转载自:https://blog.csdn.net/qq_33573235/article/details/79530792 1. 二维数组和指针 要用指针处理二维数组,首先要解决从存储的角度对二 ...

随机推荐

  1. PowerShell管理Azure

    PowerShell第一次连接Azure1.下载Azure SDK,安装azure powershell http://azure.microsoft.com/zh-cn/downloads/?rnd ...

  2. Angular2 备忘

    ng serve --port 80 --disable-host-check  启动80端口,禁用host检查 要在 component 内绑定全局事件的话,可以使用 @HostListener, ...

  3. 删除datatable的行后,出现“不能通过已删除的行访问该行的信息”的错误,即DeletedRowInaccessibleException

    删除datatable的行后,出现“不能通过已删除的行访问该行的信息”的错误 =========================================================== 采 ...

  4. The categories of Reinforcement Learning 强化学习分类

    RL分为三大类: (1)通过行为的价值来选取特定行为的方法,具体 包括使用表格学习的 q learning, sarsa, 使用神经网络学习的 deep q network: (2)直接输出行为的 p ...

  5. POJ-1845 Sumdiv---因子和(快速幂+快速加法+因子和公式)

    题目链接: https://cn.vjudge.net/problem/POJ-1845 题目大意: 求AB的因子和 解题思路: 先将A质因数分解,然后B次方的质因数指数就是乘上B即可 这里要mod9 ...

  6. ThreadLocal介绍

    作者:知乎用户链接:https://www.zhihu.com/question/23089780/answer/62097840来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  7. 让Git不再难学

    写在前面 在团队做过软件开发的,版本控制必是不可或缺的一项.目前,版本控制主要分为集中式版本控制系统和分布式版本控制系统 ,即大家熟知的SVN和Git.Git是当下最流行的分布式版本控制系统,故,今天 ...

  8. 让NSArray数组中每个对象都调用的方法

    1. [array valueForKey:@"title"]; //Returns an array containing the results of invoking val ...

  9. Mysql不同表的同名字段索引名可以相同

    mysql中不同表的相同字段索引是可以重名的,因为索引文件一表一个: 命名规则: 普通索引:idx_字段名 唯一索引:ux_字段名

  10. 从C语言的volatile关键字,了解C#的volatile机制(转载)

    C#中有一个关键字volatile,一直不太明白到底什么时候才用它,只知道在多线程操作同一个变量的时候要使用volatile关键字,下面看到了一篇C语言关于volatile关键字的介绍,写的很不错,其 ...