C++基础第三章学习笔记

C++基础第三章学习笔记

1.形式参数:相当于局部变量     类型标识符+函数名+(形参){语句序列}

2.函数调用就是用实参初始化形参     函数名(实参)   嵌套调用:函数体内调用另一个函数    F5:执行程序

- 模拟生成随机数
函数原型:int rand(void)  
头文件:<cstdlib>

原型:void srand(unsigned int seed):为使rand()产生一序列随机整数二设置起始点.使用1作为seed参数,可以重新初始化rand(),不同的种子会产生不同的随机数序列。
参数:seed产生随机数的种子
所需头文件:<cstdlib>

-主函数
#include <iostream>
#include <cstdlib>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#define endl '\n'
using namespace std;
enum GameStatus{win,lose,playing};

//投色子、计算和、输出和
int rollDice(){
    int die1 = 1 + rand()%6;
    int die2 = 1 + rand()%6;
    int sum = die1 + die2;
    cout<<"player rolled"<<die1<<"+"<<die2<<"="<<sum<<endl;
    return sum;
}

int main(){
    int sum,mypoint;
    GameStatus status;
    unsigned seed;
    int rollDice();
    int i;
    for(i = 1;i < 7;i++){
		cout<<i<<endl;	//输出i值, 
	}
    cout<<"请输入一个未符号的整数";
    cin>>seed;//输入随机数种子
    srand(seed);//将种子传递给rand()
    sum = rollDice();//第一轮投色子、计算和数
    switch(sum){
            case 7:	//如果和数为7或10,win
        	case 11:
            	status = win;
            	break;
        	case 2:
            case 3:
            case 12:
            	status = lose;
           		break;
        	default:
            	status = playing;
            	mypoint = sum;
            	cout<<"point is"<<mypoint<<endl;
            	break;
   			 }
   			 
    while(status == playing){//只要状态为playing,继续
        sum = rollDice();
        if(sum == mypoint)	//某轮的和数等于点数则取胜
            status = win;
        else if (sum == 7) 
            status = lose;
    }
    
	//当状态不为playing时循环结束,输出游戏结果
    if(status == win)
   	 cout<<"player wins"<<endl;
    else
     cout<<"player lose"<<endl;
    return 0;
}

嵌套调用

fun1函数内嵌套fun2函数,最终返回。

递归调用

#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#define endl '\n'
using namespace std;
unsigned fac(unsigned n){
    unsigned f;
    if (n == 0)
    	f = 1;
    else
    	f = fac(n-1)+1;
    return f;
}
int main(){
	int Out;
	Out = fac(100);
	cout<<Out<<endl;
}

-  递归,汉诺塔
#include <iostream>
using namespace std;
//把src针的最上面一个盘子移动到dest针上
void move(char src, char dest){
	cout<<src<<"-->"<<dest<<endl;
}
//把n个盘子从src针移动到dest针,以medium针作为中介
void hanoi(int n, char src, char medium, char dest){
	if (n == 1)
		move(src,dest);
	else{
		hanoi(n-1,src,dest,medium);
		move(src,dest);
		hanoi(n-1,medium,src,dest);
	}
int main(){
	int m;
	cout<<"输入盘子个数";
	cin>>m;
	hanoi(m,'A','B','C');
	return 0;
}
}

函数参数传递

实参类型与形参类型必须相同
参数双向传递:<传引用>

- 引用类型
引用(&)是标识符的别名

例如:
	int i,j;
	int &ri = i;//定义int引用ri,并初始化为变量i的引用
现在ri = j;相当于i = j;

- 函数参数的传递
#include <iostream>
using namespace std;
void swap(int &a,int &b){
    int t = a;
    a = b;
    b = t;	
}
int main(){
	int a = 12,b = 13;
	swap(a,b);
	cout<<"a = "<<a<<endl;
	cout<<"b = "<<b<<endl;
	return 0;
}
*问题:可以定义指向引用的指针.(错)
解析:
引用不是对象,引用并没有在程序中占据内存空间,故没有地址的说法.
    
- 可变长度的形参表,不定义参数数量的函数
initializer_list <int> li;

内联函数

(inline)内联函数
内部不能有循环和switch语句
不能进行异常接口申明
充分简单的函数,编译器会自动将其转化成为inline形式,提高效率,节省了参数传递、控制转移等开销

*实例:
为了代码的重用,提高效率
#include <iostream>
using namespace std;

const double PI = 3.1415926535;
inline double calArea(double radius){
	return PI*radius*radius;
}
int main(){
	double r = 30;
    double area = calArea(r);
    cout<<area<<endl;
	return 0;
}

* const 是 constant 的缩写,本意是不变的,不易改变的意思。C++ const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的。 *



- 关于内联函数的一些观点 -
    
* 引入内联函数的目的是为了解决程序中函数调用的效率问题,这么说吧,程序在编译器编译的时候,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体进行替换,而对于其他的函数,都是在运行时候才被替代。这其实就是个空间代价换时间的i节省。所以内联函数一般都是1-5行的小函数。在使用内联函数时要留神:
1.在内联函数内不允许使用循环语句和开关语句;
2.内联函数的定义必须出现在内联函数第一次调用之前;
3.类结构中所在的类说明内部定义的函数是内联函数。

* Tip:只有当函数只有 10 行甚至更少时才将其定义为内联函数.

定义: 当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制进行调用.

优点: 当函数体比较小的时候, 内联该函数可以令目标代码更加高效. 对于存取函数以及其它函数体比较短, 性能关键的函数, 鼓励使用内联.

缺点: 滥用内联将导致程序变慢. 内联可能使目标代码量或增或减, 这取决于内联函数的大小. 内联非常短小的存取函数通常会减少代码大小, 但内联一个相当大的函数将戏剧性的增加代码大小. 现代处理器由于更好的利用了指令缓存, 小巧的代码往往执行更快。

结论: 一个较为合理的经验准则是, 不要内联超过 10 行的函数. 谨慎对待析构函数, 析构函数往往比其表面看起来要更长, 因为有隐含的成员和基类析构函数被调用!

另一个实用的经验准则: 内联那些包含循环或 switch 语句的函数常常是得不偿失 (除非在大多数情况下, 这些循环或 switch 语句从不被执行).

有些函数即使声明为内联的也不一定会被编译器内联, 这点很重要; 比如虚函数和递归函数就不会被正常内联. 通常, 递归函数不应该声明成内联函数.(递归调用堆栈的展开并不像循环那么简单, 比如递归层数在编译时可能是未知的, 大多数编译器都不支持内联递归函数). 虚函数内联的主要原因则是想把它的函数体放在类定义内, 为了图个方便, 抑或是当作文档描述其行为, 比如精短的存取函数.

constexpr函数

-  constexpr int get_size() { return 20; }
-  constexpr int foo = get_size();  //正确:foo是一个常量表达式

带默认参数值的函数

+ 可以预先设置默认的参数值,如果给出实参,则调用实参,否则采用预先设置的默认的形参初始值,带默认值的参数必须待在右边,调用时实参与形参结合是从左到右的。

int add(int x = 5,int y = 6){
    return x+y;
}
int main(){
    add(10,20);//10+20
    add(10);//10+6
    add();//5+6
}
函数声明或函数定义其中一个必须在前

*实例
#include <iostream>
#include <iomanip>
using namespace std;
int getVolume(int length,int width = 2,int height = 3);
int main(){
	const int X = 10,Y = 12,Z = 15;
    cout<<getVolume(X,Y,Z)<<endl;
    cout<<getVolume(X<Y)<<endl;
    cout<<getVolume(X)<<endl;
	return 0;
}
int getVolume(int length,int width,int height){
    cout<<setw(5)<<length<<setw(5)<<width<<setw(5)<<height<<'\t';
    return length*width*height;
}

setw(5) - 需要填充5个字符,默认填充的字符为' '空格

函数重载

int add(int x,int y);
double add(double x,double y);

系统函数

头文件:cmath
函数:cos sin abs sqrt

第三章小结

各类函数的来了解和使用

函数实验(上)

#include <iostream>
#include <iomanip>
using namespace std;
float Convert(float a){
	float F; 
    F = 2*a;
    return F;
}
int main(){
	cout<<Convert(2.2)<<endl;
	return 0;
}


*斐波那契数列,典型的分段函数
#include <iostream>
using namespace std;

int fib(int n){
	cout<<"processing fib("<<n<<")...";
    if(n<3)
    {
        cout<<"return 1!";
        return 1;
    }
    else
    {
        cout<<"call fib("<<n-2<<")and fib("<<n-1<<").\n";
    	return (fib(n-2)+fib(n-1));	    
    }
}
int main(){
	int n,answer;
    cout<<"请输入";
    cin<<n;
    cout<<"\n\n";
    answer = fib(n);
cout<<answer<<"is the"<<n<<"the fibonacci number\n";
	return 0;
}

函数实验(下)

#include <cmath>    使用数学的公式,例如:pow、exp等
int max1(int x,int y) //寻找两个整数中的最大值
{
    if (x == y)
        return x;
    else if(x > y)
        return x
    else 
        return y;
}

Dev C++代码调试

-代码调试方法流程
1开启调试模式
1.1 点开工具
1.2选择编译器选项
1.3 更改产生调试信息为yes
2代码调试
2.1 添加断点(单击每一行的最前边,出现红色√)
2.2开始调试(点击下方调试即可)
如下表示调试已经开始
2.3添加要查看的变量(例如添加i、sum)
2.4观察变量如何变化
快捷键     F5    开始调试
快捷键     F7    单步调试(运行下一步)
快捷键    F8    单步进入函数调试
快捷键    F9    停止调试


-软件内部的小bug,有关endl的断点处调试问题
今天使用Dev C++进行debug时,发现运行到cout语句时,按下一步没有反应。
语句为`cout << a << endl;`
查了好几个资料都没找到解决方法。
后来还是在百度知道看到了[解决方案](https://zhidao.baidu.com/question/587851726049039965.html)
原来Dev C++遇到endl会出现这种问题,改成’\n’就可以了。
`cout << a << ‘\n’;`

【另一种解决方案】
在文件开头添加宏定义:
#define endl '\n'
这样就无需修改代码了

-软件使用
一个工程项目下只能放一个代码文件,多余的文件应该移去,不能存在多个main函数

猜你喜欢

转载自blog.csdn.net/weixin_45736522/article/details/108648816