微电子2班 Group 10 C++ 小组汇报

1.类飞行棋游戏 :

要求:尝试应用enum枚举类型定义游戏的状态,包括WIN,LOSE和CONTINUE三种状态,同时应用用continue和break语句设计类似飞行棋游戏:自己定义一个规则,比如:设定目标位置是20,起始位置是0,若投掷的骰子点数+当前位置>目标位置,就进行下一次循环;否则,当前位置就改为当前位置+点数;若点数+当前位置==目标位置,就退出循环,游戏结束;游戏状态是CONTINUE,则继续游戏。点数随机获取。当游戏状态是WIN时,输出“你赢了”,游戏状态是LOSE时,输出“你输了”。

 实现代码1:

#include <iostream>
#include <ctime>
#include <windows.h>
using namespace std;

enum GameState {
	WIN,
	LOSE,
	CONTINUE
};
int main()
{
	GameState State = CONTINUE;
	const int targetPosition = 20; // 目标位置
	int currentPosition = 0; // 当前位置
	int i = 1; //游戏当前进行次数(最多循环四次)
	srand(time(0)); // 设置随机数
	cout << "开始游戏,游戏最多进行4轮" << endl;
	cout << "当前轮数:" << i << endl;
	Sleep(2000);
	cout << endl;
	cout << "当前位置:0" << endl;
	cout << endl;
	Sleep(2000);
	while (i < 5)
	{
		int diceRoll = rand() % 6 + 1; // 掷骰子,生成1到6之间的随机数
		cout << "骰子点数:" << diceRoll << endl;

		if (diceRoll + currentPosition > targetPosition)
		{
			// 若点数+当前位置超过目标位置,则进行下一次循环
			currentPosition = currentPosition + diceRoll - 20;
			i++;
			cout << "当前位置:" << currentPosition << "(超出20,未达到目标点,自动-20)\n             (游戏继续)" << endl;
			cout << "当前轮数:" << i << endl;
			cout << endl;
			State = LOSE;
			continue;
		}
		else
		{
			currentPosition += diceRoll; // 当前位置改为当前位置+点数
			cout << "当前位置:" << currentPosition << endl;
			cout << endl;
			State = CONTINUE;
			Sleep(1500);

			if (currentPosition == targetPosition)
			{
				// 若点数+当前位置等于目标位置,游戏结束,退出循环
				cout << "当前位置:20" << endl;
				State = WIN;
				break;
			}
		}
	}

	cout << "游戏结束!" << endl;
	cout << "最终位置:" << currentPosition << endl;
	cout << endl;
	if (WIN == State)
		cout << "您在第" << i << "轮达到目标位置,你赢了!" << endl;
	else if (LOSE == State)
		cout << "次数用尽仍未达到目标,你输了!" << endl;

	return 0;
}

基本思路为首先在while循环开始前srand(time(0)) 设置随机种子,接着开始循环,用rand()%+1模拟掷骰子,设置开始位置为0,目标位置为20。不断掷骰子,一旦位置超过了20,立即-20继续循环,同时将游戏轮数+1。当游戏在4轮内达到目标位置20则获胜,反之失败。

 实现代码2:

#include <iostream>
#include <ctime>
#include <cstdlib> 
using namespace std;
int main(){
	enum State{Win,Lose,Continue};
	State aState=Win;
	int aim=20;//设定
	int start=0;
	    for (;;srand(time(0))){//使种子不同
		     int num=rand()%6+1;//随机数  
			if(num+start>aim){
	        	aState=Lose;
				start=0;//新一局初始化起点 
				cout<<"你输了"<<endl; 
				continue;//大循环 
			} 
		    else{
		    	start+=num;
		    	if(num+start==aim){
		    		aState=Win;
					cout<<"你赢了"<<endl; 
					break;
				}
				if(start+num<aim){
					aState=Continue;
				} 
			}
		}; 
	return 0; 
}

实现代码3:

#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
int main()
{
	enum State{Continue,Win,Lose
	};
	State Pstate=Continue;
	cout<<"欢迎来到飞行棋游戏!"<<endl<<"您的初始位置为0,目标位置为20。您一共只有六次机会,请开始投掷骰子。"<<endl;
	int present=0;
	srand(static_cast<unsigned int>(time(0)));
	for(int i=1;i<=6;i++)
	{ 
		int origin=rand()%6+1;
		present+=origin;
		cout<<"您的当前位置是"<<present<<endl; 
		if(present>20)
		{
			Pstate=Continue;
			cout<<"您已超出目标位置,请您重新投掷骰子。"<<endl;
			present=present-origin; 
			continue; 
		}
		if(present==20)
		{
			Pstate=Win;
			cout<<"游戏结束,您赢了!"<<endl;
			break;
		}
	}
	if(present<20)
	{
		Pstate=Lose;
		cout<<"游戏结束,您输了!"<<endl;
	}
	return 0; 
}

我们一位组员用到了#include<bits/stdc++.h>头文件

#include<bits/stdc++.h>是一个非标准的头文件,它常用于竞赛编程或快速原型开发时,方便地包含了标准库中的大部分常用头文件。

<bits/stdc++.h>头文件实际上包含了以下常用的标准头文件:(下面有些看看就行)

  1. <iostream>:输入输出流库,用于标准输入输出。
  2. <iomanip>:输入输出格式库,用于流操作符的设置。
  3. <fstream>:文件输入输出库,用于文件读写操作。
  4. <cstdio>:C风格输入输出库,提供了与C语言类似的输入输出函数。
  5. <cstdlib>:C标准库,提供了一些通用的函数和类型定义。
  6. <cmath>:数学库,提供了各种数学函数。
  7. <algorithm>:算法库,提供了一些常用的算法函数。
  8. <vector>:向量容器库,提供了向量操作相关的函数和类。
  9. <list>:链表容器库,提供了链表操作相关的函数和类。
  10. <deque>:双端队列容器库,提供了双端队列操作相关的函数和类。
  11. <queue>:队列容器库,提供了队列操作相关的函数和类。
  12. <stack>:栈容器库,提供了栈操作相关的函数和类。
  13. <set>:集合容器库,提供了集合操作相关的函数和类。
  14. <map>:映射容器库,提供了映射操作相关的函数和类。
  15. <unordered_set>:无序集合容器库,提供了无序集合操作相关的函数和类。
  16. <unordered_map>:无序映射容器库,提供了无序映射操作相关的函数和类。
  17. <utility>:实用工具库,提供了一些通用的辅助函数和类。

2.健康码:

要求:

定义一个健康码枚举类型,包括RED,YELLOW,GREEN

随机产生一个1-45的整数fever,如果fever>=39, 健康码状态为RED;如果fever<37,健康码状态为GREEN;

 若fever在37—39,健康码状态为YELLOW,如果状态是YELLOW,就一直产生随机数检测体温,直到满足上述条件为止。如果状态是RED,输出“你需要退烧";如果状态是GREEN,输出“你目前健康”。

 实现代码1:

#include <iostream>
#include <ctime>
#include<windows.h>
using namespace std;

enum HealthCode { RED, YELLOW, GREEN };

int main() {
	// 产生随机数
	srand(time(nullptr));
	int fever = rand() % 10 + 35;
	cout << "您的体温为:" << fever << endl;

	// 判断健康码状态
	HealthCode code = GREEN;
	if (fever >= 39) {
		code = RED;
	}
	else if (fever <= 37) {
		code = GREEN;
	}
	else {
		code = YELLOW;
		while (code == YELLOW) {
			Sleep(1000);
			fever = rand() % 10 + 35;
			cout << "将进行再次测量" << endl;
			Sleep(500);
			cout << "您的体温为:" << fever << endl;
			if (fever >= 39) {
				code = RED;
			}
			else if (fever <= 37) {
				code = GREEN;
			}
		}
	}
	Sleep(1000);
	// 输出健康码状态
	switch (code) {
	case RED: {
		cout << "健康码状态为RED" << endl;
		cout << "您需要退烧" << endl;
	}break;
	case GREEN: {
		cout << "健康码状态为GREEN" << endl;
		cout << "您目前健康" << endl;
	}break;
	}
	return 0;
}

 实现代码2:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	enum State{RED,YELLOW,GREEN
	};
	State now=RED;
	srand(time(0));
	for(;;)
	{
	int fever=rand()%46+1;
	cout<<"你当前体温为"<<fever<<endl; 
	if(fever>=39)
	{
		now=RED;
		cout<<"你需要退烧"<<endl;
		break;
	}
	else if(fever<37)
	{
		now=GREEN;
		cout<<"你目前健康"<<endl;
		break;
	}
	else
		now=YELLOW;
    }
    return 0;
}

问题代码:

#include<iostream>
#include<iomanip>
#include<cstdlib>

using namespace std;
enum State{RED,YELLOW,GREEN};
State healthState=RED; 
int main ()
{
	for(int i=0;i<10;i++)
	{
        srand(time(0));//srand在循环内部
	    double fever=rand()%45+1;
	    if(fever>=39)
	    {
		healthState=RED;
	    }
	    if(fever<37)
	    {
		healthState=GREEN;
	    }
	    if(fever>37&&fever<39)
	    {
		healthState=YELLOW;
	    }
    
	switch(healthState)
	{
		case RED:
		    cout<<fever; 
		    cout<<"你需要退烧"<<endl;break;
		case GREEN:
		    cout<<fever;
		    cout<<"你目前健康"<<endl;break;
		case YELLOW:
		    cout<<fever;
		    continue;
	}
	} 
}

问题:如果将srand(time0))放在循环里面,则会导致“随机数”相同。0d356dedf43d411ebeb92fea24a3f9c9.png

分析:srand()函数用于设置随机数生成器的种子,将srand(time(0))放在循环内部会导致每次循环都使用相同的种子来初始化随机数生成器。而在短时间内多次调用srand(time(0)),可能得到相同的种子值,因此生成的随机数序列也会相同。

而在上述代码中,由于循环迭代非常快,每次循环都会立即调用srand(time(0)),但由于时间精度有限,则会得到相同的种子值。我们通常将srand(time(0))放在程序的开头执行一次,通过使用不同的种子值,可以获得不同的随机数序列。

所以解决方案是,可以将srand(time(0))移到循环外部,确保只调用一次,如下所示:

#include<iostream>
#include<iomanip>
#include<cstdlib>

using namespace std;
enum State{RED,YELLOW,GREEN};
State healthState=RED; 
int main ()
{
	srand(time(0));//srand在循环外部
	for(int i=0;i<10;i++)
	{
	    double fever=rand()%45+1;
	    if(fever>=39)
	    {
		healthState=RED;
	    }
	    if(fever<37)
	    {
		healthState=GREEN;
	    }
	    if(fever>37&&fever<39)
	    {
		healthState=YELLOW;
	    }
    
	switch(healthState)
	{
		case RED:
		    cout<<fever; 
		    cout<<"你需要退烧"<<endl;break;
		case GREEN:
		    cout<<fever;
		    cout<<"你目前健康"<<endl;break;
		case YELLOW:
		    cout<<fever;
		    continue;
	}
	} 
}

 运行结果如下:

ebd4901152e94253b069c3ed9a1a90de.png


3.1 星号组成的方形图案:

要求:编写一个函数,在屏幕的左边空白处显示一个由星号组成的实体正方形,边长由整数参数side指定。

 实现代码:

#include<iostream>
using namespace std;

int main() {
	int i = 0;
	int a = 0, b = 0;
	cin >> i;
	while (a < i) {
		int b = 0;
		while (b < i) {
			cout << "*";
			b++;
		}
		a++;
		cout << endl;
	}
	return 0;
}

基本思路为一个循环套一个循环,实现重复输入星号以及换行。


3.2 任意符号组成的方形图案:

要求:修改3.1的 * 为任意符号,由用户输入。

 实现代码1:

#include<iostream>
using namespace std;

int main() {
	char m;
	int i = 0;
	int a = 0, b = 0;
	cin >> i >> m;
	
	while (a < i) {
		int b = 0;
		while (b < i) {
			cout << m;
			b++;
		}
		a++;
		cout << endl;
	}
	return 0;
}

实现代码2:

#include <iostream>
#include <string>
using namespace std;
Side(int side,string s){
	for(int i=1;i<=side;i++){
		for(int t=1;t<=side;t++){
			cout<<s;
		}
		cout<<endl;
	}
}
int main(){
	int side;
	string s;
	cin>>side;
	cin>>s;
	Side(side,s);
	return 0;
}

——法二:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	srand(time(0));
	int side=rand()%10+1;
	for(int i=1;i<=side;i++) 
	{
		cout<<setfill('*')<<setw(side)<<"*"<<endl;
	}
	return 0;
}

使用iomanip头文件下的setfill()及setw()语句替代循环达到同样的效果

setfill():

setfill()函数是一个iomanip头文件中的流操作符,用于指定填充字符(默认为空格)。

它通常与setw()流操作符一起使用,用于设置输出字段的宽度和对齐方式。setfill()函数的调用格式如下:

setfill(char fill_char);

其中,fill_char是一个字符参数,表示用于填充输出字段的字符。

使用setfill()函数可以很方便地设置输出字段的填充字符。例如,可以通过以下代码将输出的宽度设置为8个字符,并使用字符'0'来填充输出字段:

#include <iostream>
#include <iomanip>

int main() {
    int num = 123;
    std::cout << std::setw(8) << std::setfill('0') << num << std::endl; 
                                                        // 输出00000123
    return 0;
}

在上面的示例中,std::setw(8)设置输出字段的宽度为8个字符,std::setfill('0')指定填充字符为字符'0'。因此,输出的字符串为"00000123"

需要注意的是,setfill()函数只会影响下一个输出,而不是全局的。也就是说,如果你想在多个输出中使用相同的填充字符,需要在每次输出前都调用一次setfill()函数。


4.抛硬币:

要求:

编写一个程序模拟抛硬币。对于每次抛硬币,程序应该打印出是正面(“Head”)还是背面(“Tail")。让程序模拟抛硬币100次,并计算正面和背面各自出现的次数,打印出结果。程序应该调用一个单独的无形参的函数flip,在硬币出现背面时它返回0,在硬币出现正面时它返回1。

注意:如果程序比较逼真地模拟出抛硬币的情况,那么硬币两面出现的次数应该是差不多的。

实现代码1:

#include<iostream>
#include<ctime>
#include<windows.h>
using namespace std;

int flip() {
	return  rand() % 2;
}

int main() {
	srand(time(0));

	int Heads = 0;
	int Tails = 0;

	for (int i = 0; i < 100; i++) {
		int result = flip();

		if (result == 0) {
			cout << "Tail" << endl;
			Sleep(200);
			Tails++;
		}
		if (result == 1) {
			cout << "Head" << endl;
			Sleep(200);
			Heads++;
	    }
	}
	cout << "Heads:" << Heads << endl;
	cout << "Tails:" << Tails << endl;

	return 0;
}

实现代码2:

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std; 
int a;
int flip(){ 
	if(a==1)
	return 1;
	else if(a==0)
	return 0; 
}
int main(){
	int n;
	srand(time(0));
	for(int i;i<100;i++){
		int num=rand()%2+0;
		a=num;
		if(num==1){
			cout<<"Head"<<endl;
			flip();
			n++;
		}
		if(num==0){
			cout<<"Tail"<<endl;
			flip();
		}
	}
	cout<<n;
	return 0;
}

实现代码3:

#include<bits/stdc++.h>
using namespace std;
enum state{Head,Tail};
    state now=Head;
int flip()
{
	if(now==Head)
	return 1;
	else
	return 0; 
};
int main()
{
	int counter1=0,counter2=0;
	srand(time(0));
	for(int i=1;i<=100;i++)
	{
		int num=rand()%2;
		if(num==1)
		{
			now=Head;
		    counter1++;
		    int call=flip();
		}
		else
		{
			now=Tail;
			counter2++;
			int call=flip();
		}	
	}
	cout<<"正面次数为"<<counter1<<endl;
	cout<<"背面次数为"<<counter2<<endl;
	return 0;
}

第一个代码的flip函数实现的功能是设置随机数,判断程序在main函数中;

第二第三个代码flip函数实现的功能是判断,设置随机数在main函数中。

两者都对flip函数返回了一个值。

补充----注意return的用法:

1.返回值: 当函数的返回类型不是void时(void 类型函数无须返回一个值),return可以用于将一个值返回给调用者。函数的返回类型必须与return后面表达式的类型匹配(char/double/int/long long/...) 。示例:

int square(int num) {
    return num * num;
}

int result = square(5); // 调用square函数并将返回值赋给result变量

2.提前终止函数: 在任何函数中,使用return可以立即终止函数的执行,无论函数是否有返回值。当return语句执行时,控制流将立即返回到函数调用的地方。示例:

void printNumber(int num) {
    if (num < 0) {
        return; // 如果num小于0则终止函数执行
    }
    std::cout << "Number: " << num << std::endl;
}

printNumber(-5); // 该调用不会输出任何东西,因为函数提前终止了

需要注意的是,如果函数声明的返回类型是void,则不需要使用return来返回值,也可以使用return来提前终止函数执行。

此外,在某些情况下,也可以在main()函数中使用return来表示程序的退出状态,例如 return 0; 表示程序正常退出,return 1; 表示程序异常退出。


5.猜数字:

要求:编写一个程序,可以玩“猜数字”的游戏。具体描述如下:程序在1~1000之间的整数中随机选择需要被猜的数,然后显示:

b6a7ea46b7414466a4864e56f0a6b24b.jpeg

玩家于是输入猜想的第一个数。程序会做出如下响应之一:

ff391bb7d9ee466aa1db5b6005d15f96.jpeg

如果玩家的猜测是不正确的,程序应继续循环,直到玩家最终猜对为止。此过程中程序要一直提
醒玩家是猜大了(“Too high”)还是猜小了(“Too low”),从而帮助玩家尽快获得正确的答案。

实现代码1:

#include<iostream>
#include<ctime>
#include<string>
using namespace std;

int main() {
	string result = "y";
	while (result == "y") {
		cout << "I have a number between 1 and 1000." << endl;
		cout << "Can you guess my number?" << endl;
		cout << "Please type your first guess." << endl;
		srand(time(0));
		int guessnumber = rand() % 1000 + 1;
		int i = 0;
		while (true) {
			cin >> i;
			if (i == guessnumber) {
				cout << "Excelent! You guessed the number!" << endl;
				cout << "Would you like to play again?(y or n)" << endl;
				break;
			}
			else if (i < guessnumber) {
				cout << "Too low. Try again." << endl;
				continue;
			}
			else if(i>guessnumber){
				cout << "Too high. Try again." << endl;
				continue;
		    }
		}
		cin >> result;
		cout << endl;
		cout << endl;
	}
	return 0;
}

实现代码2:

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main(){
	srand(time(0));
    int num=rand()%1000+1;
    for(int guess;;){
    	cout<<"猜猜看"<<endl;
		cin>>guess;
		if(guess==num){
			cout<<"猜对啦"<<endl;
			break; 
		}
		if(guess>num){
			cout<<"大了"<<endl;
			continue; 
		}
		if(guess<num){
		    cout<<"小了"<<endl;
			continue;	
		} 
	}
	return 0; 
}

实现代码3:

#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
int main()
{
	srand(time(0));
	Sleep(10);
	int num=rand()%1000+1;
	int guess=0;
	char answer; 
	cout<<"I have a number between 1 and 1000.\nCan you guess my number?\nPlease type your first guess."<<endl;
	for(int i=0;i<2;--i)
	{ 
		cin>>guess;
	    if(guess==num)
	    {
	    	cout<<"Excellent! You guessed the number!\nWould you like to play again (y or n) ?"<<endl;
	    	cin>>answer;
     	    if (answer=='n')
     	    break;
     	    else
     	    { 
     	        srand(time(0));
	            num=rand()%1000+1;
     	    	cout<<"I have a number between 1 and 1000.\nCan you guess my number?\nPlease type your first guess."<<endl;
     	    	continue;
			 }	
		}
     	else if(guess<num)
     	{
     		cout<<"Too low. Try again."<<endl;
     		continue;
		 }
		else if(guess>num)
		{
			cout<<"Too high. Try again."<<endl;
			continue;
		}
	}
	return 0;
 } 

*还是一样注意 srand(time(0)) 的位置要合适


6.递归的最大公约数:

【问题描述】整数x和y的最大公约数是可以同时整除x和y的最大整数。编写一个递归函数gcd求解x和y的最大公约数。如果y==0那么gcd(x,y)等于x;否则gcd(x,y)等于gcd(y,x%y),其中%是取模运算符。注意:对于这个算法必须自行考虑x和y的大小。

【输入形式】两个整数x y(x可能比y小)
【输出形式】一个整数
【样例输入】10 15
【样例输出】5
【样例说明】所有输入保证在int范围内

实现代码:

#include <iostream>
#include <algorithm>
using namespace std;
int gcd(int x, int y) {
	int n = max(x, y);
	int m = min(x, y);
	if (y == 0) {
		return n;
	}
	return (gcd(m, n%m));
}
int main() {
	int x, y;
	cin >> x;
	cin >> y;
	gcd(x, y);
	cout << gcd(x, y) << endl;
	return 0;
}

7.改错题(6.43):

原代码如下:

#include<iostream>
using namespace std;

int main(){
    
    int c = 0;
    
    if( (c=cin.get())!=EOF )
    {
        fun1();
        cout << c;
    }

}

代码分析:该段代码主要想实现的功能是将输入的字符通过cin.get()转化为其ASCll码进行输出

原理:在C++中,字符和整数之间存在隐式的类型转换。cin.get()方法会读取输入流中的下一个字符,并以其整数ASCll码值返回。在C++中,字符类型(如char)可以被看作是对应的ASCII码的整数值。

我们注意到上面的语句用int整型定义c,然后后面通过c = cin.get()读取输入的字符。

当我们在程序中使用int c来接收从输入流中读取的字符时,C++会根据需要进行隐式类型转换,将字符类型转换为整数类型。因此,在c = cin.get()这一行代码中,输入的字符会被转换为对应的ASCII码,并存储在整型变量c中。然后,当我们使用cout << c输出整型变量c时,就输出了原来输入字符的ASCll码。

所以,这段程序能够将输入的字符转换为输出的ASCII码,依托于字符和整数之间的隐式类型转换机制。

错因分析:调用了未定义的函数fun1()。在C++中,如果要调用一个函数,需要在调用之前进行函数的声明或者定义。在给定的代码中,并未提供fun1()函数的声明或定义。

解决方案:由于fun1()函数未给予声明,我们尝试将其直接删去,或在main函数前声明一下。

1.直接删除

#include<iostream>
using namespace std;
int main() {
	int c = 0;

	if ((c = cin.get()) != EOF)
	{
		cout << c;
	}
}

2.在main函数前声明一下空函数fun1()

#include<iostream>
using namespace std;
void fun1() {}
int main() {
	int c = 0;

	if ((c = cin.get()) != EOF)
	{
		fun1();
		cout << c;
	}
}

结果正确

148169825f9748459e9fc50a3c5fc58a.png

上述两种方案都有效解决了问题。


拓展:若要实现循环读取c,输出其ASCll码的功能,直至输入ctrl+z退出循环。

考虑将 if 改成 while    (此处直接将fun1()函数删除)

#include<iostream>
using namespace std;
int main() {
	int c = 0;

	while((c = cin.get()) != EOF)
	{
		cout << c<< endl;
	}
}

结果如下:

2cf5284965cf4a78b49a0e14052b4c44.png

我们惊讶地发现莫名其妙多了一行10。实际上这个10是换行符的ASCll值。原因可能为cin.get()语句按下enter键的同时读取了换行符。

解决方案:

法一

#include <iostream>
using namespace std;

int main() {
	int c = 0;
	while ((c = cin.get()) != EOF) {
		if (c != 10) { // 跳过换行字符的ASCII码10
			cout << c << endl;
		}
	}
	return 0;
}

法二( 当读取到换行符后,将其清除---cin.ignore() )

#include <iostream>
using namespace std;

int main() {
	int c = 0;
	while ((c = cin.get()) != EOF) {
		if (c == '\n') {
			// 清除换行符
			cin.ignore();
		}
		cout << c << endl;
	}
	return 0;
}

结果均正确

c3ddaa59e1f04ed4b4a90a067569525e.png

 

——但我们不理解的地方在于为什么if语句没有出现上述问题,而if一被改为while则会出现该问题


8.该程序做什么(6.44):

原代码如下:

#include<iostream>
using namespace std;
int mystery(int, int);
int main()
{
	int x = 0;
	int y = 0;
	cout << "Enter two integers:";
	cin >> x >> y;
	cout << "The result is " << mystery(x, y) << endl;
}
int mystery(int a, int b)
{
	if (1 == b)
		return a;
	else
		return a + mystery(a, b - 1);
}

随便输入两个数进行几次测试,不难发现这个程序实现了两个输入的数相乘的效果。

分析得出:这段代码实现了一个递归函数 mystery,就是由其实现了计算两个整数的乘积的效果。具体来说,当第二个参数 b 为 1 时,函数返回第一个参数 a 本身(因为任何数乘以 1 都等于本身);否则,函数返回第一个参数 a 加上 mystery 函数对第一个参数和第二个参数减一后的递归调用结果的和。这代表着函数会将第一个参数 a 相加 b 次,最终得到两个数的乘积。

举个例子,假设我们调用 mystery(3, 4),根据函数定义,它会调用 mystery(3, 3) 并将其结果加上 3,即 3 + mystery(3, 3)。同样地,mystery(3, 3) 又会调用 mystery(3, 2) 并将其结果加上 3,也就是 3 + mystery(3, 2)。以此类推,直到 mystery函数的第二个参数变成 1,这时函数会直接返回第一个参数 a 的值 3。然后,上述递归调用的结果会依次相加,得到最终结果:

3 + (3 + (3 + 3)) = 3×4 = 12。因此,mystery(3, 4) 的结果就是 12,即 3 乘以 4。


9.改错题(6.47):

原代码如下:

//(a)
float cube(float);

cube(float number)
{
	return number * number * number;
}

//(b)
int randomNumber = srand();

//(c)
float y = 123.45678;
int x;

x = y;
cout << static_cast<float>(x) << endl;

//(d)
double square(double number)
{
	double number = 0;
	return number * number;
}

//(e)
int sum(int n)
{
	if (0 == n)
		return 0;
	else
		return n + sum(n);
}

a) 错误:在函数定义中,应该包含函数的返回类型。函数定义形式错误。

    修改:

float cube(float number)
{
    return number * number * number;
}

b) 错误:srand()函数返回一个无符号整数,不适用于直接赋值给int类型的变量。应该使用rand()函数生成随机数。

    修改:

int randomNumber = rand();

c) 错误:尝试将浮点数赋值给整型变量会导致精度损失和数据截断。应该使用static_cast进行类型转换。

    修改:

float y = 123.45678;
int x;

x = static_cast<int>(y);
cout << static_cast<float>(x) << endl;

d) 错误:在函数体内部,不能重新声明函数参数。应该修改为不同的变量名。

    修改:

double square(double number)
{
    double result = 0;
    return number * number;
}

e) 错误:递归函数sum()没有正确终止条件,会导致无限递归。应该在递归调用之前加上判断条件。

    修改:

int sum(int n)
{
    if (0 == n)
        return 0;
    else
        return n + sum(n-1);
}

---------------汇报结束--------------

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值