十四天学会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
函数被调用来计算 num1
和 num2
的和,并将结果存储在 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;
}
在上面的示例中,add
和 divide
函数返回整数和浮点数,分别被存储在 sum
和 quotient
变量中。
返回值在表达式中的应用
函数的返回值可以直接用作表达式的一部分。这使得函数调用非常灵活,可以在数学表达式或其他计算中使用。
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中,函数是组织和结构化代码的关键工具之一。它们允许您将一段代码封装成一个可重复使用的模块,这有助于提高代码的可读性和维护性。 为什么使用函数? 函数在编程中的作用不可小觑。它们有以下几个重要用途…...
蓝桥杯每日一题2023.10.3
杨辉三角形 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 40分写法: 可以自己手动构造一个杨辉三角,然后进行循环,用cnt记录下循环数的个数,看哪个数与要找的数一样,输出cnt #include<bits/stdc.h> using na…...
JavaScript系列从入门到精通系列第十二篇:JavaScript中对象的简介和对象的基本操作以及JavaScript中的属性值和属性名
文章目录 前言 一:对象分类 1:内建对象 2:宿主对象 3:自建对象 二:对象的基本操作 1:创建对象 2:向对象中添加属性 3:读取对象中的属性 4:修改对象中的属性 三…...
OpenCV实现视频的追踪(meanshift、Camshift)
目录 1,meanshift 1.1 算法流程 1.2 算法实现 1.3 代码实现 1.4 结果展示 1,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(找根)3.3 Union(合并)3.4 IsInSet(判断两个值是否在一个集合里)3.5 SetCount(并查集中集合个数&…...
第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新开模态窗体
在写这篇文章的时候,查看了下electron最新稳定版本由几天前24.4.0升级到了25了,不得不说electron团队迭代速度之快! 前几天有分享一篇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是一个开源的分布式版本控制系统,在执行git init初始化目录的时候,会在当前目录下自动创建一个.git目录,用来记录代码的变更记录等。发布代码的时候,如果没有把.git这个目录删除ÿ…...
找不到VCRUNTIME140_1.dll怎么办,VCRUNTIME140_1.dll丢失的5个解决方法
在当今的数字时代,我们的生活和工作都离不开电脑。然而,随着科技的发展,我们也会遇到各种各样的问题。其中,VCRUNTIME140_1.dll丢失的问题是许多人都会遇到的困扰。这个问题可能会导致许多应用程序无法正常运行,给我们…...
C#生成自定义海报
安装包 SixLabors.ImageSharp.Drawing 2.0 需要的字体:宋体和微软雅黑 商用的需要授权如果商业使用可以使用方正书宋、方正黑体,他们可以免费商用 方正官网 代码 using SixLabors.Fonts; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Draw…...
BP神经网络的MATLAB实现(含源代码)
BP(back propagation)神经网络是1986年由Rumelhart和McClelland为首的科学家提出的概念,是一种按照误差逆向传播算法训练的多层前馈神经网络,是应用最广泛的神经网络模型之一 具体数学推导以及原理在本文不做详细介绍,本文将使用MATLAB进行B…...
AES和Rijndael的区别
快速链接: . 👉👉👉 个人博客笔记导读目录(全部) 👈👈👈 付费专栏-付费课程 【购买须知】:密码学实践强化训练–【目录】 👈👈👈“Rijndael” 这个词的中文谐音可以近似地发音为 “瑞恩达尔”。请注意,这只是一种近似的发音方式,因为该词是荷兰姓氏 “Ri…...
【数据结构】—堆详解(手把手带你用C语言实现)
食用指南:本文在有C基础的情况下食用更佳 🔥这就不得不推荐此专栏了:C语言 ♈️今日夜电波:水星—今泉愛夏 1:10 ━━━━━━️💟──────── 4:23 …...
关于算法复杂度的几张表
算法在改进今天的计算机与古代的计算机的区别 去除冗余 数据点 算法复杂度 傅里叶变换...
蓝桥杯每日一题2023.10.1
路径 - 蓝桥云课 (lanqiao.cn) 题目分析 求最短路问题,有多种解法,下面介绍两种蓝桥杯最常用到的两种解法 方法一 Floyd(求任意两点之间的最短路)注:不能有负权回路 初始化每个点到每个点的距离都为0x3f这样才能对…...
第三章:最新版零基础学习 PYTHON 教程(第十节 - Python 运算符—Python 中的运算符重载)
运算符重载意味着赋予超出其预定义操作含义的扩展含义。例如,运算符 + 用于添加两个整数以及连接两个字符串和合并两个列表。这是可以实现的,因为“+”运算符被 int 类和 str 类重载。您可能已经注意到,相同的内置运算符或函数对于不同类的对象显示不同的行为,这称为运算符…...
Nacos 实现服务平滑上下线(Ribbon 和 LB)
前言 不知道各位在使用 SpringCloud Gateway Nacos的时候有没有遇到过服务刚上线偶尔会出现一段时间的503 Service Unavailable,或者服务下线后,下线服务仍然被调用的问题。而以上问题都是由于Ribbon或者LoadBalancer的默认处理策略有关,其…...
c/c++里 对 共用体 union 的内存分配
对union 的内存分配,是按照最大的那个成员分配的。 谢谢...
博途SCL区间搜索指令(判断某个数属于某个区间)
S型速度曲线行车位置控制,停靠位置搜索功能会用到区间搜索指令,下面我们详细介绍区间搜索指令的相关应用。 S型加减速行车位置控制(支持点动和停车位置搜索)-CSDN博客S型加减速位置控制详细算法和应用场景介绍,请查看下面文章博客。本篇文章不再赘述,这里主要介绍点动动和…...
(三)激光线扫描-中心线提取
光条纹中心提取算法是决定线结构光三维重建精度以及光条纹轮廓定位准确性的重要因素。 1. 光条的高斯分布 激光线条和打手电筒一样,中间最亮,越像周围延申,光强越弱,这个规则符合高斯分布,如下图。 2. 传统光条纹中心提取算法 传统的光条纹中心提取算法有 灰度重心法、…...
递归与分治算法(1)--经典递归、分治问题
目录 一、递归问题 1、斐波那契数列 2、汉诺塔问题 3、全排列问题 4、整数划分问题 二、递归式求解 1、代入法 2、递归树法 3、主定理法 三、 分治问题 1、二分搜索 2、大整数乘法 一、递归问题 1、斐波那契数列 斐波那契数列不用过多介绍,斐波那契提出…...
Java之SpringCloud Alibaba【六】【Alibaba微服务分布式事务组件—Seata】
一、事务简介 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。 在关系数据库中,一个事务由一组SQL语句组成。 事务应该具有4个属性: 原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。 原子性(atomicity) ∶个事务…...
Android逆向学习(五)app进行动态调试
Android逆向学习(五)app进行动态调试 一、写在前面 非常抱歉鸽了那么久,前一段时间一直在忙,现在终于结束了,可以继续更新android逆向系列的,这个系列我会尽力做下去,然后如果可以的话我看看能…...
音频编辑软件Steinberg SpectraLayers Pro mac中文软件介绍
Steinberg SpectraLayers Pro mac是一款专业的音频编辑软件,旨在帮助音频专业人士进行精细的音频编辑和声音处理。它提供了强大的频谱编辑功能,可以对音频文件进行深入的频谱分析和编辑。 Steinberg SpectraLayers Pro mac软件特点 1. 频谱编辑ÿ…...
基于.Net Core实现自定义皮肤WidForm窗口
前言 今天一起来实现基于.Net Core、Windows Form实现自定义窗口皮肤,并实现窗口移动功能。 素材 准备素材:边框、标题栏、关闭按钮图标。 窗体设计 1、创建Window窗体项目 2、窗体设计 拖拉4个Panel控件,分别用于:标题栏、关…...
【Rust】操作日期与时间
目录 介绍 一、计算耗时 二、时间加减法 三、时区转换 四、年月日时分秒 五、时间格式化 介绍 Rust的时间操作主要用到chrono库,接下来我将简单选一些常用的操作进行介绍,如果想了解更多细节,请查看官方文档。 官方文档:chr…...
blender快捷键
1, shift a 添加物体 2,ctrl alt q 切换四格视图 3, ~ 展示物体的各个视图按钮,(~ 就是tab键上面的键) 4,a 全选,全选后,点 ctrl 鼠标框选 减去已经选择的;…...
java Spring Boot 自动启动热部署 (别再改点东西就要重启啦)
上文 java Spring Boot 手动启动热部署 我们实现了一个手动热部署的代码 但其实很多人会觉得 这叫说明热开发呀 这么捞 写完还要手动去点一下 很不友好 其实我们开发人员肯定是希望重启这种事不需要自己手动去做 那么 当然可以 我们就让它自己去做 Build Project 这个操作 我们…...
TouchGFX之后端通信
在大多数应用中,UI需以某种方式连接到系统的其余部分,并发送和接收数据。 它可能会与硬件外设(传感器数据、模数转换和串行通信等)或其他软件模块进行交互通讯。 Model类 所有TouchGFX应用都有Model类,Model类除了存…...
三级 做爰免费网站/优化科技
写在前面的话 通过上一节,知道了 K8S 有 Master / Node 组成,但是具体怎么个组成法,就是这一节具体谈的内容。概念性的东西我们会尽量以实验的形式将其复现。 部署 K8S 集群 互联网常用的 K8S 集群部署方式: 1. kubeadm࿰…...
opencms wordpress/宁波seo公司哪家好
阅读原文:技术面试中的软技能 作为求职者时,只听别人说如何面试,按部就班的做,没有特别的体会。如今作为面试官,面试别人时,才发现什么才是重要的事情。 形象 形象包括衣着发型和五官。衣着不必太正式&…...
网站开发的全套软件/卡点视频免费制作软件
McBSP包括一个数据通道和一个控制通道,通过7个引脚与外部设备连接。数据发送引脚DX负责数据的发送,数据接收引脚DR负责数据的接收,发送时钟引脚CLKX,接收时钟引脚CLKR,发送帧同步引脚FSX和接收帧同步引脚FSR提供串行时…...
建网站怎么赚流量/河北网站seo外包
0x00 前言 上次的绕过太简单,也没有能注出数据或者获取权限,这次继续绕过,获取数据 0x01 过程 还是上次的站点,简单的判断,存在注入 发现and 数字、exec、union select、 select 数字。。。被过滤 发现execute函数没被…...
优质做网站价格/线上培训
Java基础语法 今日内容介绍 u 方法 第1章 方法 1.1 方法概述 在我们的日常生活中,方法可以理解为要做某件事情,而采取的解决办法。 如:小明同学在路边准备坐车来学校学习。这就面临着一件事情(坐车到学校这件事情)需要…...
网站开发总结性报告/网站制作教程视频
原文链接:http://www.javaarch.net/jiagoushi/699.htm 怎么重置mysql的自增列 1. 支持设置自增列的值ALTER TABLE table_name AUTO_INCREMENT 1; 不过这种方式自能设置大于当前使用的值,不能设置小于等于当前已经使用的自增列的值。myisam如果设置小于等…...