十四天学会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;
}

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

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

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

相关文章

ASUS华硕飞行堡垒5笔记本FX504GM_FX80GM原装出厂Windows10系统

系统自带所有驱动、出厂主题壁纸、系统属性华硕专属LOGO标志、Office办公软件、MyASUS华硕电脑管家等预装程序 下载链接&#xff1a;https://pan.baidu.com/s/1C8vPvqiwqoUY3PxC915LXg?pwdv079

基于被囊群优化的BP神经网络(分类应用) - 附代码

基于被囊群优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于被囊群优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.被囊群优化BP神经网络3.1 BP神经网络参数设置3.2 被囊群算法应用 4.测试结果&#x…

小白自己​制作一个苹果.ios安卓.apk文件app应用手机下载的代码合并文件一码双端的落地页面详细教程

小白自己制作一个苹果.ios安卓.apk文件app应用手机下载的代码落地页面详细教程 图片取自这里哈 我们在这篇文章中教你如何制作一个手机下载引导落地页。这个落地页将可以自动识别访问者使用的是安卓还是苹果设备&#xff0c;并引导下载相应的应用程序。让我们按照以下步骤一…

Selenium 浏览器坐标转桌面坐标

背景&#xff1a; 做图表自动化项目需要做拖拽操作&#xff0c;但是selenium提供的拖拽API无效&#xff0c;因此借用pyautogui实现拖拽&#xff0c;但是pyautogui的拖拽是基于Windows桌面坐标实现的&#xff0c;另外浏览器中的坐标与windows桌面坐标并不是一比一对应的关系&am…

【计算机组成原理】考研真题攻克与重点知识点剖析 - 第 1 篇:计算机系统概述

前言 本文基础知识部分来自于b站&#xff1a;分享笔记的好人儿的思维导图&#xff0c;感谢大佬的开源精神&#xff0c;习题来自老师划的重点以及考研真题。此前我尝试了完全使用Python或是结合大语言模型对考研真题进行数据清洗与可视化分析&#xff0c;本人技术有限&#xff…

基于SpringBoot+MyBatis实现的个人博客系统(一)

这篇主要讲解一下如何基于SpringBoot和MyBatis技术实现一个简易的博客系统(前端页面主要是利用CSS,HTML进行布局书写),前端的静态页面代码可以直接复制粘贴,后端的接口以及前端发送的Ajax请求需要自己书写. 博客系统需要完成的接口: 注册登录博客列表页展示博客详情页展示发布博…

如何在 Google Earth 中创建轨迹、路线并制作动画

如何创建航迹 https://kurviger.de/en Google 地球飞行教程(天桥动画) 选择合适的点 &#xff08;可调整视图快照&#xff09;点击录制&#xff0c;依次点击图标即可

WebSocket实战之六心跳重连机制

一、前言 WebSocket应用部署到生产环境&#xff0c;我们除了会碰到因为经过代理服务器无法连接的问题&#xff08;注&#xff1a;该问题可以通过搭建WSS来解决&#xff0c;具体配置请看 WebSocket实战之四WSS配置 &#xff09;&#xff0c;另外一个问题就是外网环境不稳定经常…

基于SSM的餐厅点菜管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

使用Visual Studio调试排查Windows系统程序audiodg.exe频繁弹出报错

VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&#xff09;https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&a…

lv7 嵌入式开发-网络编程开发 03 TCP/IP与五层体系结构

目录 1 TCP/IP协议族体系结构 1.1 OSI与TCP/IP 1.2 TCP/IP 的体系结构 1.3 TCP/IP 体系结构的另一种表示方法 1.4 沙漏计时器形状的 TCP/IP 协议族 2 五层协议的体系结构 2.1 各层的主要功能 2.2 互联网中客户-服务器工作方式 2.3 同时为多个客户进程提供服务 3 练…

vertx的学习总结三

一、event bus是什么 各个verticle的通信 二、point-to-point, request-reply, publish/subscribe 通过 the event bus 例题一&#xff1a;点对点 package eventBus;import io.vertx.core.AbstractVerticle; import io.vertx.core.Vertx;public class EventBusExample exte…

Go-Python-Java-C-LeetCode高分解法-第八周合集

前言 本题解Go语言部分基于 LeetCode-Go 其他部分基于本人实践学习 个人题解GitHub连接&#xff1a;LeetCode-Go-Python-Java-C 欢迎订阅CSDN专栏&#xff0c;每日一题&#xff0c;和博主一起进步 LeetCode专栏 我搜集到了50道精选题&#xff0c;适合速成概览大部分常用算法 突…

快速选择排序

"你经过我每个灿烂时刻&#xff0c;我才真正学会如你般自由" 前些天有些无聊&#xff0c;想试试自己写的快排能否过leetcode上的排序算法题。结果是&#xff0c;不用截图可想而知&#xff0c;肯定是没过的&#xff0c;否则也不会有这篇文章的产出。 这份快排算法代码…

“链圈”十年反思

2013 年 11 月&#xff0c;Vitalik Buterin 发表了以太坊白皮书的第一个版本。事后人们经常把这视为“区块链 2.0” 时代开启的标志&#xff0c;但在当时&#xff0c;其实是以太坊的出现才使得“区块链”作为一项单独的技术从“数字货币”当中分离出来。换句话说&#xff0c;比…

软件工程与计算总结(一)软件工程基础

国庆快乐&#xff0c;今天开始更新《软件工程与计算&#xff08;卷二&#xff09;》的重要知识点内容~ 一.软件 1.软件独立于硬件 早期的软件是为了计算机硬件在研究型项目中而开发制造的&#xff0c;人们使用专门针对于硬件的指令码和汇编语言编写&#xff0c;这也是最早软件…

c++-vector

文章目录 前言一、vector介绍二、vector使用1、构造函数2、vector 元素访问3、vector iterator 的使用4、vector 空间增长问题5、vector 增删查改6、理解vector<vector< int >>7、电话号码的字母组合练习题 三、模拟实现vector1、查看STL库源码中怎样实现的vector2…

Leetcode.965 单值二叉树

本专栏内容为&#xff1a;leetcode刷题专栏&#xff0c;记录了leetcode热门题目以及重难点题目的详细记录 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;八大排序汇总 &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &…

Page Cache难以回收产生之直接内存回收引起 load 飙高或者业务时延抖动

相信你在平时的工作中&#xff0c;应该会或多或少遇到过这些情形&#xff1a;系统很卡顿&#xff0c;敲命令响应非常慢&#xff1b;应用程序的 RT 变得很高&#xff0c;或者抖动得很厉害。在发生这些问题时&#xff0c;很有可能也伴随着系统 load 飙得很高。 据我观察&#xf…

Android逆向学习(五)app进行动态调试

Android逆向学习&#xff08;五&#xff09;app进行动态调试 一、写在前面 非常抱歉鸽了那么久&#xff0c;前一段时间一直在忙&#xff0c;现在终于结束了&#xff0c;可以继续更新android逆向系列的&#xff0c;这个系列我会尽力做下去&#xff0c;然后如果可以的话我看看能…