当前位置: 首页 > news >正文

十四天学会C++之第二天(函数和库)

在这里插入图片描述

1. 函数的定义和调用

在C++中,函数是组织和结构化代码的关键工具之一。它们允许您将一段代码封装成一个可重复使用的模块,这有助于提高代码的可读性和维护性。

为什么使用函数?

函数在编程中的作用不可小觑。它们有以下几个重要用途:

  • 模块化编程: 函数允许将代码划分为小的、独立的单元,使得代码更易于理解和管理。

  • 代码重用: 一次编写,多次使用。您可以在程序的不同地方调用同一个函数,而不必重复编写相同的代码。

  • 提高可读性: 通过将代码分解为函数,您可以为每个函数取一个描述性的名字,使代码更具可读性。

定义函数

在C++中,函数的定义通常包括以下几个部分:

// 函数声明(函数原型)
返回类型 函数名(参数列表);// 函数定义
返回类型 函数名(参数列表) {// 函数体// 执行一些操作return 返回值; // 如果有返回值的话
}
  • 返回类型: 函数可以返回一个值,这个值的类型由返回类型指定。如果函数不返回任何值,可以使用 void 关键字表示。

  • 函数名: 函数的名称,是函数的标识符。

  • 参数列表: 函数可以接受零个或多个参数,这些参数在圆括号内列出,并用逗号分隔。

  • 函数体: 包含函数执行的实际代码部分。

  • 返回值: 如果函数有返回值,使用 return 语句返回该值。

函数定义:

// 函数声明
int add(int a, int b);// 函数定义
int add(int a, int b) {int result = a + b;return result;
}

调用函数

调用函数意味着执行函数内的代码。要调用函数,只需使用函数名和合适的参数列表。

int main() {int num1 = 5;int num2 = 3;int sum = add(num1, num2); // 调用add函数cout << "Sum: " << sum << endl;return 0;
}

示例中,add 函数被调用来计算 num1num2 的和,并将结果存储在 sum 变量中。

2. 参数传递

在C++中,参数传递是函数与外部世界进行数据交换的重要方式之一。它可以通过不同的方式实现,包括按值传递和按引用传递。

按值传递 vs. 按引用传递

按值传递

参数按值传递给函数时,函数会创建参数的一个副本,这意味着在函数内部对参数的更改不会影响外部的原始数据。

void modifyValue(int x) {x = 10; // 在函数内部修改副本
}int main() {int value = 5;modifyValue(value);cout << "Value after function call: " << value << endl; // 仍然是5return 0;
}
按引用传递

按引用传递参数时,函数操作的是原始数据的引用,这意味着对参数的更改会影响外部的原始数据。

void modifyValue(int &x) {x = 10; // 直接修改原始数据
}int main() {int value = 5;modifyValue(value);cout << "Value after function call: " << value << endl; // 现在是10return 0;
}

函数参数的默认值

函数的参数提供默认值,这意味着在调用函数时,可以省略某些参数,让编译器使用默认值。

void printMessage(string message = "Hello, World!") {cout << message << endl;
}int main() {printMessage(); // 使用默认消息printMessage("Custom message"); // 使用自定义消息return 0;
}

函数重载

函数重载允许在同一范围内定义多个具有相同名称但不同参数列表的函数。编译器根据函数调用的参数来选择正确的函数。

int add(int a, int b) {return a + b;
}double add(double a, double b) {return a + b;
}

示例

参数传递的不同方式和默认值的影响:

void modify(int x) {x = 10;
}void modify(double &y) {y = 3.14;
}int main() {int num = 5;double pi = 3.14159265359;modify(num); // 传值,num不变modify(pi);  // 传引用,pi被修改cout << "Modified num: " << num << endl;cout << "Modified pi: " << pi << endl;return 0;
}

在示例中,modify 函数分别按值和按引用传递参数,从而导致了不同的行为。

3. 函数的返回值

函数的返回值是函数执行后向调用者提供的结果。在C++中,您可以指定函数的返回值类型,并使用return语句从函数中返回值。

返回值类型

每个C++函数都有一个返回值类型,它指定了函数返回的数据类型。返回值类型在函数声明和定义中都必须指定。

int add(int a, int b) { // 返回值类型为intreturn a + b;
}double divide(double x, double y) { // 返回值类型为doublereturn x / y;
}

返回语句

return语句用于从函数中返回值。可以出现在函数的任何位置,但一旦执行,函数将立即终止,并将控制返回给调用者。

int multiply(int a, int b) {int result = a * b;return result; // 返回计算结果
}

示例

使用函数的返回值:

int main() {int sum = add(5, 3); // 调用add函数并接收返回值double quotient = divide(10.0, 2.0); // 调用divide函数并接收返回值cout << "Sum: " << sum << endl;cout << "Quotient: " << quotient << endl;return 0;
}

在上面的示例中,adddivide 函数返回整数和浮点数,分别被存储在 sumquotient 变量中。

返回值在表达式中的应用

函数的返回值可以直接用作表达式的一部分。这使得函数调用非常灵活,可以在数学表达式或其他计算中使用。

int main() {int result = multiply(add(2, 3), 4); // 使用函数返回值进行嵌套调用和计算cout << "Result: " << result << endl;return 0;
}

在示例中,add(2, 3) 的返回值被传递给 multiply 函数,以便进行进一步的计算。

4. 标准C++库介绍

C++作为一门强大的编程语言,拥有丰富的标准库,提供了许多有用的功能和数据结构。

包含头文件

要使用C++标准库中的功能,首先需要包含相应的头文件。头文件包含了库中的类、函数和对象的声明,它们是使用这些库的关键。

#include <iostream>  // 包含iostream头文件,用于输入输出操作
#include <string>    // 包含string头文件,用于字符串操作
#include <vector>    // 包含vector头文件,用于动态数组操作

示例用法

库的示例用法:

使用iostream进行输入和输出
#include <iostream>int main() {// 输出文本到控制台std::cout << "Hello, World!" << std::endl;// 从用户输入读取数据int num;std::cout << "Enter a number: ";std::cin >> num;// 输出读取到的数据std::cout << "You entered: " << num << std::endl;return 0;
}
使用string进行字符串操作
#include <string>int main() {std::string greeting = "Hello, ";std::string name = "John";// 字符串拼接std::string message = greeting + name;// 获取字符串长度int length = message.length();// 输出结果std::cout << message << " (Length: " << length << ")" << std::endl;return 0;
}
使用vector创建动态数组
#include <vector>int main() {std::vector<int> numbers;// 向vector添加元素numbers.push_back(1);numbers.push_back(2);numbers.push_back(3);// 遍历并输出vector的元素for (int i = 0; i < numbers.size(); ++i) {std::cout << numbers[i] << " ";}std::cout << std::endl;return 0;
}

5. 头文件和命名空间

在C++编程中,头文件和命名空间是非常重要的概念。头文件用于包含声明和定义,而命名空间则用于避免命名冲突。

头文件的作用

头文件通常包含了函数、类和变量的声明,以及必要的函数原型和常量定义。头文件的作用是将这些声明集中在一起,以便在多个源文件中共享。这有助于模块化编程,提高了代码的可维护性。

创建自定义头文件

要创建自定义头文件,只需新建一个以.h.hpp为扩展名的文本文件,并在其中包含所需的声明。例如,以下是一个名为myheader.h的头文件的示例:

#ifndef MYHEADER_H
#define MYHEADER_H// 在这里添加声明#endif

命名空间的概念

命名空间是一种将全局作用域划分为不同部分以防止命名冲突的机制。它允许您将相关的函数、类和变量组织到一个命名空间中,以避免与其他代码的命名冲突。

使用命名空间

要使用命名空间,您可以使用namespace关键字定义一个命名空间,然后将相关声明放入其中。例如:

// 定义一个名为mynamespace的命名空间
namespace mynamespace {int myVariable;void myFunction();
}
// 使用mynamespace中的变量和函数
mynamespace::myVariable = 42;
mynamespace::myFunction();

简化命名空间的使用

为了简化命名空间的使用,可以使用using关键字来声明在命名空间中的特定成员。例如:

// 使用mynamespace中的myVariable
using mynamespace::myVariable;int main() {myVariable = 42; // 不需要指定命名空间return 0;
}

6.案例分析

函数重载

#include <iostream>// 函数重载:处理整数
int add(int a, int b) {return a + b;
}// 函数重载:处理双精度浮点数
double add(double a, double b) {return a + b;
}int main() {int intResult = add(5, 7);double doubleResult = add(3.5, 2.7);std::cout << "Integer Result: " << intResult << std::endl;std::cout << "Double Result: " << doubleResult << std::endl;return 0;
}

运行结果:
在这里插入图片描述

递归函数

#include <iostream>int fibonacci(int n) {if (n <= 1) {return n;}return fibonacci(n - 1) + fibonacci(n - 2);
}int main() {int n = 10;for (int i = 0; i < n; ++i) {std::cout << fibonacci(i) << " ";}return 0;
}

运行结果:
在这里插入图片描述

Lambda表达式

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> numbers = {5, 2, 8, 1, 3};// 使用Lambda表达式对向量进行排序std::sort(numbers.begin(), numbers.end(), [](int a, int b) {return a < b;});// 使用Lambda表达式筛选出偶数auto isEven = [](int x) { return x % 2 == 0; };std::vector<int> evenNumbers;std::copy_if(numbers.begin(), numbers.end(), std::back_inserter(evenNumbers), isEven);// 输出排序后的向量std::cout << "Sorted Numbers: ";for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl;// 输出筛选后的偶数std::cout << "Even Numbers: ";for (int num : evenNumbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

运行结果:
在这里插入图片描述

字符串处理

#include <iostream>
#include <string>
#include <algorithm>int main() {std::string str = "Hello, World!";// 反转字符串std::reverse(str.begin(), str.end());std::cout << "Reversed String: " << str << std::endl;// 查找子字符串std::string subStr = "World";size_t found = str.find(subStr);if (found != std::string::npos) {std::cout << "Substring found at position: " << found << std::endl;} else {std::cout << "Substring not found." << std::endl;}// 将字符串拆分为单词std::string sentence = "This is a sample sentence";size_t startPos = 0;while (startPos < sentence.length()) {size_t spacePos = sentence.find(' ', startPos);if (spacePos == std::string::npos) {spacePos = sentence.length();}std::string word = sentence.substr(startPos, spacePos - startPos);std::cout << "Word: " << word << std::endl;startPos = spacePos + 1;}return 0;
}

运行结果:
在这里插入图片描述

容器操作

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>int main() {// 使用std::vector进行容器操作std::vector<int> numbers = {5, 2, 8, 1, 3};// 添加元素numbers.push_back(7);// 删除元素numbers.erase(std::remove(numbers.begin(), numbers.end(), 3), numbers.end());// 对容器排序std::sort(numbers.begin(), numbers.end());// 输出容器元素std::cout << "Vector Elements: ";for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl;// 使用std::map进行容器操作std::map<std::string, int> scores;// 添加键值对scores["Alice"] = 95;scores["Bob"] = 87;scores["Charlie"] = 92;// 查找元素std::string name = "Bob";if (scores.find(name) != scores.end()) {std::cout << name << "'s Score: " << scores[name] << std::endl;} else {std::cout << "Name not found." << std::endl;}return 0;
}

运行结果:
在这里插入图片描述

多线程和并发

#include <iostream>
#include <thread>
#include <vector>// 用于计算部分数组总和的函数
void partialSum(const std::vector<int>& arr, size_t start, size_t end, int& result) {result = 0;for (size_t i = start; i < end; ++i) {result += arr[i];}
}int main() {const int numThreads = 4; // 使用4个线程const int arrSize = 1000;std::vector<int> numbers(arrSize, 1); // 创建一个包含1000个1的数组std::vector<std::thread> threads(numThreads);std::vector<int> partialResults(numThreads);// 创建并启动线程for (int i = 0; i < numThreads; ++i) {size_t start = i * (arrSize / numThreads);size_t end = (i == numThreads - 1) ? arrSize : (i + 1) * (arrSize / numThreads);threads[i] = std::thread(partialSum, std::ref(numbers), start, end, std::ref(partialResults[i]));}// 等待所有线程完成for (int i = 0; i < numThreads; ++i) {threads[i].join();}// 计算总和int totalSum = 0;for (int i = 0; i < numThreads; ++i) {totalSum += partialResults[i];}std::cout << "Total Sum: " << totalSum << std::endl;return 0;
}

运行结果:
在这里插入图片描述

相关文章:

十四天学会C++之第二天(函数和库)

1. 函数的定义和调用 在C中&#xff0c;函数是组织和结构化代码的关键工具之一。它们允许您将一段代码封装成一个可重复使用的模块&#xff0c;这有助于提高代码的可读性和维护性。 为什么使用函数&#xff1f; 函数在编程中的作用不可小觑。它们有以下几个重要用途&#xf…...

蓝桥杯每日一题2023.10.3

杨辉三角形 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 40分写法&#xff1a; 可以自己手动构造一个杨辉三角&#xff0c;然后进行循环&#xff0c;用cnt记录下循环数的个数&#xff0c;看哪个数与要找的数一样&#xff0c;输出cnt #include<bits/stdc.h> using na…...

JavaScript系列从入门到精通系列第十二篇:JavaScript中对象的简介和对象的基本操作以及JavaScript中的属性值和属性名

文章目录 前言 一&#xff1a;对象分类 1&#xff1a;内建对象 2&#xff1a;宿主对象 3&#xff1a;自建对象 二&#xff1a;对象的基本操作 1&#xff1a;创建对象 2&#xff1a;向对象中添加属性 3&#xff1a;读取对象中的属性 4&#xff1a;修改对象中的属性 三…...

OpenCV实现视频的追踪(meanshift、Camshift)

目录 1&#xff0c;meanshift 1.1 算法流程 1.2 算法实现 1.3 代码实现 1.4 结果展示 1&#xff0c;meanshift 1.1 算法流程 1.2 算法实现 1.3 代码实现 import numpy as np import cv2 as cv# 读取视频 cap cv.VideoCapture(video.mp4)# 检查视频是否成功打开 if n…...

并查集详解(原理+代码实现+应用)

文章目录 1. 并查集概念2. 并查集原理2.1 合并2.1 找根 3. 并查集实现3.1 结构定义3.2 FindRoot&#xff08;找根&#xff09;3.3 Union&#xff08;合并&#xff09;3.4 IsInSet&#xff08;判断两个值是否在一个集合里&#xff09;3.5 SetCount&#xff08;并查集中集合个数&…...

第k小的数

补充习题: 第k小的数 问题描述 有两个正整数数列,元素个数分别为 N N N和 M M M.从两个数列中分别任取一个数相乘,这样一共可以得到 N M N\times M NM个数,询问这 N M N\times M NM个数中第 K K K小的数是多少. 数据范围: N , M < 200000 , K < 2.1 ∗ 1 0 10 , …...

基于electron25+vite4创建多窗口|vue3+electron25新开模态窗体

在写这篇文章的时候&#xff0c;查看了下electron最新稳定版本由几天前24.4.0升级到了25了&#xff0c;不得不说electron团队迭代速度之快&#xff01; 前几天有分享一篇electron24整合vite4全家桶技术构建桌面端vue3应用示例程序。 https://www.cnblogs.com/xiaoyan2017/p/17…...

红米手机 导出 通讯录 到电脑保存

不要搞什么 云服务 不要安装什么 手机助手 不要安装 什么app 用 usb 线 连接 手机 和 电脑 手机上会跳出 提示 选择 仅传输文件 会出现下面的 一个 盘 进入 MIUI目录 然后进入 此电脑\Redmi Note 5\内部存储设备\MIUI\backup\AllBackup\20230927_043337 如何没有上面的文件&a…...

常见web信息泄露

一、源码(备份文件)泄露 1、git泄露 Git是一个开源的分布式版本控制系统&#xff0c;在执行git init初始化目录的时候&#xff0c;会在当前目录下自动创建一个.git目录&#xff0c;用来记录代码的变更记录等。发布代码的时候&#xff0c;如果没有把.git这个目录删除&#xff…...

找不到VCRUNTIME140_1.dll怎么办,VCRUNTIME140_1.dll丢失的5个解决方法

在当今的数字时代&#xff0c;我们的生活和工作都离不开电脑。然而&#xff0c;随着科技的发展&#xff0c;我们也会遇到各种各样的问题。其中&#xff0c;VCRUNTIME140_1.dll丢失的问题是许多人都会遇到的困扰。这个问题可能会导致许多应用程序无法正常运行&#xff0c;给我们…...

C#生成自定义海报

安装包 SixLabors.ImageSharp.Drawing 2.0 需要的字体&#xff1a;宋体和微软雅黑 商用的需要授权如果商业使用可以使用方正书宋、方正黑体&#xff0c;他们可以免费商用 方正官网 代码 using SixLabors.Fonts; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Draw…...

BP神经网络的MATLAB实现(含源代码)

BP(back propagation)神经网络是1986年由Rumelhart和McClelland为首的科学家提出的概念&#xff0c;是一种按照误差逆向传播算法训练的多层前馈神经网络&#xff0c;是应用最广泛的神经网络模型之一 具体数学推导以及原理在本文不做详细介绍&#xff0c;本文将使用MATLAB进行B…...

AES和Rijndael的区别

快速链接: . 👉👉👉 个人博客笔记导读目录(全部) 👈👈👈 付费专栏-付费课程 【购买须知】:密码学实践强化训练–【目录】 👈👈👈“Rijndael” 这个词的中文谐音可以近似地发音为 “瑞恩达尔”。请注意,这只是一种近似的发音方式,因为该词是荷兰姓氏 “Ri…...

【数据结构】—堆详解(手把手带你用C语言实现)

食用指南&#xff1a;本文在有C基础的情况下食用更佳 &#x1f525;这就不得不推荐此专栏了&#xff1a;C语言 ♈️今日夜电波&#xff1a;水星—今泉愛夏 1:10 ━━━━━━️&#x1f49f;──────── 4:23 …...

关于算法复杂度的几张表

算法在改进今天的计算机与古代的计算机的区别 去除冗余 数据点 算法复杂度 傅里叶变换...

蓝桥杯每日一题2023.10.1

路径 - 蓝桥云课 (lanqiao.cn) 题目分析 求最短路问题&#xff0c;有多种解法&#xff0c;下面介绍两种蓝桥杯最常用到的两种解法 方法一 Floyd&#xff08;求任意两点之间的最短路&#xff09;注&#xff1a;不能有负权回路 初始化每个点到每个点的距离都为0x3f这样才能对…...

第三章:最新版零基础学习 PYTHON 教程(第十节 - Python 运算符—Python 中的运算符重载)

运算符重载意味着赋予超出其预定义操作含义的扩展含义。例如,运算符 + 用于添加两个整数以及连接两个字符串和合并两个列表。这是可以实现的,因为“+”运算符被 int 类和 str 类重载。您可能已经注意到,相同的内置运算符或函数对于不同类的对象显示不同的行为,这称为运算符…...

Nacos 实现服务平滑上下线(Ribbon 和 LB)

前言 不知道各位在使用 SpringCloud Gateway Nacos的时候有没有遇到过服务刚上线偶尔会出现一段时间的503 Service Unavailable&#xff0c;或者服务下线后&#xff0c;下线服务仍然被调用的问题。而以上问题都是由于Ribbon或者LoadBalancer的默认处理策略有关&#xff0c;其…...

c/c++里 对 共用体 union 的内存分配

对union 的内存分配&#xff0c;是按照最大的那个成员分配的。 谢谢...

博途SCL区间搜索指令(判断某个数属于某个区间)

S型速度曲线行车位置控制,停靠位置搜索功能会用到区间搜索指令,下面我们详细介绍区间搜索指令的相关应用。 S型加减速行车位置控制(支持点动和停车位置搜索)-CSDN博客S型加减速位置控制详细算法和应用场景介绍,请查看下面文章博客。本篇文章不再赘述,这里主要介绍点动动和…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...