二级指针:可以理解为指向指针的指针,存放的是指针变量的地址。

下面用一级指针来保存一个指针变量的地址;

#include<stdio.h>

int main()
{
int *p1;
int *p2;
int data;
p1=&data;
p2=&p1;
printf("p1保存的地址=%p\n",&data);
printf("data=%d\n",*p1);
printf("p2的地址=%p\n",&p2); return 0;
}

输出结果:

p1保存的地址=000000000061FE0C
data=0
p2的地址=000000000061FE10

现在使用二级指针来实现同样的功能:

#include<stdio.h>

int main()
{
// int *p1;
// int *p2;
// int data;
// p1=&data;
// p2=&p1;
// printf("p1保存的地址=%p\n",&data);
// printf("data=%d\n",*p1);
// printf("p2的地址=%p\n",&p2); int data;
int *p1;
int **p2;
p1=&data;
p2=&p1;
printf("p1保存的地址=%p\n",&data);
printf("data=%d\n",*p1);
printf("p2的地址=%p\n",p2);
printf("data=%d\n",**p2); return 0;
}

输出结果:

p1保存的地址=000000000061FE14
data=0
p2的地址=000000000061FE08
data=0
二级指针和二级数组避坑

#include<stdio.h>
/*
野指针是指向位置随机的(乱指一气),错误的指针,系统无法对其进行操作。野指针指向的值是非法的内存地址,指向的内存是不可用的。
*/ int main()
{
//二级指针和二维数组避坑
int scores1[3][4]={
{10,20,30,40},
{50,60,70,80},
{90,100,110,120}
};
//定义一个二级指针
int **p1;
p1=scores1;
printf("p1:%p\n",p1);
printf("scores1:%p\n",scores1);
printf("*p1:%p\n",*p1);//*p1是一个野指针,不是我们认为的会变成列地址
**p1=2200;//修改scores[0][0]
printf("done\n"); return 0;
}

如果想让一个二级指针p指向一个二级数组,那么*p不是你认为的二维数组的列地址,而是一个野指针,是无法对二维数组进行操作的。如果想对二维数组修改。,可以通过使用

数组指针来指向二维数组的地址,再让二级指针指向数组指针的地址,而不能直接让二级指针指向一个二维数组。

#include<stdio.h>

int main()
{
int scores2[3][4]={
{10,20,30,40},
{50,60,70,80},
{90,100,110,120}
};
//定义一个二级指针
int **p2;
//定义一个数组指针
int (*p3)[4]=scores2;
//让二级指针指向数组指针地址
p2=&p3;
printf("p3:%p\n",p3);
printf("scores2:%p\n",scores2);
//修改scores
p2[0][0]=120;
printf("scores2[0][0]:%d\n",scores2[0][0]);
return 0;
}

输出结果:

p3:000000000061FDE0
scores2:000000000061FDE0
scores2[0][0]:120

虽然可以实现,但是不建议这样使用,而且编译器也在编译的时候也会抛出警告。

嵌入式-C语言基础:二级指针的更多相关文章

  1. 嵌入式-C语言基础:指针函数

    指针函数:返回指针的函数,即函数返回一个地址.例如:int * a(int x,int y);由于()的优先级比*高,因此a先与()结合,a(int x,int y)显然是一个函数,函数前面带一个in ...

  2. 嵌入式-C语言基础:指针数组(和数组指针区分开来)

    指针数组:一个数组,若其元素均为指针类型的数据,称为指针数组,指针数组存放的是指针类型的数据,也就是指针数组的每个元素都存放一个地址.下面定义一个指针数组: int * p[4];//[]的优先级是比 ...

  3. 嵌入式-C语言基础:指针偏移打印数组

    在C语言中,数组名代表数组中首元素的地址,所以,下面两句获取数组的首地址是等价的: #include<stdio.h> int main() { int a[5]={1,2,3,4,5}; ...

  4. 嵌入式-C语言基础:指针是存放变量的地址,那为什么要区分类型?

    指针是存放变量的地址,那为什么要区分类型?不能所有类型的变量都用一个类型吗?下面用一个例子来说明这个问题. #include<stdio.h> int main() { int a=0x1 ...

  5. 嵌入式-C语言基础:指针

    指针就是地址,变量的值可以通过两种方式访问,一个是通过变量名,一个是通过地址访问. 从而引出一个问题,即什么是指针变量?整型(字符)变量就是存放整形(字符)的变量,指针变量就是存放指针的变量,也就是存 ...

  6. GO学习-(10) Go语言基础之指针

    Go语言基础之指针 区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,是安全指针. 要搞明白Go语言中的指针需要先知道3个概念:指针地址.指针类型和指针取值. Go语言中的指针 任何程序数 ...

  7. C语言复习: 二级指针和多级指针

    二级指针内存模型建立 void main2() {     int i = 0;       //指针数组     char * p1[] = { "123", "456 ...

  8. 由链表初始化看C语言的二级指针

    先来看C语言创建链表.插入节点和遍历链表的一段代码: #include <stdio.h> #include <stdlib.h> typedef int ElemType; ...

  9. 论C语言中二级指针和二维数组之间的区别

    刚开始学习C语言的时候,觉得一个数组可以定义一个一级指针去访问,想当然的就觉得可以定义一个二级指针去访问二维数组.很显然这是错误的. 我们来看看C语言的数组在内存中的存储方式. 实际上C语言中的数组, ...

随机推荐

  1. 报错:①Tog goal specified requires a project to execute but there is no POM in this directory......②说类HelloWorld是公共的, 应在名为 HelloWorld.java 的文件中声明 public class HelloWorld......

    在运行Maven的命令时,在DOS窗口里面必须把目录切换到项目的根部,要不然命令是找不到目的地. 下图是错误示范,项目在Demo02这个目录里,就必须将目录切换到Demo02下,否则DOS窗口只有飘红 ...

  2. 第七十六篇:ref引用(在vue中引用Dom的方法)

    好家伙, 引子: jQuery简化了程序员操作DOM的过程 vue 优势:MVVM 在vue中,程序员不需要操作DOM.程序员只需要把数据维护好即可!(数据驱动视图) 那么若要在vue中操作dom,这 ...

  3. KingbaseES 如何开启并进入数据库

    关键字: KingbaseES.sys_ctl.ksql 一.数据库启动前环境检测 1.1 查看kingbase用户环境变量配置 图1-1 查看.bashrc环境变量配置 1.2 应用环境变量 [ki ...

  4. windows清理必看

    清理缓存 代码如下 介绍此文件夹都是缓存文件全选删除即可 ctrl+A全选shift+del强制删除(不会添加到回收站) %temp% 找到C盘右击属性选择想要删除的文件进行清理即可 清理完点击清理系 ...

  5. 玩转Configmap配置应用的各种姿势

    在 k8s 中使用配置主要可以有以下几种方式来实现: 1. 向容器传递命令行参数 2. 为每个容器指定自定义的环境变量 3. 通过特殊类型的卷将配置文件挂载到容器中 在 k8s 中覆盖命令行参数 和 ...

  6. JS作用域、变量提升和闭包

    作用域 作用域可以理解为JS引擎执行代码的时候,查找变量的规则. 从确定变量访问范围的阶段的角度,可以分为2类,词法作用域和动态作用域.js是词法作用域. 从变量查找的范围的角度,可以分为3类,全局作 ...

  7. SpringBoot 配置文件使用详解

    一.创建一个SpringBoot项目 创建 SprintBoot 项目的 2 种方式: 在 https://start.spring.io/ 上创建一个 SpringBoot 项目,然后导入到 IDE ...

  8. .NET 反向代理-YARP 根据域名转发

    前段时间发布过一个关于 YARP 的简单介绍,感兴趣的小伙伴恭请移步看看 .NET 反向代理-YARP - 一事冇诚 - 博客园 (cnblogs.com) 作为反向代理,必不可少的当然是根据域名代理 ...

  9. C# 使用原生 System.IO.Compression 实现 zip 的压缩与解压

    zip 是一个非常常见的压缩包格式,本文主要用于说明如何使用代码 文件或文件夹压缩为 zip压缩包及其解压操作, 我们采用的是 微软官方的实现,所以也不需要安装第三方的组件包. 使用的时候记得 usi ...

  10. JVM运行模式和逃逸分析

    JVM三种运行模式: 解释模式(Interpreted Mode):只使用解释器(-Xint强制JVM使用解释模式),执行一行JVM字节码就编译一行为机器码.(可以马上看到效果,但是运行过程比较慢) ...