C++课程笔记.
C++简介
C语言于1969年至1973年间,为了移植与开发UNIX操作系统,由丹尼斯·里奇(Dennis Ritchie)与肯·汤普逊(Ken Thompson),以B语言为基础,在贝尔实验室设计、开发出来.
但C仅是一个面向过程的语言. 为了实现更好的C ,比雅尼·斯特劳斯特鲁普(Bjarne Stroustrup)博士在贝尔实验室工作期间在20世纪80年代发明并实现了C++. 起初,这种语言被称作“C with Classes” 作为C语言的增强版出现。随后,C++不断增加新特性。虚函数、运算符重载、多继承、标准模板库、异常处理、运行时类型信息、名字空间等概念逐渐纳入标准草案。1998年,国际标准组织颁布了C++程序设计语言的第一个国际标准ISO/IEC 14882:1998.
C++程序过程

通过编辑器等手段将程序输入到计算机, 生成.cpp磁盘文件, 编译器进行编译转换为机器语言文件.obj, 再将多个目标文件与库文件等链接生成可执行文件, 然后运行/调试.
C++关键字

C++标识符
- 以大写字母、小写字母或下划线开始。
- 可以由以大写字母、小写字母、下划线或数字 O~9 组成
- 大小写敏感, 不能是C++关键字
基本数据类型

基础
位运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| int main() { int num_1 = 015; int num_2 = 016; int num_3 = 0xffffffff; int num_4 = 0x7fffffff; int num_5 = 0xf0ffffff; printf("%o\n", num_1 & num_2); printf("%o\n", num_1 | num_2); printf("%o\n", num_1 ^ num_2); printf("%x\n", ~num_3);
printf("%o\n", num_1 << 2); printf("%o\n", num_1 >> 2);
printf("%x\n", num_3 >> 4); printf("%x\n", num_3 << 4); printf("%x\n", num_4 >> 4); printf("%x\n", num_4 << 4);
printf("%x\n", num_5 << 4); return 0; }
|
类型转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| int main() { cout << 90 + 0.3333 << endl;
cout << (int)90.5 << endl; cout << int(90.5) << endl;
cout << static_cast<bool>("slacr") << endl;
return 0; }
|
简单I/O 格式控制
iostream 和 iomanip 库中有些控制格式的函数和常量标识符
https://zh.cppreference.com/w/cpp/header/iomanip
https://learn.microsoft.com/zh-cn/cpp/standard-library/ios?view=msvc-170
https://zh.cppreference.com/w/cpp/header/ios
可能用到的几个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| int main() { unsigned int hex_num = 0xffffffff;
cout << oct << hex_num << endl; cout << dec << hex_num << endl; cout << hex << hex_num << endl;
cout << noboolalpha << true << endl; cout << boolalpha << true << endl;
cout << dec << showpos; cout << -1 << endl; cout << 1 << endl; cout << noshowpos;
cout << fixed << 333.222211 << endl; cout << scientific << 333.22221 << endl;
cout << setw(6) << left << setfill('?') << "||" << "||" << endl; cout << setprecision(2) << 7.33333 << endl; return 0; }
|
自定义数据类型
typedef
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| typedef struct { string fur_color; float weight; } Cat;
int main() { Cat gaffe; gaffe.fur_color = "orange"; gaffe.weight = 18; cout << "gaffe is a " << gaffe.fur_color << " cat" << endl; return 0; }
|
enum
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| enum Choice { A, B, C };
int main() { Choice answer_sheet[3]; answer_sheet[0] = A; answer_sheet[1] = A; answer_sheet[2] = B; int score = 0; for (int i = 0; i < 3; i++) { Choice standard_answer[3] = { C, A, B }; if (answer_sheet[i] == standard_answer[i]) { score++; } } cout << "you got " << score << "/3 in total!" << endl; return 0; }
|
函数
内联函数
类的成员函数可以分为内联函数和外联函数。内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内。而说明在类体内,定义在类体外的成员函数叫外联函数。外联函数的函数体在类的实现部分。
内联函数在调用时不是像一般的函数那样要转去执行被调用函数的函数体,执行完成后再转回调用函数中,执行其后语句,而是在调用函数处用内联函数体的代码来替换,这样将会节省调用开销,提高运行速度。
内联函数与前面讲过的带参数的宏定义进行一下比较,它们的代码效率是一样的,但是内联函数要优于宏定义,因为内联函数遵循函数的类型和作用域规则,它与一般函数更相近,在一些编译器中,一旦关上内联扩展,将与一般函数一样进行调用,调试比较方便。
内联函数不是在调用时发生控制转移, 内联函数在编译时将函数体嵌入到调用处, 节省了参数传递, 控制转移等开销.
1 2 3
| inline void inline_func() { cout << "just a inline_func |=_=|" << endl; }
|
函数默认参数
函数可以有默认参数, 默认参数只能排在参数表最后. 并且声明和实现的时候函数的默认参数只用写一次, 否则重定义.
1 2 3 4 5 6 7 8 9 10 11 12
| void getRes(string ok = "", string err = "", string def = "nothing here"); int main() { getRes("everything is ok, sever is running..."); getRes("", "compile error, `syntax` invalid! "); getRes(); return 0; } void getRes(string ok , string err, string def ) { if (ok != "") cout << ok << endl; else if (err != "") cout << err << endl; else cout << def << endl; }
|
函数重载
函数名相同, 但形参个数\类型\顺序不同, 会被编译器判定为不同的函数. 在调用的过程中, 会根据同名函数的参数表判定调用哪一个函数.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| struct Hero { string name = "undefined"; int ATK = NULL; float price = NULL; };
void showAtrr(Hero& h) { cout << "┏━━━━━━┳━━━━━━━━━━━━┓" << endl; cout << "┃ name ┃" << setw(12) << h.name << "┃" << endl; cout << "┣━━━━━━╋━━━━━━━━━━━━┫" << endl; cout << "┃ ATK ┃" << setw(12) << h.ATK << "┃" << endl; cout << "┣━━━━━━╋━━━━━━━━━━━━┫" << endl; cout << "┃ price┃" << setw(12) << h.price << "┃" << endl; cout << "┗━━━━━━┻━━━━━━━━━━━━┛" << endl; }
void setAtrr(Hero& hero, string name) { hero.name = name; cout << "set name ok" << endl; showAtrr(hero); }
void setAtrr(Hero& hero, int ATK) { hero.ATK = ATK; cout << "set ATK ok" << endl; showAtrr(hero); }
void setAtrr(Hero& hero, string name, int ATK, float price) { hero.ATK = ATK; hero.name = name; hero.price = price; cout << "set all Atrr ok" << endl; showAtrr(hero); } int main() { Hero h; setAtrr(h, "ironman"); setAtrr(h, 9999); setAtrr(h, "batman", 888, 19.99F); return 0; }
|

知识点
- 实型常量默认为
double, float型可以加后缀F以区分.
- 标识不同进制可以加后缀 H(hexadecimal, HEX) O(Octal, OCT) D(Decimal, DEC) B(Binary BIN).
- 八进制和十六进制能用转义字符表示 \nnn \xnnn. 字面量 0nnn, 0xnnn.
1 2 3 4 5 6 7
| int main() { int num = 0x12; int num_char = '\x12'; cout << "num: " << num << endl; cout << "num_char: " << num_char << endl; return 0; }
|

4. 逗号也是一个运算符, 先求左式, 在求右式, 结果为左式.
1 2 3 4 5 6
| int main() { int num = 0; num = (num++, num++, 3 * num); cout << num; return 0; }
|
参考
- 《C++语言程序设计(第4版)》 IBSN 9787302227984
- Wikipedia-C++
- C++参考手册
- Microsoft C++文档