VS Code 配置
在插件中搜索 C/C++安装
command+shift+p打开命令窗口,输入 edit选择C/Cpp: Edit Configurations生成c_cpp_properties.json
在命令行中输入gcc -v -E -x c++ -,将输出结果中的路径加到c_cpp_properties.json的includePath配置中,这样就不会出现再出现如下的报错
1 |
#include errors detected. Please update your includePath. |
C++语言数据类型
类型 | 位 | 范围 |
---|---|---|
char | 1 个字节 | -128 到 127 或者 0 到 255 |
unsigned char | 1 个字节 | 0 到 255 |
signed char | 1 个字节 | -128 到 127 |
int | 4 个字节 | -2147483648 到 2147483647 |
unsigned int | 4 个字节 | 0 到 4294967295 |
signed int | 4 个字节 | -2147483648 到 2147483647 |
short int | 2 个字节 | -32768 到 32767 |
unsigned short int | 2 个字节 | 0 到 65,535 |
signed short int | 2 个字节 | -32768 到 32767 |
long int | 4 个字节 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
signed long int | 8 个字节 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
unsigned long int | 8 个字节 | 0 到 18,446,744,073,709,551,615 |
float | 4 个字节 | 精度型占4个字节(32位)内存空间,+/- 3.4e +/- 38 (~7 个数字) |
double | 8 个字节 | 双精度型占8 个字节(64位)内存空间,+/- 1.7e +/- 308 (~15 个数字) |
long double | 16 个字节 | 长双精度型 16 个字节(128位)内存空间,可提供18-19位有效数字。 |
wchar_t | 2 或 4 个字节 | 1 个宽字符 |
常见数据类型的定义
1 2 3 4 5 6 7 8 9 |
char a[10] = "a"; short int s = 97; int m = 97; long int n = 97; float f = 97.0f; double d = 97.0; long double k = 97.0; bool b = true; wchar_t w[10] = L"a"; |
C++关键字、保留字
asm | else | new | this |
---|---|---|---|
auto | enum | operator | throw |
bool | explicit | private | true |
break | export | protected | try |
case | extern | public | typedef |
catch | false | register | typeid |
char | float | reinterpret_cast | typename |
class | for | return | union |
const | friend | short | unsigned |
const_cast | goto | signed | using |
continue | if | sizeof | virtual |
default | inline | static | void |
delete | int | static_cast | volatile |
do | long | struct | wchar_t |
double | mutable | switch | while |
dynamic_cast | namespace | template |
C++转义序列的编码
字符名称 | ASCII 符号 | C++代码 | 十进制 ASCII 码 | 十六进制 ASCII 码 |
---|---|---|---|---|
换行符 | NL(LF) | \n | 10 | 0xA |
水平制表符 | HT | \t | 9 | 0x9 |
垂直制表符 | VT | \v | 11 | 0xB |
退格 | BS | \b | 8 | 0x8 |
回车 | CR | \r | 13 | 0xD |
振铃 | BEL | \a | 7 | 0x7 |
反斜杠 | \ | \\ | 92 | 0x5C |
问号 | ? | \? | 63 | 0x3F |
单引号 | ' | \' | 39 | 0x27 |
双引号 | " | \" | 34 | 0x22 |
欧拉公式
$$e^{\pi i} + 1 = 0$$
无符号数的编码
用一个函数 B2Uw(Binary to Unsigned的缩写,长度为 w)来表示:
$$B2U_w(\vec{x})\doteq \sum_{i=0}^{w-1}{x_i2^i}$$
例:
$$B2U_4([0001]) = 0\cdot2^3 + 0\cdot2^2 + 0\cdot2^1 + 1\cdot2^0$$
有符号数的补码
用函数 B2Tw(Binary to Two’s-complement 的缩写,长度为 w)来表示:
$$B2T_w(\vec{x})\doteq -x_{w-1}2^{w-1} + \sum_{i=0}^{w-2}{x_i2^i}$$
例:
$$B2T_4([0001]) = -0\cdot2^3 + 0\cdot2^2 + 0\cdot2^1 + 1\cdot2^0$$
字节序
- Big Endian
- Little Endian
实际使用中应作用 strnlen_s, strcp_s, strncpy_s, strcat_s 这类安全 API,防止缓存区溢出等问题
C++的智能指针
- auto_ptr(已弃用)
- unique_ptr
- shared_ptr
- weak_ptr
结构体修改默认空间占用编译选项
1 2 3 4 5 6 |
// Visual C++ #pragma pack(n) // g++ __attribute__ (aligned(n)) __attribute__ (__packed__) |
C++11字符串字面值
1 2 3 4 |
wchar_t xxx[] = L"xxx"; char16_t xxx[] = u"xxx"; char32_t xxx[] = U"xxx"; R"(xxx)" // 原始字符串 |
设计模式 GoF(Gang of Four)
内存分区模型
- 代码区:存放函数体的二进制代码,由操作系统管理
- 全局区:存放全局变量、静态变量以及常量
- 栈区:由编译器自动分配释放,存放函数参数值、局部变量等
- 堆区:由程序员分配、翻译,若程序员不翻译,程序结束时由操作系统回收
推荐书籍:
入门:
《C++ Primer》 Stanley B.Lippman
最佳实践:
《C++高质量编程》 林锐
《Effective C++》侯捷(译)
《More Effective C++》侯捷(译)
《Effective STL》潘爱民(译)
《The C++ Programming Language》 Bjarne Stroustrup
深入:
《STL 源码剖析》侯捷
《COM 本质论》Don Box
《Exeptional C++》Addsion. Wesley
《Inside the C++ Object Model》Stanley B.Lippman
《The Design and Evolution of C++》Bjarne Stroustrup
Source Insight
http://download.qt.io/official_releases/qt/
一段说明运算符重载、友元函数、类、构造函数、析构函数、指针、引用、浅拷贝、深拷贝等内容的示例代码:
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
#include <iostream> using namespace std; // 自定义整型类 class MyInteger{ // 友元函数声明 friend ostream& operator<<(ostream& cout, MyInteger myInt); public: // 无参构造函数 MyInteger(){ mNum = 0; } // 有参构造函数 MyInteger(int num) { mRefNum = new int(num); } // 析构函数,清空堆区空间 ~MyInteger(){ if(mRefNum !=NULL){ delete mRefNum; mRefNum = NULL; } } // 重载前置运算符++,需返回引用,这样才能兼容++(++myInt)这样的形式 MyInteger& operator++(){ mNum++; return *this; } // 重载后置运算符++ MyInteger operator++(int){ MyInteger temp = *this; mNum++; return temp; } // 重载赋值运算符(默认为浅拷贝,重载为深拷贝,避免析构函数释放堆区空间导致的报错) MyInteger& operator=(MyInteger &m); int* mRefNum; // 公有成员变量,指针变量位于堆区,由程序员自行管理空间释放 private: int mNum; // 私有成员变量,普通变量位于栈区,程序运行结束释放空间 }; // 全局函数重置运算符<< ostream& operator<<(ostream& out, MyInteger myInt){ out << myInt.mNum; return out; } // 类内声明、类外定义 MyInteger& MyInteger::operator=(MyInteger &m){ // 释放原有堆区空间 if(mRefNum!=NULL){ delete mRefNum; mRefNum = NULL; } mRefNum = new int(*m.mRefNum); // 新开辟一段堆区空间 return *this; } void test(){ MyInteger myInt; cout << myInt++ << endl; cout << myInt << endl; cout << ++(++myInt) << endl; cout << myInt << endl; MyInteger myInt2(20); MyInteger myInt3(30); MyInteger myInt4(40); myInt3 = myInt4 = myInt2; cout << "myInt3 mRefNum: " << *myInt3.mRefNum << endl; } int main() { test(); system("read"); // macOS下无 system("pause"),使用它按Enter键后退出程序 return 0; } |
常见问题
1、 error: non-aggregate type ‘vector<int>’ cannot be initialized with an initializer list
安装C/C++ Clang Command Adapter,点击Code->Preferences->Settings, 搜索code-runner.executorMap,加入如下配置:
1 2 3 |
"code-runner.executorMap": { "cpp": "cd $dir && g++ -std=c++11 $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt", } |
其它知识
编译:Tokenization -> Syntax analysis -> Semantic analysis -> Intermediate code generation -> Optimization -> Machine code generation
1 2 3 4 5 6 7 8 9 10 11 |
# 生成待编译源码,这一步骤不进行语法检查,对宏定义的内容进行简单替换 g++ -E main.cpp # 编译为对象文件 g++ -c main.cpp # 查看编译对象文件 nm -C main.o g++ -std=c++11 main.cpp # 使用 C++ 11标准 g++ -I头文件 g++ -L链接文件 \033[xx;xxm # 设置颜色、背景 \033[0m # 重置 |
Google测试框架:https://github.com/google/googletest