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
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
using namespace std; class warrior{
public:
warrior(int life_,string name_,int num_=):life(life_),name(name_),num(num_){}
int getLife() const {return this->life;}
string getName() const {return this->name;}
int getNum() const {return this->num;}
void addOne(){this->num += ;}
private:
int num;
const string name;
const int life;
}; class headquarter{
public:
headquarter(const string quarterName_,int ALLLIFE_,vector<warrior> warriorList_):quarterName(quarterName_),
ALLLIFE(ALLLIFE_),
warriorList(warriorList_){}
bool warriorBurn(int time);
private:
inline void __successPrint(int time,const warrior ¤t_warrior) const;
inline bool __warriorBurn(warrior & burnwarrior); const string quarterName;
int ALLLIFE;
vector<warrior> warriorList;
}; void headquarter::__successPrint(int time,const warrior ¤t_warrior) const{ cout<< setfill('') << setw() << time;
cout<<' '
<<this->quarterName
<<' '<<current_warrior.getName()
<<' '
<<(time+)
<<" with strength"
<<current_warrior.getLife()
<<", "
<<current_warrior.getNum()
<<' '
<<current_warrior.getName()
<<" in"
<<this->quarterName
<<" headquarter"
<<endl;
} bool headquarter::warriorBurn(int time){ int current = time;
while(!__warriorBurn(warriorList.at(time%)))
{
time++;
if(current+ == time)
{
cout<<this->quarterName<<" stop making warriors"<<endl;
return false;
}
}
this->__successPrint(current,warriorList.at(time%));
return true;
} bool headquarter::__warriorBurn(warrior & burnwarrior){ int totalLife = ALLLIFE;
totalLife -= burnwarrior.getLife();
if(totalLife > )
{
ALLLIFE = totalLife;
burnwarrior.addOne();
return true;
}
return false;
} int main(int argc, char const *argv[])
{ int Case;
int alllife,lionlife,ninjialife,dragonlife,wolflife,icemanlife; cin>>Case;
cin>>alllife;
cin>>dragonlife>>ninjialife>>icemanlife>>lionlife>>wolflife;
cout<<"case:"<<Case<<endl; warrior lion(lionlife,"lion");
warrior ninja(ninjialife,"ninja");
warrior dragon(dragonlife,"dragon");
warrior wolf(wolflife,"wolf");
warrior iceman(icemanlife,"iceman"); std::vector<warrior> red_list;
red_list.push_back(iceman);
red_list.push_back(lion);
red_list.push_back(wolf);
red_list.push_back(ninja);
red_list.push_back(dragon); std::vector<warrior> blue_list;
blue_list.push_back(lion);
blue_list.push_back(dragon);
blue_list.push_back(ninja);
blue_list.push_back(iceman);
blue_list.push_back(wolf); headquarter red("red",alllife,red_list);
headquarter blue("blue",alllife,blue_list); int time = ;
bool red_result = true;
bool blue_result = true;
while()
{
if(red_result)
red_result = red.warriorBurn(time);
if(blue_result)
blue_result = blue.warriorBurn(time);
if(red_result || blue_result)
{
time++;
continue;
}
break;
} return ;
}
C++学习 —— 重新认识C++的更多相关文章
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- Unity3d学习 制作地形
这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...
- 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...
- 菜鸟Python学习笔记第一天:关于一些函数库的使用
2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
- node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理
一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...
随机推荐
- ftp修改上传后目录、文件权限问题 aix
问题:在AIX操作系统中,用root用户ftp文件到AIX上后,文件的默认权限是rw-r-----,Oracle用户无法读取.有没有办法指定上传文件的权限呢? 环境: AIX 6.1 解决方法: 1. ...
- python之property属性
Property的概念:property是一种特殊的属性,访问它时会执行一段功能(函数),然后返回值. import math class Circle: def __init__(self,radi ...
- Vue(二十三)vuex + axios + 缓存 运用 (以登陆功能为例)
(一)axios 封装 (1)axios拦截器 可以在axios中加入加载的代码... (2)封装请求 后期每个请求接口都可以写在这个里面... (二)vuex user.js import { lo ...
- js动态时间(转)
html代码 <span id="timeShow" show_cur_times()></span> js代码 $(function(){ //设置1秒调 ...
- Java8 stream 中利用 groupingBy 进行多字段分组求和
Java8的groupingBy实现集合的分组,类似Mysql的group by分组功能,注意得到的是一个map 对集合按照单个属性分组 case1: List<String> items ...
- kettle 6.1 按时间增量抽取数据
1.设计一个增量 配置表ETL_INCREMENTAL,用于配置表的增量时间等数据 2.增量JOB全图如下: 2.1获取增量时间变量,并设置增量变量 2.2 表的增量转换,在表中引用2.1的增量变量 ...
- LIN 笔记
LIN 使用了 1 根线来进行通信,但是,它必须要参考 VBat 和 GND.离开这两个参考电平,并没有办法来判断线上的 bit 状态. 另外,根据经典的 LIN 驱动电路(一个 OC 门),RX 接 ...
- LIBTUX_CAT:466: ERROR: tpopen TPERMERR xa_open returned XAER_INVAL
tmboot 启动Tuxedo服务失败,从ULOG日志中看到以下错误: 100534.MATHXH!TMS_ORA10G.22600.4076.0: LIBTUX_CAT:466: ERROR: tp ...
- 干货!最全羽毛球技术动态分解gif图
羽毛球的技术千变万化,但是离不开最基本的击球方法.下面通过一组形象的动态图,给你展现羽毛球的基本动作.大家,务必要收藏起来,慢慢体会哦! 一.发球 二.前场技术 1.网前球 2.搓球 3.勾球 4.推 ...
- RobotFrameWork接口项目分层及通用控制方式
1. 前言 上一篇文章介绍了在设计接口用例之前应遵守的设计规范,详见<RobotFramework接口设计规范>,当然读者公司的内部规范也不一定非得完全遵循笔者所提到的,适合自己公司内部的 ...