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

news2025/1/11 6:57:18

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.0
  cout <<  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 declared
  if (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.coloradmin.cn/o/1842473.html

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

相关文章

C语言入门2-数据类型、运算符和表达式

变量命名 命名规范 只能由字母&#xff08;含"_"&#xff09;和数字组成&#xff1b;首字母不能是数字&#xff1b;不能与关键字重名&#xff0c;例如float、double和if等。 注意事项 不使用"_"开头&#xff0c;因为很多库函数这样命名&#xff0c;容易…

【Java】已解决java.sql.SQLRecoverableException异常

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决java.sql.SQLRecoverableException异常 在Java的数据库编程中&#xff0c;java.sql.SQLRecoverableException是一个重要的异常&#xff0c;它通常表示一个可以恢复的SQL异常。…

思维导图之计算机网络整体框架

高清自行访问&#xff1a;计算机网络整体框架 (yuque.com)

汽车信息安全硬件讨论:SE vs HSM

目录 1.什么是Secure Element 2.芯片内置HSM和SE 3.未来HSM的发展 现在的智能网联汽车看起来像是一个连接万物的智能移动终端&#xff0c;它不仅可以与OEM云服务器通信接收OTA推送&#xff0c;还可以与手机蓝牙、Wifi交互完成远程汽车解锁、座舱内环境设置等等&#xff0c;借…

微信小程序 this.setData高级用法(只更改单个数据)

合理使用 setData | 微信开放文档 1、页面 <view class"h-100px"></view> <view>最简单的数据&#xff1a;</view> <button bind:tap"handleAdd" data-type"1">点我加 1&#xff1a; {{text}}</button> &…

计算几何【Pick定理】

Pick 定理 Pick 定理&#xff1a;给定顶点均为整点的简单多边形&#xff0c;皮克定理说明了其面积 A {\displaystyle A} A 和内部格点数目 i {\displaystyle i} i、边上格点数目 b {\displaystyle b} b 的关系&#xff1a; A i b 2 − 1 {\displaystyle Ai{\frac {b}{2}}…

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

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

计算机网络 —— 应用层(万维网)

计算机网络 —— 应用层&#xff08;万维网&#xff09; 万维网核心组成部分特点 URLHTTP版本请求消息结构响应消息结构工作流程 Cookie如何工作主要用途安全与隐私类型 Web缓存客户端缓存&#xff08;浏览器缓存&#xff09;服务器端缓存 今天我们来了解万维网&#xff1a; 万…

react18 实现具名插槽

效果预览 技术要点 当父组件给子组件传递的 JSX 超过一个标签时&#xff0c;子组件接收到的 children 是一个数组&#xff0c;通过解析数组中各 JSX 的属性 slot &#xff0c;即可实现具名插槽的分发&#xff01; 代码实现 Father.jsx import Child from "./Child";…

Java中OOP的概念及示例

Java中OOP的概念及示例 在本指南中&#xff0c;您将学习Java中的OOP概念。面向对象编程系统&#xff08;OOP&#xff09;是一种基于“对象”的编程概念。面向对象编程的主要目的是提高程序的可读性、灵活性和可维护性。 面向对象编程将数据及其行为集中在一个称为对象的实体中…

小学生杂志小学生杂志社小学生编辑部2024年第5期目录

教学研究 小学数学教学中易错题的纠正策略研究 黄喜军; 1-3 主题语境下小学英语作业多模态设计与实施策略研究 韩蓓; 4-6 小学美术教育中色彩教学的实施措施研究 顾雅洁; 7-9《小学生》投稿&#xff1a;cn7kantougao163.com 核心素养视域下小学英语单元整体教学…

Linux 6.10也引进了蓝屏机制

众所周知&#xff0c;win死机后会有个蓝屏死机的故障提示页面&#xff0c;Linux 6.10 开始也将引入这个机制。 Linux 6.10 引入了一个新的 DRM Panic 处理程序基础设施&#xff0c;以便于在致命错误&#xff08;Panic&#xff09;发生时显示相关信息。 Linux 6.10 还在开发之…

如何高效应用与精准选择温补晶振

温补晶振(TCXO)是一种重要的时序元件&#xff0c;因其高精度和高稳定性在通信、导航、测控等多个领域中扮演着关键角色。晶发电子接下来将为您详细阐述温补晶振的选用和使用方法&#xff0c;助您更好地理解和运用这一核心元件。 一、温补晶振的工作原理 温补晶振能够实现在广…

2024年【N1叉车司机】报名考试及N1叉车司机考试资料

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 N1叉车司机报名考试参考答案及N1叉车司机考试试题解析是安全生产模拟考试一点通题库老师及N1叉车司机操作证已考过的学员汇总&#xff0c;相对有效帮助N1叉车司机考试资料学员顺利通过考试。 1、【多选题】《特种设备…

Tailwindcss 扩展默认配置来自定义颜色

背景 项目里多个Tab标签都需要设置同样的背景颜色#F1F5FF&#xff0c;在集成tailwindcss之前就是重复该样式&#xff0c;如下图&#xff1a; .body {background-color: #f1f5ff; }集成tailwindcss时&#xff0c;我们希望在class中直接设置该背景色&#xff0c;但是默认的tai…

不懂索引,简历上都不敢写自己熟悉SQL优化

大家好&#xff0c;我是考哥。 今天给大家带来MySQL索引相关核心知识。对MySQL索引的理解甚至比你掌握SQL优化还重要&#xff0c;索引是优化SQL的前提和基础&#xff0c;我们一步步来先打好地基。 当MySQL表数据量不大时&#xff0c;缺少索引对查询性能的影响不会太大&#x…

递归算法:代码迷宫中的无限探索

✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来! 目录 前言 一 深入理解递归 二 迭代VS递归 三 递归算法题目解析 3.1 汉诺塔问题 3.2 合并两个有序链表 3.3 反转链表 3.4 两两交换链表中的节点 3.5 Pow&#xff08;x&#xff0c;n&#xff09;&#xff08;快速幂)…

DAC测试实验——FPGA学习笔记7

一、DAC简介 DAC全称Digital to Analog Converter&#xff0c;即数模转换器。它用于将主控芯片产生的数字值(0和1)转换为模拟值(电压值)。 1、DAC参数指标 2、DAC类型 常用的DAC可大致分为权电阻网络DAC、T型电阻网络DAC、倒T型电阻网络DAC以及权电流型DAC。 3、AD9708/3PD9…

【stm32-新建工程-寄存器版本】

stm32-新建工程-寄存器版本 ■ 下载相关STM32Cube官方固件包&#xff08;F1&#xff0c;F4&#xff0c;F7&#xff0c;H7&#xff09;■ 1. ST官方搜索STM32Cube■ 2. 搜索 STM32Cube■ 3. 点击获取软件■ 4. 选择对应的版本下载■ 5. 输入账号信息■ 6. 出现下载弹框&#xff…

智能座舱中的HUD介绍

HUD&#xff08;Head Up Display&#xff0c;抬头显示系统&#xff09;是将车速、油耗、胎压等行车重要信息投影到前方挡风玻璃上的一套显示系统。HUD 最早应用在战斗机上&#xff0c;旨在降低飞行员低头查看仪表的频率&#xff0c;使得飞行员能在保证正常驾驶的同时&#xff0…