函数
LiRewriter · · 个人记录
嗯...高一讲义
捎带测试一下博客好了qwq
函数的定义
回想一下高中书上对函数的定义
设
A ,B 是非空的数集,如果按照某种确定的对应关系f ,使对于集合A 中的任意一个数x ,在集合B 中都有唯一确定的数y 和它对应,那么就称映射f: A \rightarrow B 为从集合A 到集合B 的一个函数。
由于OI不涉及比较复杂的语言知识,我们避开匿名函数的问题不谈。
现在我们对这个定义进行一些拓展
由于程序不知道你的集合是数集点集还是人集狗集,所以我们必须为编译姬指明返回类型。下面列出了一些常用的返回类型。
-
void型
-
基本类型/STL已经有的类
-
指针
-
自定义类型(结构体/联合体/类)
void是空类型,这意味着你不需要返回任何东西,只需要执行即可。一个典型的例子是初始化:
void init(){
memset(a, -1, sizeof(a));
for(int i = 1; i <= n; ++i)
b[i] = 0x3fffff;
}
之后我们只要调用init()就可以完成这一操作了
而其他的返回类型,我们需要加一个return语句来告诉程序我们要返回什么东西。
int f(int x) {
return x + 1;
}
这个函数显而易见的可以返回x+1,但是怎么调用它呢?
int a = f(3) // a = 4
int a = f(b) // a = b + 1
以上的两种方式都可以完成赋值操作。其实是很直观的吧,大概。
当然,传入的参数可以是多个。比如说:
int getmax(int x, int y){
return x < y ? y : x;
}
该函数可以求出两个数中的最大值。
虽然STL病患表示algorithm库才是真爱
同时,返回的参数也可以有多个。
比如:
string qwq(string a, string b) {
if(a > b) return a + b;
else return a;
}
如果传入的两个字符串字典序第一个比较大会返回相加的结果,否则返回第一个
有什么用?别问我,我瞎yy出来的
好的,相信各位已经会写函数了,那么请各位试着写一下一个函数,输入
函数的内联
之所以单另拿出来,是因为这是很重要的卡常技巧
在函数的前面加个inline,该函数就可以变成内联函数,相当于宏定义的函数。理解不了的话没关系,总之这样比较快就对了。尤其是对使用次数较频繁的函数,加上内联可以节省很多不必要的开支。
最常见的比如:
inline int lowbit(int x) { return x & -x; }
但是要注意两个问题:
-
不建议特别频繁的使用之,因为编译姬是个傲娇,所以不一定会听你的,对于一些比较复杂的函数,编译姬会无视你的要求,反而加多了也影响美观。
-
这个东西在C++11以后取消了,请不要试图在C++11提交的时候开内联,否则会很刺激的CE
参数传递与指针和引用
首先先明确,将数组直接作为参数传递是允许的,但一般不采用,毕竟程序也会自动改为指针的形式。
说实话我不会指针,毕竟数组这种东西我都是开全局的,实际中也很少用到。因此,这里现学现卖罢
void Test(int* a, int n) {
for (int i = 0; i < n; ++i)
cout << a[i] << endl ;
}
上面的过程将数组作为指针传递,我们需要给定数组的大小,毕竟函数不知道你数组是多大的。
所以传个vector的引用不好吗
不过啊,这个东西并不是很实用,比较实用的是传递一个引用。
比如说,我们要求解二元一次方程,显然这是有两个返回值的。嫌结构体太麻烦怎么办?我们可以将目标的两个变量作为引用传入。
这之前,我们先要看一段代码:
#include <iostream>
using namespace std;
int f(int x) { ++x; return x; }
int main() {
int a = 5;
f(5);
cout<<a<<endl;
return 0;
}
a是多少?
你可能会认为是6,不过事实上,这里的函数执行时拷贝了一个a的副本进去,然后返回了这个副本的值。
如果想要改变a的值怎么办呢?我们可以这么写这个函数:
int f(int& x){ ++x; return x; }
此时再调用x值就变成了6,因为这里的x不是作为副本、而是直接传递进去的。
那么各位尝试一下如何求一元二次方程吧!
参考:
https://www.cnblogs.com/graphics/archive/2010/07/15/1777760.html