C 二维数组,以及自定义二维数组
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 二维数组,以及自定义二维数组的更多相关文章
- Android生成自定义二维码
前面说过两种二维码扫描方式,现在说如何生成自定义酷炫二维码.二维码生成需要使用Google开源库Zxing,Zxing的项目地址:https://github.com/ZBar/ZBar,我们只需要里 ...
- PHP如何判断一个数组是一维数组或者是二维数组?用什么函数?
如题:如何判断一个数组是一维数组或者是二维数组?用什么函数? 判断数量即可 <?php if (count($array) == count($array, 1)) { echo '是一维数组' ...
- C语言数组:C语言数组定义、二维数组、动态数组、字符串数组
1.C语言数组的概念 在<更加优美的C语言输出>一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下: #include <stdio.h> #include &l ...
- [zt]C++二维数组讲解、二维数组的声明和初始化
定义: int *pia = new int[10]; // array of 10 uninitialized ints 此 new 表达式分配了一个含有 10 个 int 型元素的数组,并返回指向 ...
- C++二维数组、指针、对象数组、对象指针
项目中用到,随手记一下: 1.二维数组.与指针 创建二维数组指针的方式: a.已知一维的大小 1 int **array=new int *[rows]; 2 (for int i=0;i<ro ...
- 《剑指Offer》第1题(Java实现):在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
一.题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该 ...
- 剑指Offer 1. 二维数组中的查找 (数组)
题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...
- 06-01 Java 二维数组格式、二维数组内存图解、二维数组操作
二维数组格式1 /* 二维数组:就是元素为一维数组的一个数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的 ...
- C/C++——二维数组与指针、指针数组、数组指针(行指针)、二级指针的用法
本文转载自:https://blog.csdn.net/qq_33573235/article/details/79530792 1. 二维数组和指针 要用指针处理二维数组,首先要解决从存储的角度对二 ...
随机推荐
- Ngnix学习
- Tomcat启动阻塞变慢
Tomcat 熵池阻塞变慢详解 Tomcat 启动很慢,且日志上无任何错误,在日志中查看到如下信息: Log4j:[2015-10-29 15:47:11] INFO ReadProperty:172 ...
- shell逻辑运算符 1
逻辑卷标 表示意思 1. 关于档案与目录的侦测逻辑卷标! -f 常用!侦测『档案』是否存在 eg: if [ -f filename ] -d 常用!侦测『目录』是否存在 -b 侦测是否为一个『 bl ...
- 设计模式:备忘录(Memento)模式
设计模式:备忘录(Memento)模式 一.前言 备忘录模式用于保存和恢复对象的状态,相信大家看过我前面的拙作就会想到原型模式也能保存一个对象在某一个时刻的状态,那么两者有何不同的呢?原型模式保存 ...
- 【深入理解JAVA虚拟机】第二部分.内存自动管理机制.2.HotSpot虚拟机对象探秘
对象的创建过程 1.加载类 虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载. 解析和初始化过. 如果没有,那必须 ...
- MVVM的本质:视图逻辑处理、视图管理、视数中间层
MVVM的核心是将原来Controller中的视图逻辑.视图管理.视数中间层的功能剥离出来,形成单独的模块: 大部分功能与视图相关.少部分与数据相关: 视图逻辑和业务逻辑不通: 解决的问题:UIVie ...
- 五·管理mysql
在上一篇文章中 四·安装mysql-5.7.16-linux-glibc2.5-x86_64.tar.gz(基于Centos7源码安装) 已经安装好了mysql,也正常启动了.本篇文章主要内容是管理m ...
- ADF系列-2.EO的高级属性
在上一篇博客 ADF系列-1.EO的各个属性初探 中介绍了EO的一些常用简单属性.本次将介绍EO中一些比较常用的一些高级属性 一.基于Sequence创建EO,一下介绍三种方式(以HR用户的Emplo ...
- node express 跨域问题
express = require('express'); var app = express(); //设置跨域访问 app.all('*', function(req, res, next) { ...
- springboot启动报错:Could not resolve placeholder
SpringBoot1.5,项目启动报错: Could not resolve placeholder 很明显是找不到配置文件引起的,查看配置文件目录结构如下: 很正常呀. 完全可以加载applica ...