麦克不能飞 发布的文章

8-BT7Tz6YA20nvp0M.png

高手可以从代码推导出语言的一般语法规则,我们尝试从这个Chatgpt提供的ATM实现,学习C++一些基础概念

使用C++ 实现ATM模拟程序

ChatGPT快速给出了一个很简单的模拟程序,可以显示余额,存款,取款基本操作,当然没有很华丽的程序界面,纯粹是命令行的操作
    #include <iostream>
    #include <iomanip>
    
    using namespace std;
    
    class ATM {
    private:
        double balance;
    
    public:
        ATM(double initialBalance) : balance(initialBalance) {}
    
        double getBalance() const {
            return balance;
        }
    
        void deposit(double amount) {
            if (amount > 0) {
                balance += amount;
                cout << "存款成功。当前余额为 $" << fixed << setprecision(2) << balance << endl;
            } else {
                cout << "无效的存款金额。" << endl;
            }
        }
    
        void withdraw(double amount) {
            if (amount > 0 && amount <= balance) {
                balance -= amount;
                cout << "取款成功。当前余额为 $" << fixed << setprecision(2) << balance << endl;
            } else {
                cout << "无效的取款金额或余额不足。" << endl;
            }
        }
    };
    
    int main() {
        double initialBalance;
        cout << "欢迎使用ATM模拟程序!" << endl;
        cout << "请输入您的初始余额: $";
        cin >> initialBalance;
    
        ATM atm(initialBalance);
    
        int choice;
        double amount;
    
        while (true) {
            cout << "请选择操作:" << endl;
            cout << "1. 查询余额" << endl;
            cout << "2. 存款" << endl;
            cout << "3. 取款" << endl;
            cout << "4. 退出" << endl;
            cin >> choice;
    
            switch (choice) {
                case 1:
                    cout << "当前余额为 $" << fixed << setprecision(2) << atm.getBalance() << endl;
                    break;
                case 2:
                    cout << "请输入存款金额: $";
                    cin >> amount;
                    atm.deposit(amount);
                    break;
                case 3:
                    cout << "请输入取款金额: $";
                    cin >> amount;
                    atm.withdraw(amount);
                    break;
                case 4:
                    cout << "感谢使用ATM模拟程序,再见!" << endl;
                    return 0;
                default:
                    cout << "无效的选项,请重新选择。" << endl;
                    break;
            }
        }
    
        return 0;
    }

这个简单的ATM模拟程序允许用户查询余额、存款、取款以及退出。用户可以根据菜单中的选项进行操作,并得到相应的反馈。请注意,这只是一个基本的示例程序,实际的ATM系统会更复杂,包括更多的功能和安全性考虑。希望这个示例有助于你理解如何编写一个简单的ATM模拟程序。

代码解释

这段代码是一个简单的C++程序,它模拟了一个基本的ATM(自动取款机)程序。ATM程序允许用户查询余额、存款、取款和退出。下面是对这段代码的解释:

  • 引入头文件和命名空间:

      #include <iostream>
      #include <iomanip>
      
      using namespace std;

    这里引入了两个C++标准库的头文件, 用于输入和输出, 用于格式化输出。using namespace std; 语句是为了简化代码,允许在代码中直接使用标准命名空间 std 中的函数和对象,而无需前缀 std::。

  • 定义ATM

      class ATM {
      private:
          double balance;
      
      public:
          ATM(double initialBalance) : balance(initialBalance) {}
      
          double getBalance() const {
              return balance;
          }
      
          void deposit(double amount) {
              if (amount > 0) {
                  balance += amount;
                  cout << "存款成功。当前余额为 $" << fixed << setprecision(2) << balance << endl;
              } else {
                  cout << "无效的存款金额。" << endl;
              }
          }
      
          void withdraw(double amount) {
              if (amount > 0 && amount <= balance) {
                  balance -= amount;
                  cout << "取款成功。当前余额为 $" << fixed << setprecision(2) << balance << endl;
              } else {
                  cout << "无效的取款金额或余额不足。" << endl;
              }
          }
      };

这里定义了一个 ATM 类,该类包含了账户余额(balance)和三个公有成员函数:ATM 构造函数,getBalance 函数用于查询余额,deposit 函数用于存款,withdraw 函数用于取款。构造函数初始化账户余额。

  • main函数
    int main() {
        double initialBalance;
        cout << "欢迎使用ATM模拟程序!" << endl;
        cout << "请输入您的初始余额: $";
        cin >> initialBalance;
        ATM atm(initialBalance);
    
        int choice;
        double amount;
    
        while (true) {
            cout << "请选择操作:" << endl;
            cout << "1. 查询余额" << endl;
            cout << "2. 存款" << endl;
            cout << "3. 取款" << endl;
            cout << "4. 退出" << endl;
            cin >> choice;
    
            switch (choice) {
                case 1:
                    cout << "当前余额为 $" << fixed << setprecision(2) << atm.getBalance() << endl;
                    break;
                case 2:
                    cout << "请输入存款金额: $";
                    cin >> amount;
                    atm.deposit(amount);
                    break;
                case 3:
                    cout << "请输入取款金额: $";
                    cin >> amount;
                    atm.withdraw(amount);
                    break;
                case 4:
                    cout << "感谢使用ATM模拟程序,再见!" << endl;
                    return 0;
                default:
                    cout << "无效的选项,请重新选择。" << endl;
                    break;
            }
        }
    
        return 0;
    }
  • main函数首先询问用户输入初始余额,并根据用户输入创建一个 ATM 对象。
  • 然后,使用一个无限循环来提供菜单选项,用户可以选择查询余额、存款、取款或退出。
  • 用户的选择由 cin 输入获取,并使用 switch 语句进行相应的处理。
  • 如果用户选择查询余额,ATM 对象的 getBalance 函数会被调用并显示当前余额。
  • 如果用户选择存款或取款,程序会要求用户输入金额,并调用相应的 deposit 或 withdraw 函数来更新余额。
  • 如果用户选择退出,程序会显示感谢消息并退出。
  • 如果用户输入无效的选项,程序会输出相应的错误消息。
这个程序模拟了一个简单的ATM功能,用户可以进行基本的查询和交易操作

拓展?

如果我们要给这个程序增加操作历史的查询功能该怎么搞?

8-gUJHttA242VwOeZ.png

C++中,你可以使用cout和cin进行格式化输出和输入。下面是几个示例,演示如何使用格式化控制符来控制输出和输入的格式。

格式化输出示例:

  • 输出浮点数时指定小数点位数:

      #include <iostream>
      #include <iomanip>
      
      using namespace std;
      
      int main() {
          double number = 123.45678;
          cout << fixed << setprecision(2) << number << endl; // 输出: 123.46
          return 0;
      }
  • 设置输出字段宽度:

      #include <iostream>
      #include <iomanip>
      
      using namespace std;
      
      int main() {
          int num1 = 123;
          int num2 = 45678;
          cout << setw(10) << num1 << setw(10) << num2 << endl; // 输出: "       123     45678"
          return 0;
      }

    格式化输入示例

  • 从用户输入中读取整数:

      #include <iostream>
      
      using namespace std;
      
      int main() {
          int num;
          cout << "请输入一个整数: ";
          cin >> num;
          cout << "您输入的整数是: " << num << endl;
          return 0;
      }
  • 从用户输入中读取浮点数:

    #include <iostream>
    #include <iomanip>
    
      using namespace std;
      
      int main() {
          double num;
          cout << "请输入一个浮点数: ";
          cin >> num;
          cout << "您输入的浮点数是: " << fixed << setprecision(2) << num << endl;
          return 0;
      }

    不同数制输出格式

  • 十进制数制输出

      #include <iostream>
      
      using namespace std;
      
      int main() {
          int decimalNumber = 123;
          cout << "十进制数:" << decimalNumber << endl; // 输出:十进制数:123
          return 0;
      }
  • 八进制数制输出:

      #include <iostream>
      #include <iomanip>
      
      using namespace std;
      
      int main() {
          int octalNumber = 0123; // 八进制数,前面加0表示
          cout << "八进制数:" << oct << octalNumber << endl; // 输出:八进制数:123
          return 0;
      }
  • 十六进制数制输出:

      #include <iostream>
      #include <iomanip>
      
      using namespace std;
      
      int main() {
          int hexadecimalNumber = 0x1A; // 十六进制数,前面加0x表示
          cout << "十六进制数:" << hex << uppercase << hexadecimalNumber << endl; // 输出:十六进制数:1A
          return 0;
      }

    cin输入出错或者异常处理

    在C++中,可以使用异常处理机制来处理cin输入的错误或异常情况。通常,cin可能会在以下情况下引发异常或错误:

  • 非法输入数据类型: 用户输入的数据类型与期望的不匹配。
  • 流状态错误: 例如,当文件结束或文件读取错误时。
  • 输入缓冲区溢出: 用户输入的数据超出了程序预期的范围。
  • 以下是一些处理cin输入异常的方法,使用了C++的异常处理机制:

      #include <iostream>
      #include <stdexcept>
      
      using namespace std;
      
      int main() {
          int num;
      
          try {
              cout << "请输入一个整数: ";
              if (!(cin >> num)) {
                  throw runtime_error("输入无效"); // 抛出运行时异常
              }
      
              // 处理正常输入
              cout << "您输入的整数是: " << num << endl;
          } catch (const exception& e) {
              cerr << "发生异常: " << e.what() << endl;
              // 清除输入缓冲区
              cin.clear();
              cin.ignore(numeric_limits<streamsize>::max(), '\n');
          }
      
          return 0;
      }

    在上述示例中,我们使用了try和catch块来处理异常情况。如果用户输入的不是整数,cin会抛出一个异常,然后我们在catch块中捕获并处理异常,输出错误消息并清除输入缓冲区。

    在异常处理中,你可以采取适当的措施,例如重新请求用户输入、输出错误消息、记录错误等,以便更好地处理cin输入引发的异常。

    请注意,异常处理是一种处理输入错误的一种方法,但不是唯一的方法。你还可以使用其他方式来验证和处理输入,根据具体需求来选择最合适的方法。

8-FCxNfOuUU6NV7V5.png

开灯问题

  • 问题描述:

    n盏灯,编号1~n,第一个人把所有灯打开,第二个人按下所有编号为2的倍数的开关,第三个人按下所有编号为3的倍数的开关,以此类推,一共有k个人,文最后有哪些等开着,输入n和k,输出开着的灯的编号: k<=n<=1000, 编写C++程序?

例子1:
输入:

10 5

输出:

1 4 6 7 8 10

例子2:
输入:

20 7

输出:

1 4 8 10 11 12 13 14 15 16 17 19

编写一个C++程序来模拟这个问题,根据输入的n和k计算最后哪些灯开着

#include <iostream>
#include <vector>

using namespace std;

int main() {
    int n, k;
    cout << "请输入灯的数量 n:";
    cin >> n;
    cout << "请输入操作次数 k:";
    cin >> k;

    vector<bool> lights(n, false);

    for (int i = 1; i <= k; ++i) {
        for (int j = i - 1; j < n; j += i) {
            lights[j] = !lights[j];
        }
    }

    cout << "最后开着的灯的编号是:";
    for (int i = 0; i < n; ++i) {
        if (lights[i]) {
            cout << i + 1 << " ";
        }
    }
    cout << endl;

    return 0;
}

这个程序首先读取输入的灯的数量n和操作次数k,然后创建一个bool型的vector来表示每盏灯的状态,初始状态都是关着的(false)。

然后,程序使用两层循环来模拟每个人的操作。外层循环迭代k次,模拟k个人的操作,内层循环按照当前人的编号(i)来切换对应编号的灯的状态。

最后,程序遍历vector,找出开着的灯的编号并输出。

对于比赛,程序应该严格按照题目要求,不能有多余的输入和输出; 这里为了方便演示,多了一些额外的输入与输出提示

蛇形填数

  • 问题描述:

    蛇形填数问题:在nn的方阵里面填入1, 2, ..., nn,
    要求填成蛇形,从左上角第一个格子开始,第一行开始,然后最后一列,最后一行,依次类推,构成蛇形,编写C++程序实现

例子1:
输入:

4

输出:

1       2       3       4
12      13      14      5
11      16      15      6
10      9       8       7

例子2:
请输入n的值:10
蛇形填数结果:
1 2 3 4 5 6 7 8 9 10
36 37 38 39 40 41 42 43 44 11
35 64 65 66 67 68 69 70 45 12
34 63 84 85 86 87 88 71 46 13
33 62 83 96 97 98 89 72 47 14
32 61 82 95 100 99 90 73 48 15
31 60 81 94 93 92 91 74 49 16
30 59 80 79 78 77 76 75 50 17
29 58 57 56 55 54 53 52 51 18
28 27 26 25 24 23 22 21 20 19

你可以输入不同的n和k来测试程序的功能。这个程序适用于n和k的范围在1到1000之间的情况。

#include <iostream>
#include <vector>

using namespace std;

int main() {
    int n;
    cout << "请输入n的值:";
    cin >> n;

    vector<vector<int>> matrix(n, vector<int>(n, 0));

    int num = 1;
    int row = 0, col = 0;
    int direction = 0; // 0: 向右,1: 向下,2: 向左,3: 向上

    while (num <= n * n) {
        matrix[row][col] = num++;
        
        // 向右
        if (direction == 0) {
            if (col + 1 < n && matrix[row][col + 1] == 0) {
                col++;
            } else {
                direction = 1;
                row++;
            }
        }
        // 向下
        else if (direction == 1) {
            if (row + 1 < n && matrix[row + 1][col] == 0) {
                row++;
            } else {
                direction = 2;
                col--;
            }
        }
        // 向左
        else if (direction == 2) {
            if (col - 1 >= 0 && matrix[row][col - 1] == 0) {
                col--;
            } else {
                direction = 3;
                row--;
            }
        }
        // 向上
        else if (direction == 3) {
            if (row - 1 >= 0 && matrix[row - 1][col] == 0) {
                row--;
            } else {
                direction = 0;
                col++;
            }
        }
    }

    // 输出结果
    cout << "蛇形填数结果:" << endl;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cout << matrix[i][j] << "\t";
        }
        cout << endl;
    }

    return 0;
}

8-es7xztRr0fgvXfT.png

挺不错的C++入门教程www.learncpp.com

对于将C++编程作为比赛工具学生来说,快速入门,不需要太深入语言的细节,各种高阶的语言特性、复杂的应用设计等高阶概念,能够比较熟练C++常规的语言特性,构建比赛程序足以

要快速入门,和学习大部分语言类似,从开发环境搭建、hello world程序到调试工具的使用

  • 开发环境搭建
  • hello world
  • 调试工具(IDE)
这里就将语言背景介绍略过了,有心人可以从网络搜索到各种背景知识!

C++程序开发流程

2023-09-16T02:45:15.png

上图比较概括描述了C++程序是如何被开发出来的

  • Step 1: 定义我们需要解决的问题
  • Step 2: 设计一个解决方案
  • Step 3: 编写一个程序,实现这个方案
  • Step 4: 编译这个程序
  • Step 5: 链接目标文件
  • Step 6: 测试程序
  • Step 7: 调试程序(如果有问题,不符合预期等)

    #include

    int main()
    {

      std::cout << "Colored text!";
      return 0;

    }

一些工具的介绍

  • compiler 编译器
  • linker 链接器
  • libraries 库

如果我们有多个*.cpp文件,编译器会生成的哦个object(目标)文件,如下图:
2023-09-16T02:50:26.png

链接器程序将目标文件整合成可执行程序,比如Calculator.exe

IDE(Integrated Development Enironments) 集成开发环境

从命令行到图形化开发环境,可以使用的工具很多,初学者开始可能不习惯命令行,GUI(Graphics User
Interface)图形化用户界面可能更友好一些,但是对于专业开发人员,掌握命令行的工具使用,很有必要!
  • Windows上有微软的Visual Studio 版本,
    免费的社区版,可以供学习使用;商用的适合专业开发人员
    2023-09-16T02:54:36.png
  • Code::Blocks(跨平台使用,Linux or Windows)
    Code::Blocks官方下载链接
    CodeBlocks-IDE.png
Window上下载安装比较直观;Linux上也有比较简单的安装步骤,并不复杂

为每个程序创建独立的project

在Code::Blocks里面只有创建的project,才能使用调试功能;独立建立的文件无法使用内建的调试插件
  • 在Code::Blocks里面创建一个工程:

2023-09-16T03:43:11.png

  • 需要给工程选择一个目录,用来存储工程、程序文件:
    2023-09-16T03:43:35.png
  • 建好之后,在IDE里面有个专门工程管理窗口,列出工程相关的信息、文件列表等:
    2023-09-16T03:44:12.png
    默认建立的工程代码:

    #include

    int main()
    {

      std::cout << "Hello, world!";
      return 0;

    }

  • 编译执行,快捷键Ctrl-F9, 或者Build菜单->Build

2023-09-16T04:05:02.png

8-0u1CMzUE8CXOTIK.png

一个适合中学生NOI(全国青少年信息学奥林匹克竞赛)比赛的C++编程题目入门示例。 这个题目涉及到基本的算法和数据结构,适合初学者练习。

题目:计算数字的平均值

问题描述:

给定一组整数,计算它们的平均值,并找出大于平均值的整数的数量。

输入:

第一行包含一个整数n(1 <= n <= 100),表示整数的数量。
接下来的一行包含n个整数,每个整数都在-100到100之间。

输出:

第一行输出平均值(保留两位小数)。
第二行输出大于平均值的整数的数量。

示例输入:

5
12 7 3 15 9

示例输出

9.20
3

编程要求:

请使用C++编写一个程序,读取输入数据并计算平均值以及大于平均值的整数数量。然后输出结果。

这个题目可以帮助学生练习基本的输入/输出操作,循环和条件语句的使用,以及基本的数学运算。同时,它也可以帮助他们熟悉C++的语法和编程环境。如果需要更多的编程题目,可以考虑扩展这个题目或查找其他类似的问题。

参考实现代码

#include <iostream>
#include <vector>

using namespace std;

int main() {
    int n;
    cin >> n;

    vector<int> numbers(n);
    int sum = 0;

    for (int i = 0; i < n; ++i) {
        cin >> numbers[i];
        sum += numbers[i];
    }

    double average = static_cast<double>(sum) / n;

    int countAboveAverage = 0;
    for (int i = 0; i < n; ++i) {
        if (numbers[i] > average) {
            countAboveAverage++;
        }
    }

    cout << fixed;
    cout.precision(2);
    cout << average << endl;
    cout << countAboveAverage << endl;

    return 0;
}

这段代码首先读取整数的数量n,然后使用一个vector来存储输入的整数。接着,它计算这些整数的总和,然后通过总和除以n来计算平均值。最后,它遍历整数数组,计算大于平均值的整数数量,并将结果输出到标准输出。

你可以将这段代码复制到C++编译器中进行编译和运行,以查看它的工作方式并测试不同的输入。希望这有助于你练习编程和理解基本的C++编程概念。

其他入门题目

题目1:计算阶乘

问题描述:

给定一个正整数n,计算n的阶乘。

输入:

一个正整数n(1 <= n <= 10)。

输出:

n的阶乘。

示例输入:

5

示例输出:

120

题目2:查找最大元素

问题描述:

给定一组整数,找出其中的最大元素。

输入:

第一行包含一个整数n(1 <= n <= 100),表示整数的数量。
接下来的一行包含n个整数,每个整数都在-100到100之间。

输出:

最大的整数。

示例输入:

7
12 7 3 15 9 21 8

示例输出:

21

题目3:数字反转

问题描述:

给定一个正整数,将其各位数字反转。

输入:

一个正整数x(1 <= x <= 10^9)。

输出:

x的各位数字反转后的结果。

示例输入:

12345

示例输出:

54321

这些题目涵盖了一些基本的算法和数据结构概念,包括循环、条件语句和基本的数学运算。它们可以帮助学生巩固C++编程基础和解决问题的能力。你可以使用这些题目作为练习,或者根据需要进行扩展和修改,以满足学生的需求和挑战级别

参考实现代码

题目1:计算阶乘

#include <iostream>

using namespace std;

int main() {
    int n;
    cin >> n;

    int factorial = 1;
    for (int i = 1; i <= n; ++i) {
        factorial *= i;
    }

    cout << factorial << endl;

    return 0;
}

题目2:查找最大元素

#include <iostream>
#include <vector>

using namespace std;

int main() {
    int n;
    cin >> n;

    vector<int> numbers(n);

    for (int i = 0; i < n; ++i) {
        cin >> numbers[i];
    }

    int maxNumber = numbers[0];
    for (int i = 1; i < n; ++i) {
        if (numbers[i] > maxNumber) {
            maxNumber = numbers[i];
        }
    }

    cout << maxNumber << endl;

    return 0;
}

题目3:数字反转

#include <iostream>

using namespace std;

int main() {
    int x;
    cin >> x;

    int reversed = 0;
    while (x > 0) {
        reversed = reversed * 10 + x % 10;
        x /= 10;
    }

    cout << reversed << endl;

    return 0;
}