C++是遲早要過的坎,爲了JNI,仍是稍微拾起來一些吧。ios
我想用最簡單的事物,講述最複雜的道理,用最有趣的方式,引導最無聊的你。
面試
本故事純屬虛構
背景1988年,龍少參加
星宇國際
的面試,由於打印出了"Hello, World!"而震驚全場,馬上獲得offer.編程
林兮,20歲(
選擇困難症,需求改不斷
)
龍少,20歲(會打印輸出語句的初級工程師
)
捷特,21歲(擁有面向對象的思想中級工程師
)bash
捷特:
龍少,C++學的怎麼樣?
龍少:感受很不錯,如今我都能打印Hello,World了
捷特:不錯不錯,再接再礪
函數
#include <iostream>
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
---->[打印]----
Hello, World!
複製代碼
林夕:
用C++給我畫個臉
龍少:給你一個嘟嘴的臉
ui
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了
spa
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;
}
複製代碼
林夕:
我仔細想了一下,從美學的角度,上用波浪,下用直線,眉毛也用波浪會更好。
龍少:老哥你到底想咋樣,改來改去,很累的好嘛。
林夕:還不錯,先這樣,去午休吧,下午再說。
code
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循環
cdn
在捷特的指導下,龍少將代碼用for循環重構
#include <iostream>
using namespace std;
int main() {
auto top="~";
for (int i = 0; i < 10; ++i) {
i!=9?cout << top: cout << top<<endl;
}
std::cout << "| ~ ~ |" << 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<<endl;
}
std::cout << "| ~ ~ |" << std::endl;
std::cout << "| . . |" << std::endl;
std::cout << "| -} |" << std::endl;
for (int i = 0; i < 10; ++i) {
i!=9?cout << bottom: cout << bottom<<endl;
}
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<<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;
}
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<<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;
}
//打印第二個臉
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;
}
return 0;
}
複製代碼
捷特:
咱們要有世界設計師的自尊,決不能稱本身是CV工程師。
龍少:原本就是嘛,咱們不就是將別的東西抄抄改改嗎。
捷特無奈搖搖頭:哎,如今的年輕人啊。這樣,若是要打印兩個臉不同怎麼辦?
龍少:你是說再定義一組變量?
捷特無奈:那打印100個臉,你的代碼還能不能看了?
龍少:100個...我選擇死亡....
捷特:是時候讓函數幫你了,它能夠封裝若干條語句,而且能夠經過參數控制語句。
#include <iostream>
//聲明函數
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<<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;
}
}
複製代碼
龍少:
難以置信,居然還有這種操做,調用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 <iostream>
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 <iostream>
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;
}
複製代碼