C++函数进阶(各种函数的运用)
- 函数知识简单描述
- 各种常见、常运用的函数总结
- 1. next_permutation - 需要头文件 algorithm
- 2. 取整函数 - 需要头文件 cmath
- 3. fill()填充函数 - 需要头文件 algorithm
- 4. memset()赋初值函数 - 需要头文件 string.h
- memset()和fill()函数对比
- 5. lower_bound() 和 upper_bound() 函数 - 需头文件 algorithm
- 6. int stoi()函数 - 需要头文件 cstring
- 7. int atoi()函数 - 需要头文件 cstring
- 8. memcpy()函数 - 需要头文件 cstring
- 9. string to_string()函数 - 需要头文件 iostream
- 10. stringstream函数
- 11. resize()和reserve()函数 - 需要头文件 algorithm
- 12. scanf()函数 - 需要头文件 stdio.h
- 13. sprintf()函数 - 需要头文件 stdio.h
- 14. vector中的自定义sort排序函数 - 需要头文件 vector
- 15. 读入控制台输入字符串时含有的空格
函数知识简单描述
这里说以下C++的一些函数知识,给大家巩固下。
- 常规函数:调用时,跳转到标记函数起点的内存单元,然后执行函数代码,执行完后跳回到地址被保存的命令处。来回跳跃并记录跳跃位置是需要一定开销的
- 内联函数:直接用函数代码替换了函数调用(当内联函数里面包含的代码过多的话与常规函数基本无异)
- const运用:用&引用时,想让对变量的修改操作不生效,即只读,那么用const修饰即可,在函数中常用来作为“拷贝构造”(如下面代码)
String(const String & str); //拷贝构造
//常用拷贝构造的场景:
//1、当类的对象被初始化为同一类的另一个对象时
//2、当对象被作为参数传递给一个函数时
//3、当函数返回一个对象时
- 函数默认参数:某个参数提供默认值时,该参数右边其他的参数即使没赋值,都会默认为与该参数的值相同
记住一点:参数赋值应该从右边的参数开始 - 函数重载:如果调用函数时函数参数不完全匹配,就会进行强制类型转换后再匹配
各种常见、常运用的函数总结
1. next_permutation - 需要头文件 algorithm
用法:next_permutation(序列起始地址,序列结束地址)
功能:按序列,生成下一个比当前序列大的序列
正确用法如下举例
int a[10]={1,2,3};
do{
cout << a[0] << a[1] << a[2];
}while(next_permutation(a,a+3));
// Output:
// 1 2 3 2 1 3 3 1 2
// 1 3 2 2 3 1 3 2 1
2. 取整函数 - 需要头文件 cmath
ceil():向上取整 floor():向下取整
注意下负数时候的取整情况
正确用法如下举例
int a = 10.5, b = -10.5;
ceil(a); // Output:11
floor(a); // Output:10
ceil(b); // Output:-10
floor(b); // Output:-11
3. fill()填充函数 - 需要头文件 algorithm
用法:fill(起始地址,结束地址,填充值)
注意:用new创建的数组,不能用fill填充(因为new出来的数组内存不一定是连续的)
正确用法如下举例
//对一维数组填充:
fill(array,array+4,5); // Output:array[0] = array[1] = array[2] = array[3] = 5
//对二维数组填充:
int G[6][4]; //fill()填充只能用于静态数组
fill(G[0],G[0]+6*4,520);
4. memset()赋初值函数 - 需要头文件 string.h
详解见:教你学会memset()函数
用法:memset(指针或者数组,赋值,指针或数组的长度)
注意:memset对非字符型数组赋初值是不可取的,它方便清空一个结构类型的变量或数组,常用于内存空间初始化
正确用法如下举例
char buffer[] = "Hello world\n";
memset(buffer, '*', sizeof(buffer));
memset()和fill()函数对比
memset是对字节进行操作,所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值;fill原理是把那一块单元赋成指定的值,也就是说任何值都可以。
5. lower_bound() 和 upper_bound() 函数 - 需头文件 algorithm
注意下面范围的区间括号
lower_bound(起始地址,结束地址,val): 用来寻找在数组或容器的[first,last)范围内第一个值大于等于val元素的位置
upper_bound(first,last,val) :用来寻找在数组或容器的[first,last)范围内第一个值大于val元素的位置
如果是数组,返回该位置的指针;若果是容器,返回该位置的迭代器
6. int stoi()函数 - 需要头文件 cstring
用法:int stoi(const string*)
功能:字符处理函数,用于把字符串转换成int输出。
stoi()会做范围检查,默认范围是在int的范围内的,超出范围发生runtime error
7. int atoi()函数 - 需要头文件 cstring
用法:int atoi(const char*)
功能:字符处理函数,用于把字符串转换成int输出,返回一个int类型的值
注意:该函数不会做范围检查,超出上界,则输出上界,超出下界,则输出下界
参数是一个const char*,因此想要处理string,需要使用string.c_str()作为参数,调用 c_str()的方法把这个string转换成 const char*类型
正确用法如下举例
//对于string类型的变量
string s4 = ‘abcd’;
cout << atoi(s4.c_str()) << endl;
8. memcpy()函数 - 需要头文件 cstring
用法:memcpy(destin,source,n)
功能:把source地址开始的n个值赋值给从destin地址开始的n个值
,与strcpy相比,memcpy并不是遇到’\0’就结束,而是一定会拷贝完n个字节,strcpy就只能拷贝字符串了,它遇到’\0’就结束拷贝
需要注意事项: 👉点这里
正确用法如下举例
//解释:将s中的字符串复制到字符数组d中、将s某个字符后的字符连续复制到d中、复制后覆盖原有部分数据
char * s = "Golden Global View";
char d[20];
memcpy(d,s+14,4); //从第14个字符(V)开始复制,连续复制4个字符(View)
9. string to_string()函数 - 需要头文件 iostream
用法:string to_string(int)
功能:输入一个int型参数,然后会把int转换成string类型来返回
注意:若传入的是单个字符,会先把它转换成int型(即字符的ascii码值),再转成string型
10. stringstream函数
功能:实现读取字符串里的数字,并可以任意类型的转换
详解:教你学会stringstream函数运用
11. resize()和reserve()函数 - 需要头文件 algorithm
快速理解打比方:正在建造的一辆公交车,车里面可以设置40个座椅(reserve(40);),这是它的容量,但并不是说它里面就有了40个座椅,只能说明这部车内部空间大小可以放得下40张座椅而已。而车里面安装了40个座椅resize(40),这个时候车里面才真正有了40个座椅,这些座椅就可以使用了
12. scanf()函数 - 需要头文件 stdio.h
用法:scanf(“格式化字符串”,参数)
**功能:**执行格式化输入
详解: 👉学会使用scanf()函数
格式化字符串:
%a 读入一个浮点值(仅C99有效) %A 同上
%c 读入一个字符
%d 读入十进制整数
%i 读入十进制,八进制,十六进制整数
%o 读入八进制整数
%x 读入十六进制整数
%X 同上
%c 读入一个字符
%s 读入一个字符串
%f 读入一个浮点数
%F 同上
%e 同上
%E 同上
%g 同上
%G 同上
%p 读入一个指针
%u 读入一个无符号十进制整数
%n 至此已读入值的等价字符数
%[] 扫描字符集合
%% 读%符号
13. sprintf()函数 - 需要头文件 stdio.h
用法:sprintf(char字符数组,“格式化字符串”,参数)
功能: 执行格式化的存储(即将当前数字格式化后存到 char 类型数组中),一般用于整数转成八进制、十六进制
格式化字符串:
%c 整数转成对应的 ASCII 码
%d 十进位输出
%o 整数转成八进位输出
%s 整数转成字符串
%x 整数转成小写十六进位
%X 整数转成大写十六进位
%% 输出百分比符号,不转换
正确用法如例题:👉点这里,代码使用如下
练习题:👉点这里,需要注意 char 在定义数组时一定要多开辟个空间给到 ‘\0’
#include <bits/stdc++.h>
using namespace std;
int n;
int main(){
cin >> n;
string str1 = "0469AD";
string str2 = "8B";
char tmp[20];
int a = 0, res = 0;
sprintf(tmp, "%X", n); //将 n 转为16进制存储到 tmp 中
for(int i = 0; tmp[i]; i++){
if(str1.find(tmp[i]) != string::npos) res += 1;
else if(str2.find(tmp[i]) != string::npos) res += 2;
}
cout << res << endl;
return 0;
}
14. vector中的自定义sort排序函数 - 需要头文件 vector
原理:采用快速排序(选择一个参照元素,按排序规则把每一个数组内的元素拿来和参照元素作比较,按排序规则,在前面的放前面,在后面的放后面)
用法:sort(vec.begin(), vec.end(), cmp) //自定义规则函数返回的一定是bool类型,cmp是自定义的排序规则
结合题目来理解:洛谷题源
该题的sort代码如下:
sort(vec.begin(), vec.end(),[](node &x,node &y ){
return (x.t*x.k==y.t*y.k && (x.t>y.t||(x.t==y.t&&x.pos<y.pos))) || x.t*x.k>y.t*y.k;}) x和y分别是两名志愿者,系统会给[]自动匹配为bool类型
15. 读入控制台输入字符串时含有的空格
我们会遇到这样的一个问题 “从控制台录入字符到字符数组或者字符串时,如何让空格也被录入?”,下面的方法要用到头文件 string.h
1. 对于录入的是string类型:
getline(cin,str) //将读入整行str中
2.对于字符数组
gets(a) //PAT比赛不让用gets()
cin.getline(a,10) //将一行的10个字符,包含‘\0’读入字符数组a中。
路漫漫其修远兮,吾将上下而求索