一:函数的定义和使用
1.函数的定义:
类型说明符 函数名(含类型说明的形参表)
{
语句序列
}
如:
int GetSum(int a, int b)
{
return a + b;
}
2.形式参数:
形式参数的作用是实现主函数与被调函数之间的联系。
3.函数的返回值和返回类型
函数可以有一个返回值,返回值非空类型函数必须有一个返回值,否则会报错。函数的返回值由return 语句给出。
二:函数的调用
1.函数的调用形式
- 变量在使用前需要首先声明,类似地,函数在调用之前也需要声明。函数的定义就属于函数的声明,因此,在定义了一个函数之后,可以直接调用这个函数。但如果希望在定义一个函数之前调用它,则需要在调用函数之前添加该函数的函数原型声明。形式如下:
类型说明符 函数名(形参表);
细节:声明函数时,形参表只要包含完整的类型信息即可,形参名可以省略。
- 声明函数原型后,便可以调用函数。调用形式如下:
函数名(实参表);
GetSum(a, b);
实参列表应给出与函数原型形参个数相同、类型相符的实参,每个实参都是一个表达式。
2.嵌套调用
即不同函数之间的相互调用(非自身调用)。
3.递归调用
函数可以直接或者间接的调用自己,称为递归调用。
三:函数的参数传递
1.值传递
当发生函数调用时,给形参分配内存空间,并用实参来初始化形参。实际上值传递相当于拷贝了一份实参,此后形参的变化与实参无联系。
2.引用传递
给一个变量起别名。通过引用名与通过变量名访问变量的效果相同。
- 声明一个引用时,必须同时对它初始化,使它指向一个已经存在的对象。
- 一个引用一旦被初始化之后,对不能改为指向其他对象。换句话说,一个引用,从它诞生起,就必须确定是那个变量的别名,而且始终只能作为这一个变量的别名。
引用类型的形参通过实形结合,成为了实参的一个别名,对形参的任何操作也就会直接作用于实参,相当于就是对实参进行操作。
#include<iostream>
using namespace std;
void swap1(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
void swap2(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int x = 5, y = 10;
swap1(x, y);
cout << x << ends << y << endl; //输出5 10
swap2(x, y);
cout << x << ends << y << endl; //输出10 5
}
三:内联函数
内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用出。(牺牲空间来换运行效率)
内联函数定义形式:
inline 类型说明符 函数名(形参列表)
{
语句序列
}
四:带默认形参值的函数
函数在定义时可以预先声明默认的形参值。
- 有默认值的形参必须在形参列表的最后,也就是说,在有默认形参值的形参后面,不能出现无默认值的形参。因为在函数调用中,实参与形参是按从左向右的顺序建立对应关系的。
- 在相同的作用域内,不允许在同一个函数的多个声明中对同一个参数的默认值重复定义,即使前后定义的值相同。换句话说,就是函数的声明和定义中,一个形参的默认值要么在声明中说明,要么在定义在说明。
五:函数重载
两个及两个以上的函数,具有相同的函数名,但是形参的个数或者类型不同,这就是函数的重载。
- 注意:重载函数的形参必须不同:个数或者类型不同。
- 当使用具有默认形参值的函数重载形式时,需要注意防止二义性。
void fun(int length, int width = 2, int height = 33);
void fun(int length);
int main()
{
fun(1); //具有二义性,编译器不知道调用哪个函数。
}
六:C++常用系统函数
数学<math.h>:
1.三角函数
double sin (double);
double cos (double);
double tan (double);
2.反三角函数
double asin (double); 结果介于[-PI/2, PI/2]
double acos (double); 结果介于[0, PI]
double atan (double); 反正切(主值), 结果介于[-PI/2, PI/2]
double atan2 (double, double); 反正切(整圆值), 结果介于[-PI/2, PI/2]
3.双曲三角函数
double sinh (double);
double cosh (double);
double tanh (double);
4.指数与对数
double exp (double x); e的x次幂
double pow (double x, double y); x的y次幂
double sqrt (double);
double log (double x); 以e为底的对数,即ln x
double log10 (double x); log10(x) 以10为底。
没有以2为底的函数但是可以用换底公式解 决:log2(N)=log10(N)/log10(2)
5.取整
double ceil (double); 不小于x的最小整数
double floor (double); 不大于x的最大整数
6.绝对值
int abs(int); 整型
long labs(long); 长整型
double fabs (double); 浮点型
7.标准化浮点数
double frexp (double f, int p); 标准化浮点数, f = x * 2^p, 已知f求x, p ( x介于[0.5, 1] )
double ldexp (double x, int p); 与frexp相反, 已知x, p求f
8.取整与取余
double modf (double, double); 将参数的整数部分通过指针回传, 返回小数部分
double fmod (double, double); 返回两参数相除的余数
9.平方根
double sqrt(double x);
字符<ctype.h>:
int isalpha(int c); c是否为字母
int isdigit(int c); c是否为数字
int tolower(int c); 将c转换为小写字母
int toupper(int c); 将c转换为大写字母
字符串<string.h>:
char *strcpy(char *sl,char *s2); 将字符串s2复制给s1,即覆盖
unsigned strlen(char *sr); 求字符串str长度
内存操作<memory.h>:
void *memcpy(void *d,void *s,int c); 将s指向的内存区域的c个字节复制到d指向的区域
类型转换<stdlib.h>:
int atoi(char *s); 将字符串转化为整数
char *itoa(int v,char *s,int x); 将整数v按x进制转成字符串s
时间<time.h>:
time_t time(time_t *timer); 返回1970/1/1零点到目前的秒数
其他<stdlib.h>:
srand(unsigned seed); 设置随机数的种子
int rand(); 产生0-RAND_MAX的随机数
exit(int); 终止正在执行的程序