
🫧个人主页:小年糕是糕手
🎨你不能左右天气,但你可以改变心情;你不能改变过去,但你可以决定未来!
目录
[3°stoi / stol](#3°stoi / stol)
[4°stod / stof](#4°stod / stof)
前言
前面博客的习题量有点大,而且在中间可能涉及了一些函数,但是博客中并未提及,以至于写题目效率不高,这里为大家带来一期补充包,帮助大家更好的解题
一、输入输出函数
这里最基本的cin、cout、scanf、printf就不为大家过多介绍了,我们来看另一个比赛中常用的函数:getline()
1°getline
getline是 C++ 中用于读取整行字符串 的核心函数,专门解决cin >>读取字符串时 "遇到空格 / 换行就停止" 的问题,新手在处理带空格的输入(比如姓名、句子)时一定要会用。
这部分内容我们string中也会介绍,大家可以先了解一下,方便解题
cpp
#include <iostream>
#include <string> // 必须包含这个头文件!
using namespace std;
int main() {
string line; // 用string类型接收,不能用char数组
cout << "请输入一行文字(可以包含空格):" << endl;
getline(cin, line); // 核心:读取整行,直到按回车结束
cout << "你输入的内容是:" << line << endl;
return 0;
}

getline核心功能是读取带空格的整行字符串 ,需包含<string>头文件;- 避坑关键:
cin后接getline要先调用cin.ignore()清空回车;- 适用场景:读取姓名、句子、带空格的文本,而
cin >>适合读取单个数字 / 单词。
二、数学类函数
1°sqrt
函数sqrt(),头文件是#include<cmath>,他的作用求一个数(>=0)的算术平方根:
cpp
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int n = 4;
cout << sqrt(n) << endl;
int m = 0;
cout << sqrt(m) << endl;
return 0;
}

2°pow
函数pow(a,b)是求a的b次方的,头文件是#include<cmath>:
cpp
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int a = 2;
int b = 3;
cout << pow(2, 3) << endl;
return 0;
}

3°fmod
我们知道整数取模运算使用%,当时我们说的是小数不能取模其实是不对的,浮点数也可以取模,只不过有特定的函数fmod(x,y),头文件是#include<cmath>:
| 特性 | fmod(x, y) |
% 运算符 |
|---|---|---|
| 支持数据类型 | 浮点数(float/double/long double) | 仅整数(int/long 等) |
| 计算逻辑 | 返回 x - y × trunc(x/y)(保留小数部分) |
返回整数余数,要求操作数为整数 |
| 示例(x=5.5, y=2) | fmod(5.5, 2) = 1.5 |
5 % 2 = 1(5.5%2 报错) |
%只能算整数取余 ,写5.5 % 2会直接编译报错;fmod()能算浮点数取余,比如 5.5 除以 2,商是 2,余数是 1.5。
cpp
#include <iostream>
#include <cmath> // 必须包含这个头文件!
using namespace std;
int main() {
double x = 5.5, y = 2.0;
double result = fmod(x, y); // 计算5.5 % 2.0的余数
cout << "fmod(5.5, 2.0) = " << result << endl; // 输出1.5
// 更多示例
cout << "fmod(7.8, 3.1) = " << fmod(7.8, 3.1) << endl; // 输出1.6
cout << "fmod(-5.5, 2.0) = " << fmod(-5.5, 2.0) << endl; // 输出-1.5(符号与x一致)
cout << "fmod(5.5, -2.0) = " << fmod(5.5, -2.0) << endl; // 输出1.5(符号只看x)
return 0;
}

fmod(x, y)是浮点数取模函数,需包含<cmath>头文件;- 结果符号与被除数
x一致,除数y为 0 时返回NaN;- 核心优势:解决
%只能处理整数取模的问题,适用于浮点数余数计算。
4°abs和fabs
函数abs()和fabs()都是绝对值函数,abs是用来处理整数的,fabs是用来处理浮点数的,头文件是#include<camth>:
cpp
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int n1 = 4;
int m1 = -4;
double n2 = 7.2;
double m2 = -7.2;
cout << abs(n1) << " " << abs(m1) << endl;
cout << fabs(n2) << " " << fabs(m2) << endl;
return 0;
}

5°ceil和floor
函数ceil对一个浮点数向上取整,需要头文件#include<cmath>;
函数floor对一个浮点数向下取整,需要头文件#include<cmath>:
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
//ceil浮点数向上取整
cout << ceil(2.3) << endl;
cout << ceil(3.8) << endl;
cout << ceil(-2.3) << endl;
cout << ceil(-3.8) << endl;
//floor浮点数向下取整
cout << floor(2.3) << endl;
cout << floor(3.8) << endl;
cout << floor(-2.3) << endl;
cout << floor(-3.8) << endl;
return 0;
}

三、string
之前上一篇博客中的string类定义的成员函数都是,下面为大家额外补充几个:
1°append
函数原型如下:

append单词是追加的意思,下面我们来进行代码演示:
cpp
#include<iostream>
#include<string>
using namespace std;
int main()
{
//append
string s1("hello world");
//我们想要插入一个字符
cout << s1 << endl;
s1.push_back('%');
cout << s1 << endl;
//我们想要插入多个字符
s1.append("hello byte");
cout << s1 << endl;
//我想在后面插入10个#号
s1.append(10, '#');
cout << s1 << endl;
string s2(" hello apple!");
//假如我插入的时候不想要空格和! -- 可以采用给迭代区间
s2.append(++s2.begin(), --s2.end());
cout << s2 << endl;
return 0;
}

2°isspace
判断一个字符是不是「空白字符」
空白字符包括:
- 空格
' '→ ASCII 32- 换行
'\n'→ ASCII 10- 回车
'\r'→ ASCII 13- 制表符
'\t'→ tab 键- 垂直制表符、换页符(比赛基本不用)
一句话:只要是看不见的空白,isspace 都能识别!
这里需要注意的两点是:1)他必须包含头文件#include<cctype>;2)它只能判断「单个字符」,不能判断字符串!
cpp
isspace(' '); // ✅ 正确
isspace(" "); // ❌ 错误
返回值是什么?
- 是空白字符 → 返回 非 0 值(真)
- 不是空白字符 → 返回 0(假)
3°stoi / stol
stoi是将字符串转换成int类型的值stol是将字符串转换成long int类型的值这两个函数非常类似,这里以
stoi为例讲解一下这个函数的使用方式。
stoi函数其实可以将一个string类型的字符串,转化为整型,函数原型如下:
cppint stoi(const string& str, size_t* idx = 0, int base = 10); long stol(const string& str, size_t* idx = 0, int base = 10);stoi(字符串, &位置, 进制)
参数解读:
str表示被转换的string类型的字符串idx是一个输出型参数,也就是通过这个参数会带回一个值。idx是一个指针,需要在外边创建一个size_t类型的值,传递它的地址给idx,这个参数将会带回str中无法正确匹配数字的第一个字符的位置。base表示被解析的字符串中数字的进制值,可能是2,8,10,16或者0。
- 默认情况下这个值是
10,表示10进制数字- 如果传递的是
2,表示被解析的字符串中是2进制的数字,最终会转换成10进制- 如果传递的是
8,表示被解析的字符串中是8进制的数字,最终会转换成10进制- 如果传递的是
16,表示被解析的字符串中是16进制的数字,最终会转换成10进制- 如果传递的是
0,会根据字符串的内容的信息自动推导进制,比如:字符串中有0x,就认为是16进制,0开头会被认为是8进制,最终会转换成10进制。- 大家记住一点就是不管你base传的是几,最终都是要转换为10进制的数字
cpp
#include <iostream>
#include<string>
//stoi(字符串, &位置, 进制)
using namespace std;
int main()
{
string s = "11x22";
size_t pos = 0;
int ret = stoi(s, &pos);//默认认为s中的数字是10进制的
cout << ret << endl;
cout << pos << endl;
return 0;
}
我们首先来看上述的一串简单代码:我们定义的string类的字符串并且赋值"11x22",然后定义了size_t类型的pos,用int类型ret来接受stoi,我们取的字符串是s,位置是从0位置开始的,默认是10进制,我们取到x的时候发生了错误直接返回,此时ret就是11,发生错误的位置是x,所以pos返回2,这里需要注意的一点是如果大家不想用第二个参数,可以直接传个NULL或0
下面我们来看另一段代码,大家可以自行尝试去解决:
cpp
#include <iostream>
#include<string>
//stoi(字符串, &位置, 进制)
using namespace std;
int main()
{
size_t pos = 0;
string s1 = "11x34";
int ret1 = stoi(s1, &pos, 16);
cout << ret1 << endl;
cout << "pos:" << pos << endl;
string s2 = "11x34";
int ret2 = stoi(s2, &pos, 2);
cout << ret2 << endl;
cout << "pos:" << pos << endl;
string s3 = "0x11x34";
int ret3 = stoi(s3, &pos, 0);
cout << ret3 << endl;
cout << "pos:" << pos << endl;
return 0;
}
我们首先定义了一个size_t类型的pos,接着定义了string类型的s1,整型类型的ret1去接收stoi,我们认为s1中的是十六进制的,1,1都符合,但是x不符合,所以我们认为十六进制数字就是11,转换成十进制就是17,pos是第一次发生错误的位置所以就是2;下面又去定义s2,我们认为s2中的是二进制的,1,1都符合的但是x不符合,所以我们认为二进制的数字就是11,转换成十进制就是3,pos是第一次发生错误的位置,所以就是2;最后我们定义了s3,这次我们传入的是0,我们上面说过:如果传递的是 0,会根据字符串的内容的信息自动推导进制,比如:字符串中有 0x,就认为是 16 进制,0 开头会被认为是 8 进制,最终会转换成 10 进制,所以我们认为这串字符是十六进制的,从1开始看,与s1的结果是相同的,只是pos的位置在这里是4,下面我们来看打印结果是否符合我们上述的分析:
4°stod / stof
stod 是将字符串转换成 double 类型的值,函数原型如下,和 stoi 函数的比较的话,少了描述字符串中数字进制的参数,其他参数一致。stof 是将字符串转换成 float 类型的值
函数原型如下:
cpp
double stod(const string& str, size_t* idx = 0);
float stof(const string& str, size_t* idx = 0);
cpp
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s = "3.14abc234";
size_t pos;
double d = stod(s, &pos);
cout << d << endl;
cout << pos << endl;
return 0;
}
通过上面的stoi的学习这个stod相信大家一眼就看出结果了,这里需要注意的是,pos返回的是4,这个点也是占一个位置的,当然如果我们不想去传pos,可以直接传个NULL或者0
5°to_string
上面我们说的是将字符串变成整型或者浮点型,这里我们要说的就是将整型或者浮点型变成字符串,函数原型如下:
cpp
string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);
to_string函数可以将数字转换成字符串,从上述函数原型的角度看的话,可以将整型、浮点型的数字转换成字符串的,使用起来也非常简单
cpp
#include <iostream>
#include <string>
using namespace std;
int main()
{
string pi = "pi is " + to_string(3.14159);
cout << pi << endl;
return 0;
}
我们来看这串代码我们的预想打印"pi is 3.14159",这里使用string中的加,但是不可以直接+,所以这里我们采用to_string将其转换成字符串,下面我们来看打印结果:

这里需要注意的to_string默认是打印到小数点后六位的
四、拓展函数、
在C++编程中,尤其是算法竞赛和数学计算场景下,最大公约数(GCD) 、最小公倍数(LCM) 和 快速幂(qpow) 是三个非常基础且重要的工具。下面将详细解释它们的数学定义、实现原理、C++标准库支持以及手动实现方法,并给出代码示例和注意事项。
但是注意gcd和lcm比赛一般是不能用的,需要大家自己去写这个函数
1°最大公约数(GCD)

注意事项
当参数为负数时,
std::gcd返回非负结果(例如std::gcd(-12, 18) = 6)。如果两个参数都是 0,标准未定义(某些实现返回 0),建议避免使用 gcd(0,0)。
手动实现时建议处理负数(取绝对值)。

下面举个例子:
cpp
#include <numeric>
#include<iostream>
using namespace std;
int main()
{
int ret = gcd(12, 18);
cout << ret << endl; //6
return 0;
}
2°最小公倍数(LCM)

实现注意
防止溢出 :直接计算
a * b可能溢出,因此推荐先除后乘:
(a / gcd(a, b)) * b或a / gcd(a, b) * b(需保证整除)。处理零的情况:通常认为任何数与 0 的 lcm 为 0(因为 0 是任何非零数的倍数?实际上数学上 lcm(0, a) 没有定义,但 C++17 标准库将其定义为 0)。
3°快速幂(qpow)
qpow 到底是干啥的?
一句话:qpow = 快速算 a 的 b 次方,并且对一个数取模!
cpp
long long qpow(a, b, mod);
//求(a的b次方)对mod取模的结果

cpp
#include <iostream> // 只有这个是为了 cout
using namespace std;
// ======================
// qpow 快速幂(手写函数,无任何头文件)
// ======================
long long qpow(long long a, long long b, long long mod) {
long long res = 1;
a = a % mod;
while (b > 0) {
if (b & 1)
res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int main() {
// 计算 2^3 % 100 = 8
cout << qpow(2, 3, 100) << endl;
return 0;
}

