C语言复习---二维数组和二级指针的关系:没关系,别瞎想(重点)
前提:一维数组和一维指针为什么可以替换使用?
int a[] = { , , };
int *p = a;
for (int i = ; i < ; i++)
printf("%d ", *(p + i));

上面测试表示可以相互替换使用

printf("%p %p, %p", a, &a[],p);

a是数组名,在数组中代表了数组首地址,类似于&a[]。
而int *p是一个int类型指针,也是指向每一个地址,所以两者的类型相同,都是代表int类型字节地址。
int *p = a;是正确的。
我们再使用*(p+),就是将指针P所指向的位置加上一个int类型字节(),正好到达了a[]的数据地址。所以这种使用方法是正确的。
一:二维数组的数组名代表了什么?
int a[][] = { { , , }, { , , }, { , , } };

这里数组名,还是整个数组的首地址,也可以看做第一行的首地址,还可以看做第一行第一列元素的首地址
printf("%p %p %p\n", a, &a[], &a[][]);

要是我们想要获取每一行的地址呢?
其实我们上面就使用了&a[]获取了第1行的首地址
printf("%p %p\n",&a[], &a[][]); //测试第二行的地址

注意:
数组名a是一个地址,无论是几维数组。都是数组的首地址
二:二级指针又代表了什么?
对于一级指针:
每次谈到指针,想到的就是一个带有门牌号的钥匙,我们根据门牌号,才能找到对应的房间,才可以进去拿东西。
对于二级指针理解可以相同:
我们考虑,家里有个书房。书房要是在客厅。
那么我们现在人在外面,要回去去一本小黄书呵...
我们先要根据我们手中的要是找到房间号,开门进去,获取到第二把钥匙,查看标签是书房的,我们就可以使用这把要是去开书房的门,获取书籍来学习
我们可以看做:最靠近目标空间的那把钥匙是一级指针,然后再远一点的那把钥匙就是二级指针,以此类推...就是多级指针了
就如同上面钥匙和门牌号一样,指针和地址也是密不可分的。指针变量中存放的就是地址
除了一级指针可以直接获取到数据,其他级别的指针都是指向上一级指针的存储地址。我们可以根据地址,一级一级直到获取到一级指针就可以获取到数据了,使用*就可以开门获取数据了。
*星号的理解
int* p; //这是声明了一个一级指针变量p,p是一个地址
*p; //*p就是去这个地址中获取数据 int **p //这个P,也是一个指针变量,而且是一个二级,内部存放的也是一个地址
*p //就是使用二级地址去获取了其中内容(内容是一级指针的地址)
*(*p) //*p先获取了一级指针的地址,*(*p)就是根据一级指针地址去获取数据
二:二级指针和二维数组的错误用法
int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
int **p=a;

或许你因为这只是一个警告而觉得无所谓。但是当你使用的时候,就会出现错误,崩溃
原因解析:
p是一个二级指针,p变量存放地址。a代表了数组的首地址。虽然间接级别不同,但是地址赋给地址,也没有啥错,所以只是警告
但是当我们试图使用二级指针时:
num = *(*(p+) + );
我们是想用*(p+)获取第一行的地址,然后使用*(*(p+)+)获取第一行第一列的地址
但是会报错

原因解析:

从上一个原因解析我们知道,是将a的地址赋给了二级指针p.
所以a=0x0028fce0 p=0x0028fce0
当我们使用*(p+0)==*p试图去获取一级指针地址时,结果发现地址0x0028fce0下存放的不是一个地址,而是1,
那么只能强制转换1为地址0x00000001,所以*p=0x00000001。当我们再去尝试访问这块地址时*(*(p+0)+0)==**p,这不是我们能访问的,所以报错
三:正确的使用指针和二维数组
(一)int(*p)[3] = a;
int a[][] = { { , , }, { , , }, { , , } };
int(*p)[] = a; //指针变量p指向包含3个整型元素的一维数组
int num;
printf("%p %p %p\n", p, p+, p+);
num = *(*(p + ) + ); //指向第二行第二个
printf("%d\n", num);

指针变量p指向包含3个整型元素的一维数组,所以p的步长是其内部数据字节长度,所以p+1就是7B4-7A8=C===12就是含有3个整型元素的一维数组长度
int(*p)[] = a;
p+==a[]
p+==a[]
(二)int *p=a;//根据指针寻址是按照步长
int *p=a;将a的地址赋给p
而p是一个int* 指针,所以他的步长就是int类型4字节一步长。
因为数组在内存中的数据存储时连续的,所以可以使用一级指针寻址获取所有的数据
int a[][] = { { , , }, { , , }, { , , } };
int *p = a;
for (int i = ; i < ;i++)
printf("%d ", *p++); //p就是一个地址,每次按照步长增加四

四:正确使用二级指针
int **arr = (int **)malloc(n*sizeof(int*));
for (int i = ; i < n; i++)
{
arr[i] = (int *)malloc(n*sizeof(int));
memset(arr[i], , n*sizeof(int));
} for (int i = ; i < n; i++)
{
for (int j = ; j < n; j++)
printf("%2d", arr[i][j]);
printf("\n");
}
C语言复习---二维数组和二级指针的关系:没关系,别瞎想(重点)的更多相关文章
- 二维数组是二级指针pointer to pointer!
二维数组居然是个类似于二级指针(pointer to pointer)的东西,十分震惊! #include <stdio.h> int main() { ][]={{,,,},{,,,}, ...
- 计算机二级-C语言-对二维数组数据进行处理。对文件进行数据输入。形参与实参。
//函数fun的功能为:计算x所指数组中N个数的平均值(规定所有数都为正数),平均值通过形参返回给主函数,将小于平均值且最接近平均值的数作为函数值返回,并输出. //重难点:形参与实参之间,是否进行了 ...
- C语言中将二维数组作为函数参数来传递
c语言中经常需要通过函数传递二维数组,有三种方法可以实现,如下: 方法一, 形参给出第二维的长度. 例如: #include <stdio.h> void func(int n, char ...
- C语言之二维数组
二维数组 还是一个数组,只不过数组中得每一个元素又是一个数组 1). 声明语法 类型 数组名[行][列]; 例: int nums[2][3];//2行3列的二维数组,保存的数据类型是int类型 c ...
- C语言 字符二维数组(多个字符串)探讨 求解
什么是二维字符数组? 二维字符数组中为什么定义字符串是一行一个? “hello world”在C语言中代表什么? 为什么只能在定义时才能写成char a[10]="jvssj" ...
- C语言传递二维数组
方法一, 形参给出第二维的长度. 例如: #include <stdio.h> ] ) { int i; ; i < n; i++) printf("/nstr[%d] = ...
- C语言回顾-二维数组
1.二维数组:是一个特殊的一维数组 完全初始化: 1)int a[2][3]={{1,2,3},{2,3,4}}; 2)连续赋值int a[2][3]={1,2,3,2,3,4}; 3)可以省略第一维 ...
- C语言教学--二维数组和指针的理解
对于初学者对二维数组和指针的理解很模糊, 或者感觉很难理解, 其实我们和生活联系起来, 这一切都会变得清晰透彻. 我们用理解一维数组的思想来理解二维数组, 对于一维数组,每个箱子里存放的是具体的苹果, ...
- C语言基础--二维数组
二维数组概念: 数组中的每一个元素又是一个数组, 那么这个数组就称之为二维数组,二维数组是特殊的一维数组. 二维数组格式: 元素类型 数组名称[一维数组的个数][每个一维数组的元素个数]; 元素类型 ...
随机推荐
- OLEDB 命令转换组件的用法
在数据流任务组件中,OLEDB 命令转换组件对输入的每行数据调用TSQL,该组件能够把输入的数据作为参数,因此,该转换组件主要用于运行参数化的查询. 命令转换组件的配置十分简单,只有三个可编辑属性,位 ...
- Revit二次开发-根据视图阶段(Phase)创建房间
最近开发业务中,有一个自动创建房间的功能,很自然的想到了Document.NewRooms2方法.但是当前功能的特殊之处在于,Revit项目视图是分阶段(Phase)的,不同阶段的房间是互相独立的. ...
- 开源一个最近写的spring与mongodb结合的demo(spring-mongodb-demo)
由于工作需要,给同事们分享了一下mongodb的使用,其中主要就是做了一个spring-data+mongodb的小例子,本着分享的精神,就上传到了github.com上,有需要的同学请移步githu ...
- FPGA千兆位收发器选择指南
选择合适的千兆位收发器(GT)是通信和实时处理领域尤其需要重点考虑的设计事项,但特定的市场领域可能会存在太多的标准.协议或使用模型.有时针对某一种应用就会涉及到好几种标准,为了选择最适合的千兆位收发器 ...
- alpha发布排序结果
友组所做排序 其中有一组是教师排序. 序号 组名 组长 项目简称 匿名1组 匿名2组 匿名3组 匿名4组 匿名5组 匿名6组 匿名7组 匿名8组 平均 1 新蜂 武志远 俄罗斯 2 3 3 4 4 5 ...
- LeetCode 167. 两数之和 II - 输入有序数组
题目: 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值index1 和 index2,其中 index1 必须小于 index2. 说明: 返回的 ...
- 团队作业(五)-笔记app top5
在互联网快速发展的情况下,各个行业的软件层出不穷,五花八门.各个行业都有相当多的软件介入其中,在如此多的软件之中,便有了相当激烈的竞争角逐.今天我们十五万的总冠军就着笔记APP行业中位列top 5的软 ...
- windows 服务实现定时任务调度(Quartz.Net)
我们通常在一些情况下需要软件具有一个自动执行某些任务的功能,但是又不希望直接启动软件,或者每次都要手动的来启动软件,这时我们可可以考虑到windows服务了. 首先创建一个windows服务项目(详细 ...
- PAT 甲级 1145 Hashing - Average Search Time
https://pintia.cn/problem-sets/994805342720868352/problems/994805343236767744 The task of this probl ...
- centos7 登陆报错 grep:write error
出现这个原因是因为磁盘空间满了 通过df -h查看存储空间 发现磁盘空间满了,可以用 find / -type f -size +1000M 查找大于1000M的文件删除 然后找到用rm -rf 命令 ...