zoukankan      html  css  js  c++  java
  • c++提高学习笔记——05-c++STLday13_贪吃蛇案例

    在学习c++提高-STL总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

    05-c++STLday13_贪吃蛇案例

    目录:
    一、上节作业——综合案例(学校演讲比赛)
    二、贪食蛇案例

    一、上节作业——综合案例(学校演讲比赛

    》比赛规则:某市举行一场演讲比赛( speech_contest ),共有24个人参加。比赛共三轮,前两轮为淘汰赛,第三轮为决赛。

    》比赛方式:分组比赛,每组6个人;选手每次要随机分组,进行比赛;

    >第一轮分为4个小组,每组6个人。比如编号为: 100-123.  整体进行抽签(draw)后顺序演讲。当小组演讲完后,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。

    >第二轮分为2个小组,每组6人。比赛完毕,淘汰组内排名最后的三个选手,然后继续下一个小组的比赛。

    >第三轮只剩下1组6个人,本轮为决赛,选出前三名。
        
    》比赛评分:10个评委打分,去除最低、最高分,求平均分每个选手演讲完由10个评委分别打分。该选手的最终得分是去掉一个最高分和一个最低分,求得剩下的8个成绩的平均分。选手的名次按得分降序排列。

    用STL编程,求解这个问题
    1)请打印出所有选手的名字与参赛号,并以参赛号的升序排列。
    2)打印每一轮比赛后,小组比赛成绩和小组晋级名单



    需求分析
    1) 产生选手 ( ABCDEFGHIJKLMNOPQRSTUVWX ) 姓名、得分;选手编号
    2) 第1轮    选手抽签 选手比赛 查看比赛结果
    3) 第2轮    选手抽签 选手比赛 查看比赛结果
    4) 第3轮    选手抽签 选手比赛 查看比赛结果

    实现思路
    需要把选手信息、选手得分信息、选手比赛抽签信息、选手的晋级信息保存在容器中,需要涉及到各个容器的选型。
    选手可以设计一个类Speaker(姓名和得分)
    所有选手的编号可以单独放在一个vector容器中,做抽签用

    所有选手编号和选手信息,可以放在容器内:map<int, Speaker>

    所有选手的编号名单,可以放在容器:vecter<int> v1中

    第1轮晋级编号名单,可以放在容器vecter<int> v2中

    第2轮晋级编号名单,可以放在容器vecter<int> v3中

    第3轮前三名名单,可以放在容器vecter<int> v4中

    每个小组的比赛得分信息,按照从大到小的顺序放在multimap<成绩, 编号, greater<int>>中

    每个选手的得分,可以放在容器deque<int> dscore; 方便去除最低最高分.


    代码如下:

      1 #define _CRT_SECURE_NO_WARNINGS
      2 #include<iostream>
      3 using namespace std;
      4 #include<vector>
      5 #include<map>
      6 #include<string>
      7 #include<algorithm>
      8 #include<deque>
      9 #include<numric>
     10 #include<functional>
     11 #inlcude<ctime>
     12 
     13 /*
     14 需求分析:
     15 1) 产生选手 ( ABCDEFGHIJKLMNOPQRSTUVWX ) 姓名、得分;选手编号
     16 
     17 2) 第1轮    选手抽签 选手比赛 查看比赛结果 
     18 3) 第2轮    选手抽签 选手比赛 查看比赛结果
     19 4) 第3轮    选手抽签 选手比赛 查看比赛结果
     20 
     21 */
     22 class Speaker
     23 {
     24 public:
     25     
     26     string m_Name;//姓名
     27     int m_Score[3];//得分数组
     28 };
     29 
     30 void createSpeaker(vector<int>& v, map<int, Speaker>& m)
     31 {
     32     string nameSeed = "ABCDEFGHIJKLMNOPQRSTUVWX";
     33     for(int i = 0; i < nameSeed.size(); i++)
     34     {
     35         string name = "选手";
     36         name += nameSeed[i];
     37         
     38         Speaker sp;
     39         sp.m_Name = name;
     40         for(int j = 0; j < 3; j++)
     41         {
     42             sp.m_Score[j] = 0;
     43         }
     44         
     45         v.push_back(i + 100);//编号100~123
     46         m.insert(make_pair(i + 100, sp));
     47     }
     48     
     49 }
     50 
     51 //抽签
     52 void speechDraw(vector<int>v)
     53 {
     54     //洗牌
     55     random_shuffle(v.begin(), v.end());
     56 }
     57 
     58 //index存放第几轮,v1存放比赛选手编号,m是选手编号和具体选手,v2存放晋级选手编号容器
     59 void speechContest(int index,vector<int>& v1, map<int, Speaker>& m, vector<int>& v2)
     60 {
     61     //临时容器:key 分数,value 编号
     62     multimap<int, int, greater<int>>groupMap;
     63     int num = 0;
     64     for(vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
     65     {
     66         num++;
     67         deque<int>d;
     68         for(int i = 0; i < 10; i++)
     69         {
     70             int score = rand() % 41 + 60;//60~100
     71             d.push_back(score);
     72         }
     73         //排序
     74         sort(d.begin(), d.end());
     75         //去除最高最低分
     76         d.pop_back();
     77         d.pop_front();
     78         //累积分数
     79         int sum = accumulate(d.begin(), d.end(), 0);
     80         int avg = sum / d.size();
     81         
     82         //将平均分放入到m容器中
     83         m[*it].m_Score[index - 1] = avg;
     84         
     85         //每6个人,取前三名晋级
     86         //临时容器,保存6个人
     87         //临时容器,存入数据
     88         groupMap.insert(make_pair(avg, *it));
     89         
     90         if(num % 6 == 0)
     91         {
     92             /*
     93             cout << "各个小组比赛成绩如下:" << endl;
     94             for(multimap<int, int, greater>:: iterator mit = groupMap.begin(); mit != groupMap.end(); mit++)
     95             {
     96                 cout << "选手编号:" << mit->second << "  姓名:" << m[mit->second].m_Name << "  得分:" << m[mit->second].m_Score[index-1] << endl;
     97             }
     98             */
     99             
    100             //取前三名
    101             int count = 0;
    102             for(multimap<int, int, greater>:: iterator mit = groupMap.begin(); mit != groupMap.end(), count < 3; mit++, count++)
    103             {
    104                 //晋级容器,获取数据
    105                 v2.push_back(mit->second);
    106             }
    107             
    108             groupMap.clear();//清空临时容器
    109         }
    110     }
    111     
    112     
    113     
    114 }
    115 
    116 
    117 void showScore(int index, vector<int>& v, map<int, Speaker>& m)
    118 {
    119     cout << "" << index << "轮,比赛成绩如下:" << endl;
    120     
    121     for(map<int, Speaker>::iterator it = m.begin(); it != m.end(); it++)
    122     {
    123         cout << "选手编号:" << it->first << "姓名:" << it->second.m_Name << "分数:" << it->second.m_Score[index-1] << endl;
    124     }
    125     
    126     cout << "晋级选手编号" << endl;
    127     for(vector<int>::iterator it = v.begin(); it != v.end(); it++)
    128     {
    129         cout << *it << endl;
    130     }
    131     
    132 }
    133 
    134 
    135 
    136 void test01()
    137 {
    138     //最后添加随机数种子
    139     srand((unsigned int)time(NULL));
    140     
    141     vector<int>v1;//选手编号
    142     
    143     map<int, Speaker>m;//存放选手编号和对应的具体的选手
    144     
    145     //创建选手
    146     createSpeaker(v1, m);
    147     
    148     /*
    149     //测试
    150     for(map<int, Speaker>::iterator it = m.begin(); it!= m.end(); it++)
    151     {
    152         cout << "选手编号:" << it->first << "姓名:" << it->second.m_Name << endl;
    153     }
    154     */
    155     
    156     //抽签
    157     speechDraw(v1);
    158     
    159     vector<int>v2;//进入下一轮比赛的人员编号
    160     
    161     //第一轮比赛
    162     speechContest(1, v1, m, v2);
    163     
    164     //显示比赛结果
    165     showScore(1, v2, m);//轮数 晋级编号 具体人员信息
    166     
    167     //第二轮比赛
    168     speechDraw(v2);
    169     vector<int>v3;//进入下一轮比赛的人员编号
    170     speechContest(2, v2, m, v3);
    171     showScore(2, v3, m);
    172     
    173     //第三轮比赛
    174     speechDraw(v3);
    175     vector<int>v4;//进入下一轮比赛的人员编号
    176     speechContest(3, v3, m, v4);
    177     showScore(3, v4, m);
    178     
    179 }
    180 
    181 int main()
    182 {
    183     test01();
    184     
    185     system("pause");
    186     return EXIT_SUCCESS;
    187 }

    二、贪食蛇案例

    总结:

    1、玩法介绍

    2、具体实现

    3、墙模块

    3.1 二维数组维护,游戏内容

    3.2 初始化二维数组:initwall

    3.3 画出墙壁 drawwall

    3.4 提供对外接口setwall、getwall

    3.5测试

    4、蛇模块

    4.1 初始化蛇

    4.2 销毁所有结点

    4.3 添加新结点

    5、食物模块

    5.1 foodX、foodY位置

    5.2 setFood对外接口,可以设置食物

    5.3 随机出两个可以放置的位置,设置#

    6、删除结点和移动蛇的封装

    6.1 删除结点,通过两个临时结点,删除尾结点

    6.2 移动,判断用户输入内容,然后进行移动操作

    7、接收用户输入

    7.1 接收一个字符,让蛇移动第一步

    7.2 用户输入按键后,进行自动移动

    8、解决bug

    8.1 按键冲突

    8.2 180度不可以转

    8.3 死亡撞墙,多走一步

    8.4 循环追尾,不要进入死亡判断

    9、辅助玩法

    9.1 难度设定,根据蛇身段,产生不同难度

    9.2 分数设定

    10、优化游戏

    代码如下:

    game.cpp

      1 #define _CRT_SECURE_NO_WARNINGS
      2 #include<iostream>
      3 using namespace std;
      4 #include"wall.h"
      5 #include"snake.h"
      6 #include"food.h"
      7 #include<ctime>
      8 #include<conio.h>
      9 #include<window.h>
     10 
     11 void gotoxy(HANDLE hOut, int x, int y)
     12 {
     13     COORD pos;
     14     pos.X = x;             //横坐标
     15     pos.Y = y;            //纵坐标
     16     SetConsoleCursorPosition(hOut, pos);
     17 }
     18 HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//定义显示器句柄变量
     19 
     20 
     21 
     22 void test01()
     23 {
     24     //添加随机种子
     25     srand((unsigned int)time(NULL));
     26     
     27     //是否死亡的标识
     28     bool isDead = false;
     29     
     30     //上一步的标识
     31     char preKey = NULL;
     32     
     33     Wall wall;
     34     wall.initWall();
     35     wall.drawWall();
     36     
     37     /*
     38     //测试
     39     wall.setWall(5, 4, '=');
     40     wall.setWall(5, 5, '=');
     41     wall.setWall(5, 6, '@');
     42     
     43     wall.drawWall();
     44     
     45     cout << wall.getWall(0, 0) << endl;
     46     cout << wall.getWall(5, 4) << endl;
     47     cout << wall.getWall(5, 6) << endl;
     48     cout << wall.getWall(1, 1) << endl;
     49     */
     50     Food food(wall);
     51     food.setFood();
     52     
     53     Snake snake(wall, food);
     54     snake.initSnake();
     55     
     56     /*
     57     //测试
     58     snake.move('w');
     59     snake.move('w');
     60     snake.move('a');
     61     */
     62     //snake.delPoint();//测试删结点
     63     
     64     //wall.drawWall();
     65     gotoxy(hOut, 0, Wall::ROW);
     66     
     67     cout << "得分:" << snake.getScore() << "" << endl;
     68     
     69     //gotoxy(hOut, 10, 5);//坐标系相反;y*2,x
     70     
     71     //接收用户的输入
     72     while(!isDead)
     73     {
     74         char key = _getch();
     75         
     76         //判断,如果是第一次按了左键,才不能激活游戏
     77         //判断上一次移动方向
     78         if(preKey == NULL && key == snake.LEFT)
     79         {
     80             continue;
     81         }
     82         
     83         do
     84         {
     85             if(key == snake.UP || key == snake.DOWN || key == snake.LEFT || key == snake.RIGHT)
     86             {
     87                 //判断本次按键是否与上次冲突
     88                 if((key == snake.LEFT && preKey == snake.RIGHT)||(key == snake.RIGHT && preKey == snake.LEFT)||(key == snake.UP && preKey == snake.DOWN)||(key == snake.DOWN && preKey == snake.UP))
     89                 {
     90                     key = preKey;
     91                 }
     92                 else
     93                 {
     94                     preKey = key; //不是冲突按键,可以更新按键
     95                 }
     96                 
     97                 if(snake.move(key) == true)
     98                 {
     99                     //移动成功 代码
    100                     //system("cls");
    101                     //wall.drawWall();
    102                     gotoxy(hOut, 0, Wall::ROW);
    103                     
    104                     cout << "得分:" << snake.getScore() << "" << endl;
    105                     Sleep(snake.getSleepTime());
    106                 }
    107                 else
    108                 {
    109                     isDead = true;
    110                     break;
    111                 }
    112             }
    113             else
    114             {
    115                 key = preKey;//强制将错误按键变为上一次移动的方向
    116             }
    117     
    118         }while(!_kbhit());//当没有键盘输入的时候,返回0
    119         
    120 
    121     }
    122 
    123     
    124 }
    125 
    126 int main()
    127 {
    128     test01();
    129     
    130     system("pause");
    131     return EXIT_SUCCESS;
    132 }

    wall.cpp

     1 #include"wall.h"
     2 
     3 
     4 void Wall::initWall()
     5 {
     6     for(int i = 0; i < ROW; i++)
     7     {
     8         for(int j = 0; j < COL; j++)
     9         {
    10             //放墙壁
    11             if(i == 0 || j == 0 || i == ROW - 1 || j == COL -1)
    12             {
    13                 gameArray[i][j] = '*';
    14             }
    15             else
    16             {
    17                 gameArray[i][j] = ' ';
    18             }
    19         }
    20         
    21     }
    22 }
    23 
    24 
    25 void Wall::drawWall()
    26 {
    27     for(int i = 0; i < ROW; i++)
    28     {
    29         for(int j = 0; j < COL; j++)
    30         {
    31             cout << gameArray[i][j] << " ";
    32         }
    33         if(i == 5)
    34         {
    35             cout << "create by wp";
    36         }
    37         if(i == 6)
    38         {
    39             cout << "a:left";
    40         }
    41         if(i == 7)
    42         {
    43             cout << "d:right";
    44         }
    45         if(i == 8)
    46         {
    47             cout << "w:up";
    48         }
    49         if(i == 9)
    50         {
    51             cout << "s:down";
    52         }
    53 
    54         
    55         cout << endl;
    56     }
    57 }
    58 
    59 
    60 void Wall::setWall(int x, int y, char c)
    61 {
    62     gameArray[x][y] = c;
    63 }
    64 
    65 char Wall::getWall(int x, int y)
    66 {
    67     return gameArray[x][y];
    68 }

    wall.h

     1 #ifndef _WALL_HEAD
     2 #define _WALL_HEAD
     3 #include<iostream>
     4 using namespace std;
     5 
     6 class Wall
     7 {
     8 public:
     9     enum{ROW = 26, COL = 26};
    10     
    11     //初始化墙壁
    12     void initWall();
    13     
    14     //画出墙壁
    15     void drawWall();
    16     
    17     //根据索引设置二维数组里的内容
    18     void setWall(int x, int y, char c);
    19     
    20     //根据索引获取当前位置的符号
    21     char getWall(int x, int y);
    22     
    23 private:
    24     char gameArray[ROW][COL];
    25     
    26 };
    27 
    28 
    29 
    30 
    31 
    32 
    33 #endif

    snake.cpp

      1 #include"snake.h"
      2 #include<window.h>
      3 
      4 void gotoxy1(HANDLE hOut1, int x, int y)
      5 {
      6     COORD pos;
      7     pos.X = x;             //横坐标
      8     pos.Y = y;            //纵坐标
      9     SetConsoleCursorPosition(hOut1, pos);
     10 }
     11 HANDLE hOut1 = GetStdHandle(STD_OUTPUT_HANDLE);//定义显示器句柄变量
     12 
     13 Snake::Snake(Wall& tempWall, Food& tmpFood):wall(tempWall),food(tmpFood)
     14 {
     15     pHead = NULL;
     16     isRool = false;
     17 }
     18 
     19 void Snake::initSnake()
     20 {
     21     destroyPoint();
     22     addPoint(5, 3);
     23     addPoint(5, 4);
     24     addPoint(5, 5);
     25 }
     26 
     27 void Snake::destroyPoint()
     28 {
     29     Point* pCur = pHead;
     30     
     31     while(pHead != NULL)
     32     {
     33         pCur = pHead->next;
     34         delete pHead;
     35         
     36         pHead = pCur;
     37     }
     38     
     39 }
     40 
     41 void Snake::addPoint(int x, int y)
     42 {
     43     //创建新结点
     44     Point* newPoint = new Point;
     45     newPoint->x = x;
     46     newPoint->y = y;
     47     newPoint->next = NULL;
     48     
     49     //如果原来头不为空,改为身子
     50     if(pHead != NULL)
     51     {
     52         wall.setWall(pHead->x, pHead->y, '=');
     53         
     54         gotoxy1(hOut1, pHead->y * 2, pHead->x);
     55         cout << "=";
     56     }
     57     
     58     newPoint->next = pHead;
     59     
     60     pHead = newPoint;//更新头部
     61     
     62     wall.setWall(pHead->x, pHead->y, '@');
     63     
     64     gotoxy1(hOut1, pHead->y * 2, pHead->x);
     65     cout << "@";
     66 }
     67 
     68 void Snake::delPoint()
     69 {
     70     //两个结点以上,才去做删除操作
     71     if(pHead == NULL || pHead->next == NULL)
     72     {
     73         return;
     74     }
     75     
     76     Point* pCur = pHead->next;
     77     Point* pPre = pHead;
     78     
     79     while(pCur->next != NULL)
     80     {
     81         pPre = pPre->next;
     82         pCur = pCur->next;
     83     }
     84     //删除尾结点
     85     
     86     wall.setWall(pCur->x, pCur->y, ' ');
     87     gotoxy1(hOut1, pCur->y * 2, pCur->x);
     88     cout << " ";
     89     
     90     delete pCur;
     91     pCur = NULL;
     92     pPre->next = NULL;
     93 }
     94 
     95 bool Snake::move(char key)
     96 {
     97     int x = pHead->x;
     98     int y = pHead->y;
     99     
    100     switch(key)
    101     {
    102         case UP:
    103             x--;
    104             break;
    105         case DOWN:
    106             x++;
    107             break;
    108         case LEFT:
    109             y--;
    110             break;
    111         case RIGHT:
    112             y++;
    113             break;
    114         default:
    115             break;
    116     }
    117     
    118     //判断:如果是下一步碰到的尾巴,不应该死亡
    119     Point* pCur = pHead->next;
    120     Point* pPre = pHead;
    121     
    122     while(pCur->next != NULL)
    123     {
    124         pPre = pPre->next;
    125         pCur = pCur->next;
    126     }
    127     if(pCur->x == x && pCur->y == y)
    128     {
    129         //碰到尾巴,成为循环
    130         isRool = true;
    131     }
    132     else
    133     {
    134         //判断用户到达位置是否成功
    135         if(wall.getWall(x, y) == '*' || wall.getWall(x, y) = '=')
    136         {
    137             addPoint(x,y);//如果是*的话,再多走一步,但是吃掉自己也会出问题,可以更改上面的if分开进行判断
    138             delPoint();
    139             system("cls");
    140             wall.drawWall();
    141             
    142             cout << "得分:" << getScore() << "" << endl;
    143             cout << "GAME OVER!!!" << endl;
    144             return false;
    145         }
    146     }
    147 
    148     
    149     //移动成功分两种
    150     //吃到食物 未吃到食物
    151     if(wall.getWall(x, y) == '#')
    152     {
    153         addPoint(x, y);
    154         
    155         //重新设置食物
    156         food.setFood();
    157     }
    158     else
    159     {
    160         addPoint(x, y);
    161         delPoint();
    162         if(isRool == true)
    163         {
    164             wall.setWall(x, y, '@');
    165             gotoxy1(hOut1, y * 2, x);
    166             cout << "@";
    167         }
    168     }
    169     return true;
    170 }
    171 
    172 int Snake::getSleepTime()
    173 {
    174     int sleepTime = 0;
    175     int size = countList();
    176     if(size < 5)
    177     {
    178         sleepTime = 300;
    179     }
    180     else if(size >= 5 && size <= 8)
    181     {
    182         sleepTime = 200;
    183     }
    184     else
    185     {
    186         sleepTime = 100;
    187     }
    188     return sleepTime;
    189 }
    190 int Snake::countList()
    191 {
    192     int size = 0;
    193     Point* curPoint = pHead;
    194     while(curPoint != NULL)
    195     {
    196         size++;
    197         curPoint = curPoint->next;
    198     }
    199     return size;
    200 }
    201 
    202 int Snake::getScore()
    203 {
    204     int size = countList();
    205     
    206     int score = (size - 3) * 100;
    207     
    208     return score;
    209 }

    snake.h

     1 #pragma once
     2 #include<iostream>
     3 using namespace std;
     4 #include"wall.h"
     5 #include"food.h"
     6 
     7 class Snake
     8 {
     9 public:
    10     
    11     Snake(Wall& tempWall, Food& food);
    12     
    13     enum{ UP = 'w', DOWN = 's', LEFT = 'a', RIGHT = 'd'};
    14     
    15     
    16     //结点
    17     struct Point
    18     {
    19         //数据域
    20         int x;
    21         int y;
    22         
    23         //指针域
    24         Point* next;
    25     };
    26     
    27     //初始化
    28     void initSnake();
    29     
    30     //销毁所有结点
    31     void destroyPoint();
    32     
    33     //添加结点
    34     void addPoint(int x, int y);
    35     
    36     //删除结点
    37     void delPoint();
    38     
    39     //移动蛇操作
    40     //返回值代表移动是否成功
    41     bool move(char key);
    42     
    43     //设定难度
    44     //设定刷屏时间
    45     int getSleepTime();
    46     //获取蛇身段
    47     int countList();
    48     
    49     //获取分数
    50     int getScore();
    51     
    52     Point* pHead;
    53     
    54     Wall& wall;
    55     
    56     Food& food;
    57     
    58     bool isRool;//判断碰到尾巴的标识
    59 };

    food.cpp

     1 #pragma once
     2 #include<iostream>
     3 using namespace std;
     4 #include"wall.h"
     5 
     6 class Food
     7 {
     8 public:
     9     Food(Wall& tempWall);
    10     
    11     //设置食物
    12     void setFood();
    13     
    14     int foodX;
    15     int foodY;
    16     
    17     Wall& wall;
    18 };

    food.h

     1 #include"food.h"
     2 #include<window.h>
     3 
     4 void gotoxy2(HANDLE hOut2, int x, int y)
     5 {
     6     COORD pos;
     7     pos.X = x;             //横坐标
     8     pos.Y = y;            //纵坐标
     9     SetConsoleCursorPosition(hOut2, pos);
    10 }
    11 HANDLE hOut2 = GetStdHandle(STD_OUTPUT_HANDLE);//定义显示器句柄变量
    12 
    13 Food::Food(Wall& tempWall):wall(tempWall)
    14 {
    15     
    16 }
    17 
    18 void Food::setFood()
    19 {
    20     
    21     while(true)
    22     {
    23         foodX = rand() % (Wall::ROW - 2) + 1;
    24         foodY = rand() % (Wall::COL - 2) + 1;
    25         
    26         //如果随机的位置是蛇头或蛇身,就重新生成随机数
    27         if(wall.getWall(foodX, foodY) == ' ')
    28         {
    29             wall.setWall(foodX, foodY, '#');
    30             gotoxy2(hOut2, foodY * 2, foodX);
    31             cout << "#";
    32             break;
    33         }
    34     }
    35 }

    在学习c++提高-STL总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

  • 相关阅读:
    149. Max Points on a Line(js)
    148. Sort List(js)
    147. Insertion Sort List(js)
    146. LRU Cache(js)
    145. Binary Tree Postorder Traversal(js)
    144. Binary Tree Preorder Traversal(js)
    143. Reorder List(js)
    142. Linked List Cycle II(js)
    141. Linked List Cycle(js)
    140. Word Break II(js)
  • 原文地址:https://www.cnblogs.com/Alliswell-WP/p/CPlusPlus_ImprovedLearning_04.html
Copyright © 2011-2022 走看看