写在前面
这里利用优快云记录C++代码,方便自己查看
本文参考书籍《C++程序设计》第二版 杨长兴
函数的声明
注意: 函数声明语句的位置可以放在主调函数中,也可以放在函数外面,只要出现在调用语句之前即有效。
推荐将函数声明的语句写在最前面,即using namespace std;这一句下面。
//求圆的面积和圆柱体的体积
#include<iostream>
#define PI 3.14159
using namespace std;
float area(float r);//函数声明写在最前有分号
float vol(float r, float h);//函数声明写在最前有分号
void main()
{
float r;
float h;
cout<<"请依次输入半径r与高度h"<<endl;
cin>>r>>h;
cout<<"圆的面积为"<<area(r)<<endl;
cout<<"圆柱体的体积为"<<vol(r,h)<<endl;
}
float area(float r)
{
return PI*r*r;
}
float vol(float r, float h)
{
return area(r)*h;
}
函数的参数传递
参数的值传递:传递到形参位置的实际参数本身不会改变;
参数的地址传递:传递到形参位置的实际参数会随函数体的运行发生变化。
参数的值传递
#include<iostream>
using namespace std;
void tiao(int y);
void main()
{
int y=5;
cout<<"y的初始值为"<<y<<endl;
tiao(y);
cout<<"函数执行后y的值为"<<y<<endl;
}
void tiao(int y)
{
y++;
}
运行结果如图所示
参数的地址传递
#include<iostream>
using namespace std;
void tiao(int *p);
void main()
{
int y=5;
cout<<"y的初始值为"<<y<<endl;
tiao(&y);
cout<<"函数执行后y的值为"<<y<<endl;
}
void tiao(int *p)
{
(*p)++;
}
运行结果如图
函数的嵌套使用(计算组合公式)
题目: 计算组合公式
C
m
n
=
m
!
n
!
(
m
−
n
)
!
C_{m}^{n}=\frac{m!}{n!(m-n)!}
Cmn=n!(m−n)!m!
关键: 特别注意系统中,整数的除法是整数,需要调整数据类型。
#include<iostream>
using namespace std;
float combi(int m,int n);
int jc(int n);
void main()
{
int m,n;
cout<<"请分别输入m和n(其中m>n)"<<endl;
cin>>m>>n;
cout<<"组合式的值为"<<combi(m,n)<<endl;
}
float combi(int m,int n)
{
return float(1)*jc(m)/jc(n)/jc(m-n);
//这里用了float(1)来调整数据类型,重要
}
int jc(int n)
{
int s=1;
for(int i=1;i<=n;i++)
{
s=s*i;
}
return s;
}
函数的递归调用(汉诺塔问题)
函数的递归调用指的是,在定义该函数的时候用到了本函数
重点:
- 需要有递归终止条件
- 递归调用的规则
总结:一般在运用函数的递归时,定义递归函数,函数体依次写递归终止条件→递归调用的原则→返回值return XX。需要使用if…else选择语句.
题目: 汉诺塔问题是经典的递归问题,现有num个金片,底座上有3根针,开始时所有的金片按照从上到下从小到大累叠,现要求将所有金片全部移动到第3根针上。
要求:每次只能移动一个金片;任何时候不允许大金片在小金片上方
//函数的递归调用(汉诺塔问题)
#include<iostream>
using namespace std;
int Total1(int n);
void Total2(int n, char x,char y,char z);
void main()
{
int num;
cout<<"请输入金属块的总数目num"<<endl;
cin>>num;
cout<<"需要移动的总次数"<<Total1(num)<<endl;
Total2(num,'X','Y','Z');//这里不需要cout,路径在函数内部已经输出
//这2-4个参数需要用单引号,是字符常量
}
int Total1(int n)
{
int f;
if(n==1)
{
f=1;
}else{
f=1+2*Total1(n-1);
}
return f;
}
void Total2(int n, char x,char y,char z)
{ //实现从第一根搬到第三根
if(n==1)
{
cout<<x<<"->"<<z<<endl;
}else{
Total2(n-1,x,z,y);//将n-1块从第一根搬到第二根
cout<<x<<"->"<<z<<endl;
Total2(n-1,y,x,z);//将n-1块从第二根搬到第三根
}
}
执行结果
内部函数
- 写在同一个cpp文件中 的自定义函数为内部函数,当定义或声明函数时用了inline关键字,则该自定义函数为内置函数,形式与普通自定义函数一致,只是运行速度稍快。
- 写在不同cpp文件中 的自定义函数为外部函数,在main()函数中调用外部函数时需要在函数声明的最左端写上extern关键字,自定义函数的第一句最左端也要写extern.同时main.cpp与fextern.cpp文件需要存放位置一致,均放在一个工程中的source Files里面。
内置函数
为了节省程序调用函数的时间,可以将自定义函数设定为内置函数,设置为内置函数只需要在函数声明的最左端加上inline ,在函数定义的第一句最左端加上inline。自定义函数的位置还是写在主调函数的外面,但是在程序编译的时候系统会将主调函数中调用函数的语句替换为被调函数体的内容,这个替换是系统操作的不需要认为改动。
//内置函数,一般不怎么用,了解就好
#include<iostream>
using namespace std;
inline void jh(int a,int b);
void main()
{
int a=3,b=5;
cout<<"初始a和b的值分别为:"<<a<<'\t'<<b<<endl;
cout<<"交换值之后a和b分别为:";
jh(a,b);
}
inline void jh(int a,int b)
{
int t=a;
a=b;
b=t;
cout<<a<<'\t'<<b<<endl;
}
//试一下引用其他文件内的自定义函数
#include<iostream>
using namespace std;
void main()
{
extern double fac2(int);
int n;
cout<<"请输入整数n:";
cin>>n;
cout<<n<<"!!="<<fac2(n)<<endl;
}
普通自定义函数
这里所说的普通自定义函数即除了不加inline 没有什么鬼区别的自定义函数
外部函数
//*******main.cpp*****
//试一下引用其他文件内的自定义函数
#include<iostream>
using namespace std;
void main()
{
extern double fac2(int);
int n;
cout<<"请输入整数n:";
cin>>n;
cout<<n<<"!!="<<fac2(n)<<endl;
}
//******fac2.cpp*****
//放在同一工程的Source Files里面
#include<iostream>
using namespace std;
extern double fac2(int m)
{
int n;
double s=1;
n=m;
while(n>=1)
{
s=s*n;
n=n-2;
}
return s;
}
存放位置图
编译预处理
编译预处理代码即C++源代码最开始的加井号"#"的符号进行的说明,并且预处理代码结束时不加分号。
宏定义
宏定义内容在代码运行时机械地进行替换而不会进行计算
//如
#define P M-2
//若函数体内有p*3的运算,则替换为M-2*3,它不会给你加括号啊喂!!!
文件包含
这里所包含的文件一般有C++系统目录的文件,也有自定义的文件,用include来表示包含该文件。
//包含系统自带的文件,类似于R语言里面加载包,注意这里都是用的尖括号
#include<iostream>
#include<cmath>
#include<iomanip>
//包含自己写的文件
#include"chap3_3.cpp"
//注意!注意!该文件不能添加到工程中,在新建该文件时仍然选用C++ Source Files,但是取消添加到工程即可。
条件编译
条件编译是写在main()函数里面的内容
void main()
{
#ifdef M//如果M在之前被定义过则执行,注意是“有没有被定义”
{
.....
}
#else
{
...
}
#endif
}
void main()
{
#ifndef M //如果M之前没有被定义则执行,if not define
{
.....
}
#else
{
...
}
#endif
}
void main()
{
#if M==1//如果之前定义的M的值等于1,则执行程序块
{...}
#elif M==2
{...}
#else
{...}
#endif
}