C++函数(函数原型,指标、参考、预设、可变参数)第一部

函数原型

自订函数的定义需要放在main()或呼叫之前,如果放在main()或呼叫之后,例如

#include <iostream>int main() {do_something("What's truth?");do_something("There is no spoon.");return 0;
}void do_something(char* s) {std::cout << s << std::endl;
}

这样无法通过编译

$ g++ u0801_1.cpp
u0801_1.cpp:4:5:错误:使用未声明的标识符“do_something”do_something(“真相是什么?”)^
u0801_1.cpp:5:5:错误:使用未声明的标识符“do_something”do_something("没有勺子。");^
产生了2个错误。
$

因为C++ 预设任何识别字使用前都得先定义或宣告,如果我们要把自订函数的定义放在main()或呼叫之后,就要先宣告函数原型(function prototype) ,因此上例要改写如下

#include <iostream>void do_something(char*);int main() {do_something("What's truth?");do_something("There is no spoon.");return 0;
}void do_something(char* s) {std::cout << s << std::endl;
}

函数原型的宣告在第3 行

void do_something(char*);

参数列方面宣告参数的型态即可,编译执行结果如下

$ g++ u0801_2.cpp
$./a.out 复制代码
什麼是真實呢?
没有勺子。
$

通常函数原型的宣告会放在标头档(header file) 之中,函数实作则会放在其他程式档案。

指标参数

如果有需要用函数直接修改某些变数(variable) ,就可以用该变数的指标(pointer) 当参数,例如

#include <iostream>void do_something(int* n_ptr) {*n_ptr = 10;
}int main() {int a = 22;std::cout << a << std::endl;do_something(&a);std::cout << a << std::endl;return 0;
}

do_something()接受一个整数指标参数,然后将参数重新设定为10

void do_something(int* n_ptr) {*n_ptr = 10;
}

编译执行,结果如下

$ g++ u0802_1.cpp
$./a.out 复制代码
22
10
$

由于函数只能有一个回传值,因此当程式中有多个变数需要用函数修改时,利用指标当参数为一个解决方案,另举一例如下

#include <iostream>int do_something2(int* n1_ptr, int* n2_ptr) {*n1_ptr *= 2;*n2_ptr *= 2;return *n1_ptr + *n2_ptr;
}int main() {int a = 22;int b = 33;std::cout << "a + b: " << do_something2(&a, &b) << std::endl;std::cout << "a: " << a << std::endl;std::cout << "b: " << b << std::endl;return 0;
}
$ g++ u0802_2.cpp
$./a.out 复制代码
a+b:110
答:44
乙:66
$

参考参数

如果有需要用函数直接修改某些变数,就可以设计接收参考参数(reference parameter) 的函数,例如

#include <iostream>void do_something(int& n_ref) {n_ref = 10;
}int main() {int a = 22;std::cout << a << std::endl;do_something(a);std::cout << a << std::endl;return 0;
}

do_something()接受一个整数参考参数,然后将参数重新设定为10

void do_something(int& n_ref) {
n_ref = 10;
}

编译执行,结果如下

$ g++ u0803_1.cpp
$./a.out 复制代码
22
10
$

由于函数只能有一个回传值,因此当程式中有多个变数需要用函数修改时,利用参考当参数为一个解决方案,另举一例如下

#include <iostream>int do_something2(int &n1_ref, int &n2_ref) {n1_ref *= 2;n2_ref *= 2;return n1_ref + n2_ref;
}int main() {int a = 22;int b = 33;std::cout << "a + b: " << do_something2(a, b) << std::endl;std::cout << "a: " << a << std::endl;std::cout << "b: " << b << std::endl;return 0;
}

编译执行,结果如下

$ g++ u0803_2.cpp
$./a.out 复制代码
a+b:110
答:44
乙:66
$

预设参数

函数可以有预设参数(default parameter) ,也就是替参数设定预设值,例如

#include <iostream>void do_something(int n = 22) {std::cout << n << std::endl;
}int main() {do_something(11);do_something();do_something();return 0;
}

替参数n设定预设值,就是直接在参数列指派数值

void do_something(int n = 22) {

这样不使用参数也可以呼叫

do_something(11);
do_something();
do_something();

编译执行,结果如下

$ g++ u0804_1.cpp
$./a.out 复制代码
11
22
22
$

预设参数可以是选择性的,也就是可以替特定参数设定预设值,其他参数则须呼叫时填入小括弧,需要注意这样的预设参数必须放在参数列的后面,例如

#include <iostream>void do_something2(int n1, int n2 = 5, int n3 = 0) {std::cout << n1 + n2 + n3 << std::endl;
}int main() {do_something2(6);do_something2(6, 9);do_something2(3, 4, 5);return 0;
}

留意n1并没有预设值

void do_something2(int n1, int n2 = 5, int n3 = 0) {std::cout << n1 + n2 + n3 << std::endl;
}

因此呼叫时至少要有一个参数

do_something2(6);
do_something2(6, 9);
do_something2(3, 4, 5);

编译执行,结果如下

$ g++ u0804_2.cpp
$./a.out 复制代码
11
15
12
$

此外要注意参数列的顺序,预设参数只能放在参数列的后面,像是下面就无法通过编译

void do_something2(int n1 = 6, int n2, int n3 = 0) {

可变参数

函数的参数数量也可以不固定,这是在参数列里利用...构成可变参数(variadic arguments) ,举例如下

#include <iostream>
#include <cstdarg>int sum(int n_args, ...) {va_list ap;va_start(ap, n_args);int sum = va_arg(ap, int);for (int i = 2; i <= n_args; i++) {sum += va_arg(ap, int);}va_end(ap);return sum;
}int main() {std::cout << sum(3, 11, 22, 33) << std::endl;std::cout << sum(3, 19, 20, 21) << std::endl;std::cout << sum(3, 3, 65, 101) << std::endl;return 0;
}

此例的sum()用来计算参数的总和,除了第一个参数n_args为计算总和的数量之外,其他的参数都会被累加起来,结果回传为整数

int sum(int n_args, ...) {va_list ap;va_start(ap, n_args);int sum = va_arg(ap, int);for (int i = 2; i <= n_args; i++) {sum += va_arg(ap, int);}va_end(ap);return sum;
}

编译执行,结果如下

$ g++ u0805.cpp
$./a.out 复制代码
66
60
169
$

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

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

相关文章

paddleocr icdar2015数据集训练dbnet检测模型

参考&#xff1a;https://github.com/PaddlePaddle/PaddleOCR/blob/main/doc/doc_ch/detection.md 原理 DBNET论文 Real-time Scene Text Detection with Differentiable Binarization 参考&#xff1a;https://blog.csdn.net/qq_35756383/article/details/118679258 Real-T…

7,SSH scp 命令

scp 命令 scp是 SSH 提供的一个客户端程序&#xff0c;用来在两台主机之间加密传送文件&#xff08;即复制文件&#xff09;。 简介 scp是 secure copy 的缩写&#xff0c;相当于cp命令 SSH。它的底层是 SSH 协议&#xff0c;默认端口是22&#xff0c;相当于先使用ssh命令登…

【STC89C51单片机】定时器/计数器的理解

目录 定时器/计数器1. 定时器怎么定时简单理解&#xff08;加1经过了多少时间&#xff09;什么是时钟周期什么是机器周期 2.如何设置定时基本结构相关寄存器1. TMOD寄存器2. TCON寄存器 代码示例 定时器/计数器 STC89C51单片机的定时器和计数器&#xff08;Timers and Counter…

【BUG】已解决:NameError: name ‘XXX‘ is not defined

已解决&#xff1a;NameError: name ‘XXX‘ is not defined 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开发者社…

Harmony 状态管理 @Local 和 @Param

Harmony 状态管理 Local 和 Param Local 背景 Local 是harmony应用开发中的v2版本中 对标**State**的状态管理修饰器&#xff0c;它解决了 State 对状态变量更改的检测混乱的问题&#xff1a; State 修饰的状态变量 可以是组件内部自己定义的State 修饰的状态 也可以由外部父…

路径规划 | 基于DQN深度强化学习算法的路径规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 DQN路径规划算法 基于深度强化学习算法的路径规划 matlab2023b 栅格环境&#xff0c;走迷宫&#xff0c;可以通过窗口界面方便观察交互过程&#xff0c;代码注释详尽。 程序设计 完整源码和数据私信博主回复基于DQN深…

Vue学习---vue cli 项目创建

使用的编辑工具webStorm 创建例子: hello vue create hello 选择 vue3 进行创建 运行 npm run serve 测试访问&#xff1a;http://localhost:8080 改动内容重新编译&#xff1a; npm run build dist 目录就是编译后的可运行内容

1分钟带你了解苹果手机删除照片恢复全过程

在日常使用苹果手机时&#xff0c;我们可能会不小心删除掉一些重要的照片&#xff0c;这让人非常烦恼。那么苹果手机怎么恢复删除的照片&#xff1f;下面小编将会向大家介绍苹果手机恢复删除的照片的方法&#xff0c;帮助大家轻松找回你丢失的照片。 一、利用“最近删除”文件夹…

ChatGPT:为什么计数排序需要进行累加操作

ChatGPT&#xff1a;为什么计数排序需要进行累加操作 第一种写法 private static void countSort() {int[] MaxMin findMaxMin();int max MaxMin[0];int min MaxMin[1];int[] counts new int[max - min 1];for (int num : nums) {counts[num - min];}int index 0;for (i…

甲骨文面试题【动态规划】力扣377.组合总和IV

给你一个由 不同 整数组成的数组 nums &#xff0c;和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证答案符合 32 位整数范围。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3], target 4 输出&#xff1a;7 解释&#x…

【Linux】详解加锁实现线程互斥

一、多线程不加线程互斥可能会引发的问题 下面是一个抢标逻辑。抢票为什么会抢到负数&#xff1a;假设当票数为1时&#xff0c;此时四个进程的判断条件tickets都大于0&#xff0c;都会进入抢票操作&#xff0c;第一个进程抢完票以后tickets0并写回内存&#xff0c;第二个进程再…

Xcode进行真机测试时总是断连,如何解决?

嗨。大家好&#xff0c;我是兰若姐姐。最近我在用真机进行app自动化测试的时候&#xff0c;经常会遇到xcode和手机断连&#xff0c;每次断连之后需要重新连接&#xff0c;每次断开都会出现以下截图的报错 当这种情况出现时&#xff0c;之前执行的用例就相当于白执行了&#xff…

Adobe XD中文设置指南:专业设计师的现场解答

Adobe XD是世界领先的在线合作UI设计工具。它摆脱了Sketch、Figma等传统设计软件对设备的依赖&#xff0c;使设计师可以随时随地使用任何设备打开网页浏览器&#xff0c;轻松实现跨平台、跨时空的设计合作。然后&#xff0c;为了提高国内设计师的使用体验&#xff0c;Adobe XD如…

爬虫(二)——爬虫的伪装

前言 本文是爬虫系列的第二篇文章&#xff0c;主要讲解关于爬虫的简单伪装&#xff0c;以及如何爬取B站的视频。建议先看完上一篇文章&#xff0c;再来看这一篇文章。要注意的是&#xff0c;本文介绍的方法只能爬取免费视频&#xff0c;会员视频是无法爬取的哦。 爬虫的伪装 …

C++类与对象(补)

感谢大佬的光临各位&#xff0c;希望和大家一起进步&#xff0c;望得到你的三连&#xff0c;互三支持&#xff0c;一起进步 个人主页&#xff1a;LaNzikinh-CSDN博客 文章目录 前言一.默认成员函数二.static三.友元四.匿名对象总结 前言 类的默认成员函数&#xff0c;默认成员…

linux centos limits.conf 修改错误,无法登陆问题修复 centos7.9

一、问题描述 由于修改/etc/security/limits.conf这个文件中的值不当&#xff0c;重启后会导致其账户无法远程登录&#xff0c;本机登录。 如改成这样《错误示范》&#xff1a; 会出现&#xff1a; 二、解决 现在知道是由于修改limits.conf文件不当造成的&#xff0c;那么就…

Android-- 集成谷歌地图

引言 项目需求需要在谷歌地图&#xff1a; 地图展示&#xff0c;设备点聚合&#xff0c;设备站点&#xff0c;绘制点和区域等功能。 我只针对我涉及到的技术做一下总结&#xff0c;希望能帮到开始接触谷歌地图的伙伴们。 集成步骤 1、在项目的modle的build.gradle中添加依赖如…

p19 C语言操作符详解

算术操作符 1.除了%操作符之外&#xff0c;其他的几个操作符可以作用于整数和浮点数。 2.对于/操作符如果两个操作数都为整数&#xff0c;执行整数除法。而只要有浮点数值型的就是浮点除法。 3.%操作符的两个操作数必须为 整数。返回的是整除之后的余数。 #include<std…

计算机毕业设计-基于Springboot的养老院管理系统-源码程序文档

项目源码&#xff0c;请关注❥点赞收藏并私信博主&#xff0c;谢谢~ 本系统开发采用技术为JSP、Bootstrap、Ajax、SSM、Java、Tomcat、Maven 此文章为本人亲自指导加编写&#xff0c;禁止任何人抄袭以及各类盈利性传播&#xff0c; 相关的代码部署论文ppt代码讲解答辩指导文件…

SpringBoot以及swagger的基本使用

1、SpringBoot是什么&#xff1f; 一种快速开发、启动Spring的框架、脚手架 遵循“约定优于配置”的思想&#xff0c;使得能够快速创建和配置Spring应用 2、SpringBoot的核心特性 自动配置&#xff0c;一些依赖、默认配置都预设好了&#xff0c;减少了配置量起步依赖&#x…