C++是早晚要过的坎,为了JNI,还是稍微拾起来一些吧。
我想用最简单的事物,讲述最复杂的道理,用最有趣的方式,引导最无聊的你。
本故事纯属虚构
背景1988年,龙少参加
星宇国际
的面试,因为打印出了"Hello, World!"而震惊全场,立刻得到offer.林兮,20岁(
选择困难症,需求改不断
) 龙少,20岁(会打印输出语句的初级工程师
) 捷特,21岁(拥有面向对象的思想中级工程师
)
捷特:
龙少,C++学的怎么样?
龙少:感觉很不错,现在我都能打印Hello,World了
捷特:不错不错,再接再厉
#include
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
---->[打印]----
Hello, World!
复制代码
林夕:
用C++给我画个脸
龙少:给你一个嘟嘴的脸
int main() {
std::cout << "----------" << std::endl;
std::cout << "| - - |" << std::endl;
std::cout << "| . . |" << std::endl;
std::cout << "| -} |" << std::endl;
std::cout << "----------" << std::endl;
return 0;
}
复制代码
林夕:
不怎么好看,把-改成~,我来瞅瞅
龙少:好嘞,这简单,一个个字符改一下就OK了
int main() {
std::cout << "~~~~~~~~~~" << std::endl;
std::cout << "| ~ ~ |" << std::endl;
std::cout << "| . . |" << std::endl;
std::cout << "| -} |" << std::endl;
std::cout << "~~~~~~~~~~" << std::endl;
return 0;
}
复制代码
林夕:
算了,改回来吧,这样好搓
龙少:你莫不是在玩老子?一个个字符改一下...TM真麻烦
int main() {
std::cout << "----------" << std::endl;
std::cout << "| - - |" << std::endl;
std::cout << "| . . |" << std::endl;
std::cout << "| -} |" << std::endl;
std::cout << "----------" << std::endl;
return 0;
}
复制代码
林夕:
我仔细想了一下,从美学的角度,上用波浪,下用直线,眉毛也用波浪会更好。
龙少:老哥你到底想咋样,改来改去,很累的好嘛。
林夕:还不错,先这样,去午休吧,下午再说。
int main() {
std::cout << "~~~~~~~~~~" << std::endl;
std::cout << "| ~ ~ |" << std::endl;
std::cout << "| . . |" << std::endl;
std::cout << "| -} |" << std::endl;
std::cout << "----------" << std::endl;
return 0;
}
复制代码
龙少中午愤愤不平地将这件事告诉捷特 捷特:
如果是上下一百行,你还能一个个改吗?
龙少:如果这样,我只写一遍,谁让我改,我跟谁急。
捷特:哎,年轻人就是心浮气躁。我来教你提取变量和for循环
在捷特的指导下,龙少将代码用for循环重构
#include
using namespace std;
int main() {
auto top="~";
for (int i = 0; i < 10; ++i) {
i!=9?cout << top: cout << top<"| ~ ~ |" << std::endl;
std::cout << "| . . |" << std::endl;
std::cout << "| -} |" << std::endl;
std::cout << "~~~~~~~~~~" << std::endl;
return 0;
}
复制代码
龙少:
虽然正确,但看着有点糟心,感觉比我的代码复杂了好多啊。
捷特:简单必有简单的成本,复杂必有复杂的价值。
如果林夕再让你改上面,你只要改一处就行了。
int main() {
auto top="#";
//英雄所见...
}
复制代码
龙少:
咦,果然,这样就少改9次,爽歪歪。
捷特:那下面你也照样子改一下。
虽说龙少是个萌新,但理解力还是非常好的。秒写:
int main() {
auto top="#";
auto bottom="-";
for (int i = 0; i < 10; ++i) {
i!=9?cout << top: cout << top<"| ~ ~ |" << std::endl;
std::cout << "| . . |" << std::endl;
std::cout << "| -} |" << std::endl;
for (int i = 0; i < 10; ++i) {
i!=9?cout << bottom: cout << bottom<return 0;
}
复制代码
甚至这小子还能举一反三:
int main() {
auto top="#";
auto bottom="-";
auto brow="~";
auto eyes="X";
for (int i = 0; i < 10; ++i) {
i!=9?cout << top: cout << top<"| "<< brow <<" "<< brow <<" |" << endl;
cout << "| "<< eyes <<" "<< eyes <<" |" << endl;
cout << "| -} |" << endl;
for (int i = 0; i < 10; ++i) {
i!=9?cout << bottom: cout << bottom<return 0;
}
复制代码
捷特:优秀如你,一看就是学编程的料,不过给你一点建议,勤加注释。
龙少:好,老哥说加,我就加。虽然已经面目全非,但是真的挺好用啊,下午我可以不用怕林夕了。
捷特:呵呵,你太小瞧产品的需求力了。
捷特:
如果打印两个脸该怎么办?
龙少:对于CV工程师,这易如反掌。
int main() {
auto top="#";//顶部
auto bottom="-";//底部
auto brow="~";//眉毛
auto eyes="X";//眼睛
//打印第一个脸
for (int i = 0; i < 10; ++i) {
i!=9?cout << top: cout << top<"| "<< brow <<" "<< brow <<" |" << endl;
cout << "| "<< eyes <<" "<< eyes <<" |" << endl;
cout << "| -} |" << endl;
for (int i = 0; i < 10; ++i) {
i!=9?cout << bottom: cout << bottom<for (int i = 0; i < 10; ++i) {
i!=9?cout << top: cout << top<"| "<< brow <<" "<< brow <<" |" << endl;
cout << "| "<< eyes <<" "<< eyes <<" |" << endl;
cout << "| -} |" << endl;
for (int i = 0; i < 10; ++i) {
i!=9?cout << bottom: cout << bottom<return 0;
}
复制代码
捷特:
我们要有世界设计师的自尊,决不能称自己是CV工程师。
龙少:本来就是嘛,我们不就是将别的东西抄抄改改吗。
捷特无奈摇摇头:哎,现在的年轻人啊。这样,如果要打印两个脸不一样怎么办?
龙少:你是说再定义一组变量?
捷特无奈:那打印100个脸,你的代码还能不能看了?
龙少:100个...我选择死亡....
捷特:是时候让函数帮你了,它可以封装若干条语句,并且可以通过参数控制语句。
#include
//声明函数
void printFace(const char *top, const char *bottom, const char *brow, const char *eyes);
using namespace std;
int main() {
printFace("#", "-", "~", "X");
printFace("O", "N", ".", "$");
return 0;
}
/**
* 打印一个脸
* @param top 顶部
* @param bottom 底部
* @param brow 眉毛
* @param eyes 眼睛
*/
void printFace(const char *top, const char *bottom, const char *brow, const char *eyes) {
for (int i = 0; i < 10; ++i) {
i!=9?cout << top: cout << top<"| "<< brow <<" "<< brow <<" |" << endl;
cout << "| "<< eyes <<" "<< eyes <<" |" << endl;
cout << "| -} |" << endl;
for (int i = 0; i < 10; ++i) {
i!=9?cout << bottom: cout << bottom<复制代码
龙少:
难以置信,竟然还有这种操作,调用printFace,传入四个字符就行了
捷特:现在有没有对C++有一点更深的认识?
龙少连连点头。下午面对林夕的百般刁难,龙少轻松搞定。 林夕纳闷:哥还治不了你,打印得太小了,给我放大一倍。
龙少:你怎么不让老鼠变大去抓猫
。两人小吵一架,下班后不欢而散。
捷特和龙少是邻居,也是从小到大的玩伴。两个一起坐公交回家。 龙少:
你给评评理,是不是他刁钻了。
捷特:确实有点,不过这也确实是个需求。先不说这个,给你说说面向对象编程。
龙少:哎,单身狗一个,哪有机会面向对象编程。
捷特:不是那个对象,你看,我们现在在坐公交对吧,为什么不自己走?
龙少:十几里路,你傻啊,腿走断了,太麻烦。
捷特:为什么不自己造一个公交车,自己开?
龙少:成本啊,坐个公交三毛三,造个公交少说几十万,够坐一辈子了。
捷特:所以我们只要通过 bus.go(0.33),就可以很简单的到家,其实编程里也有这种思想,就是面向对象。如果有一个Facer的小伙伴,你只需要通过它的printFace()就可以打印出一个脸,你想不想认识他? 就像这样:
#include "Facer.h"
using namespace std;
int main() {
Facer face("#", "-", "~", "X");
face.printFace();
face.bottom="V";
face.printFace();
return 0;
}
复制代码
龙少:
感觉挺棒的,要的要的。快告诉我怎么实现?
首先定义一个头文件
Facer.h
,来说明Facer的属性(字段)和能力(方法)
#include
using namespace std;
#ifndef TOLYC_FACER_H
#define TOLYC_FACER_H
class Facer {
public:
Facer(const string &top="#", const string &bottom="#", const string &brow="~", const string &eyes=".");
~Facer();
public:
string top;
string bottom;
string brow;
string eyes;
public:
void printFace() ;
};
#endif //TOLYC_FACER_H
在
Facer.cpp
中实现构造、析构方法以及功能方法的实现。
#include "Facer.h"
Facer::Facer(
const string &top,
const string &bottom,
const string &brow,
const string &eyes) : top(top),
bottom(bottom),
brow(brow),
eyes(eyes) {}
void Facer::printFace() {
for (int i = 0; i < 10; ++i) {
i != 9 ? cout << top : cout << top << endl;
}
cout << "| " << brow << " " << brow << " |" << endl;
cout << "| " << eyes << " " << eyes << " |" << endl;
cout << "| -} |" << endl;
for (int i = 0; i < 10; ++i) {
i != 9 ? cout << bottom : cout << bottom << endl;
}
}
Facer::~Facer() {
}
复制代码
龙少:
我明白了,这挺简单嘛,面向对象不过如此。
捷特:too yong too simple,这只是面向对象的冰山一角,以后有机会我跟你好好说说。这里用cout处理并不灵活,我们可以使用字符串进行拼接,再一次打印。
//
// Created by 张风捷特烈 on 2019/10/3.
//
#include
using namespace std;
#ifndef TOLYC_FACER_H
#define TOLYC_FACER_H
class Facer {
public:
Facer(const string &top="#", const string &bottom="#", const string &brow="~", const string &eyes=".");
~Facer();
public:
string top;
string bottom;
string brow;
string eyes;
public:
void printFace() ;
string getFace();
};
#endif //TOLYC_FACER_H
//
// Created by 张风捷特烈 on 2019/10/3.
//
#include "Facer.h"
Facer::Facer(
const string &top,
const string &bottom,
const string &brow,
const string &eyes) : top(top),
bottom(bottom),
brow(brow),
eyes(eyes) {}
void Facer::printFace() {
cout<< getFace() << endl;
}
Facer::~Facer() {
}
string Facer::getFace() {
string result;
for (int i = 0; i < 10; ++i) {
i != 9 ? result+=top : result+=top+"\n";
}
result+= "| " +brow + " " + brow + " |" +"\n";
result+= "| " +eyes + " " + eyes + " |" +"\n";
result+= "| -} |\n";
for (int i = 0; i < 10; ++i) {
i != 9 ? result+=bottom : result+=bottom+"\n";
}
return result;
}