C++初学者指南第一步---9.函数

C++初学者指南第一步—9.函数

文章目录

  • C++初学者指南第一步---9.函数
    • 1.输入和输出
      • 1.1第一个例子
      • 1.2返回类型
      • 1.3函数参数
        • 常量参数
        • 默认值参数
      • 1.4函数重载
    • 2.函数执行
      • 2.1递归
      • 2.2 声明和定义
    • 3.函数设计
      • 3.1约定
      • 3.2 特性[[nodiscard]] (C++17)
      • 3.3 不抛出异常保证:noexcept (C++11)
    • 4.一些常用数学函数

1.输入和输出

1.1第一个例子

计算两个数的平均值函数

double mean (double a, double b) {return (a + b) / 2;
}
int main () {std::cout << mean(2, 6) <<'\n';  // prints 4
}
  • 封装实现细节
  • 通过将问题分解为单独的函数,更容易对正确性和测试进行推理
  • 避免重复常见任务的代码
    在这里插入图片描述
// "call" at "call site",在“调用点”调用函数
auto result = name(argument1, argument2);

1.2返回类型

返回类型可以是任何值:int、double、…或者为"空":void
double square (double x) {
return (x * x);
}
int max (int x, int y) {
if (x > y) return x; else return y;
}
void print_squares (int n) {
for (int i = 1; i <= n; ++i)
cout << square(i) << ‘\n’;
}

完整返回类型推导 (C++14)(推导 = 编译器自动确定类型)

auto foo (int i, double d) {…return i;
}
//  正确: 返回类型: int
auto foo (int i, double d) {return i;  //  int…return d;  //  double
} 
//  错误: 返回类型不一致!

1.3函数参数

  • 无参数:f( )
  • 一个或多个参数:g(int a, double b, int c, …)
  • 参数名称在参数列表中必须是唯一的,即参数名称不能重复
常量参数
int foo (int a, int const b) {a += 5;   // b += 10;  //  编译错误: 不能改变常量参数return (a + b);
}
// 调用foo:
foo(2,9);  // 常量不影响这里
  • 传递给foo的任何第二个参数都将被复制到本地变量b中,b是const的事实在foo之外无效。
    注意:如果在函数内部不需要或者不允许改变参数的数值,那就把它们设置成 const 吧!
默认值参数
double f (double a, double b = 1.5) {return (a * b);
}
int main () {cout <<  f(2);     // 1个参数  → 3.0cout <<  f(2, 3);  // 2个参数  → 6.0
}
void foo (int i = 0);  //正确
void foo (int n, double x = 2.5);  //正确
void foo (int a, int b = 1, float c = 3.5f);  //正确
void foo (int a, int b = 1, int c );  //错误

注意:第一个默认值参数后面的每个参数也必须有默认值

1.4函数重载

  • 名称相同但参数列表不同的函数
  • 无法仅靠返回类型重载

正确重载
名称相同,不同参数列表

int abs (int i) {return ((i < 0) ? -i : i);
}double abs (double d) {return ((d < 0.0) ? -d : d);
}
int a = -5;
double b = -2.23;
auto x = abs(a); // int abs(int)
auto y = abs(b); // double abs(double)

错误重载
名称相同,相同参数列表

int foo (int i) {  //错误return (2 * i);
}double foo (int i) { //错误return (2.5 * i);
}

无法编译!

2.函数执行

2.1递归

递归 = 函数调用自身

  • 需要一个中断条件
  • 看起来比循环更优雅,但在许多情况下速度更慢
  • 递归的深度有限制(受栈大小限制)
int factorial (int n) {// 中断条件:if (n < 2) return 1;  // 递归调用: n! = n * (n-1)!return (n * factorial(n - 1));  
}

2.2 声明和定义

  • 只能调用已知的函数(在之前/上方已知)。
  • 每个源文件(翻译单元)只允许一个定义。
  • 任意数量的函数声明都可以 = 通过指定函数的签名来宣布函数的存在。

错误例子:
COMPILER ERROR: - ‘odd’/‘even’ not known before ‘main’!
COMPILER ERROR: - ‘odd’ not known before ‘even’!

int main () {int i = 0;cin >> i;if (odd(i))  cout << "is odd\n";if (even(i)) cout << "is even\n";
}
bool even (int n) {return !odd(n);
}
bool odd (int n) {return (n % 2);
}

正确例子:

bool even (int);  // declaration
bool odd (int);   // declaration
int main () {     // definition of 'main'int i = 0; cin >> i;if (odd(i))  cout << "is odd\n";   // OK, already declaredif (even(i)) cout << "is even\n";  // OK, already declared
}
bool even (int n) { // definition of 'even'return !odd(n);  // OK, already declared
}
bool odd (int n) {  // definition of 'odd'return (n % 2);
}

3.函数设计

== 接口应该易于正确使用,难以错误使用。 —斯科特·迈耶斯—==

3.1约定

设计函数时请考虑:

  • 前提条件:您对输入值有何期望/要求?
  • 后置条件:对于输出值你应该给出什么保证?
  • 不变量:函数的调用者/用户希望不改变什么?
  • 目的:您的函数有明确定义的目的吗?
  • 名称:函数的名称是否反映了其用途?
  • 参数:调用者/用户是否容易混淆它们的含义?

在这里插入图片描述
前提条件检查

  • 广契约函数执行前提条件检查,即检查输入参数值(或程序状态)的有效性。
  • 窄契约函数不执行前置检查,即,调用者必须确保输入参数(以及程序状态)有效。

3.2 特性[[nodiscard]] (C++17)

鼓励编译器在函数返回值被丢弃时发出警告。

[[nodiscard]] bool prime (int i) { … }
// 返回值被使用:
bool const yes = prime(47);
if (prime(47)) { … }
// 返回值被丢弃/忽略:
prime(47);  //  编译警告

标准库中的示例:
std::vector的empty()函数在c++ 20中使用[[nodiscard]]声明,因为它可能与clear()混淆:

std::vector<int> v;
// …
if (v.empty()) { … }  // 正确
v.empty();  // C++20:  编译警告
// 哎呀...是不是有人想要清除它?

用[[nodiscard]]声明你的函数返回值:

  • 如果在任何情况下不使用返回值都毫无意义
  • 如果用户对其目的感到困惑,如果返回值被忽略。

3.3 不抛出异常保证:noexcept (C++11)

C++有一种像许多/大多数其他编程语言一样使用异常报告错误的机制。别担心,如果你不知道异常是什么,它们将在后面的章节中详细解释。
noexcept关键字指定一个函数承诺永远不会抛出异常/让异常逃逸:

void foo () noexcept { … }

如果异常从 noexcept 函数中逸出, 该程序将被中止。

4.一些常用数学函数

在这里插入图片描述
附上原文链接
如果文章对您有用,请随手点个赞,谢谢!^_^

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

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

相关文章

【Python驯化-01】python中set去重数据每次结果不一致问题解决

【Python驯化-01】python中set去重数据每次结果不一致问题解决 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 免费获取相关内容文档关注…

考研计组chap2数据的表示和运算

3一、进位计数制 1.r进制 第i位表示r进制的权为i 2.进制转换 &#xff08;1&#xff09;r->10 对应位置数*权值 &#xff08;2&#xff09;2 -> 16 or 8 每三位2进制数可表示1位16进制 每四位2进制数可表示1位16进制 so 分开之后转为16进制即可 eg&#xff1a;1…

基于51单片机恒温箱设计

基于51单片机恒温箱设计 &#xff08;程序&#xff0b;原理图&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 本设计由STC89C52单片机电路数字温度传感器DS18B20电路按键电路蜂鸣器报警电路继电器控制电路LCD1602液晶显示电路电源电路组成。 1.LCD1602液…

偏微分方程算法之抛物型方程差分格式编程示例四(Richardson外推)

目录 一、研究问题 二、C++代码 三、结果分析 一、研究问题 已知其精确解为。分别取以下三种步长: ①

树形dp,CF 1926 G - Vlad and Trouble at MIT

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - G - Codeforces 二、解题报告 1、思路分析 考虑每个结点最终状态只可能为和P连通或者和S连通 我们我们自然而然的将问题划分为这样的状态 f[x][0]代表结点x和P连通需要割掉最少的边 f[x][1]代…

Windows Server配置NFS,做ESXI共享存储

1:登录wINDOWS系统&#xff0c;点击添加角色和功能。 2:根据向导提示&#xff0c;一路下一步。在服务器角色中选择文件和存储服务器在文件和iSCSI服务中勾选NFS服务器。 3&#xff1a;按照提示一路下一步&#xff0c;安装NFS。 4&#xff1a;安装完成后关闭安装界面。 5&#x…

代码随想录算法训练营第六十五天 | 岛屿数量 深搜、岛屿数量 广搜、岛屿的最大面积

岛屿数量 深搜 题目链接&#xff1a;99. 岛屿数量 文字讲解&#xff1a;99. 岛屿数量 | 代码随想录 解题思路 本题已经说明&#xff0c;只有水平方向和竖直方向才能组成岛屿 本题思路&#xff0c;是遇到一个没有遍历过的节点陆地&#xff0c;计数器就加一&#xff0c;然后把…

为电脑小白推荐的5款实用工具软件

​ 电脑上的各类软件有很多&#xff0c;除了那些常见的大众化软件&#xff0c;还有很多不为人知的小众软件&#xff0c;专注于实用功能&#xff0c;简洁干净、功能强悍。 1.磁盘空间分析——TreeSize Free ​ TreeSize Free是一款免费的磁盘空间分析工具&#xff0c;能够扫描…

Sip协议(四) -注册流程

Sip协议(四) -注册流程 本文主要介绍下sip协议中, agent的注册流程. 一: 流程图 简单的流程图如下: agent发起注册fs 返回401 ,并携带WWW-Authenticateagent第二次发起注册,增加Authorizationfs返回授权成功, 或者失败. 二: sip流程 发起注册REGISTER 首先agent发起注册请求…

重磅!鹅厂大牛带你30分钟玩转AI智能结对编程!

在大模型时代&#xff0c;人工智能技术的突破性进展正重塑着软件开发的面貌。AI的融入不仅优化了代码编写过程&#xff0c;更开启了智能编程的新纪元&#xff0c;为开发者带来了前所未有的工作效率和创新可能。AI结对编程不仅能够极大提升研发效率&#xff0c;还能通过智能分析…

【查缺补漏】python

python查缺补漏 底板除 还有一种除法是//&#xff0c;称为地板除&#xff0c;两个整数的除法仍然是整数&#xff1a; >>> 10 // 3 3你没有看错&#xff0c;整数的地板除//永远是整数&#xff0c;即使除不尽。要做精确的除法&#xff0c;使用/就可以。 因为//除法只…

rsa加签验签C#和js、java、微信小程序互通

js实现rsa加签验签 https://github.com/kjur/jsrsasign 11.1.0版本 解压选择需要的版本&#xff0c;这里选择all版本了 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>JS RSA加签验签</title&g…

有趣网站分享 - 生成 O‘Reilly 类型封面

文章目录 网站介绍效果 网站介绍 –> O’RLY 封面工厂 https://orly.nanmu.me 你可以… 设置文本内容 选择图片 选择颜色 效果 2024-06-20&#xff08;四&#xff09;

前端网页开发学习(HTML+CSS+JS)有这一篇就够!

目录 HTML教程 ▐ 概述 ▐ 基础语法 ▐ 文本标签 ▐ 列表标签 ▐ 表格标签 ▐ 表单标签 CSS教程 ▐ 概述 ▐ 基础语法 ▐ 选择器 ▐ 修饰文本 ▐ 修饰背景 ▐ 透明度 ▐ 伪类 ▐ 盒子模型 ▐ 浮动 ▐ 定位 JavaScript教程 ▐ 概述 ▐ 基础语法 ▐ 函数 …

契约锁电子签章平台 add 远程命令执行漏洞复现(XVE-2023-23720)

0x01 产品简介 契约锁电子签章平台是上海亘岩网络科技有限公司推出的一套数字签章解决方案。契约锁为中大型组织提供“数字身份、电子签章、印章管控以及数据存证服务”于一体的数字可信基础解决方案,可无缝集成各类系统,让其具有电子化签署的能力,实现组织全程数字化办公。通…

还在为Android开发找不到图片测试资源发愁吗? DummyImage来助你加速开发

使用 DummyImage 模拟电影应用数据 在开发和测试过程中&#xff0c;模拟数据是不可或缺的工具。它可以帮助我们在没有真实数据的情况下测试应用程序的功能和性能。本文将介绍如何使用 [DummyImage]https://dummyimage.com生成占位符图像来模拟电影应用的数据&#xff0c;并深入…

专家观点∣企企通采购供应链数字化总监于海生:如何利用数字化技术重构采购流程,推动企业降本增效?

摘要 数字化转型现已成为企业提升竞争力、实现降本增效的必由之路。企业应主动参与到数字经济的建设中&#xff0c;以数据资源为关键要素&#xff0c;以现代信息网络为主要载体&#xff0c;以信息通信技术的有效使用作为效率提升和经济结构优化的重要推动力的一系列经济活动&a…

80W大功率钓鱼灯调光调色方案 | 非同步降压 LED 驱动芯片FP7195,将PWM信号转为模拟信号进行调光,深度可达0.1%

夜钓作为一种受欢迎的休闲娱乐方式&#xff0c;随着LED照明技术的不断发展&#xff0c;钓鱼爱好者们对于钓鱼灯的光照效果和调光调色功能提出了更高的要求。传统的调光方案往往无法满足钓鱼爱好者对于光线亮度和色温的精准控制需求。 对此&#xff0c;我司推出一个80W大功率夜钓…

部署RAC到单实例ADG(11G)

服务器信息 主库RAC环境信息 主库RAC基本环境 节点1 节点2 OS centos 7.9 centos 7.9 数据库版本 11.2.0.4 11.2.0.4 规格 1C4G 1C4G 主机名 racdb01 racdb02 public ip 192.168.40.135 192.168.40.145 vip 192.168.40.13 192.168.40.14 private ip 192…

【开关电源】Buck 降压电路

文章目录 前言基本组成工作原理电路特点工作模式设计与实现 前言 Buck降压电路&#xff0c;也称为降-降&#xff08;step-down&#xff09;转换器&#xff0c;是一种直流-直流&#xff08;DC-DC&#xff09;电源转换器&#xff0c;用于将输入电压转换为较低的输出电压。这种电…