├── 0.我的第一个C++2z程序:Helloworld.md ├── 1.0.基本数据类型.md ├── 1.3.语句.md ├── C++ 2z from beginner to abdicator.pdf └── README.md /0.我的第一个C++2z程序:Helloworld.md: -------------------------------------------------------------------------------- 1 | 0. 我的第一个C++2z程序:Helloworld 2 | ============ 3 | 4 | ###0. Helloworld 5 | 6 | 在之前的伪代码课程之中,我们借伪代码讲解了变量、函数与模块等概念。现在,让我们通过Helloworld来了解一下真实的C++代码。 7 | 8 | ``` 9 | import std.io; 10 | int main() 11 | { 12 | std::cout << u8"Hello, world!" << std::endl; 13 | } 14 | ``` 15 | 16 | 将这段代码输入你喜欢的编译器中并运行,你将可以看到它的输出: 17 | 18 | ```text 19 | Hello, world! 20 | ``` 21 | 22 | Well done! 你已经完成了你的第一个程序了。 23 | 24 | ###1.从读代码开始 25 | 26 | 让我们来分析一下这段代码吧 27 | 28 | ``` 29 | import std.io; 30 | int main() 31 | { 32 | std::cout << u8"Hello, world!" << std::endl; 33 | return 0; 34 | } 35 | ``` 36 | 37 | import 关键字代表导入一个模块。std.io 模块包含了主要的输入输出功能,下文中的std::cout 与 std::endl 即来自于这个模块。 38 | 39 | int main(){…} 是一个函数定义,它定义了一个返回类型为 int ,名为 main ,无参数的函数。 40 | 41 | main函数是C++中一个特殊的函数,一般代表程序的主入口点。 42 | 43 | {} 函数主体用花括号包围。 44 | 45 | std::cout …; 是一个语句,他完成了向屏幕输出并换行的功能。 46 | 47 | std::cout 是来自于std.io 模块的一个全局变量,它以“流”的形式代表了程序的基本输出。 std 是一个命名空间,用以区分不同的名称。cout 是这个变量的变量名。 48 | 49 | << (ASCII+60)与 + 、 - 一样是一个运算符,代表了向“流”中插入数据。 50 | 51 | u8"Hello, world!" 是一个字符串字面量,常常用来存储一段文本。 52 | u8 表示字符串的编码为UTF-8 53 | "…" 由双引号(ASCII+34)括起来的文本就是字符串字面量的内容了。 54 | 55 | std::endl 也是一个全局变量,用来表示刷新输出流并换行。 56 | 57 | ; 语句末尾以分号结束。 58 | 59 | return 0; 返回语句。 60 | return 是返回关键字。 61 | 0 为返回值,在main函数中返回0表示程序正常退出。 62 | 63 | 也许一些名词的细节你们现在还不了解,这些在接下来的课程中都将会有详细介绍。 64 | -------------------------------------------------------------------------------- /1.0.基本数据类型.md: -------------------------------------------------------------------------------- 1 | 基本数据类型 2 | ============ 3 | 4 | ###0.数据的内存表示 5 | 6 | ###1.整数类型 7 | 8 | int 是最基本的整数类型,至少有16位,在绝大多数的环境中都至少有32位。 9 | 10 | 对于整数类型,有两类修饰符: 11 | 12 | 符号性: 13 | 14 | signed – 有符号(整数类型默认为有符号,如果省略) 15 | unsigned – 无符号 16 | 17 | 宽度: 18 | 19 | short – 至少为16位 20 | long - 至少为32位 21 | long long - 至少为64位 22 | 23 | 有修饰符的时候,int 可省略。修饰符与int 的排列顺序任意。 24 | 25 | 例如,unsigned long long int 代表无符号至少为64位的整数类型,signed short 代表有符号至少16位的整数类型。int long unsigned 代表无符号至少32位的整数类型。 26 | 27 | ####定宽整数 28 | 29 | 对于以上的类型,我们可以注意到对于他们对宽度的描述,都有“至少”这样的描述,这表示他们的宽度是由具体实现决定的。在某些需要一个确定宽度的场合,我们则需要一系列定宽类型。 30 | 31 | 定宽类型具有以下形式 32 | 33 | [u]int{8, 16, 32, 64}_t ,特定位数的、无/有符号的整数类型。u表示是否有符号,数值代表特定位数。如uint64_t 表示64位无符号数,int16_t 表示16位有符号数。特别地,对于有符号数,定宽整数没有填充位且由补码实现。某些平台可能不完全支持这些类型。 34 | 35 | 除此之外,还有一些针对特定宽度的整数类型 36 | 37 | [u]int_least{8, 16, 32, 64}_t 最小的至少拥有特定位数的无/有符号整数类型。 38 | 39 | [u]int_fast{8, 16, 32, 64}_t 最快的至少拥有特定位数的无/有符号整数类型。 40 | 41 | [u]intmax_t 平台支持的最大的无/有符号整数类型 42 | 43 | ####特殊整数类型 44 | 45 | 常见的整数类型还有size_t 与 intptr_t 、ptrdiff_t 。 46 | 47 | size_t 常用来表示大小、数组下标等等的非负整数。 48 | 49 | [u]intptr_t 可以容纳一个指针的无/有符号整数类型。 50 | 51 | ptrdiff_t 用来表示两个指针之差的有符号整数类型。 52 | 53 | ####整数类型的范围 54 | 55 | ####整形字面量 56 | 57 | ####整数类型的选择 58 | 59 | ###2.字符类型 60 | 61 | 0) char 字符型,用来表示系统中的字符,是C++里宽度最小的类型。char 至少可以表示256个不同的值(常见的如[0, 255]或者[-128, 127])。 62 | 63 | 1) signed char 代表有符号字符 64 | 65 | 2) unsigned char 代表无符号字符。 66 | 67 | char 必然与signed char 或unsigned char 之一有相同的表示方法(但它们是三个独立的类型)。在多数环境中,它们的宽度都是 8 bit = 1 byte ,即八位二进制,其中有符号的数以补码表示。大多数环境的内存最小单元也是 8 bit = 1 byte,这使得char 特别是unsigned char 可以作为直接表示内存、对象结构的类型。 68 | 69 | 3) char16_t UTF-16字符型,至少有16位的无符号数。 70 | 71 | 4) char32_t UTF-32字符型,至少有32位的无符号数。 72 | 73 | 对于这些整数型和字符型的宽度,我们有 74 | 75 | ``` 76 | 1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long) 77 | ``` 78 | 79 | ###3.布尔类型 80 | 81 | bool 是一种用来存储布尔值的类型。它只有两个值:true 与 false 。在转换为整数类型时,true 会转换为1, false 则会转换为0。 82 | 83 | ###4.浮点类型 84 | 85 | 浮点数即我们常说的小数,有以下三种类型。 86 | 87 | float 单精度浮点类型。通常是符合IEEE-754 标准的 32 位浮点数。 88 | 89 | double 双精度浮点类型。通常是符合IEEE-754 标准的 64 位浮点数。 90 | 91 | long double 扩展精度浮点类型。多数为 80 位浮点数。 92 | 93 | ####浮点类型的范围 94 | 95 | ####浮点字面量 96 | 97 | ####浮点类型的选择 98 | 99 | -------------------------------------------------------------------------------- /1.3.语句.md: -------------------------------------------------------------------------------- 1 | 3.语句 2 | ============ 3 | 4 | ###0.表达式语句 5 | 6 | 将表达式末尾加上分号; (ASCII+59),就成为了一个表达式语句。特别地,单独的一个分号 ; 可以看作一个空语句。例如以下每一行都是一个表达式语句: 7 | 8 | ```cpp 9 | a + b; 10 | f(a); 11 | x = a – b; 12 | std::cin >> a; 13 | ; 14 | ``` 15 | 16 | ###1.复合语句 17 | 18 | 将多个语句由{} (ASCII+123 125)包围起来,就形成了复合语句。例如 19 | 20 | ```cpp 21 | { 22 | auto x = 0; 23 | int a, b; 24 | std::cin >> a >> b; 25 | x = a – b; 26 | std::cout << x; 27 | } 28 | ``` 29 | 30 | 这个整体就是一个复合语句。 31 | 32 | ###2.选择执行语句 33 | 34 | if 与 switch 可以被归类为选择执行语句。它们可以根据条件选择是否执行、执行哪个语句的能力。 35 | 36 | ####if 语句 37 | 38 | if 语句用来根据条件选择一个语句是否执行(单独使用if),或者从两个语句中选择一个执行(使用if … else …)。 39 | 40 | 以下是一些if 语句的例子: 41 | ``` 42 | if constexpr (constexpr int i = 5 + 6;i > 10) { 43 | std::cout << u8"5 + 6 = " << i << u8", which is greater than 10! " << std::endl; 44 | } 45 | 46 | if (a > b) a = b; 47 | else { 48 | auto c = a; 49 | a = -b; 50 | b = c; 51 | } 52 | 53 | if (int diff = a - b;a > b) c = a; 54 | else { 55 | if (a < b) c = diff; 56 | else c = b; 57 | } 58 | 59 | if (int diff = a - b) c = b; 60 | else { 61 | if (diff < 0) c = diff; 62 | else c = a; 63 | } 64 | ``` 65 | 66 | if 语句拥有以下形式: 67 | 68 | ``` 69 | if constexpr可选 (声明语句可选 条件) 语句 70 | ``` 71 | 72 | 以及 73 | 74 | ``` 75 | if constexpr可选 (初始化语句可选 条件) 语句 else 语句 76 | ``` 77 | 78 | 如果条件为真(即为true 或可以转换为true),则if 后的语句被执行,如果为假则不执行或执行else 后的语句。 79 | 80 | 例如 81 | 82 | ```cpp 83 | auto a = 0, b = 1; 84 | if (a > b) a = b; 85 | ``` 86 | 87 | 中a = b; 将不会被执行。 88 | 89 | 括号中还可以包含一个初始化语句,可用来定义变量或者执行任意表达式。 90 | 91 | 例如 92 | 93 | ``` 94 | int32_t a = 2, b = 1, c; 95 | if ( auto diff = a - b; diff > 0) c = diff; else c = - diff; 96 | ``` 97 | 98 | 其中,初始化语句定义了变量diff 并初始化为 a – b 即1 ,条件 diff > 0 成立,执行c = diff; 99 | 100 | 注意条件本身也可为一个声明(如if (int diff = a - b) ),这使得我们可以写出这样的if 语句: 101 | 102 | ``` 103 | if (int32_t diff = a - b; uint32_t diff_abs = diff > 0 ? diff : -diff){ 104 | std::cout << u8"a != b and" 105 | << u8" a - b is " << diff 106 | << u8" abs(a - b) is " << diff_abs 107 | << std::endl; 108 | } 109 | ``` 110 | 111 | 对于if … if … else … 这种情形,我们规定这个else属于最近的第一个还没有else 的if 语句。 112 | 113 | 如果if 语句是if constexpr 的形式,则要求条件是一个常量表达式。 114 | 115 | ####switch 语句 116 | 117 | switch 语句用来根据条件,转移到某一个语句执行。 118 | 119 | 以下是一些switch 语句的例子: 120 | 121 | ``` 122 | switch (a - b) { 123 | case 0: 124 | std::cout << "a - b = 0" << std::endl; 125 | break; 126 | case 1: 127 | std::cout << "a - b = 1" << std::endl; 128 | break; 129 | case 2: 130 | std::cout << "a - b = 2" << std::endl; 131 | break; 132 | case 3: 133 | std::cout << "a - b = 3" << std::endl; 134 | [[fallthrough]]; 135 | case 4: 136 | std::cout << "a - b = 3 or 4" << std::endl; 137 | break; 138 | default : 139 | std::cout << "a - b fall out of range of [0, 4]" << std::endl; 140 | } 141 | 142 | switch (int x = a) { 143 | case 0: 144 | [[fallthrough]]; 145 | case 1: 146 | [[fallthrough]]; 147 | case 2: 148 | [[fallthrough]]; 149 | case 3: 150 | std::cout << x << "belongs to [0, 3]" << std::endl; 151 | break; 152 | case 4: 153 | std::cout << x << " = 4" << std::endl; 154 | break; 155 | default : 156 | std::cout << "x fall out of range of [0, 4]" << std::endl; 157 | } 158 | ``` 159 | 160 | switch 语句拥有以下形式: 161 | 162 | ``` 163 | switch (声明语句可选 条件) 语句 164 | ``` 165 | 166 | 其中,语句中可包含case 标签与 default 标签和 break 语句,其中 case 标签与 default 标签有以下形式: 167 | ``` 168 | case 常量表达式: 语句 169 | 170 | default : 语句 171 | ``` 172 | 173 | switch 语句根据条件,跳转到对应的case 标签(如果有)或 default 标签开始执行,直到结束或遇到break 语句。switch 语句允许跨过case 标签执行(如上例0-3都会执行至std::cout << x << "belongs to [0, 3]" << std::endl;),即“fallthrough “。但大多数编译器都会在没有显式提供[[fallthrough]] 时发出警告。 174 | 175 | 声明语句和条件的要求与if 语句基本一致。 176 | 177 | ###3.循环语句 178 | 179 | ####while 语句 180 | 181 | while 语句用于条件不为false时循环执行语句。 182 | 183 | 以下是一些while 语句的例子: 184 | 185 | ``` 186 | int a = 20; 187 | while (a > 0) std::cout << a-- << std::endl; 188 | 189 | int a = 20; 190 | while (int b = f(a)) { 191 | std::cout << b << std::endl; 192 | } 193 | ``` 194 | 195 | while 语句拥有以下形式: 196 | 197 | ``` 198 | while (条件) 语句 199 | ``` 200 | 201 | 如果条件不为false,则执行语句并再次开始循环。即每次执行语句前检查条件,条件为真就最新语句并再次检查,条件为假则跳出。 202 | 203 | 与if 语句等相似,while 语句的条件也可以是一个声明,但应注意的是这个声明是对应于特定的迭代的,即每次执行条件都是一个独立的声明。 204 | 205 | break 语句可用于跳出while 语句,结束整个循环。 206 | 207 | ```cpp 208 | int a = 20; 209 | while (a > 0) { 210 | std::cout << a << std::endl; 211 | if(a-- == 10) break; 212 | } 213 | ``` 214 | 215 | continue 语句可用于提前结束一次循环。 216 | 217 | ```cpp 218 | int a = 20; 219 | while (a > 0) { 220 | if(a % 2) continue; 221 | std::cout << a-- << std::endl; 222 | } 223 | ``` 224 | 225 | ####do 语句 226 | 227 | do 语句( do…while )用来循环执行语句直到条件为false。 228 | 229 | 以下是do 语句的例子: 230 | 231 | ```cpp 232 | int a = 0; 233 | do{ 234 | std::cout << a-- << std::endl; 235 | } while (a > 0) 236 | 237 | int a = 20; 238 | do{ 239 | if(a % 2) continue; 240 | std::cout << a-- << std::endl; 241 | } while (a > 0) 242 | ``` 243 | 244 | do 语句拥有以下形式: 245 | 246 | ``` 247 | do 语句 while (表达式); 248 | ``` 249 | 250 | do 语句与while 语句的主要不同在于它在循环结束后判断表达式的值,如果为真则继续循环,即必定执行一次循环。 251 | 252 | break 语句与continue 语句的作用与while 语句中相似。 253 | 254 | ####for 语句(基本形式) 255 | 256 | 执行初始化语句,条件不为false时循环执行循环体与迭代表达式。 257 | 258 | 以下是for 语句的例子: 259 | 260 | ```cpp 261 | for(int a = 20; a > 0; --a){ 262 | if(a % 2) continue; 263 | std::cout << a << std::endl; 264 | } 265 | 266 | for(int a = 20;; --a){ 267 | if(a % 2) continue; 268 | std::cout << a << std::endl; 269 | if(a == 1) break; 270 | } 271 | ``` 272 | 273 | for 语句拥有以下形式: 274 | 275 | ``` 276 | for (声明语句 条件可选; 迭代表达式可选) 语句 277 | ``` 278 | 279 | 其中,声明语句中的声明可以覆盖所有循环,即在for 语句中只在最开头执行一次。 280 | 281 | 条件与迭代表达式都是可选的,且条件为空时默认为真 282 | 283 | 如果条件与迭代表达式都不选,而声明语句为空语句时,for 语句如 284 | 285 | ```cpp 286 | int a = 20; 287 | for(;;){ 288 | std::cout << a << std::endl; 289 | if(a == 1) break; 290 | --a; 291 | } 292 | ``` 293 | 294 | ###4.跳转语句 295 | 296 | ####break 语句与continue 语句 297 | 298 | 这两个语句作用于循环语句与 switch 语句,在对应的语句中分别有介绍。 299 | 300 | ####goto 语句 301 | 302 | goto 语句用于跳转到特定的标签执行。 303 | 304 | ```cpp 305 | int a = 10; 306 | label: 307 | std::cout << a << " "; 308 | a = a - 2; 309 | 310 | if (a != 0) { 311 | goto label; 312 | } 313 | std::cout << '\n'; 314 | 315 | for (int x = 0; x < 3; x++) { 316 | for (int y = 0; y < 3; y++) { 317 | std::cout << "(" << x << ";" << y << ") " << '\n'; 318 | if (x + y >= 3) { 319 | goto endloop; 320 | } 321 | } 322 | } 323 | endloop: 324 | std::cout << std::endl; 325 | ``` 326 | -------------------------------------------------------------------------------- /C++ 2z from beginner to abdicator.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Librazy/Cpp-2z-from-beginner-to-abdicator/d84c8f2db766b2abae1d70d12529435eeee4ac9f/C++ 2z from beginner to abdicator.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | C++ 2z 从入门到放弃 2 | 3 | //论TS全开的C++17 4 | --------------------------------------------------------------------------------