数组与指针之二——二级指针之一

定义是这样:

多级指针(二级指针),C语言多级指针的用法详解 (biancheng.net)

这是针对变量,且是一级一级的取的。但是我们经常要面对数组,用到二级指针。如前面第一篇所述,对一维数组名取地址,则表示数组地址,再对其求值,则表示首元素的地址,所以按说对一维数组名取地址就是二级指针,可以定义一个二级指针,然后将一维数组名取地址赋值给它。

但是,实际写程序发现会报错:

编辑器就报错了。编译:

可见,虽然&a是指向指针的指针,但如第一篇所述,它确是指向4个元素数组的指针,也就是指向一个行数组的首个元素,是有限制的,类型是int (*)[4],并不表示是指向一个int变量的地址,即int **。

那么,按说,因为数组第一个元素是int型,我对数组第一个元素取地址后再取地址,应该是二级指针int**了吧?尝试:

pp = &(&a[0]);

编译报错:

这里用了两个&号,表示取两次地址,含义 上是没错的,这报错,是C语法的问题,是将前面一个&当成与操作,所以需要左值是变量或者函数调用形式,而右边只有括号里的&是真取了地址,所以报C2440,无法从int*转换为int**。

那么,这种赋值是不行的么?难道说二级指针不能指向数组的么?非也!这里就有个神奇的讲究了。其实就是和参考文章中一样,也就是一般二级指针赋值一样,分两次赋值就可以啦!

int a[4] = {1,3,5,4};
int** pp;  // 二级指针 
int* p;
p = &a[0];
pp = &p;

这种其实是多此一举了,还不如直接用p,因为其实pp表示存第一个元素的地址的地址,pp+1这种操作已经和原数组没什么关系了。程序:

#include <stdio.h>int main()
{int a[4] = {1,3,5,4};int* p;int** pp;printf("a=%d\n", a);printf("&a=%d\n", &a);printf("*a=%d\n", *a);printf("a+1=%d\n", a + 1);printf("&a+1=%d\n", &a + 1);printf("*a+1=%d\n", *a + 1);p = &a[0];//a代表数组首元素地址pp = &p;printf("p=%d\n", p);printf("pp=%d\n", pp);printf("*p=%d\n", *p);printf("*pp=%d\n", *pp);printf("**pp=%d\n", **pp);printf("p+1=%d\n", p + 1);printf("pp+1=%d\n", pp + 1);printf("*(p+1)=%d\n", *(p + 1));printf("**(pp+1)=%d\n", **(pp + 1));  // 这行编译不报错,但运行报错,非法访问内存空间return 0;
}

运行到倒数第二个printf:

a=177208296
&a=177208296
*a=1
a+1=177208300
&a+1=177208312
*a+1=2
p=177208296
pp=177208344
*p=1
*pp=177208296
**pp=1
p+1=177208300
pp+1=177208352
*(p+1)=3

 

注意看*(p+1),即可表示下一个元素,但是**(pp+1),并不是表示第二个元素值,而是因为pp+1这个地址不允许访问而执行出错!

将上面程序中的p初始化赋值语句改为:

p = a;

结果是一样的。其实也是,因为一维数组名就是首元素的地址。

所以,重点来了,对于一维数组,这种二级指针其实是多此一举了,那么对于二维数组呢?应该是刚刚好了吧?

下篇讨论吧~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/521374.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用于回归的概率模型

机器学习中的回归方法&#xff1a; 机器学习中的概率模型 机器学习&#xff5c;总结了11种非线性回归模型&#xff08;理论代码可视化&#xff09; 高斯过程回归&#xff1a; Gaussian Processes for Machine Learning GPML——Datasets and Code Gaussian Processes 学…

windows@查看主机名@查看IP地址

文章目录 计算机名获取ip地址方式0(最可靠)方式1方式2 查看到多个ip安装了vmware其他情况 计算机名 开始菜单中直接搜索计算机名可以进入到设置查看 更通用的办法是打开cmd或powershell 输入hostname.exe PS>HOSTNAME.EXE ColorfulCxxu返回的ColorfulCxxu就是计算机名 或…

EdgeX Foundry - 连接 Modbus 设备

文章目录 一、概述1.安装说明2.Modbus Slave 工具 二、连接 Modbus 设备1.docker-comepse2.设备配置文件3.启动 EdgeX Foundry4.访问 UI4.1. consul4.2. EdgeX Console 5.创建 Modbus 设备5.1.创建设备配置文件5.2.添加设备 6.测试6.1.命令6.2.事件6.3.读值 EdgeX Foundry # E…

Navicat连接数据库出现的问题

Navicat使用教程——连接/新建数据库、SQL实现表的创建/数据插入、解决报错【2059-authentication plugin‘caching_sha2_password’……】_2059authentication plugin-CSDN博客

优思学院|拉丁方实验设计是什么?

今天&#xff0c;我要给大家带来一个六西格玛实验设计的小窍门——拉丁方设计。这是一种巧妙的方式&#xff0c;帮助我们探索不同因素&#xff08;输入&#xff09;对结果&#xff08;输出&#xff09;的影响&#xff0c;同时巧妙地处理那些我们不想要的“噪音因素”。 想象一…

融资项目——网关微服务

1. 网关的路由转发功能 在前后端分离的项目中&#xff0c;网关服务可以将前端的相关请求转发到相应的后端微服务中。 2. 网关微服务的配置 首先需要创建一个网关微服务&#xff0c;并添加依赖。 <!-- 网关 --><dependency><groupId>org.springframework.cl…

了解开源可视化表单的主要优势

为什么可视化表单深受大家喜爱&#xff1f;这就需要了解开源可视化表单的优势和特点了。在流程化办公深入人心的今天&#xff0c;提高办公协作效率早已成为大家的发展目标&#xff0c;低代码技术平台、开源可视化表单是提升办公协作效率的得力助手&#xff0c;一起来看看它的优…

mysql的语法学习总结3(一些常见的问题)

执行后&#xff0c;MySQL 会重新加载授权表并更新权限。 FLUSH PRIVILEGES; 怎么检查自己的电脑端口3306有没有被占用&#xff1f; ESTABLISHED表示被占用&#xff0c;LISTENING表示端口正在被监听&#xff0c;22696是占用该端口的进程的PID&#xff08;进程标识符&#xff0…

DNDC模型下载与安装、建模方法、结果分析、率定验证

目录 专题一 DNDC模型介绍 专题二 DNDC初步操作 专题三 遥感和GIS基础 专题四 DNDC气象数据 专题五 DNDC土地数据 专题六 DNDC土壤数据 专题七 DNDC结果分析 专题八 DNDC率定验证 专题九 土壤碳储量与作物产量 专题十 温室气体排放分析 专题十一 农田减排潜力分析 …

商业前端TS开发自动化工具

本期作者 一、背景 商业侧的业务比较复杂&#xff0c;B端项目中含有大量常量类的类型判断&#xff0c;且因历史原因&#xff0c;很多常量值前端无法直接知其含义&#xff0c;这既不利于新人的上手&#xff0c;也不利于项目的维护。 在开发协作上&#xff0c;前后端的API沟通&a…

2024最新图标设计趋势!附超好用的图标工具清单

图标&#xff0c;在界面设计中的作用不容小觑。正所谓浓缩的就是精华&#xff0c;一个小小的图标&#xff0c;却有着高效传递信息、美化界面排版、提升用户体验的巨大能力。 既然图标如此重要&#xff0c;了解图标设计趋势对设计师来说几乎是必须要做的事&#xff0c;它可以让…

Java+SpringBoot+Vue+MySQL实战:打造智能餐厅点餐系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…