C++ 语法基础(二)

结构化程序设计

自顶向下的分解,每个小问题设计为一个函数,公共小问题可以设计成一个库实现阶段

自底向上的实现

程序由3种基本结构组成

  • 顺序
  • 分支
  • 循环

功能

  • 提供游戏指南
  • 计算机随机产生正反面,让用户猜,报告对错结果
  • 重复玩游戏过程,直到用户不想玩了为止

顶层分解

程序要做两件事:显示程序指南;模拟玩游戏的过程。

void prn_instruction();
void play();

prn_instruction()的实现

只要一系列的输出语句把程序指南显示一下就可以了

void prn_instruction()
{
    cout << "这是一个猜硬币正反面的游戏.\n";
    cout << "我会扔一个硬币,你来猜.\n";
    cout << "如果猜对了,你赢,否则我赢。\n";
}

play()函数的实现

随机产生正反面,让用户猜,报告对错结果,然后询问是否要继续玩

  • 生成正反面:生成0和1两个随机数
  • 输入用户的猜测:抽象成一个函数get_call_from_user。

void play()
{ 
        char flag = ‘y’;
        while ( flag == ‘Y’ || flag == ‘y’)
        { 
                coin = 生成正反面;
                输入用户的猜测;
                if  (用户猜测 == coin) 
                	报告本次猜测结果正确;
                else  
                	报告本次猜测结果错误;
                询问是否继续游戏
        }
}

产生随机数

srand(time(NULL));
coin = rand() * 2 / RAND_MAX;

get_call_from_user()的实现

该函数接收用户输入的一个整型数。如果输入的数不是0或1,则重新输入,否则返回输入的值

int get_call_from_user()
{
    int guess;
    do
    {
        cout << "\n输入你的选择(0表示正面,1表示反面):";
        cin >> guess;
    } while (guess != 0 && guess != 1);
    return guess;
}

 枚举类型与头文件

知识点

程序设计时,应先考虑总体,后考虑细节;先考虑全局目标,后考虑局部目标。不要一开始就过多追求众多的细节,先从最上层总目标开始设计,逐步使问题具体化。

石头、剪子、布游戏

要求

  • 游戏规则:布覆盖石头;石头砸坏剪刀;剪刀剪碎布

  • 游戏过程:

    • 游戏者选择出石头、剪子或布

    • 计算机也随机选择一个

    • 输出输赢结果

    • 继续游戏,直到游戏者选择结束为止

    • 在此过程中,游戏者也可以阅读游戏指南或看看当前战况

第一层的分解:函数抽取(获取用户输入;获取机器输入;评判结果 ;报告结果并记录结果信息;显示目前战况;显示帮助信息)

 

类型定义格式

                          enum 枚举类型名 {元素表};

石头、剪子、布中的枚举类型

                         用户输入值的类型:enum p_r_s { paper, rock, scissor, game, help, quit } ;

                         比较结果类型:enum outcome { win, lose, tie } ;

枚举类型变量的定义

                        p_r_s select;

枚举类型变量的使用

                       赋值: select = paper;

                       比较:paper < rock 比较这两个值的内部表示

                      枚举类型不能直接输入输出

枚举类型的内部表示

  • 采用编码表示:默认用0代表pape, 1代表rock ,…,5 表示quit

  • 指定编码值

    • 希望从1而不是0开始编号,可以这样定义

      enum p_r_s { paper = 1, rock, scissor, game, help, quit } ;

    • 可以从中间某一个开始重新指定,如

      enum p_r_s { paper, rock = 5, scissor, game, help, quit } ;

 

选择题

1.

阅读下面的代码,写出输出结果

#include <bits/stdc++.h>
using namespace std;

enum fruits
{
    apple,
    banana,
    orange,
    grapes = 4,
    strawberry,
    pear
};
enum students
{
    math,
    chemistry,
    cs,
    physics,
    biology
};

int main()
{
    fruits a = apple, b = orange, c = strawberry;
    students d = math, e = physics;
    cout << (int)a << ' ' << (int)b << endl;
    cout << ((a == d) ? "Yes" : "No") << endl;
    cout << ((c <= e) ? "Yes" : "No") << endl;
    return 0;
}

 

概念

                         把程序再分成几个小的源文件。每个源文件都包含一组相关的函数

                         一个源文件被称为一个模块

模块划分标准

                       同一模块中的函数比较类似

                       块内联系尽可能大,块间联系尽可能小

案例——石头、剪刀、布游戏

游戏规则

                     布覆盖石头,石头砸坏剪刀,剪刀剪碎布

游戏的过程

  1. 游戏者选择出石头、剪子或布
  2. 计算机也随机选择一个
  3. 输出输赢结果
  4. 继续游戏,直到游戏者选择结束为止
  5. 在此过程中,游戏者也可以阅读游戏指南或看看当前战况。

石头、剪子、布中的枚举类型定义

  • 用户输入值的类型:enum p_r_s { paper, rock, scissor, game, help, quit } ;
  • 比较结果类型:enum outcome { win, lose, tie } ;

模块划分

  • 主模块:main函数
  • 获取选择的模块: selection_by_player、selection_by_machine
  • 比较模块:compare
  • 输出模块: report、prn_game_status、prn_help

Select模块的设计

  • selection_by_player

    功能:从键盘接收用户的输入并返回此输入值

    原型: p_r_s selection_by_player();

  • selection_by_machine

    功能:由机器产生一个石头、剪子、布的值,并返回

    原型: p_r_s selection_by_machine();

Compare模块的设计

  • 功能:compare函数比较用户输入的值和机器产生的值,确定输赢
  • 参数:用户输入的值和机器产生的值,都是p_r_s类型的
  • 返回值:判断的结果 , 是outcome类型
  • 原型outcome compare( p_r_s, p_r_s );

print模块的设计

  • prn_help

    功能:显示一个用户输入的指南,告诉用户如何输入他的选择。它没有参数也没有返回值

    原型: void prn_help();

  • Report

    功能:函数报告输赢结果,并记录输赢的次数

    参数:输赢结果、输的次数、赢的次数和平局的次数

    返回值:无

    原型:void report(outcome result);

  • prn_game_status

    功能:报告至今为止的战况

    参数:输的次数、赢的次数和平的次数

    返回值:无

    原型:void prn_game_status();

 

 

头文件

包含所有的符号常量定义、类型定义和函数原型声明

每个模块都include这个头文件

注意

链接时,编译器会发现这些类型定义、符号常量和函数原型的声明在程序中反复出现多次

解决方法

需要用到一个新的编译预处理命令:

 

#ifndef  标识符
… 
#endif

头文件实现格式

 

#ifndef _name_h
#define _name_h
    头文件真正需要写的内容
#endif

石头、剪刀、布游戏的头文件

 

// 文件:p_r_s.h
// 本文件定义了两个枚举类型,声明了本程序包括的所有函数原型
#ifndef P_R_S
#define P_R_S
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

enum p_r_s
{
    paper,
    rock,
    scissor,
    game,
    help,
    quit
};
enum outcome
{
    win,
    lose,
    tie
};

outcome compare(p_r_s player_choice, p_r_s machine_choice);
void prn_game_status();
void prn_help();
void report(outcome result);
p_r_s selection_by_machine();
p_r_s selection_by_player();
#endif

 

 

1.在cpp文件内include自定义的头文件,例如myMath.h,则代码是:#include ___________

 

 

2.为了防止对某个头文件的重复包含,需要在每个头文件的开头添加编译预处理指令,指令名是_______和_______

 

3.c++支持将cpp实现代码混入头文件中,来简化代码编写,c++程序的头文件后缀名是 ____

 

 

4.在头文件.h中如果要声明一个int型变量x,需要在代码int x;之前添加 ______ 关键字,并在.cpp文件中定义int x;

 主模块的实现

// 文件:main.cpp
// 石头、剪子、布游戏的主模块

#include "p_r_s.h"

int main()
{
    outcome result;
    p_r_s player_choice, machine_choice;
    // seed the random number generator
    srand(time(NULL));
    while ((player_choice = selection_by_player()) != quit)
        switch (player_choice)
        {
        case paper:
        case rock:
        case scissor:
            machine_choice = selection_by_machine();
            result = compare(player_choice, machine_choice);
            report(result);
            break;
        case game:
            prn_game_status();
            break;
        case help:
            prn_help();
        }
    prn_game_status();
    return 0;
}

 Select模块的实现

//文件:select.cpp
//包括机器选择selection_by_machine和玩家选择selection_by_player函数的实现

#include "p_r_s.h"

p_r_s selection_by_machine()
{
    int select = (rand() * 3 / (RAND_MAX + 1));
    cout << " I am ";
    switch (select)
    {
    case 0:
        cout << "paper. ";
        break;
    case 1:
        cout << "rock. ";
        break;
    case 2:
        cout << "scissor. ";
        break;
    }
    return ((p_r_s)select);
}

p_r_s selection_by_player()
{
    char c;
    p_r_s player_choice;
    prn_help();
    cout << "please select: ";
    cin >> c;
    switch (c)
    {
    case 'p':
        player_choice = paper;
        cout << "you are paper. ";
        break;
    case 'r':
        player_choice = rock;
        cout << "you are rock. ";
        break;
    case 's':
        player_choice = scissor;
        cout << "you are scissor. ";
        break;
    case 'g':
        player_choice = game;
        break;
    case 'q':
        player_choice = quit;
        break;
    default:
        player_choice = help;
        break;
    }
    return player_choice;
}

Compare模块的实现

//文件:compare.cpp 
//包括compare函数的实现

#include "p_r_s.h"

outcome compare(p_r_s player_choice, p_r_s machine_choice)
{
    outcome result;
    if (player_choice == machine_choice)
        return tie;
    switch (player_choice)
    {
    case paper:
        result = (machine_choice == rock) ? win : lose;
        break;
    case rock:
        result = (machine_choice == scissor) ? win : lose;
        break;
    case scissor:
        result = (machine_choice == paper) ? win : lose;
    }
    return result;
}

Print模块的实现

//文件:print.cpp 
//包括所有与输出有关的模块。
//有prn_game_status,prn_help和report函数

#include "p_r_s.h“
static int win_cnt = 0, lose_cnt = 0, tie_cnt = 0; //模块的内部状态

void report(outcome result)
{
    switch (result)
    {
    case win:
        ++win_cnt;
        cout << "You win. \n";
        break;
    case lose:
        ++lose_cnt;
        cout << "You lose.\n";
        break;
    case tie:
        ++tie_cnt;
        cout << "A  tie.\n";
        break;
    }
}

void prn_game_status()
{
    cout << endl;
    cout << "GAME STATUS:" << endl;
    cout << "win:" << win_cnt << endl;
    cout << "Lose:" << lose_cnt << endl;
    cout << "tie:" << tie_cnt << endl;
    cout << "Total:" << win_cnt + lose_cnt + tie_cnt << endl;
}

void prn_help()
{
    cout << endl
         << "The following characters can be used:\n"
         << "   p  for paper\n"
         << "   r   for rock\n"
         << "   s   for scissors\n"
         << "   g   print the game status\n"
         << "   h   help, print this list\n"
         << "   q   quit the game\n";
}

 设计自己的库

库的概念

:常用的工具

库的主题:同一个库中的函数都应该是处理同一类问题,自己设计的库也要有一个主题

库的通用性:在某一应用程序中提取库内容时应尽量考虑到兼容更多的应用,使其他应用程序也能共享这个库

库的设计和实现

设计库的接口:库的用户必须了解的内容,包括库中函数的原型、这些函数用到的符号常量和自定义类型,接口表现为一个头文件

设计库中的函数的实现:表现为一个源文件

库的这种实现方法称为信息隐藏

 

 

接口文件

头文件的格式

注释

头文件头上有段注释,说明库的主题、功能

每个函数声明前有一段注释,告诉用户如何使用这些函数

随机函数库接口文件

 

//文件:Random.h
//随机函数库的头文件

#ifndef _random_h
#define _random_h

//函数:RandomInit
//用法:RandomInit()
//作用:此函数初始化随机数种子
void RandomInit();

//函数:RandomInteger
//用法:n = RandomInteger(low,  high)
//作用:此函数返回一个 low 到 high 之间的随机数,包括 low 和 high
int RandomInteger(int low,  int high);

#endif

库的实现

实现文件名:与头文件的名字是相同

实现文件的格式

  • 注释(这一部分简单介绍库的功能)
  • includecpp文件所需的头文件
  • 每个实现要包含自己的头文件,以便编译器能检查函数定义和函数原型声明的一致性
  • 每个函数的实现代码(在每个函数实现的前面也必须有一段注释)

随机函数库实现文件

 

//文件:Random.cpp
//该文件实现了Random库
#include <cstdlib>
#include <ctime>
#include "Random.h"

//函数:RandomInit
//该函数取当前系统时间作为随机数发生器的种子
void RandomInit()
{
    srand(time(NULL));
}

// 函数:RandomInteger
// 该函数将0到RAND_MAX的区间的划分成high - low + 1 个 子区间。当产生的随机数落在第一个
// 子区间时,则映射成low。 当落在最后一个子区间时,映射成high。当落在第 i 个子区间时
//(i 从 0 到 high-low),则映射到low + i
int RandomInteger(int low, int high)
{
    return (low + (high - low + 1) * rand() / (RAND_MAX + 1));
}

1.统计学的一些计算在计算机的帮助下变得准确和高效,下面请给出这个有关统计学的函数库的接口文件,其中需要包含的函数和要求如下。

  1. 算数平均值计算Average():传入两个double指针代表数组的起始位置和结束位置的后一位,返回一个double表示答案
  2. 最值统计MinMax():数组表示同上,同时通过两个double的引用传递记录最小最大值的答案,无返回值
  3. 中位数统计Median():数组表示同上,返回一个double表示答案
  4. 众数统计Mode():数组表示同上,返回一个double表示答案

 

//文件:statistics.h
//统计学函数库

#ifndef _statistics_h
#define _statistics_h

//函数:Average
//用法:double ave = Average(double*, double*)
//作用:计算从数组中所有实数的算数平均值
double Average(double *begin, double *end);

//函数:MinMax
//用法:MinMax(double *, double *, double &, double &)
//作用:统计数组的最小最大值,并且通过引用传参得到结果
void MinMax(double *begin, double *end, double &Min, double &Max);

//函数:Median
//用法:double med = Median(double*, double*)
//作用:计算从数组中所有实数的中位数
double Median(double *begin, double *end);

//函数:Mode
//用法:double mod = Mode(double*, double*)
//作用:计算从数组中所有实数的众数
double Mode(double *begin, double *end);

#endif

龟兔赛跑规则

 

解题思路

  • 分别用变量tortoise和hare代表乌龟和兔子的当前位置
  • 时间用秒计算
  • 用随机数来决定乌龟和兔子在每一秒的动作
  • 根据动作决定乌龟和兔子的位置的移动
  • 跑道的长度设为70个点

模块划分

主模块:main

移动模块:move_tortoise、move_hare

输出模块:print_position

实现

主模块

#include "Random.h" //包含随机数库
#include <iostream>
using namespace std;

const int RACE_END = 70; //设置跑道的长度

int move_tortoise();
int move_hare();
void print_position(int, int, int);

int main()
{
    int hare = 0, tortoise = 0, timer = 0;

    RandomInit();                      //随机数初始化
    cout << "timer  tortoise  hare\n"; //输出表头
    while (hare < RACE_END && tortoise < RACE_END)
    {
        tortoise += move_tortoise(); //乌龟移动
        hare += move_hare();         //兔子移动
        print_position(timer, tortoise, hare);
        ++timer;
    }
    if (hare > tortoise)
        cout << "\n hare wins!\n";
    else
        cout << "\n tortoise wins!\n";

    return 0;
}

 

Move模块

用户行为生成方法

  • 利用随机数的等概率生成0-9之间的随机数
  • 当生成的随机数为0-4时,认为是第一种情况,5-6是第二种情况,7-9是第三种情况

 

// 文件名:move.cpp
#include "Random.h" //本模块用到了随机函数库

int move_tortoise()
{
    int probability = RandomInteger(0, 9); //产生0到9之间的随机数

    if (probability < 5)
        return 3; //快走
    else if (probability < 7)
        return -6; //后滑
    else
        return 1; //慢走
}
int move_hare()
{
    int probability = RandomInteger(0, 9);

    if (probability < 2)
        return 0; //睡觉
    else if (probability < 4)
        return -9; //大后滑
    else if (probability < 5)
        return 14; //快走
    else if (probability < 8)
        return 3; //小步跳
    else
        return -2; //慢后滑
}

 Print模块

// 文件名:print.cpp

#include <iostream>
using namespace std;

void print_position(int timer, int t, int h)
{
    if (timer % 6 == 0) //每隔6秒空一行
        cout << endl;
    cout << timer << '\t' << t << '\t' << h << '\n';
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++是一种通用的编程语言,它支持面向对象的编程风格,并且具有强大的系统编程能力。下面是C++的一些基础语法: 1. 注释:在C++中,注释可以用来解释代码,以便于其他人阅读和理解。单行注释使用双斜线(//),多行注释使用斜线和星号(/* ... */)。 2. 标识符:标识符是变量、函数、类等的名称。标识符由字母、数字和下划线组成,并且以字母或下划线开头。 3. 变量:在C++中,需要声明变量来存储数据。变量的声明包括类型和名称。例如,int表示整数类型,而float表示浮点数类型。 4. 数据类型:C++提供了多种数据类型,包括整型(int、short、long)、浮点型(float、double)、字符型(char)、尔型(bool)等。 5. 运算符:C++支持各种运算符,例如算术运算符(+、-、*、/)、关系运算符(==、!=、<、>)、逻辑运算符(&&、||、!)等。 6. 控制流语句:C++提供了多种控制流语句,例如条件语句(if-else)、循环语句(for、while、do-while)、跳转语句(break、continue、return)等。 7. 函数函数是可重用的代码块,用于执行特定的任务。函数函数头和函数体组成,函数头包括返回类型、函数名和参数列表。 8. 类和对象:C++是面向对象的语言,支持类和对象的概念。类是一种用户定义的数据类型,用于封装数据和方法。对象是类的实例,可以通过调用对象的方法来操作数据。 这只是C++语言的一些基础语法,还有很多其他的概念和特性。如果你对某个特定的主题有更深入的兴趣,我可以为你提供更详细的信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小馨馨的小翟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值