C++中将指针传递给函数
C++中将指针传递给函数
指针是一种将内存空间传递给函数的有效方式,其中可包含函数完成其工作所需的数据,也可包含操作结果。将指针作为函数参数时,确保函数只能修改您希望它修改的参数很重要。例如,如果函数根据以指针方式传入的半径计算圆的面积,就不应允许它修改半径。为控制函数可修改哪些参数以及不能修改哪些参数,可使用关键字 const,如以下示例程序所示:
#include <iostream>
using namespace std;void CalcArea(const double* const ptrPi, // const pointer to const dataconst double* const ptrRadius, // i.e. no changes alloweddouble* const ptrArea) // can change data pointed to
{// check pointers for validity before using!if (ptrPi && ptrRadius && ptrArea) *ptrArea = (*ptrPi) * (*ptrRadius) * (*ptrRadius);
}int main()
{const double Pi = 3.1416;cout << "Enter radius of circle: ";double radius = 0;cin >> radius;double area = 0;CalcArea (&Pi, &radius, &area);cout << "Area is = " << area << endl;return 0;
}
输出:
Enter radius of circle: 10.5
Area is = 346.361
分析:
第 3~5 行演示了两种 const 指针, ptrRadius 和 ptrPi 被声明为“指向 const 数据的 const 指针”,因此不能修改指针包含的地址,也不能修改它指向的数据。 ptrArea 显然是用于存储输出的参数,因为不能修改该指针的值(地址),但可修改它指向的数据。第 8 行在使用函数的指针参数前检查其有效性。在调用者不小心将这三个参数之一设置为 NULL 指针时,您不希望函数计算面积,因为这种非法访问将导致应用程序崩溃。
无可否认,引用变量比指针更容易处理,因为引用变量隐藏了所有的解引用和间接引用"机制"。但是,程序员仍然应该学会使用指针作为函数参数,因为有一些任务,特别是在处理 C 字符串时,最好使用指针完成、另外,C++库中还有许多使用指针作为形参的函数。
以下是使用指针形参的函数的定义:
void doubleValue(int *val)
{*val *= 2;
}
这个函数的目的是使 val 指向的变量翻倍。当 val 被解引用时,*= 运算符对 val 指向的变量起作用。该语句可以将地址存储在 val 中的原始变量乘以 2。当然,当调用该函数时,必须使用被翻倍的变量地址作为实参,而不是变量本身作为实参。
以下是一个调用 doubleValue 函数的示例:
doubleValue(&number);
该语句使用了地址运算符(&)将 number 的地址传递到 val 形参中。函数执行后,number 的内容将被乘以 2。下面的程序演示了该函数的用法:
//This program uses two functions that accept addresses of variables as arguments.
#include <iostream>
using namespace std;
//Function prototypes
void getNumber(int *);
void doubleValue(int *);int main()
{int number;//Call getNumber and pass the address of numbergetNumber(&number);// Call doubleValue and pass the address of numberdoubleValue(&number);// Display the value in numbercout << "That value doubled is " << number << endl;return 0;
}
void getNumber(int *input)
{cout << "Enter an integer number: ";cin >> *input;
}void doubleValue(int *val)
{*val *= 2;
}
程序输出结果:
Enter an integer number: 10
That value doubled is 20
此程序有两个使用指针作为参数的函数。请看以下函数原型:
void getNumber(int *);
void doubleValue(int *);
每一个函数原型都使用符号 int * 来表示该形参是一个指向 int 的指针。与所有其他类型的形参一样,不需要在原型中指定变量的名称,但星号(*)则是必需。
getNumber 函数要求用户输入一个整数值。以下 cin 语句可以将用户输入的值存储在内存中:
cin >> *input;
间接运算符会使用户输入的值存储在 input 指向的变量中,而不是 input 中。
在上面的语句中,使用间接运算符是非常重要的。没有它,则 cin 会将用户输入的值存储在 input 中,就像该值是一个内存地址一样。如果发生这种情况,则 input 将不再指向 main 函数中的 number 变量。如此一来,对该指针(input)的后续使用即使不会产生灾难性的结果,也必然出现错误。
当调用 getNumber 函数时,函数 main 中 number 变量的地址作为实参传递。该函数执行后,用户输入的数值将被存储在 number 中。接下来,调用 doubleValue 函数,同样是将 number 的地址作为实参传递,这使得 number 被乘以 2。
指针变量也可以用来接收数组地址作为实参,此后,无论是下标还是指针符号都可以用来处理数组的内容。下面的程序演示了这一点:
//This program demonstrates that a pointer may be used as a parameter to accept the address of an array. Either subscript or pointer notation may be used.
#include <iostream>
#include <iomanip>
using namespace std;
// Function prototypes
void getSales(double *sales, int size);
double totalSales(double *sales, int size);int main()
{const int QUARTERS = 4;double sales[QUARTERS];getSales(sales, QUARTERS);cout << setprecision(2);cout << fixed << showpoint;cout << "The total sales for the year are $";cout << totalSales(sales, QUARTERS) << endl;return 0;
}
void getSales(double *array, int size)
{for (int count = 0; count < size; count++){cout << "Enter the sales figure for quarter ";cout << (count + 1) << ": ";cin >> array[count];}
}double totalSales(double *array, int size)
{double sum = 0.0;for (int count = 0; count < size; count++){sum += *array;array++;}return sum;
}
程序输出结果:
Enter the sales figure for quarter 1: 10263.98
Enter the sales figure for quarter 2: 12369.69
Enter the sales figure for quarter 3: 11542.13
Enter the sales figure for quarter 4: 14792.06
The total sales for the year are $48967.86
请注意,该程序的 getSales 函数中,即使把形参 array 定义为一个指针,其下标符号仍然可以在 cin 语句中使用:
cin >> array[count];
在 totalSales 函数中,array 还可以与以下语句中的间接运算符一起使用:
sum += *array;
而在接下来的语句中,array 中的地址则可以递增,以使指向下一个元素:
array++;
上面介绍的两个语句也可以合并成以下语句:
sum += *array++;
* 运算符将首先解引用 array,然后 ++ 运算符将使得 array 中的地址递增。
该文章会更新,欢迎大家批评指正。
推荐一个零声学院的C++服务器开发课程,个人觉得老师讲得不错,
分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容
点击立即学习:C/C++后台高级服务器课程
相关文章:
C++中将指针传递给函数
C中将指针传递给函数 指针是一种将内存空间传递给函数的有效方式,其中可包含函数完成其工作所需的数据,也可包含操作结果。将指针作为函数参数时,确保函数只能修改您希望它修改的参数很重要。例如,如果函数根据以指针方式传入的半…...
【51单片机编写占空比按秒渐亮与渐暗】2023-10-2
昨天刚在W10上安装CH340驱动,又下载到板子上LCD1602定时器时钟程序,为了调试,调用了一个LED观察控制蜂鸣器按秒响的变量,几经调试才发觉该开发板用的是有源蜂鸣器,不用IO取反操作,直接控制IO的高低电平即可…...
OCI 发布了容器运行时和镜像规范!
7 月 19 日是开放容器计划Open Container Initiative(OCI)的一个重要里程碑,OCI 发布了容器运行时和镜像规范的 1.0 版本,而 Docker 在这过去两年中一直充当着推动和引领的核心角色。 我们的目标是为社区、客户以及更广泛的容器行…...
C++学习笔记一: 变量和基本类型
本章讲解C内置的数据类型(如:字符、整型、浮点数等)和自定义数据类型的机制。下一章讲解C标准库里面定义的更加复杂的数据类型,比如可变长字符串和向量等。 1.基本内置类型 C内置的基本类型包括:算术类型和空类型。算…...
探索ClickHouse——同时支持导入导出功能的文件格式
在《探索ClickHouse——安装和测试》中,我们使用clickhouse直接从文件中读取数据。clickhouse支持多种格式文件的导入导出,本节我们对此进行分类介绍。 按常见格式区分 JSON 原始的JSON格式只支持导入,不支持导入。同时支持导入和导出的是…...
Scipy库提供了多种正态性检验和假设检验方法
Scipy库提供了多种正态性检验和假设检验方法。以下是一些常用的检验方法的列表: 正态性检验方法: Shapiro-Wilk检验:scipy.stats.shapiroAnderson-Darling检验:scipy.stats.andersonKolmogorov-Smirnov检验:scipy.st…...
去雨去雪去雾算法之本地与服务器的TensorBoard使用教程
在进行去雨去雾去雪算法实验时,需要注意几个参数设置,num_workers只能设置为0,否则会报各种稀奇古怪的错误。 本地使用TensorBoard 此外,发现生成的文件是events.out.tfevents格式的,查询了一番得知该文件是通过Tens…...
【小沐学前端】Node.js实现基于Protobuf协议的WebSocket通信
文章目录 1、简介1.1 Node1.2 WebSocket1.3 Protobuf 2、安装2.1 Node2.2 WebSocket2.2.1 nodejs-websocket2.2.2 ws 2.3 Protobuf 3、代码测试3.1 例子1:websocket(html)3.1.1 客户端:yxy_wsclient1.html3.1.2 客户端:…...
MySQL学习笔记24
MySQL的物理备份: xtrabackup备份介绍: xtrabackup优缺点: 优点: 1、备份过程快速、可靠(因为是物理备份);直接拷贝物理文件。 2、支持增量备份,更为灵活; 3、备份…...
objective-c 基础学习
目录 第一节:OC 介绍 第二节:Fundation 框架 第三节:NSLog 相对于print 的增强 第四节:NSString 第五节:oc新增数据类型 第六节: 类和对象 类的方法的声明与实现 第七节:类…...
【精彩回顾】 用sCrypt在Bitcoin上构建智能合约
2023年3月24日,sCrypt在英国Exeter大学举办了关于智能合约的大学讲学。sCrypt首席执行官刘晓晖做了题为“用sCrypt在Bitcoin上构建智能合约”的演讲,并与到场的老师、学生进行了深入交流、互动。这次课程着重讲解了 BSV 智能合约的基础概念,以…...
Kotlin 使用泛型
在 Kotlin 中,我们可以使用泛型(Generics)来编写具有通用性的代码,以增强代码的可重用性和类型安全性。通过使用泛型,我们可以在不指定具体类型的情况下编写适用于多种类型的函数和类。 以下是 Kotlin 中使用泛型的几…...
深度学习 二:COVID 19 Cases Prediction (Regression)
Deep Learning 1. 回归算法思路2. 代码2.1 基础操作2.2 定义相关函数2.3.1 定义图像绘制函数2.3.2 数据集加载及预处理2.3.3 构造数据加载器2.3.4 构建前馈神经网络(Feedforward Neural Network)模型2.3.5 神经网络的训练过程2.3.6 模型评估2.3.7 模型测…...
UG\NX二次开发 信息窗口的4种输出方式 NXOpen::ListingWindow::DeviceType
文章作者:里海 来源网站:《里海NX二次开发3000例专栏》 简介 UG\NX二次开发 信息窗口的4种输出方式 NXOpen::ListingWindow::DeviceType 信息窗口的输出类型 enum NXOpen::ListingWindow::DeviceType 枚举值描述 DeviceTypeWindow0输出将写入“信息”窗口DeviceTypeFile1输出…...
mavn打包时如何把外部依赖加进去?
一、添加依赖: <dependency><groupId>com.dm</groupId><artifactId>DmJdbcDriver</artifactId><version>18</version><scope>system</scope><systemPath>${project.basedir}/lib/DmJdbcDriver18.jar</systemP…...
爬虫代理请求转换selenium添加带有账密的socks5代理
爬虫代理请求转换selenium添加带有账密的socks5代理。 一、安装三方库 二、使用方法 1、在cmd命令行输入: 2、给selenium添加代理 最近因为工作需要,需要selenium添加带有账密的socks5代理,贴出一个可用的方法。 把带有账密的socks5代理&am…...
Redis 如何实现数据不丢失的?
Redis 实现数据不丢失的关键在于使用了多种持久化机制,以确保数据在内存和磁盘之间的持久性。以下是 Redis 实现数据不丢失的主要方法: 快照(Snapshot)持久化: Redis 使用快照持久化来定期将内存中的数据写入磁盘。快照是一个数据库状态的副本,包含了所有键和与其相关联的…...
[高等数学]同济版高等数学【第七版】上下册教材+习题全解PDF
laiyuan 「高等数学 第7版 同济大学」 https://www.aliyundrive.com/s/5fpFJb3asYk 提取码: 61ao 通过百度网盘分享的文件:同济版高数教材及… 链接:https://pan.baidu.com/s/1gyy-GMGjwguAjYijrpC8RA?pwdyhnr 提取码:yhnr 高等数学相关: The Ca…...
【面试题精讲】Java超过long类型的数据如何表示
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址[1] 面试题手册[2] 系列文章地址[3] 在 Java 中,如果需要表示超过 long 类型范围的数据,可以使用 BigInteger 类…...
Shapiro-Wilk正态性检验(Shapiro和Wilk于1965年提出)
Shapiro-Wilk正态性检验是一种用于确定数据集是否服从正态分布的统计方法。它基于Shapiro和Wilk于1965年提出的检验统计量。以下是其基本原理和用途: 基本原理: 零假设(Null Hypothesis):Shapiro-Wilk检验的零假设是数…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
