C++学习 —— 重新认识C++

  我大概是从读研究生入学那天开始,想要学好C++的,学习C++几乎也成了我每个学期的计划之一。为什么会每个学期都想要学好C++呢?因为每次学习都失败了啊。。。

  本月,我开始再Coursera上学习Heterogeneous Parallel Programming 以及 北京大学的C++。也从此时开始思考C++或者说编程到底是什么,以及如何学习。

1、C++到底是什么

  我以前一直以为C++是一种语言。我的女朋友很长一段时间都和我说“帮我用VC++写个程序”,显然她觉得C++就是那个VC6.0的IDE了。经过一段时间的学习,我发现C++并不完全是一种语言,它是一种标准。就像汉字,点横竖撇捺组成方块字,每个字都是标准的,你自己不许造,造了就是错别字。如果我们自己造了C++的语法,那当然编译器是不认的。C++仅仅是一堆语法吗?

  

  不是的,C++的意义还包括了“特性”,特性和语法其实是两个层面上的东西,语法需要死记硬背,而特性则更容易被理解。C++的特性指的应该是那些比较高级的功能,继承、组合、委托、封装、泛型、模版......这些功能是为了更好的帮助我们完成程序设计。包括更少的编码,更好的管理、重用代码,更利于阅读等等。这些特性强依赖于标准,必须以标准的方式来表达,才能使用这些特性。C++强大是因为它的特性方便吗?

  

  也不完全是,C++的强大还在于它历史悠久,效率高,有很多可以使用的“库函数”。库与特性又不一样,库更接近我们的专业知识,比如PCL, OPENCV, Boost, Eigen, BLAS, 这些都是基于C/C++的库。它离我们的专业知识仅有一步之遥。很多时候我们解决专业问题会想着使用库,然后程序编译失败,程序崩溃,最终自己也崩溃了。开始质疑人生质疑价值观。这怪C++吗?

 

  这还真不怪C++,编译失败可能是语法不符合C++的标准,可能是使用某特性时没有很好的理解导致程序太乱,自己无法收场。可能是库函数本身不靠谱,可能时自己没有读明白库函数的API文档。可能是自己对专业知识的理解有问题,建模失败,导致程序里的变量和你期望的值不一样。

  

2、学习C++

  C++本身强调松耦合,然后我们在学习C++的时候,各个环节却是紧耦合的... 任何一个层面出问题,都会崩盘...

  我觉得学习C++应该是一个使用的过程,天天写些hello world除了能验证工具链正确,偶尔在语法层面做些验证以外,没有任何作用。关键的关键,就是需要一个足够大的项目,能够让C++的各种特性有用武之地,能够提升自己对C++特性的理解。至于标准层面的学习,应该是在编译器不停的报错中学会处理的吧。强大的面向对象工具 =  特性+标准。 这个工具和我们的专业知识,或者其他库函数并不耦合,不妨先用matlab完成专业知识的训练,一边训练C++的技能。一定曾都的时候将专业知识代码移植到C++上,来感受C++的效率以及自己的能力。

  我觉得学习C++就应该从特性入手,到大型程序里取体会。没写过个一两千行代码,是没法聊C++的特性的。总而言之,I have a plan, attack.

 

3、面向对象

  在完成第三周魔兽世界相关的作业后,我对类和对象又有了新的认识。C++需要我们做的就是抽象,不停的找到共性,具体的每个对象再分配特性。共性的部分就是类的成员变量名,特性的部分就是成员变量的取值不同。货车轿车本质是一类,只不过“载重”这个成员变量的取值不同。轿车消防车却不是一类,轿车并没有一个成员变量叫做”载水量“ 啊。C++的特性就是为了让我们能把心里想好的抽象能够实现出来。特性只能帮助我们实现脑子里的抽象,它并不能替我们抽象,自己脑子里都不知道应该怎样抽象,不能怪C++的特性难啊。总之面向对象是一种思路。

  最后附上第三周作业的一些代码,这些代码不能通过考核,因为Coursera 的平台不支持C++11.

  

编程题#4:魔兽世界之一:备战

 

注意: 总时间限制: 1000ms 内存限制: 65536kB

描述

魔兽世界的西面是红魔军的司令部,东面是蓝魔军的司令部。两个司令部之间是依次排列的若干城市。

红司令部,City 1,City 2,……,City n,蓝司令部

两军的司令部都会制造武士。武士一共有 dragon 、ninja、iceman、lion、wolf 五种。每种武士都有编号、生命值、攻击力这三种属性。

双方的武士编号都是从1开始计算。红方制造出来的第n个武士,编号就是n。同样,蓝方制造出来的第n个武士,编号也是n。

武士在刚降生的时候有一个生命值。

在每个整点,双方的司令部中各有一个武士降生。

红方司令部按照iceman、lion、wolf、ninja、dragon的顺序循环制造武士。

蓝方司令部按照lion、dragon、ninja、iceman、wolf的顺序循环制造武士。

制造武士需要生命元。

制造一个初始生命值为m的武士,司令部中的生命元就要减少m个。

如果司令部中的生命元不足以制造某个按顺序应该制造的武士,那么司令部就试图制造下一个。如果所有武士都不能制造了,则司令部停止制造武士。

给定一个时间,和双方司令部的初始生命元数目,要求你将从0点0分开始到双方司令部停止制造武士为止的所有事件按顺序输出。

一共有两种事件,其对应的输出样例如下:

1) 武士降生

输出样例: 004 blue lion 5 born with strength 5,2 lion in red headquarter

表示在4点整,编号为5的蓝魔lion武士降生,它降生时生命值为5,降生后蓝魔司令部里共有2个lion武士。(为简单起见,不考虑单词的复数形式)注意,每制造出一个新的武士,都要输出此时司令部里共有多少个该种武士。

2) 司令部停止制造武士

输出样例: 010 red headquarter stops making warriors

表示在10点整,红方司令部停止制造武士

输出事件时:

首先按时间顺序输出;

同一时间发生的事件,先输出红司令部的,再输出蓝司令部的。

 

输入

第一行是一个整数,代表测试数据组数。

每组测试数据共两行。

第一行:一个整数M。其含义为, 每个司令部一开始都有M个生命元( 1 <= M <= 10000)。

第二行:五个整数,依次是 dragon 、ninja、iceman、lion、wolf 的初始生命值。它们都大于0小于等于10000。

 

输出

对每组测试数据,要求输出从0时0分开始,到双方司令部都停止制造武士为止的所有事件。

对每组测试数据,首先输出"Case:n" n是测试数据的编号,从1开始 。

接下来按恰当的顺序和格式输出所有事件。每个事件都以事件发生的时间开头,时间以小时为单位,有三位。

 

样例输入            

1
20
3 4 5 6 7

           

         样例输出

Case:1
000 red iceman 1 born with strength 5,1 iceman in red headquarter
000 blue lion 1 born with strength 6,1 lion in blue headquarter
001 red lion 2 born with strength 6,1 lion in red headquarter
001 blue dragon 2 born with strength 3,1 dragon in blue headquarter
002 red wolf 3 born with strength 7,1 wolf in red headquarter
002 blue ninja 3 born with strength 4,1 ninja in blue headquarter
003 red headquarter stops making warriors
003 blue iceman 4 born with strength 5,1 iceman in blue headquarter
004 blue headquarter stops making warriors

  1 #include <iostream>
  2 #include <vector>
  3 #include <string>
  4 #include <iomanip>
  5 using namespace std;
  6 
  7 
  8 class warrior{
  9 public:
 10     warrior(int life_,string name_,int num_=0):life(life_),name(name_),num(num_){}
 11     int getLife()    const {return this->life;}
 12     string getName() const {return this->name;}
 13     int getNum()     const {return this->num;}
 14     void addOne(){this->num += 1;}
 15 private:
 16     int num;
 17     const string name;
 18     const int life;    
 19 };
 20 
 21 
 22 class headquarter{
 23 public:
 24     headquarter(const string quarterName_,int ALLLIFE_,vector<warrior> warriorList_):quarterName(quarterName_),
 25                                                                               ALLLIFE(ALLLIFE_),
 26                                                                               warriorList(warriorList_){}
 27     bool warriorBurn(int time);
 28 private:
 29     inline void __successPrint(int time,const warrior &current_warrior) const;
 30     inline bool __warriorBurn(warrior & burnwarrior);
 31     
 32     const string quarterName;
 33     int ALLLIFE;
 34     vector<warrior> warriorList;
 35 };
 36 
 37 
 38 void headquarter::__successPrint(int time,const warrior &current_warrior) const{
 39     
 40      cout<< setfill('0') << setw(3) << time;
 41     cout<<' '
 42         <<this->quarterName
 43         <<' '<<current_warrior.getName()
 44         <<' '
 45         <<(time+1)
 46         <<" with strength"
 47         <<current_warrior.getLife()
 48         <<", "
 49         <<current_warrior.getNum()
 50         <<' '
 51         <<current_warrior.getName()
 52         <<" in"
 53         <<this->quarterName
 54         <<" headquarter"
 55         <<endl;
 56 }
 57 
 58 bool headquarter::warriorBurn(int time){
 59 
 60     int current = time;
 61     while(!__warriorBurn(warriorList.at(time%5)))
 62     {
 63         time++;
 64         if(current+5 == time)
 65             {
 66                 cout<<this->quarterName<<" stop making warriors"<<endl;
 67                 return false;
 68             }
 69     }
 70     this->__successPrint(current,warriorList.at(time%5));
 71     return true;
 72 }
 73 
 74 
 75 bool headquarter::__warriorBurn(warrior & burnwarrior){
 76     
 77     int totalLife = ALLLIFE;
 78     totalLife -= burnwarrior.getLife();
 79     if(totalLife > 0)
 80     {
 81         ALLLIFE = totalLife; 
 82         burnwarrior.addOne();
 83         return true;
 84     }
 85     return false;
 86 }
 87 
 88 
 89 int main(int argc, char const *argv[])
 90 {
 91 
 92 
 93 
 94     int Case;
 95     int alllife,lionlife,ninjialife,dragonlife,wolflife,icemanlife;
 96 
 97     cin>>Case;
 98     cin>>alllife;
 99     cin>>dragonlife>>ninjialife>>icemanlife>>lionlife>>wolflife;    
100     cout<<"case:"<<Case<<endl;
101 
102 
103 
104     warrior lion(lionlife,"lion");
105     warrior ninja(ninjialife,"ninja");
106     warrior dragon(dragonlife,"dragon");
107     warrior wolf(wolflife,"wolf");
108     warrior iceman(icemanlife,"iceman");
109 
110     std::vector<warrior> red_list;
111     red_list.push_back(iceman);
112     red_list.push_back(lion);
113     red_list.push_back(wolf);
114     red_list.push_back(ninja);
115     red_list.push_back(dragon);
116 
117 
118     std::vector<warrior> blue_list;
119     blue_list.push_back(lion);
120     blue_list.push_back(dragon);
121     blue_list.push_back(ninja);
122     blue_list.push_back(iceman);
123     blue_list.push_back(wolf);
124 
125     headquarter red("red",alllife,red_list);
126     headquarter blue("blue",alllife,blue_list);
127 
128     int time = 0;
129     bool red_result = true;
130     bool blue_result = true;
131     while(1)
132     {    
133         if(red_result)
134             red_result = red.warriorBurn(time);
135         if(blue_result)
136             blue_result = blue.warriorBurn(time);
137         if(red_result || blue_result)
138         {
139             time++;
140             continue;
141         }
142         break;
143     }
144     
145     return 0;
146 }
View Code

 

posted @ 2016-07-01 16:38  IronStark  阅读(1090)  评论(0编辑  收藏  举报