{"./":{"url":"./","title":"C","keywords":"","body":"C C 是一种通用程序设计语言，广泛用于系统软件与应用软件的开发。 "},"docs/一切的开始.html":{"url":"docs/一切的开始.html","title":"一切的开始","keywords":"","body":"一切的开始 以下是第一个 C 语言程序，也是一切的开始。 #include int main(int argc, char const *argv[]) { printf(\"Hello World!\\n\"); return 0; } "},"docs/类型、运算符与表达式.html":{"url":"docs/类型、运算符与表达式.html","title":"类型、运算符与表达式","keywords":"","body":"类型、运算符与表达式 变量名 数据类型 常量 声明 算术运算符 逻辑运算符 类型转换 自增自减运算符 位运算符 赋值运算符 条件表达式 "},"docs/类型、运算符与表达式/变量名.html":{"url":"docs/类型、运算符与表达式/变量名.html","title":"变量名","keywords":"","body":"变量名 C 语言变量名是由字母、数字和下划线组成的序列，但其第一个字符必须为字母，且严格区分大小写。 类似于 if 、 else 、 int 、 float 等关键字是保留给 C 语言本身使用的，不能用作变量名。 "},"docs/类型、运算符与表达式/数据类型.html":{"url":"docs/类型、运算符与表达式/数据类型.html","title":"数据类型","keywords":"","body":"数据类型 C 语言提供了下列几种基本数据类型。 #include int main(int argc, char const *argv[]) { char c = 'A'; printf(\"%c\\n\", c); int i = 233; printf(\"%d\\n\", i); float f = 123.456; printf(\"%f\\n\", f); double d = 123.456; printf(\"%lf\\n\", d); return 0; } 此外，还有 signed 与 unsigned 等类型限定符。 "},"docs/类型、运算符与表达式/常量.html":{"url":"docs/类型、运算符与表达式/常量.html","title":"常量","keywords":"","body":"常量 类似于以下的整数常量属于 int 类型。 #include int main(int argc, char const *argv[]) { printf(\"%d\\n\", 233); return 0; } long 类型的常量以字母 l 或 L 结尾。 #include int main(int argc, char const *argv[]) { printf(\"%d\\n\", 123456789L); return 0; } 无符号常量以字母 u 或 U 结尾。 #include int main(int argc, char const *argv[]) { printf(\"%d\\n\", 233U); return 0; } 后缀 ul 或 UL 表明是 unsigned long 类型。 #include int main(int argc, char const *argv[]) { printf(\"%d\\n\", 123456789UL); return 0; } 浮点数常量中包含一个小数点，如 123.4 。或以指数形式表示， 如 1e-2 。 #include int main(int argc, char const *argv[]) { printf(\"%f\\n\", 123.4); printf(\"%f\\n\", 1e-2); return 0; } 一个字符常量是一个整数，书写时将一个字符括在单引号中，字符在机器字符集中的数值就是字符常量的值。字符常量一般用来与其他字符进行比较，但也可以像其他整数一样参与数值运算。 #include int main(int argc, char const *argv[]) { printf(\"%c\\n\", 'A'); printf(\"%d\\n\", 'A'); return 0; } 字符常量 \\0 表示值为 0 的字符，也就是空字符 null 。 #include int main(int argc, char const *argv[]) { printf(\"%c\\n\", '\\0'); printf(\"%d\\n\", '\\0'); return 0; } 常量表达式是仅仅包含常量的表达式，这种表达式在编译时求值，而不在运行时求值。 #include int main(int argc, char const *argv[]) { int a[1 + 2 + 3]; return 0; } 字符串常量也叫字符串字面值，是用双引号括起来的 0 个或多个字符组成的字符序列。 #include int main(int argc, char const *argv[]) { printf(\"%s\\n\", \"I am a string.\"); return 0; } 编译时可以将多个字符串常量连接起来。 #include int main(int argc, char const *argv[]) { printf(\"%s\\n\", \"Hello \" \"World!\"); return 0; } 枚举是一个常量整型值的列表。 #include int main(int argc, char const *argv[]) { enum months {JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC}; printf(\"%d\\n\", JUL); return 0; } "},"docs/类型、运算符与表达式/声明.html":{"url":"docs/类型、运算符与表达式/声明.html","title":"声明","keywords":"","body":"声明 所有变量都必须先声明后使用。 #include int main(int argc, char const *argv[]) { int i1 = 233; int i2 = 666; printf(\"%d\\n\", i1); printf(\"%d\\n\", i2); return 0; } 一个声明指定一种变量类型，后面所带的变量表可以包含一个或多个该类型的变量。 #include int main(int argc, char const *argv[]) { int i1, i2; i1 = 233; i2 = 666; printf(\"%d\\n\", i1); printf(\"%d\\n\", i2); return 0; } 任何变量的声明都可以使用 const 限定符限定，该限定符指定变量的值不能被修改。 #include int main(int argc, char const *argv[]) { const int i1 = 233; const int i2 = 666; printf(\"%d\\n\", i1); printf(\"%d\\n\", i2); return 0; } const 限定符也可配合数组使用，这表明数组所有元素的值都不能被修改。 #include int main(int argc, char const *argv[]) { const char str[] = \"I am a string.\"; printf(\"%s\\n\", str); return 0; } "},"docs/类型、运算符与表达式/算术运算符.html":{"url":"docs/类型、运算符与表达式/算术运算符.html","title":"算术运算符","keywords":"","body":"算术运算符 执行下面的代码，进行算术运算。 #include int main(int argc, char const *argv[]) { int i1 = 233; int i2 = 666; printf(\"%d\\n\", i1 + i2); printf(\"%d\\n\", i1 - i2); printf(\"%d\\n\", i1 * i2); printf(\"%d\\n\", i1 / i2); printf(\"%d\\n\", i1 % i2); return 0; } 整数除法会截断结果中的小数部分。 #include int main(int argc, char const *argv[]) { int i1 = 10; int i2 = 3; printf(\"%d\\n\", i1 / i2); return 0; } 执行下面的代码，判断是否是闰年。 #include int main(int argc, char const *argv[]) { int year = 2000; if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { printf(\"%d is a leap year.\\n\", year); } else { printf(\"%d is not a leap year.\\n\", year); } return 0; } "},"docs/类型、运算符与表达式/逻辑运算符.html":{"url":"docs/类型、运算符与表达式/逻辑运算符.html","title":"逻辑运算符","keywords":"","body":"逻辑运算符 执行下面的代码，进行逻辑运算。 #include int main(int argc, char const *argv[]) { int i1 = 233; int i2 = 666; int i3 = 1; printf(\"%d\\n\", i1 > i2); printf(\"%d\\n\", i1 >= i2); printf(\"%d\\n\", i1 "},"docs/类型、运算符与表达式/类型转换.html":{"url":"docs/类型、运算符与表达式/类型转换.html","title":"类型转换","keywords":"","body":"类型转换 当一个运算符的几个操作数类型不同时，就需要通过一些规则把它们转换为某种共同的类型。 #include int main(int argc, char const *argv[]) { int i = 233; float f = 666.666; printf(\"%f\\n\", i + f); printf(\"%d\\n\", i + (int)f); return 0; } 执行下面的代码，将字符串类型的数字转换为整型。 #include int main(int argc, char const *argv[]) { char str[] = \"123456\"; int num = 0; for (int i = 0; str[i] >= '0' && str[i] "},"docs/类型、运算符与表达式/自增自减运算符.html":{"url":"docs/类型、运算符与表达式/自增自减运算符.html","title":"自增自减运算符","keywords":"","body":"自增自减运算符 自增运算符使其操作数递增 1 ，自减运算符使其操作数递减 1 。 #include int main(int argc, char const *argv[]) { int i = 233; i++; printf(\"%d\\n\", i); i--; printf(\"%d\\n\", i); return 0; } 自增自减运算符既可以用作前缀运算符，也可以用作后缀运算符。对于不同的上下文来说，效果是不同的。 #include int main(int argc, char const *argv[]) { int i1 = 233; int i2 = 666; int num; num = i1++; printf(\"%d\\n\", num); num = ++i2; printf(\"%d\\n\", num); return 0; } "},"docs/类型、运算符与表达式/位运算符.html":{"url":"docs/类型、运算符与表达式/位运算符.html","title":"位运算符","keywords":"","body":"位运算符 执行下面的代码，进行位运算。 #include int main(int argc, char const *argv[]) { int i1 = 5; int i2 = 3; printf(\"%d\\n\", i1 & i2); printf(\"%d\\n\", i1 | i2); printf(\"%d\\n\", i1 ^ i2); printf(\"%d\\n\", i1 > 2); printf(\"%d\\n\", ~i1); return 0; } "},"docs/类型、运算符与表达式/赋值运算符.html":{"url":"docs/类型、运算符与表达式/赋值运算符.html","title":"赋值运算符","keywords":"","body":"赋值运算符 大多数二元运算符都有一个相应的赋值运算符。 #include int main(int argc, char const *argv[]) { int i1 = 5; int i2 = 3; i1 += i2; printf(\"%d\\n\", i1); i1 -= i2; printf(\"%d\\n\", i1); i1 *= i2; printf(\"%d\\n\", i1); i1 /= i2; printf(\"%d\\n\", i1); i1 %= i2; printf(\"%d\\n\", i1); i1 >= i2; printf(\"%d\\n\", i1); i1 &= i2; printf(\"%d\\n\", i1); i1 |= i2; printf(\"%d\\n\", i1); i1 ^= i2; printf(\"%d\\n\", i1); return 0; } "},"docs/类型、运算符与表达式/条件表达式.html":{"url":"docs/类型、运算符与表达式/条件表达式.html","title":"条件表达式","keywords":"","body":"条件表达式 执行下面的代码，进行条件判断。 #include int main(int argc, char const *argv[]) { int i1 = 233; int i2 = 666; int max; if (i1 > i2) { max = i1; } else { max = i2; } printf(\"%d\\n\", max); return 0; } 也可以使用三元运算符简化上面的代码。 #include int main(int argc, char const *argv[]) { int i1 = 233; int i2 = 666; int max; max = i1 > i2 ? i1 : i2; printf(\"%d\\n\", max); return 0; } "},"docs/控制流.html":{"url":"docs/控制流.html","title":"控制流","keywords":"","body":"控制流 if-else else-if switch for while do-while break continue goto "},"docs/控制流/if-else.html":{"url":"docs/控制流/if-else.html","title":"if-else","keywords":"","body":"if-else 执行下面的代码，进行条件判断。 #include int main(int argc, char const *argv[]) { int i = 233; if (i > 0) { printf(\"Yes.\\n\"); } else { printf(\"No.\\n\"); } return 0; } "},"docs/控制流/else-if.html":{"url":"docs/控制流/else-if.html","title":"else-if","keywords":"","body":"else-if 执行下面的代码，进行条件判断。 #include int main(int argc, char const *argv[]) { char c = '6'; if (c >= 'a' && c = 'A' && c = '0' && c "},"docs/控制流/switch.html":{"url":"docs/控制流/switch.html","title":"switch","keywords":"","body":"switch 执行下面的代码，进行多路判定。 #include int main(int argc, char const *argv[]) { char c = '6'; switch (c) { case 'a': printf(\"Letter a.\\n\"); break; case '6': printf(\"Number 6.\\n\"); break; case 'c': printf(\"Letter c.\\n\"); break; default: printf(\"Other.\\n\");; break; } return 0; } "},"docs/控制流/for.html":{"url":"docs/控制流/for.html","title":"for","keywords":"","body":"for 执行下面的代码，进行条件循环。 #include int main(int argc, char const *argv[]) { int i; for (i = 0; i "},"docs/控制流/while.html":{"url":"docs/控制流/while.html","title":"while","keywords":"","body":"while 执行下面的代码，进行条件循环。 #include int main(int argc, char const *argv[]) { int i = 9; while (i) { printf(\"%d\\n\", i); i--; } return 0; } "},"docs/控制流/do-while.html":{"url":"docs/控制流/do-while.html","title":"do-while","keywords":"","body":"do-while 执行下面的代码，进行条件循环。 #include int main(int argc, char const *argv[]) { int i = 9; do { printf(\"%d\\n\", i); i--; } while (i); return 0; } "},"docs/控制流/break.html":{"url":"docs/控制流/break.html","title":"break","keywords":"","body":"break 执行下面的代码，在循环中根据指定条件跳出循环。 #include int main(int argc, char const *argv[]) { int i; for (i = 0; i "},"docs/控制流/continue.html":{"url":"docs/控制流/continue.html","title":"continue","keywords":"","body":"continue 执行下面的代码，在循环中根据指定条件进行下一次循环。 #include int main(int argc, char const *argv[]) { int i; for (i = 0; i "},"docs/控制流/goto.html":{"url":"docs/控制流/goto.html","title":"goto","keywords":"","body":"goto 执行下面的代码，在循环中根据指定条件跳转至标记位置。注意，大多数情况下使用 goto 语句将造成程序难以理解和维护。 #include int main(int argc, char const *argv[]) { int i; for (i = 1; i "},"docs/函数与程序结构.html":{"url":"docs/函数与程序结构.html","title":"函数与程序结构","keywords":"","body":"函数与程序结构 函数基本功能 全局变量 外部变量 静态变量 寄存器变量 递归 文件包含 条件包含 宏替换 "},"docs/函数与程序结构/函数基本功能.html":{"url":"docs/函数与程序结构/函数基本功能.html","title":"函数基本功能","keywords":"","body":"函数基本功能 执行下面的代码，定义并调用指定的函数。 #include void print() { printf(\"Hello World!\"); } int main(int argc, char const *argv[]) { print(); return 0; } 执行下面的代码，定义并调用实现两数加法的函数。 #include int sum(int a, int b) { return a + b; } int main(int argc, char const *argv[]) { int i1 = 233; int i2 = 666; printf(\"%d\\n\", sum(i1, i2)); return 0; } "},"docs/函数与程序结构/全局变量.html":{"url":"docs/函数与程序结构/全局变量.html","title":"全局变量","keywords":"","body":"全局变量 任何函数都可以通过变量名访问一个全局变量。 #include int i = 233; int main(int argc, char const *argv[]) { printf(\"%d\\n\", i); i = 666; printf(\"%d\\n\", i); return 0; } "},"docs/函数与程序结构/外部变量.html":{"url":"docs/函数与程序结构/外部变量.html","title":"外部变量","keywords":"","body":"外部变量 目录下新建 extern.h 文件，代码如下。 extern int i = 233; 执行下面的代码，即可访问外部变量。 #include #include \"extern.h\" int main(int argc, char const *argv[]) { printf(\"%d\\n\", i); return 0; } "},"docs/函数与程序结构/静态变量.html":{"url":"docs/函数与程序结构/静态变量.html","title":"静态变量","keywords":"","body":"静态变量 局部静态变量只在第一次进入函数时初始化一次，之后的函数调用将保留上一次的值。 #include void print() { static int i = 1; printf(\"%d\\n\", i); i++; } int main(int argc, char const *argv[]) { print(); print(); print(); return 0; } "},"docs/函数与程序结构/寄存器变量.html":{"url":"docs/函数与程序结构/寄存器变量.html","title":"寄存器变量","keywords":"","body":"寄存器变量 定义寄存器变量将告诉编译器，所声明的变量在程序中使用频率较高。 #include int main(int argc, char const *argv[]) { register int i = 233; printf(\"%d\\n\", i); return 0; } "},"docs/函数与程序结构/递归.html":{"url":"docs/函数与程序结构/递归.html","title":"递归","keywords":"","body":"递归 递归调用即函数可以直接或间接调用自身。 #include void print(int x) { if (x > 0) { printf(\"%d\\n\", x); print(--x); } } int main(int argc, char const *argv[]) { int i = 5; print(i); return 0; } "},"docs/函数与程序结构/文件包含.html":{"url":"docs/函数与程序结构/文件包含.html","title":"文件包含","keywords":"","body":"文件包含 使用预处理指令 #include 用于在编译期间把指定文件的内容包含进当前文件。如果文件名用双引号引起来，则在源文件所在目录查找该文件。如果在该位置没有找到文件，或者如果文件名用尖括号括起来，则将根据相应的规则查找该文件。 #include #include \"file.h\" int main(int argc, char const *argv[]) { return 0; } "},"docs/函数与程序结构/条件包含.html":{"url":"docs/函数与程序结构/条件包含.html","title":"条件包含","keywords":"","body":"条件包含 也可以使用条件语句对预处理本身进行控制。 #include #ifndef NUMBER #define NUMBER 233 #endif int main(int argc, char const *argv[]) { printf(\"%d\\n\", NUMBER); return 0; } "},"docs/函数与程序结构/宏替换.html":{"url":"docs/函数与程序结构/宏替换.html","title":"宏替换","keywords":"","body":"宏替换 宏替换可以将后续所有出现记号的地方替换为指定的文本。 #include #define NUMBER 233 int main(int argc, char const *argv[]) { printf(\"%d\\n\", NUMBER); return 0; } 宏替换也可以带参数，这样可以对不同的宏调用使用不同的替换文本。 #include #define MAX(x, y) (x > y ? x : y) int main(int argc, char const *argv[]) { int i1 = 233; int i2 = 666; printf(\"%d\\n\", MAX(i1, i2)); return 0; } "},"docs/指针与数组.html":{"url":"docs/指针与数组.html","title":"指针与数组","keywords":"","body":"指针与数组 指针与地址 指针与函数参数 指针与数组 地址算术运算 字符指针与函数 指针数组与指向指针的指针 多维数组 指针与多维数组 命令行参数 指向函数的指针 "},"docs/指针与数组/指针与地址.html":{"url":"docs/指针与数组/指针与地址.html","title":"指针与地址","keywords":"","body":"指针与地址 指针是一种保存变量地址的变量。执行下面的代码，获取变量的地址。 #include int main(int argc, char const *argv[]) { int i = 233; int *p = &i; printf(\"%d\\n\", i); printf(\"%p\\n\", p); return 0; } 执行下面的代码，通过指针获取并修改变量的值。 #include int main(int argc, char const *argv[]) { int i = 233; int *p = &i; printf(\"%d\\n\", *p); *p = 666; printf(\"%d\\n\", i); printf(\"%d\\n\", *p); return 0; } "},"docs/指针与数组/指针与函数参数.html":{"url":"docs/指针与数组/指针与函数参数.html","title":"指针与函数参数","keywords":"","body":"指针与函数参数 被调用函数不能直接修改主调函数中变量的值，但通过传递指针即可实现。 #include void swap1(int x, int y) { int tmp; tmp = x; x = y; y = tmp; } void swap2(int *x, int *y) { int tmp; tmp = *x; *x = *y; *y = tmp; } int main(int argc, char const *argv[]) { int i1 = 233; int i2 = 666; swap1(i1, i2); printf(\"i1 = %d, i2 = %d.\\n\", i1, i2); swap2(&i1, &i2); printf(\"i1 = %d, i2 = %d.\\n\", i1, i2); return 0; } "},"docs/指针与数组/指针与数组.html":{"url":"docs/指针与数组/指针与数组.html","title":"指针与数组","keywords":"","body":"指针与数组 执行下面的代码，将指针指向数组中的第一个元素。 #include int main(int argc, char const *argv[]) { int arr[] = {1, 3, 5, 7, 9}; int *p, *q; p = &arr[0]; q = arr; printf(\"%d\\n\", *p); printf(\"%p\\n\", p); printf(\"%d\\n\", *q); printf(\"%p\\n\", q); return 0; } 根据指针运算定义，指向数组的指针“加1”意味着指向当前数组元素的下一个元素。 #include int main(int argc, char const *argv[]) { int arr[] = {1, 3, 5, 7, 9}; int *p; p = arr; printf(\"%d\\n\", *p); printf(\"%d\\n\", arr[0]); printf(\"%d\\n\", *(p + 1)); printf(\"%d\\n\", arr[1]); printf(\"%d\\n\", *(p + 2)); printf(\"%d\\n\", arr[2]); return 0; } 执行下面的代码，统计字符串的长度。 #include int main(int argc, char const *argv[]) { char *str = \"Hello World!\"; int len = 0; for (; *str != '\\0'; str++) { len++; } printf(\"%d\\n\", len); return 0; } "},"docs/指针与数组/地址算术运算.html":{"url":"docs/指针与数组/地址算术运算.html","title":"地址算术运算","keywords":"","body":"地址算术运算 如果两个指针指向同一个数组中的不同元素，那么它们之间就可以进行关系比较运算。 #include int main(int argc, char const *argv[]) { char *str = \"Hello World!\"; char *p, *q; p = &str[4]; q = &str[7]; printf(\"%c\\n\", *p); printf(\"%c\\n\", *q); printf(\"%d\\n\", p "},"docs/指针与数组/字符指针与函数.html":{"url":"docs/指针与数组/字符指针与函数.html","title":"字符指针与函数","keywords":"","body":"字符指针与函数 下面两种定义方式中， str1 是一个仅仅足以存放初始化字符串以及空字符 \\0 的一维数组，数组中的单个字符可以进行修改，但 str1 始终指向同一个存储位置。而 str2 是一个指针，其初值指向一个字符串常量，之后它可以被修改以指向其他地址。 #include int main(int argc, char const *argv[]) { char str1[] = \"Hello World!\"; char *str2 = \"Hello World!\"; return 0; } 执行下面的代码，实现字符串复制功能。 #include int main(int argc, char const *argv[]) { char str1[] = \"Hello World!\"; char str2[] = \"Welcome!\"; char *p, *q; p = str1; q = str2; while ((*p = *q) != '\\0') { p++; q++; } printf(\"%s\\n\", str1); return 0; } "},"docs/指针与数组/指针数组与指向指针的指针.html":{"url":"docs/指针与数组/指针数组与指向指针的指针.html","title":"指针数组与指向指针的指针","keywords":"","body":"指针数组与指向指针的指针 由于指针本身也是变量，因此也可以像其他变量一样存储在数组中。 #include int main(int argc, char const *argv[]) { char str1[] = \"Hello World!\"; char str2[] = \"Welcome!\"; char str3[] = \"Hello C!\"; char *p, *q, *r; char *points[3]; p = str1; q = str2; r = str3; points[0] = p; points[1] = q; points[2] = r; printf(\"%s\\n\", points[0]); printf(\"%s\\n\", *points); printf(\"%s\\n\", points[1]); printf(\"%s\\n\", *(points + 1)); printf(\"%s\\n\", points[2]); printf(\"%s\\n\", *(points + 2)); return 0; } "},"docs/指针与数组/多维数组.html":{"url":"docs/指针与数组/多维数组.html","title":"多维数组","keywords":"","body":"多维数组 二维数组实际上是一种特殊的一维数组，它的每个元素也是一个一维数组。 #include int main(int argc, char const *argv[]) { char month[12][4] = { {\"Jan\"}, {\"Feb\"}, {\"Mar\"}, {\"Apr\"}, {\"May\"}, {\"Jun\"}, {\"Jul\"}, {\"Aug\"}, {\"Sep\"}, {\"Oct\"}, {\"Nov\"}, {\"Dec\"} }; printf(\"%s\\n\", month[0]); printf(\"%s\\n\", month[6]); printf(\"%s\\n\", month[11]); return 0; } "},"docs/指针与数组/指针与多维数组.html":{"url":"docs/指针与数组/指针与多维数组.html","title":"指针与多维数组","keywords":"","body":"指针与多维数组 下面两种定义方式中， a[10][20] 是一个真正的二维数组，它分配了 200 个整型长度的存储空间，并且通过常规的矩阵下标计算公式得到具体元素的位置。但是对于 b[10] 来说，该定义仅仅分配了 10 个指针，假定 b[10] 的每个元素都指向一个具有 20 个元素的数组，那么编译器就要为它分配 200 个整型长度的存储空间以及 10 个指针的存储空间。 #include int main(int argc, char const *argv[]) { int a[10][20]; int *b[10]; return 0; } 指针数组最频繁的用处是存放具有不同长度的字符串。 "},"docs/指针与数组/命令行参数.html":{"url":"docs/指针与数组/命令行参数.html","title":"命令行参数","keywords":"","body":"命令行参数 调用主函数时带有两个参数分别为 argc 、 argv ， argc 表示运行程序时命令行中参数的数目， argv 是一个指向字符串数组的指针，其中每个字符串对应一个参数。 #include int main(int argc, char const *argv[]) { int i; for (i = 0; i "},"docs/指针与数组/指向函数的指针.html":{"url":"docs/指针与数组/指向函数的指针.html","title":"指向函数的指针","keywords":"","body":"指向函数的指针 函数本身不是变量，但可以定义指向函数的指针。 #include int max(int x, int y) { return x > y ? x : y; } int main(int argc, char const *argv[]) { int i1 = 233; int i2 = 666; int (*p)(int, int); p = max; printf(\"%d\\n\", max(i1, i2)); printf(\"%d\\n\", p(i1, i2)); return 0; } "},"docs/结构.html":{"url":"docs/结构.html","title":"结构","keywords":"","body":"结构 结构基本功能 结构与函数 结构数组 指向结构的指针 自引用结构 类型定义 联合 位字段 "},"docs/结构/结构基本功能.html":{"url":"docs/结构/结构基本功能.html","title":"结构基本功能","keywords":"","body":"结构基本功能 结构声明由包含在花括号内的一系列声明组成，结构中定义的变量称为成员。 #include struct point { int x; int y; }; int main(int argc, char const *argv[]) { return 0; } 如果结构声明的后面不带变量名，则不需要为它分配存储空间，它仅仅描述了一个结构的模板或轮廓。如果结构声明后面带变量名，则可以通过该变量名直接使用结构功能。 #include struct point { int x; int y; } p1, p2; int main(int argc, char const *argv[]) { p1.x = 233; p1.y = 666; printf(\"x = %d, y = %d.\\n\", p1.x, p1.y); p2.x = 100; p2.y = 200; printf(\"x = %d, y = %d.\\n\", p2.x, p2.y); struct point p3; p3.x = 200; p3.y = 100; printf(\"x = %d, y = %d.\\n\", p3.x, p3.y); struct point p4 = {666, 233}; printf(\"x = %d, y = %d.\\n\", p4.x, p4.y); return 0; } 结构可以嵌套。 #include struct point { int x; int y; }; struct info { int width; int height; }; struct rect { struct point point; struct info info; }; int main(int argc, char const *argv[]) { struct rect rect; rect.point.x = 100; rect.point.y = 100; rect.info.width = 300; rect.info.height = 200; printf(\"x: %d, y: %d.\\n\", rect.point.x, rect.point.y); printf(\"width: %d, height: %d.\\n\", rect.info.width, rect.info.height); return 0; } "},"docs/结构/结构与函数.html":{"url":"docs/结构/结构与函数.html","title":"结构与函数","keywords":"","body":"结构与函数 执行下面的代码，定义返回值为结构的函数。 #include struct point { int x; int y; }; struct point initialize(int x, int y) { struct point p = {x, y}; return p; } int main(int argc, char const *argv[]) { struct point p = initialize(100, 100); printf(\"x: %d, y: %d.\\n\", p.x, p.y); return 0; } "},"docs/结构/结构数组.html":{"url":"docs/结构/结构数组.html","title":"结构数组","keywords":"","body":"结构数组 执行下面的代码，声明结构数组。 #include #include struct person { char name[20]; int age; }; int main(int argc, char const *argv[]) { struct person p[3]; strcpy(p[0].name, \"Tom\"); p[0].age = 18; printf(\"name: %s, age: %d.\\n\", p[0].name, p[0].age); strcpy(p[1].name, \"Jerry\"); p[1].age = 16; printf(\"name: %s, age: %d.\\n\", p[1].name, p[1].age); strcpy(p[2].name, \"Spike\"); p[2].age = 20; printf(\"name: %s, age: %d.\\n\", p[2].name, p[2].age); return 0; } 也可以通过下面的方式声明结构数组并进行初始化。 #include struct person { char name[20]; int age; } p[3] = { {\"Tom\", 18}, {\"Jerry\", 16}, {\"Spike\", 20} }; int main(int argc, char const *argv[]) { printf(\"name: %s, age: %d.\\n\", p[0].name, p[0].age); printf(\"name: %s, age: %d.\\n\", p[1].name, p[1].age); printf(\"name: %s, age: %d.\\n\", p[2].name, p[2].age); return 0; } 执行下面的代码，计算结构所占用的存储空间字节数。 #include struct person { char name[20]; int age; }; int main(int argc, char const *argv[]) { struct person p[3]; printf(\"%d\\n\", sizeof p); printf(\"%d\\n\", sizeof(p)); return 0; } "},"docs/结构/指向结构的指针.html":{"url":"docs/结构/指向结构的指针.html","title":"指向结构的指针","keywords":"","body":"指向结构的指针 结构指针类似于普通变量指针。 #include struct point { int x; int y; }; int main(int argc, char const *argv[]) { struct point p1 = {100, 100}; struct point *p2; p2 = &p1; printf(\"x: %d, y: %d.\\n\", p1.x, p1.y); printf(\"x: %d, y: %d.\\n\", p2->x, p2->y); printf(\"x: %d, y: %d.\\n\", (*p2).x, (*p2).y); return 0; } "},"docs/结构/自引用结构.html":{"url":"docs/结构/自引用结构.html","title":"自引用结构","keywords":"","body":"自引用结构 可以使用结构定义二叉树结构。 #include struct node { int data; struct node *left; struct node *right; }; int main(int argc, char const *argv[]) { struct node rootNode, leftNode, rightNode; rootNode.data = 1; rootNode.left = &leftNode; rootNode.right = &rightNode; leftNode.data = 2; leftNode.left = NULL; leftNode.right = NULL; rightNode.data = 3; rightNode.left = NULL; rightNode.right = NULL; printf(\"root: %d.\\n\", rootNode.data); printf(\"left: %d.\\n\", rootNode.left->data); printf(\"right: %d.\\n\", rootNode.right->data); return 0; } 执行下面的代码，动态分配结构的存储空间。 #include #include struct node { int data; struct node *left; struct node *right; }; int main(int argc, char const *argv[]) { struct node *rootNode = (struct node *)malloc(sizeof(struct node)); struct node *leftNode = (struct node *)malloc(sizeof(struct node)); struct node *rightNode = (struct node *)malloc(sizeof(struct node)); rootNode->data = 1; rootNode->left = leftNode; rootNode->right = rightNode; leftNode->data = 2; leftNode->left = NULL; leftNode->right = NULL; rightNode->data = 3; rightNode->left = NULL; rightNode->right = NULL; printf(\"root: %d.\\n\", rootNode->data); printf(\"left: %d.\\n\", rootNode->left->data); printf(\"right: %d.\\n\", rootNode->right->data); free(rootNode); free(leftNode); free(rightNode); return 0; } "},"docs/结构/类型定义.html":{"url":"docs/结构/类型定义.html","title":"类型定义","keywords":"","body":"类型定义 可以用类型定义来建立新的数据类型名。 #include typedef int integer; typedef char *string; int main(int argc, char const *argv[]) { integer i = 233; printf(\"%d\\n\", i); string str = \"Hello World!\"; printf(\"%s\\n\", str); return 0; } 也可以与结构定义结合使用。 #include #include struct node { int data; struct node *left; struct node *right; }; typedef struct node n; int main(int argc, char const *argv[]) { n *rootNode = (n *)malloc(sizeof(n)); n *leftNode = (n *)malloc(sizeof(n)); n *rightNode = (n *)malloc(sizeof(n)); rootNode->data = 1; rootNode->left = leftNode; rootNode->right = rightNode; leftNode->data = 2; leftNode->left = NULL; leftNode->right = NULL; rightNode->data = 3; rightNode->left = NULL; rightNode->right = NULL; printf(\"root: %d.\\n\", rootNode->data); printf(\"left: %d.\\n\", rootNode->left->data); printf(\"right: %d.\\n\", rootNode->right->data); free(rootNode); free(leftNode); free(rightNode); return 0; } "},"docs/结构/联合.html":{"url":"docs/结构/联合.html","title":"联合","keywords":"","body":"联合 联合是一种特殊的数据类型，它允许在同一内存位置存储不同类型的数据。联合的所有成员共享同一块内存空间，这意味着在任何给定时刻，联合体只能包含一个成员的值。 #include #include union data { int i; float f; char s[20]; }; int main(int argc, char const *argv[]) { union data u; u.i = 233; printf(\"%d\\n\", u.i); u.f = 6.66; printf(\"%d\\n\", u.i); printf(\"%f\\n\", u.f); strcpy(u.s, \"Hello World!\"); printf(\"%d\\n\", u.i); printf(\"%f\\n\", u.f); printf(\"%s\\n\", u.s); return 0; } 联合默认用其第一个成员类型的值进行初始化，或者使用指定初始化器来初始化特定的成员。 #include union data { int i; float f; char s[20]; }; int main(int argc, char const *argv[]) { union data u1 = {233}; printf(\"%d\\n\", u1.i); printf(\"%f\\n\", u1.f); printf(\"%s\\n\", u1.s); union data u2 = {.f = 6.66}; printf(\"%d\\n\", u2.i); printf(\"%f\\n\", u2.f); printf(\"%s\\n\", u2.s); union data u3 = {.s = \"Hello World!\"}; printf(\"%d\\n\", u3.i); printf(\"%f\\n\", u3.f); printf(\"%s\\n\", u3.s); return 0; } "},"docs/结构/位字段.html":{"url":"docs/结构/位字段.html","title":"位字段","keywords":"","body":"位字段 在存储空间很宝贵的情况下，有可能需要将多个对象保存在一个机器字中。 #include struct config { unsigned int c1: 8; unsigned int c2: 16; unsigned int c3: 8; }; int main(int argc, char const *argv[]) { struct config cfg; printf(\"size: %d.\\n\", sizeof(cfg)); cfg.c1 = 255; cfg.c2 = 65535; cfg.c3 = 255; printf(\"c1: %d, c2: %d, c3: %d.\\n\", cfg.c1, cfg.c2, cfg.c3); return 0; } "},"docs/输入与输出.html":{"url":"docs/输入与输出.html","title":"输入与输出","keywords":"","body":"输入与输出 标准输入输出 格式化输出 格式化输入 文件访问 行输入和行输出 "},"docs/输入与输出/标准输入输出.html":{"url":"docs/输入与输出/标准输入输出.html","title":"标准输入输出","keywords":"","body":"标准输入输出 执行下面的代码，从标准输入中一次读取一个字符。 #include int main(int argc, char const *argv[]) { int c; c = getchar(); printf(\"%c\\n\", c); return 0; } 执行下面的代码，将输入的一个字符输出。 #include int main(int argc, char const *argv[]) { int c; c = getchar(); putchar(c); return 0; } 执行下面的代码，从标准输入中读取一行字符串。 #include int main(int argc, char const *argv[]) { int c; while ((c = getchar()) != EOF) { putchar(c); } return 0; } "},"docs/输入与输出/格式化输出.html":{"url":"docs/输入与输出/格式化输出.html","title":"格式化输出","keywords":"","body":"格式化输出 执行下面的代码，将参数进行转换与格式化，并在标准输出设备上打印出来。 #include int main(int argc, char const *argv[]) { int i = 233; float f = 6.66; char *s = \"Hello World!\"; printf(\"%d\\n\", i); printf(\"%f\\n\", f); printf(\"%s\\n\", s); return 0; } "},"docs/输入与输出/格式化输入.html":{"url":"docs/输入与输出/格式化输入.html","title":"格式化输入","keywords":"","body":"格式化输入 执行下面的代码，按格式说明对字符序列进行解释，并将结果保存到参数中。 #include int main(int argc, char const *argv[]) { int i; float f; char s[20]; scanf(\"%d\", &i); printf(\"%d\\n\", i); scanf(\"%f\", &f); printf(\"%f\\n\", f); scanf(\"%s\", s); printf(\"%s\\n\", s); return 0; } 执行下面的代码，从键盘输入两个整数，求和后输出。 #include int main(int argc, char const *argv[]) { int i1, i2; scanf(\"%d %d\", &i1, &i2); printf(\"%d\\n\", i1 + i2); return 0; } 执行下面的代码，从字符串中读取字符序列。 #include int main(int argc, char const *argv[]) { char str[20]; sscanf(\"Hello!\", \"%s\", str); printf(\"%s\", str); return 0; } 也可以解析并读取稍微复杂的字符串。 #include int main(int argc, char const *argv[]) { char s1[20], s2[20]; int i; float f; sscanf(\"Hello World! 233 6.66\", \"%s %s %d %f\", s1, s2, &i, &f); printf(\"%s\\n\", s1); printf(\"%s\\n\", s2); printf(\"%i\\n\", i); printf(\"%f\\n\", f); return 0; } "},"docs/输入与输出/文件访问.html":{"url":"docs/输入与输出/文件访问.html","title":"文件访问","keywords":"","body":"文件访问 执行下面的代码，以只读方式打开指定的文件。 #include int main(int argc, char const *argv[]) { FILE *fp; fp = fopen(\"index.txt\", \"r\"); fclose(fp); return 0; } 执行下面的代码，从文件中逐个读取字符并输出。 #include int main(int argc, char const *argv[]) { FILE *fp; int c; fp = fopen(\"index.txt\", \"r\"); while ((c = getc(fp)) != EOF) { printf(\"%c\", c); } fclose(fp); return 0; } 执行下面的代码，逐个将字符写入文件中。 #include int main(int argc, char const *argv[]) { FILE *fp; int c; fp = fopen(\"index.txt\", \"w+\"); c = 'H'; putc(c, fp); c = 'e'; putc(c, fp); c = 'l'; putc(c, fp); c = 'l'; putc(c, fp); c = 'o'; putc(c, fp); c = ' '; putc(c, fp); c = 'W'; putc(c, fp); c = 'o'; putc(c, fp); c = 'r'; putc(c, fp); c = 'l'; putc(c, fp); c = 'd'; putc(c, fp); c = '!'; putc(c, fp); fclose(fp); return 0; } 执行下面的代码，实现文件的格式化输入或输出。 #include int main(int argc, char const *argv[]) { FILE *fp; int i; float f; char s[20]; fp = fopen(\"index.txt\", \"w+\"); fprintf(fp, \"%d %f %s\", 233, 6.66, \"Hello!\"); rewind(fp); fscanf(fp, \"%d %f %s\", &i, &f, s); printf(\"%d %f %s\", i, f, s); fclose(fp); return 0; } "},"docs/输入与输出/行输入和行输出.html":{"url":"docs/输入与输出/行输入和行输出.html","title":"行输入和行输出","keywords":"","body":"行输入和行输出 执行下面的代码，从标准输入中读取一行，然后输出。 #include int main(int argc, char const *argv[]) { char str[20]; gets(str); puts(str); return 0; } 执行下面的代码，从文件中读取一行，输出后再向文件中写入一行。 #include int main(int argc, char const *argv[]) { FILE *fp; char str[20]; fp = fopen(\"index.txt\", \"w+\"); fgets(str, 20, fp); puts(str); fputs(\"Hello C!\", fp); fclose(fp); return 0; } "}}