├── .gitignore ├── s.bat ├── math ├── README.md ├── cpu-calculation.md └── information-in-computer.md ├── package.json ├── SUMMARY.md ├── README.md ├── basics ├── 01_hello.md ├── 05_function.md ├── 03_expression.md ├── 06.md ├── 02_var.md ├── 08_pointer_basic.md ├── 07_array.md ├── 04_selection_&_loop.md ├── 09_pointer_&_array.md ├── 11_debug.md ├── 12_struct.md └── 10_string.md ├── Gruntfile.js └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .grunt 3 | /_book/ 4 | -------------------------------------------------------------------------------- /s.bat: -------------------------------------------------------------------------------- 1 | del _book/* -f 2 | gitbook build . -g Lellansin/C-basic-tutorial 3 | explorer _book/index.html -------------------------------------------------------------------------------- /math/README.md: -------------------------------------------------------------------------------- 1 | 信息存储 2 | 3.1 计算机数据存储单位 3 | 3.2 进制转换 4 | 3.2.1 常见的进制转换 5 | 3.2.2 二进制简介 6 | 3.2.3 进制计算的基本概念 7 | 3.2.3.1 七进制计算 8 | 3.2.3.2 六十进制计算 9 | 3.2.3.3 十进制计算 10 | 3.2.3.4 进制计算的规律与公式推导 11 | 3.2.4 二进制与十进制的转换 12 | 3.2.4.1 二进制转十进制 13 | 3.2.4.2 十进制转二进制 14 | 3.2.4.2.1 六十进制中 15 | 3.2.4.2.2 十进制中 16 | 3.2.4.2.3 除二取余法原理 17 | 3.2.5 二进制与十六进制的转换 18 | 3.2.6 大端法与小端法机器 19 | 3.3 数字与编码 20 | 3.3.1 ASCII编码 21 | 3.3.2 数字的计算 22 | 3.3.3 计算机中的数字与编码对比 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Javascript", 3 | "version": "0.0.5", 4 | "description": "", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/GitbookIO/javascript.git" 8 | }, 9 | "author": "Samy Pesse ", 10 | "license": "Apache 2", 11 | "dependencies": {}, 12 | "devDependencies": { 13 | "grunt": "~0.4.1", 14 | "grunt-gitbook": "0.1.2", 15 | "grunt-gh-pages": "0.9.1", 16 | "grunt-contrib-clean": "~0.5.0" 17 | }, 18 | "peerDependencies": { 19 | "grunt": "~0.4.1" 20 | } 21 | } -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [入门教程](basics/01_hello.md) 4 | * [数值、字符与字符串](basics/02_var.md) 5 | * [运算符及表达式](basics/03_expression.md) 6 | * [选择结构与循环结构](basics/04_selection_&_loop.md) 7 | * [函数基本概念及作用域](basics/05_function.md) 8 | * [编译预处理命令](basics/06.md) 9 | * [数组](basics/07_array.md) 10 | * [指针的基本概念](basics/08_pointer_basic.md) 11 | * [指针与数组](basics/09_pointer_&_array.md) 12 | * [字符串处理](basics/10_string.md) 13 | * [调试以及资料收集](basics/11_debug.md) 14 | * [结构体](basics/12_struct.md) 15 | * [数学基础](math/README.md) 16 | * [信息存储](math/information-in-computer.md) 17 | * [CPU四则运算](math/cpu-calculation.md) 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C/C++ 学习教程 2 | 3 | * [入门教程](basics/README.html) 4 | 5 | * [hello world](basics/01_hello.html) 6 | * [数值、字符与字符串](basics/02_var.html) 7 | * [运算符及表达式](basics/03_expression.html) 8 | * [选择结构与循环结构](basics/04_selection_&_loop.html) 9 | * [函数基本概念及作用域](basics/05_function.html) 10 | * [编译预处理命令](basics/06.html) 11 | * [数组](basics/07_array.html) 12 | * [指针的基本概念](basics/08_pointer_basic.html) 13 | * [指针与数组](basics/09_pointer_&_array.html) 14 | * [字符串处理](basics/10_string.html) 15 | * [调试以及资料收集](basics/11_debug.html) 16 | * [结构体](basics/12_struct.html) 17 | 18 | * [数学基础](math/README.html) 19 | 20 | * [信息存储](math/information-in-computer.html) 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /basics/01_hello.md: -------------------------------------------------------------------------------- 1 | Hello world 2 | ============ 3 | 4 | 压缩版下载地址:vc6_cn_setup 5 | 完整版、加强版等下载地址:Visual C++ 6.0 6 | 7 | 1.下载 vc6_cn_setup.exe 或者是其他版本的vc6 (推荐下载完整版,或者不嫌麻烦的可以去下载 visual studio 2010 或 2012) 8 | 2.安装vc 6.0 (一路确定过去就行了) 9 | 3.打开安装好的vc 6.0,如果操作系统是win7的话会提示不兼容,这个可以直接忽略,直接运行程序就可以了。 10 | 11 | 关掉每日提示,文件->新建->切换到文件->C++ source file->确定 12 | 13 | 到这里,我们可以先保存一下,保存的时候,劲量新建一个文件夹,保存在新文件夹内。避免编译之类的操作新生成一些文件,使得文件看起来很乱。 14 | 15 | 接下来开始输入第一个程序的代码: 16 | 17 | 18 | ```cpp 19 | #include 20 | int main() 21 | { 22 | printf("Hello world"); 23 | } 24 | ``` 25 | 26 | 输入完后记得保存(快捷键ctrl+s),然后找到菜单上的 组建->编译, 组建->执行 27 | 28 | 如果运行成功,那么恭喜你,你已经开始了你的编程之旅 29 | 如果有报错,可以仔细核对一下你的代码,看看是不是拼写有错 30 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | 3 | module.exports = function (grunt) { 4 | grunt.loadNpmTasks('grunt-gitbook'); 5 | grunt.loadNpmTasks('grunt-gh-pages'); 6 | grunt.loadNpmTasks('grunt-contrib-clean'); 7 | 8 | grunt.initConfig({ 9 | 'gitbook': { 10 | development: { 11 | output: path.join(__dirname, ".grunt/gitbook"), 12 | input: "./", 13 | title: "Learn Javascript", 14 | description: "Interactive online course for learning Javascript.", 15 | github: "GitbookIO/javascript" 16 | } 17 | }, 18 | 'gh-pages': { 19 | options: { 20 | base: '.grunt/gitbook' 21 | }, 22 | src: ['**'] 23 | }, 24 | 'clean': { 25 | files: '.grunt' 26 | } 27 | }); 28 | 29 | grunt.registerTask('publish', [ 30 | 'gitbook', 31 | 'gh-pages', 32 | 'clean' 33 | ]); 34 | grunt.registerTask('default', 'gitbook'); 35 | }; -------------------------------------------------------------------------------- /basics/05_function.md: -------------------------------------------------------------------------------- 1 | 函数的基本概念 2 | ========== 3 | 4 | 5 | 6 | 7 | ```cpp 8 | // 初中 9 | y = 3x + 2 10 | 11 | // 高中 12 | f(x) = 3x + 2 13 | 14 | // c语言 15 | int f(int x) 16 | { 17 | return x * 3 + 2; 18 | } 19 | ``` 20 | 21 |

C语言中的函数

22 | 23 | 1.函数名 24 | 2.参数 25 | 3.返回值 26 | 27 | 28 | ```cpp 29 | #include 30 | 31 | /* 32 | sum函数名 返回值为int 33 | int a, int b 为sum的参数及其类型 34 | 返回值为 ( a + b ) 这个表达式的值 35 | */ 36 | int sum(int a, int b) 37 | { 38 | return a + b; 39 | } 40 | int main() 41 | { 42 | int i, j; 43 | printf("请输入两个数:\n"); 44 | scanf("%d%d", &i, &j); 45 | printf("%d\n", sum(i, j)); // sum(参数,参数)的形式调用,返回两数之和 46 | } 47 | ``` 48 | 49 |

函数的作用域

50 | 51 | 52 | ```cpp 53 | #include 54 | 55 | void swap(int i, int j) 56 | { 57 | int temp; 58 | temp = i; i = j; j = temp; 59 | printf("x=%d, y=%d", x, y); 60 | } 61 | int main() 62 | { 63 | int i = 30, j = 75; 64 | swap(i, j); 65 | printf("i=%d, j=%d\n", i, j), 66 | } 67 | ``` 68 | int main()中的 i, j 与 swap() 中的 i,j 不是相同的变量 69 | 两个函数,是两个不同的内存块.两个变量名称相同,但不在同一个内存上 70 | 所以,如果其中某个变量有改变与另一个函数中的变量无关 71 | 72 | -------------------------------------------------------------------------------- /basics/03_expression.md: -------------------------------------------------------------------------------- 1 | 运算符以及表达式 2 | ========== 3 | 4 | ```cpp 5 | // 算术运算符 6 | 7 | #include 8 | int main() 9 | { 10 | int i = 7, j = 8; 11 | 12 | printf("i+j=%d\n", i + j ); //15 13 | printf("i-j=%d\n", i - j ); //0 14 | printf("i*j=%d\n", i * j ); //56 15 | printf("i/j=%d\n", i / j ); //0 16 | printf("i%%j=%d\n", i % j );//7 17 | 18 | i++; 19 | printf("i++后i的值为%d\n",i); //8 20 | printf("++i后i的值为%d\n",++i);//9 21 | 22 | printf("j--后j的值为%d\n",j--);//8 23 | printf("--j后j的值为%d\n",--j);//6 24 | } 25 | ``` 26 | 27 | 28 | 29 | ```cpp 30 | // 关系与逻辑运算符 31 | 32 | #include 33 | int main() 34 | { 35 | int Alan = 18, Sam = 18, Jack = 16; 36 | 37 | printf("%d\n", Alan > Jack ); // 1 38 | printf("%d\n", Sam < Jack ); // 0 39 | printf("%d\n", Alan != Sam ); // 0 40 | printf("%d\n", Alan == Sam ); // 1 41 | printf("%d\n", Alan >= Sam ); // 1 42 | printf("%d\n", (Sam>Jack) && (Sam>Jack) ); //1 43 | printf("%d\n", Alan > Jack );//1 44 | printf("%d\n", ! Sam ); //0 45 | } 46 | ``` 47 | 48 |   49 | 50 | 51 | ```cpp 52 | /* 53 | 数据类型转换 54 | 形式: 55 | (类型) (表达式) 56 | */ 57 | 58 | #include 59 | int main() 60 | { 61 | int chinese, math, english, sum; 62 | 63 | printf("请输入语数英三科的成绩:(以空格隔开)\n"); 64 | scanf("%d%d%d", &chinese, &math, &english); 65 | 66 | sum = (chinese + math + english); 67 | 68 | printf("平均分为%d\n", sum/3); 69 | printf("平均分为%f\n", (float)sum/3); 70 | } 71 | ``` 72 | 73 | 需要注意的是“=”与“==”之间的区别: 74 | “=”是赋值运算 75 | “==”是逻辑运算 76 | 77 | 78 | ```cpp 79 | #include 80 | int main() 81 | { 82 | int i = 5, b = 10; 83 | 84 | printf(" a=b 值为 %d\n", a = b ); //10 85 | printf("a==b 值为 %d\n", a == b); //0 86 | 87 | } 88 | ``` 89 | 90 | -------------------------------------------------------------------------------- /basics/06.md: -------------------------------------------------------------------------------- 1 | 编译预处理 2 | =========== 3 | 4 |

预处理指令

5 | 6 | #include 引用各种函数库 7 | #define 定义常用的宏 8 | 9 | 10 |

条件编译

11 | 12 | 根据表达式的结果来决定要编译的内容 13 | #if 14 | #else 15 | #elif 16 | #endif 17 | 18 | // 根据变量或宏等是否定义来决定要编译的内容 19 | #ifdef 20 | #ifndef 21 | 22 |

#include

23 | 24 | 25 | ```cpp 26 | // 1)两种形式: 27 | #include // 到配置目录中找 28 | #include "stdio.h" // 从当前目录开始找,无则到配置目录中找 29 | 30 | // 2)文件包含允许嵌套 31 | // 文件A包含了文件B,文件B又包含了文件C,最终文件B和C都会被引入A文件 32 | ``` 33 | 34 |

#define

35 | 宏定义,用一个标示符来表示一个字符串,这个字符串可以使常量、变量或表达式。在宏调用中,将用该字符串替换宏名。 36 | 37 | ```cpp 38 | #include 39 | // 1) 无参数宏 40 | #define PI 3.14 41 | #define M (a+b+c)/2.0 42 | int main() 43 | { 44 |   int a = 1, b = 2, c = 3; 45 |   printf("面积为%f", PI*2*2); 46 |   printf("%f", M); 47 | } 48 | ``` 49 | 50 | 51 | ```cpp 52 | // 2)带参数宏 53 | #define f(x) x*x+3*x 54 | #define Sum(a,b,c) a=b*c;b=c*a;a=b*c 55 | 56 | printf("%d", 3*f(2)); 57 | 58 | ``` 59 | PS:非值传递,而是传递形参字符 60 | 61 |

条件编译

62 | 63 | #if (常量表达式) =====> 注意常量,非变量 64 | 仅当表达式为真,则编译它与 #endif 之间的代码 65 | 66 | 67 | ```cpp 68 | #include 69 | 70 | #define debug = 0 71 | #define beta = 1 72 | #define status = 1 73 | int main() 74 | { 75 | #if (status == debug) 76 | printf("程序调试中\n"); 77 | #elif (status == beta) 78 | printf("程序测试中\n"); 79 | #else 80 | printf("欢迎使用正式版!\n"); 81 | #endif 82 | } 83 | ``` 84 | 85 | #ifdef 如果有定义 (if define) 86 | #ifndef 如果没定义 (if not define) 87 | 88 | 89 | ```cpp 90 | #ifndef PI 91 | define PI 3.14 92 | #endif 93 | ``` 94 | #ifdef 和 #ifndef 主要是用来避免重定义 95 | 96 |

c语言入门教程 第7讲 数组

97 | 98 | 额外内容: 99 | 使用CL.exe编译c程序 -------------------------------------------------------------------------------- /basics/02_var.md: -------------------------------------------------------------------------------- 1 | 数值、字符与字符串 2 | ============ 3 | 4 | 5 | 6 |

声明方式

7 | 数据类型 变量名; 8 | 9 | 举例: 10 | 11 | 12 | ```cpp 13 | // int类型 14 | int i; /* 普通声明 */ 15 | int j,k; /* 同时声明多个 */ 16 | int age = 18; /* 声明的同时赋值 */ 17 | int Alan ,Sam=16;/* 声明与同时赋值 */ 18 | 19 | // float类型 20 | float f; /* 普通声明 */ 21 | float q,money; /* 同时声明多个 */ 22 | float v = 2.0; /* 声明的同时赋值 */ 23 | 24 | // char类型 25 | 26 | char c; /* 普通声明 */ 27 | char zh,text; /* 同时声明多个 */ 28 | char letter = 'A'; /* 声明的同时赋值 */ 29 | 30 | // char数组(字符串) 31 | 32 | char c[20] = { 'H','e','l','l','o',' ','w','o','r','l','d' }; 33 | char name[] = { 'A', 'l', 'a', 'n' }; 34 | ``` 35 | 36 |

转义字符

37 | 38 | 在一段字符串中,不能直接出现,需要转义的字符,例如: 39 | 40 | '\n' 换行 41 | '\t'' 水平制表 42 | '\'' 单引号 43 | '\"' 双引号 44 | '\\' 反斜杠 45 | 46 | 47 | ```cpp 48 | #include 49 | main() 50 | { 51 | printf("Num\tName\n"); 52 | printf("001\tAlan\n"); 53 | printf("002\tLellansin\n"); 54 | } 55 | ``` 56 | 57 | 58 | ```cpp 59 | 输出结果: 60 | Num   Name 61 | 001   Alan 62 | 002   Lellansin 63 | ``` 64 | 65 |

printf与scanf

66 | 67 | printf 打印,scanf 为输入 68 | 69 | 形式 70 | 71 | ```cpp 72 | printf(字符串,... ); // 点点点为多个参数 73 | scanf(字符串,... ); 74 | ``` 75 | 76 |

占位符

77 | 78 | 对于 printf 输出的情况而言,占位符的意思是先占个位置的符号,至于这个位置将来会放什么还不确定,只能先确定是占位符所指明的类型,具体的值还要等稍后的参数中补充。对于 scanf 来说,则是相反的情况。 79 | 80 | 常见格式: 81 | 82 | %d   十进制整数 83 | %i   十进制整数 84 | %c   单个字符 85 | %s   字符串 86 | %f   浮点数 87 | 88 | 如: 89 | 90 | 91 | ```cpp 92 | // 输出字符串要输出的年龄尚未确实值知道是 %d 十进制整数类型, 93 | // 具体输出来是什么值则看后面 age 的具体值 94 | printf("Alan的年龄是%d", age); 95 | 96 | // 接手用户输入的一个十进制整数,注意输入是要加 & 符号 97 | // 如果用户输入 10.2 则存入变量i中的值是 10,因为格式是十进制整数 98 | scanf("%d", &i); 99 | 100 | ``` 101 | 102 | 举例: 103 | 104 | 105 | ```cpp 106 | #include 107 | int main() 108 | { 109 | int age; 110 | printf("你的年龄是?\n"); 111 | scanf("%d",&age); // 输入时变量前加上 “&” 符号 112 | printf("你的年龄是%d",age); 113 | } 114 | ``` 115 | 116 | -------------------------------------------------------------------------------- /math/cpu-calculation.md: -------------------------------------------------------------------------------- 1 | CPU如何进行数学运算 2 | ============================ 3 | 4 |
    5 |
  1. 位运算 6 |
      7 |
    • 与或非 8 |
        9 |
      • 按位与
      • 10 |
      • 按位或
      • 11 |
      • 按位取反
      • 12 |
      13 |
    • 14 |
    • 位移 15 |
        16 |
      • 左移
      • 17 |
      • 右移
      • 18 |
      • 算术位移与逻辑位移
      • 19 |
      20 |
    • 21 |
    22 |
  2. 23 |
  3. 四则运算 24 |
      25 |
    • 26 |
    • 27 |
    • 28 |
    • 29 |
    30 |
  4. 31 |
32 | 33 | 位运算 34 | ------------------ 35 | 36 | 37 | ###与或非 38 | 39 | ####按位与 40 | 41 | 符号: & 42 | 示例: 43 |
 44 | 1(10进制)  =  0000 0001 (2进制)
 45 | 9(10进制)  =  0000 1001 (2进制)
 46 | 1  &  9    =  0000 0001 (2进制)
 47 |            =  1 (10进制)
 48 | 
49 | 50 | 计算遵守:都为真则真, 除此之外为假 51 | 52 | ####按位或 53 | 54 | 符号:| 55 | 示例: 56 |
 57 | 5(10进制)  =  0000 0101 (2进制)
 58 | 8(10进制)  =  0000 1000 (2进制)
 59 | 5  |  8    =  0000 1101 (2进制)
 60 |            =  13 (10进制)
 61 | 
62 | 63 | 计算遵守:只有要一个是真结果就是真, 都为假才假 64 | 65 | ####按位取反 66 | 67 | 符号:~ 68 | 示例: 69 |
 70 | 5(10进制)  =  0000 0101 (2进制)
 71 |     ~5     =  1111 1010 (2进制)
 72 |            =  -6 (10进制)
 73 | 
74 | 75 | 计算遵守:真变假,假变真 76 | 77 | PS:二进制负数的计算是 78 | 79 |
 80 |             0  =  0000 0000
 81 |  0 - 1  =  -1  =  1111 1111
 82 | -1 - 1  =  -2  =  1111 1110
 83 | -2 - 1  =  -3  =  1111 1101
 84 | -3 - 1  =  -4  =  1111 1100
 85 | -4 - 1  =  -5  =  1111 1011
 86 | -5 - 1  =  -6  =  1111 1010
 87 | 
88 | 89 | 90 | ###位移 91 | 92 | ####左移 93 | 94 | 符号:<< 95 | 运算:直接将数据向左移动一位,并补零 96 | 97 |
 98 | 1 (10进制) = 0000 0001 (2进制)
 99 | 1  <<  1   = 0000 0010 (2进制)
100 |            = 2
101 | 
102 | 1  <<  3   = 0000 1000 (2进制)
103 |            = 8
104 | 
105 | 106 | ####右移 107 | 108 | 符号:>> 109 | 运算:直接将数据向左右动一位,并补零 110 | 111 |
112 | 9 (10进制) = 0000 1001 (2进制)
113 | 9  >>  1   = 0000 0100 (2进制)
114 |            = 4
115 | 
116 | 9  <<  3   = 0000 0001 (2进制)
117 |            = 1
118 | 
119 | 120 | ####算术位移与逻辑位移 121 | 122 | 位移包括算术位移和逻辑位移两种情况。逻辑位移是指位移过后直接补零。 123 | 124 | 算术位移是指在保持符号位不变的情况下进行的位移。 125 | 126 | 例如: 127 |
128 | -6 (10进制) = 1111 1010 (2进制)
129 | -6  >>  1   = 1111 1101 (2进制)
130 |             = -3
131 | 
132 | -6  >>  2   = 1111 1110 (2进制)
133 |             = -1
134 | 
135 | 136 | 对于 -6 而言最高位 1 是负数标识的符号位,在进行位移的时候该符号位会保持不变,这种位移叫做算术位移。而不论如何位移过后都补零的情况测试逻辑位移 137 | 138 | 四则运算 139 | ------------------ 140 | 141 | 142 | ###加 143 | 144 | 145 | ###减 146 | 147 | 148 | ###乘 149 | 150 | 151 | ###除 152 | -------------------------------------------------------------------------------- /basics/08_pointer_basic.md: -------------------------------------------------------------------------------- 1 | 指针的基本概念 2 | ============ 3 | 4 | “&” 与 “*” 5 | ------------ 6 | 7 | 取地址与指针运算符(取值运算) 8 | 9 | “&” 对变量进行取地址运算: 10 | &(变量名) => 获取变量的地址 11 | 如: 12 | 13 | ```cpp 14 | int i; 15 | printf("%d", &i); // 打印出地址 16 | ``` 17 | 18 | 如: 19 | 20 | ```cpp 21 | scanf("%d", &i); // 传入一个地址 22 | ``` 23 | 24 | 而“*”作为指针运算符,当然我更乐意称它为取值运算: 25 | *(变量名) => 将变量当做地址,到相应的地址取值 26 | 27 | 思考: 28 | 29 | *(&(变量名)) 是什么? 30 | 31 | 32 | ```cpp 33 | int i = 6; 34 | printf( "%d", *(&i) ); 35 | ``` 36 | 37 | 什么是指针变量? 38 | ------------ 39 | 40 | 指针变量就是用来存储地址的变量 41 | 42 | 任何变量都它存储的地址,这个地址是随机分配的。如: 43 | 44 | ```cpp 45 | int i = 10; 46 | ``` 47 | i 这个变量的地址,是系统随机分配的。而我们对其进行 “&” 运算之后就可以得到它的地址,并且 (&i) 这个表达式就是一个指向i的指针。 48 | 49 | 这个指针所指向的地址中存储的值则是: 50 | *(&i) ==> i 51 | 52 | 53 | 54 | 声明与初始化 55 | ------------ 56 | 57 | 声明方式: 58 | 59 | 指针类型 * 指针变量名; 60 | 61 | 例如: 62 | 63 | ```cpp 64 | int *p1; 65 | char *name; 66 | ``` 67 | 68 | 初始化: 69 | 70 | 1)普通写法 71 | 72 | ```cpp 73 | int x; 74 | int *p; 75 | p = &x; 76 | ``` 77 | 2)省略写法 78 | 79 | ```cpp 80 | int x; 81 | int *p = &x; 82 | ``` 83 | 84 | 上述两种写法都声明了一个指针p,并且这个指针是指向变量 x 的 85 | 对于变量 x, (&x) 则是一个指向x的指针 (指针存放的就是地址, 而&运算得到的地址表达式也就是指向其本身的指针) 86 | 并且通过 *(指针) 取到这个地址中的值 87 | 88 | 常见错误 89 | ------------ 90 | 91 | 请不要人为的指派地址: 92 | 93 | ```cpp 94 | // 错误1 95 | int *p; 96 | p = 10010; 97 | 98 | // 错误2 99 | int x = 20; 100 | printf("%d", &(*x) ); 101 | 102 | // 正确形式: 103 | int i, *p, *t; 104 | p = &i; 105 | t = p; 106 | ``` 107 | 只能通过已有的变量传递 108 | 109 |

经典的错误 - Scanf函数

110 | 111 | 112 | ```cpp 113 | int score; 114 | printf("请输入你的分数:\n"); 115 | scanf("%d", score); 116 | ``` 117 | 上述代码在编译时没有错,运行时会出现严重的错误 118 | 119 | 错误原因: 120 | scanf() 函数后面的参数应该传入的是指针,而这里直接把 score 的值传了进去。 121 | 122 | 正确应该是: 123 | 124 | ```cpp 125 | int score; 126 | printf("请输入你的分数:\n"); 127 | scanf("%d", &score); 128 | ``` 129 | 130 | 131 |

Swap交换两个变量

132 | 133 | 与第五讲中不同的是,使用指针到某个地址中取访问它的值,就没有了作用域的限制 134 | 135 | 136 | ```cpp 137 | #include 138 | 139 | void swap(int *x, int *y) 140 | { 141 | int temp; 142 | temp = *x; 143 | *x = *y; 144 | *y = temp; 145 | printf("x=%d, y=%d \n", *x, *y); 146 | } 147 | int main() 148 | { 149 | int i = 13, j = 45; 150 | swap(&i, &j); 151 | printf("i=%d, j=%d\n", i, j); 152 | } 153 | ``` 154 | 155 | 156 | 本讲小结 157 | ------------ 158 | 159 | 1) “&” 和 “*” 160 | 161 | 取地址与取值运算符 ==> 互为逆运算 162 | 163 | 2)指针变量是什么? 164 | 165 | 指针变量就是用来存储地址的变量 166 | 如,&i 就是一个指向变量i 的指针 167 | 通过*(指针)取值 168 | 169 | 3)声明 170 | 171 | int *p1; 172 | char *name; 173 | 174 | 4)初始化 175 | 176 | 普通写法 177 | 178 | ```cpp 179 | int x; 180 | int *p; 181 | p = &x; 182 | ``` 183 | 184 | 省略写法 185 | 186 | ```cpp 187 | int x; 188 | int *p = &x; 189 | ``` 190 | 191 | 5)指针的作用 192 | 引用类型,传递地址,减少内存消耗 193 | 194 | 195 | 课后作业 196 | ------------ 197 | 198 | 现在有一个数组,存储的是一个同学的期中考试成绩。 199 | 200 | ```cpp 201 | int score[8] = { 75, 86, 70, 88, 62, 87, 69, 77 }; 202 | ``` 203 | 那么现在我们要做的事情是: 204 | 205 | 1)求总分,求平均分 206 | 207 | 2)用指针遍历数组,求最大值和最小值 208 | 209 | 附加题: 210 | 用一个二维数组存储八门课的名称,例如: 211 | 212 | ```cpp 213 | char course[8][256] = { "chinese", "English", ... } 214 | ``` 215 | 再用二维数组,存储多个人的成绩,用指针遍历求出每门课的平均分 216 | 217 | 218 | C语言入门教程 第9讲 指针与数组 219 | ------------ -------------------------------------------------------------------------------- /basics/07_array.md: -------------------------------------------------------------------------------- 1 | 数组 2 | ======== 3 | 4 | 一维数组 5 | --------------- 6 | 7 | 同类元素的集合,称为数组 8 | 9 | ###定义方式 10 | 11 | 数据类型 数组名 [常量表达式]; 举例: 12 | 13 | 14 | ```cpp 15 | int a[5]; 16 | float score[8]; 17 | double d[10]; 18 | char name[256]; 19 | ``` 20 | 21 | ###初始化 22 | 23 | 24 | ```cpp 25 | 26 | int a[3]; 27 | a[0] = 1; 28 | a[1] = 2; 29 | a[2] = 3; 30 | 31 | int b[5] = { 1, 2, 3, 4, 5 }; // 省略写法 32 | 33 | float score[8] = { 1.0, 1.2 }; // 后面未赋值则为零 34 | 35 | char name[] = "Alan"; // 省略写法,单独定义时必须声明大小 36 | 37 | ``` 38 | 39 | ###一维数组的下标 40 | 41 | 数组的下标实际上是关于数组第一个元素的偏移量 比如,定义一个数组array[5]。它的第一个元素跟数组的第一个元素的偏移量为0 所以,数组的第一个元素应该是array[0] 数组的第二个元素跟数组的第一个元素偏移量为1 所以,数组的第二个元素应该是array[1] 以此类推,数组的第五个元素与第一个元素的偏移量为4 所以,数组array的第五个元素应该是array[4] 结论: 一位数组最后一个元素的下标为 (长度 - 1) 并且对于一个数组它的第几个元素的下标就是几减一 42 | 43 | ###循环初始化: 44 | 45 | 46 | ```cpp 47 | 48 | #include 49 | int main() 50 | { 51 | int a[10], b[3], i; 52 | 53 | // 有规律的循环赋值 54 | for( i = 0; i < 10; i++ ) 55 | { 56 | a[i] = i; 57 | } 58 | 59 | // 多次输入赋值 60 | for( i = 0; i < 3; i++ ) 61 | { 62 | scanf("%d", b[i]); 63 | } 64 | } 65 | ``` 66 | 67 | 注意如果一次输入多个数用scanf循环去接收的话,空格也会被当做字符(或数值)来保存 68 | 69 | ###一维数组遍历 70 | 71 | 72 | ```cpp 73 | #include 74 | int main() 75 | { 76 | int a[8] = { 1, 1, 2, 3, 5, 8, 13, 21 }; 77 | int i; 78 | 79 | for( i = 0; i < 8; i++ ) 80 | { 81 | printf("%d ", a[i]); 82 | } 83 | } 84 | ``` 85 | 86 | 一维数组应用示例 87 | 88 | 89 | ```cpp 90 | #include 91 | int main() 92 | { 93 | int a[8] = { 80, 90, 85, 84, 70, 76, 75, 83 }; 94 | int i, max = 0, min = 100; 95 | 96 | for( i = 0; i < 8; i++ ) 97 | { 98 | if( a[i] > max ) 99 | { 100 | max = a[i]; 101 | }else if( a[i] < min ) 102 | { 103 | min = a[i]; 104 | } 105 | } 106 | printf("最高分为:%d 最低分为:%d", max, min); 107 | } 108 | 109 | ``` 110 | 111 | 112 | 二维数组 113 | --------------- 114 | 115 | ###定义 116 | 117 | 118 | ```cpp 119 | //数据类型 数组名 [常量表达式][常量表达式]; 120 | 121 | int a[56][3]; 122 | char name[5][256]; 123 | ``` 124 | 125 | ###初始化 126 | 127 | 128 | ```cpp 129 | 130 | // 1)分段赋值 131 | int grade[2][3] = { {80,75,92}, {61,65,71} }; 132 | 133 | // 2)连续赋值 134 | int a[2][3] = { 80, 75, 92, 61, 65, 71 }; 135 | 136 | // 3)连续省略赋值 137 | int a[][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 138 | 139 | ``` 140 | 141 | ###二维数组的遍历 142 | 143 | 144 | ```cpp 145 | 146 | #include 147 | 148 | int main() 149 | { 150 | int grade[4][3] = {82,77,76,90,87,56,87,48,75,86,86,66}; 151 | int i, j; 152 | for( i = 0; i < 4; i++ ) 153 | { 154 | for( j = 0; j < 3; j++ ) 155 | { 156 | if( grade[i][j] < 60 ) 157 | { 158 | printf("第%d位学生不及格"); 159 | continue; 160 | } 161 | } 162 | } 163 | } 164 | 165 | ``` 166 | 167 | ###本讲小结 168 | 169 | 一、数组由类型说明符、数组名、数组长度(数组的个数)三部分组成 170 | int a[10]; float money[2][3]; // 注意下标 171 | 172 | 二、数组的初始化 173 | 1)声明之后一个个赋值 174 | 2)省略形式赋值: char name[] = "Sam"; 175 | 176 | 三、数组的遍历 177 | 通过while、do while、for等循环遍历 178 | 179 | 四、数组的作用 180 | 数组是程序设计中最常用的数据结构,属于构造类型。它将相同类型的数据连续组合在一起,简化了命名和赋值过程。相较单一的数据类型,能够更快更方便的处理更多的数据。 181 | 182 |

C语言入门教程 第8讲 指针的基本概念

-------------------------------------------------------------------------------- /basics/04_selection_&_loop.md: -------------------------------------------------------------------------------- 1 | 选择结构与循环结构 2 | ============ 3 | 4 |

选择结构

5 |
  6 | 1.if() else
  7 | 2.switch() case:
  8 | 
9 | 10 |

循环结构

11 |
 12 | 1.while() 循环
 13 | 2.do while() 循环
 14 | 3.for() 循环
 15 | 
16 | 17 | 终止循环: 18 | 1.continue 终止该次循环 19 | 2.break 终止该循环 20 |

if else

21 | 22 | ```cpp 23 | // 形式1 24 | if(条件) 25 | { /*条件为真执行*/ 26 | ... 27 | } 28 | 29 | // 形式2 30 | if(条件) 31 | { /*条件为真执行*/ 32 | ... 33 | }else 34 | { /*条件为假执行*/ 35 | ... 36 | } 37 | 38 | // 更多形式.. 39 | if(条件1) 40 | { /*条件1为真执行*/ 41 | ... 42 | }else if(条件2) 43 | { /*条件2为真执行*/ 44 | ... 45 | }else 46 | { /*条件1、2为假才执行*/ 47 | ... 48 | } 49 | ``` 50 | 51 | 代码示例: 52 | 53 | 54 | ```cpp 55 | #include 56 | int main() 57 | { 58 | int salary = 2500; 59 | int rent = 850; 60 | int life_cost = 1000; 61 | 62 | if( salary > (rent + life_cost) ) 63 | { 64 | printf("还过的下去"); 65 | }else if( salary < (rent + life_cost) ) 66 | { 67 | printf("活不下去了!"); 68 | }else 69 | { 70 | printf("妈的!"); 71 | } 72 | } 73 | 74 | ``` 75 | 76 |

switch

77 | 78 | 79 | ```cpp 80 | switch(变量) 81 | { 82 | case 情况1 : 83 | ... 84 | break; 85 | 86 | case 情况2 : 87 | ... 88 | break; 89 | 90 | case 情况3 : 91 | ... 92 | break; 93 | 94 | default : /* 默认情况 */ 95 | ... 96 | } 97 | ``` 98 | 99 | 代码示例 100 | 101 | 102 | ```cpp 103 | #include 104 | int main() 105 | { 106 | char cmd; 107 | 108 | printf("确认要删除吗?"); 109 | scanf("%c", cmd); 110 | 111 | switch(cmd) 112 | { 113 | case 'Y': 114 | printf("文件正在删除\n"); 115 | break; 116 | case 'N': 117 | printf("取消删除\n"); 118 | break; 119 | defualt: 120 | printf("用户未响应,操作取消\n"); 121 | } 122 | } 123 | ``` 124 | 125 | 关于case穿透 126 | 127 | 128 | ```cpp 129 | #include 130 | int main() 131 | { 132 | int score = 80; 133 | 134 | switch(math/10) 135 | { 136 | case 1: 137 | case 2: 138 | case 3: 139 | case 4: 140 | case 5: 141 | printf("不及格\n"); 142 | case 6: 143 | case 7: 144 | case 8: 145 | printf("及格\n"); 146 | case 9: 147 | case 10: 148 | printf("满分\n"); 149 | } 150 | } 151 | 152 | ``` 153 | 154 |

while 循环

155 | 156 | 157 | ```cpp 158 | #include 159 | int main() 160 | { 161 | int i = 0; 162 | while(i < 10) 163 | { 164 | printf("%d ", i); 165 | } 166 | } 167 | ``` 168 | 169 |

do while 循环

170 | 171 | 172 | ```cpp 173 | #include 174 | int main() 175 | { 176 | char c; 177 | 178 | do 179 | { 180 | printf("请问你是⑨吗?(Y/N)\n") 181 | scanf("%c", &c); 182 | }while( c != 'Y'); 183 | 184 | } 185 | ``` 186 | 187 |

for 循环

188 | 189 | 190 | ```cpp 191 | // 形式 192 | for( 初始值; 条件; 变化 ) 193 | { 194 | ... 195 | } 196 | ``` 197 | 198 | 示例: 199 | 200 | 201 | ```cpp 202 | #include 203 | int main() 204 | { 205 | int i; 206 | for( i = 0; i < 10; i++ ) 207 | { 208 | printf("%d\n", i); 209 | } 210 | } 211 | ``` 212 | 213 |

continue与break

214 | 215 | 终止循环: 216 | 1.continue 终止该次循环 217 | 2.break 终止该循环 218 | 219 | 220 | ```cpp 221 | #include 222 | main() 223 | { 224 | int i; 225 | for( i = 0; i < 10; i++) 226 | { 227 | if( i == 3 ) 228 | continue; 229 | printf("%d ", i); 230 | } 231 | } 232 | ``` 233 | 234 | -------------------------------------------------------------------------------- /basics/09_pointer_&_array.md: -------------------------------------------------------------------------------- 1 | 指针与数组 2 | ============ 3 | 4 | ###上节课后作业 5 | 6 | 现在有一个数组,存储的是一个同学的期中考试成绩。 7 | 8 | int score[8] = { 75, 86, 70, 88, 62, 87, 69, 77 }; 9 | 10 | 那么现在我们要做的事情是: 11 | 12 | 1)求总分,求平均分 13 | 14 | 2)用指针遍历数组,求最大值和最小值 15 | 16 | 附加题: 17 | 用一个二维数组存储八门课的名称,例如: 18 | char course[8][256] = { "chinese", "English" ... } 19 | 再用二维数组,存储多个人的成绩,用指针遍历求出每门课的平均分 20 | 21 | 22 | ```cpp 23 | #include 24 | #include 25 | 26 | int main() 27 | { 28 | // 现在有一个数组,存储的是一个同学的期中考试成绩。 29 | char course[8][256] = { "语文", "数学", "英语", "物理", "化学", "生物", "历史", "地理" }; 30 | char name[5][256] = {"Alan", "Bob", "Clain", "David", "Elis"}; 31 | int score[5][8]; 32 | int sum[5] = {0}; 33 | float avg[8] = {0}; 34 | 35 | int i,j; 36 | 37 | for(i = 0; i < 5; i++) 38 | { 39 | for(j = 0; j < 8; j++) 40 | { 41 | score[i][j] = rand() % 100; 42 | } 43 | } 44 | 45 | 46 | for(i = 0; i < 5; i++) 47 | { 48 | for(j = 0; j < 8; j++) 49 | { 50 | sum[i] += score[i][j]; 51 | avg[j] += score[i][j]; 52 | } 53 | } 54 | 55 | 56 | for(i = 0; i < 8; i++) 57 | { 58 | printf("\t%s", course[i]); 59 | } 60 | 61 | printf("\t总分"); 62 | 63 | for(i = 0; i < 5; i++) 64 | { 65 | printf("\n%s", name[i]); 66 | for(j = 0; j < 8; j++) 67 | { 68 | printf("\t %d",score[i][j]); 69 | } 70 | printf("\t%d", sum[i]); 71 | } 72 | 73 | printf("\n平均分"); 74 | 75 | for(j = 0; j < 8; j++) 76 | { 77 | printf("\t%.1f", avg[j] / 8.0); 78 | } 79 | 80 | printf("\n"); 81 | return 0; 82 | } 83 | ``` 84 | 85 | 字符数组与指针 86 | ---------------- 87 | 88 | 字符串 == 字符数组+'\0'结尾 89 | 90 | 91 | ```cpp 92 | // 对于字符串"Hello world"相当于如下的字符数组 93 | char hi[] = {'h','e','l','l','o',' ','w','o','r','l','d', '\0'}; 94 | 95 | printf("%c \n", hi[1]); // e 96 | printf("%c \n", "Hello world"[1]); // e 97 | 98 | ``` 99 | 因为字符串相当于字符数组,所以"Hello world"[1]越数组hi[1]的值一样。 100 | 101 | 数组名 == 起始地址 102 | ---------------- 103 | 104 | 学会自己研究各种变量 105 | 106 | 1)如何研究? 107 | 学会善用printf 108 | 109 | 2)怎么知道变量是不是一个指针(或地址) 110 | 学会使用* 111 | 112 | 113 | ```cpp 114 | int a[5] = { 1, 3, 5 }; 115 | 116 | printf("%d", a); // 1638196 117 | printf("%d", *a); // 1 118 | printf("%d", *(a+1)); // 3 119 | ``` 120 | 运行成功,表示这个变量的类型即使不是指针,也是一个地址 121 | 122 | 常见用法: 123 | 124 | ```cpp 125 | int a[5] = { 1, 3, 5 }; 126 | int *p; 127 | p = a; 128 | printf("%d", *(p+1)); // 3 129 | printf("%d", *(p+2)); // 5 130 | ``` 131 | 132 | "Hello world"究竟是? 133 | ---------------- 134 | 135 | 有了上面的两个结论之后,我就可以继续使用printf来探讨更多的东西。 136 | 比如"Hello world"这个字符串所代表的意义。 137 | 我们已经知道这个字符串实际上就是一个字符数组,通过"Hello world"[1]甚至可以取到其中的值。那么对于这样一个字符串而言它的数组名(地址)是什么? 138 | 运用以上相同的方法可以看到: 139 | 140 | ```cpp 141 | printf("%d", "Hello world" ); // 4337572 142 | printf("%d", *("Hello world")); // 72 143 | printf("%c", *("Hello world")); // H 144 | printf("%c", *("Hello world"+1)); // e 145 | ``` 146 | 147 | 多个名字如何用char数组存储? 148 | ---------------- 149 | 150 | 多个人的名字: 151 | 152 | ```cpp 153 | char a[256] = "Alan"; 154 | char b[256] = "Bob"; 155 | char c[256] = "Cici"; 156 | ``` 157 | 158 | 现在要用数组来存储这三个人的名字。 159 | 也就是要用一个数组来存储三个数组,数组的每一个元素是一个数组: 160 | 161 | 162 | ```cpp 163 | char name[3][256] = {"Alan", "Bob", "Cici" }; 164 | ``` 165 | 166 | 如何使用指针遍历 167 | ---------------- 168 | 169 | 170 | ```cpp 171 | int arr[8] = { 1, 1, 2, 3, 5, 8, 13, 21 }; 172 | int i; 173 | int *p; 174 | // 普通遍历 175 | for(i = 0; i < 8; i++) 176 | { 177 | printf("%d ", arr[i]); 178 | } 179 | // 指针遍历 180 | for(p = &(arr[0]); p <= &(arr[7]); p++) 181 | { 182 | printf("%d ", *p); 183 | } 184 | // 数组名获取指针地址 185 | for(p = arr; p < (arr+8); p++) 186 | { 187 | printf("%d ", *p); 188 | } 189 | ``` 190 | 191 | 本讲小结 192 | ---------------- 193 | 194 | 1)如何使用指针遍历数组? 195 | 使用循环 196 | 197 | 2)如何研究各种变量? 198 | 尝试使用printf 199 | 200 | 3)数组与指针什么关系? 201 | 数组名就是一个地址,指向这个数据的开端 202 | 203 | 204 | ```cpp 205 | int a[] = {1, 3, 5, 7, 9}; 206 | int *p = a; 207 | 208 | printf( "%d \n", *p == a[0] ); // 1 209 | printf( "%d \n", *(p+1) == a[1] ); // 1 210 | printf( "%d \n", *(p+2) == a[2] ); // 1 211 | ``` 212 | 213 | 可以知道: 214 | 215 | ```cpp 216 | *(p+n) == a[n] 217 | ``` 218 | 219 | 引申推导: 220 | 221 | ```cpp 222 | a[n] = *(p+n) 223 | = *(n+p) 224 | = n[a] 225 | ``` 226 | 227 | 即: 228 | 229 | ```cpp 230 | a[n] = n[a] 231 | ``` 232 | 233 | 可以这样理解,下标对于数组来说,就是相对于起始地址的一个偏移量。 -------------------------------------------------------------------------------- /basics/11_debug.md: -------------------------------------------------------------------------------- 1 | 调试以及资料收集 2 | =============== 3 | 4 | 视频地址 5 | 6 | A站:http://www.acfun.tv/v/ac479828 7 | B站:http://www.bilibili.tv/video/av400594/ 8 | 新浪:http://video.sina.com.cn/v/b/90825190-2731231323.html 9 | 10 | 如何进行调试 11 | 12 | 1)注释调试 13 | 2)printf打印调试 14 | 3)根据报错信息找错 15 | 4)使用调试工具 16 | 5)求助网络 17 | 18 | 查询文档 19 | 20 | 1.右键查看定义 21 | 2.度娘谷歌 22 | 3.手册 23 | 4.自己撰写自己的文档 24 | 25 | 如何查看函数以及变量的引用? 26 | 使用工具自带的功能。 27 | 28 | 如何查看函数的使用方法? 29 | 度娘谷歌等,vs下可按F1查看微软的帮助文档 30 | 31 | 基础的东西学完了如果知道下一步学什么? 32 | 通过相关的书籍、论坛帖子或者博客博文 33 | 34 | 提高自己的查找能力 35 | 36 | 查询: 37 | http://www.baidu.com/               度娘 38 | http://www.google.com.hk/        谷歌 39 | http://msdn.microsoft.com/        MSDN 40 | 41 | 百度知道、各大博客论坛的搜索功能 42 | 43 | 资料网站: 44 | http://www.verycd.com                电驴 45 | http://www.51cto.com                  51CTO 46 | http://club.topsage.com/               大家网 47 | http://www.oschina.net/             开源中国 48 | 49 | 论坛: 50 | http://bbs.chinaunix.net/            ChinaUnix论坛 51 | http://bbs.51cto.com/                51cto论坛 52 | http://www.itpub.net/                 itpub论坛 53 | http://bbs.pediy.com/                 看雪学院 54 | http://www.cctry.com/               vc驿站 55 | http://bbs.fishc.com/                  鱼C论坛 56 | http://bbs.bccn.net/                   编程论坛 57 | http://www.rupeng.com/                   如鹏网 58 | 59 | 技术博客聚集区: 60 | http://blogs.msdn.com/              MSDN博客 61 | http://www.cnblogs.com/           博客园 62 | http://blog.51cto.com/               51cto博客 63 | http://www.iteye.com/blogs        iteye博客 64 | http://space.itpub.net/                itpub博客 65 | http://wo.zdnet.com.cn/             ZDNet技术社区 66 | http://www.oschina.net/blog             开源中国 67 | 68 | 英文网站: 69 | http://sourceforge.net/ 70 | http://www.cplusplus.com 71 | http://www.codeguru.com/ 72 | http://www.codeproject.com/ 73 | 74 | 书籍教程推荐 75 | 76 | 《C语言自学教程》郝斌 77 | 《数据结构自学视频》郝斌 78 | 《C Primer Plus》中文版 79 | 《C语言程序设计 现代方法》 80 | 《狂人C-程序员入门必备》 81 | 《C和指针》人民邮电出版社 82 | 《C语言实例解析精粹》曹衍龙 83 | 84 | 如何学习? 85 | 86 | 1.理解编程过程中的知识点 87 | 2.使用自己理解知识去编程、在编程的过程中验证所学 88 | 3.尝试去寻找题目编写 89 | 4.在调试中寻找自己的不足 90 | 5.阅读好的书籍,查漏补缺(可搜索笔记) 91 | 92 | 小结 93 | 94 | 1.调试的基本方法 95 | 2.去哪里找资料? 96 | 3.如何学习比较好? 97 | 98 | 如果有发现不错的网站或者资料可以向博主推荐 99 | 特别是各个博客区中比较好的博客 100 | 后期还会再排版,汇总推荐 101 | 102 | C/C++ Beginner 一群 10191598 103 | C/C++ Beginner 二群 163859361 (感谢One day捐助) 104 | C/C++ Beginner 三群 10366953 (感谢Vol jun捐助) 105 | 106 |

c语言入门教程 第12讲 结构体

-------------------------------------------------------------------------------- /basics/12_struct.md: -------------------------------------------------------------------------------- 1 | 结构体 2 | ============ 3 | 4 | 结构体 5 | 6 | 可以将多种数据类型组合起来的结构 7 | 8 | 声明方式 9 | 10 | struct 结构体名称{ 11 | 成员1的类型  成员1的名称; 12 | 成员2的类型 成员2的名称; 13 | ...... 14 | 成员3的类型  成员3的名称; 15 | } ; 16 | 17 | 举例: 18 | 19 | ```cpp 20 | struct time{ 21 | int hour; 22 | int minute; 23 | int second; 24 | } ; 25 | ``` 26 | 27 | 28 | 29 | 注意不要漏掉了最后的分号 30 | 31 | 结构体的定义 32 | 33 | 1)常规定义 34 | 35 | ```cpp 36 | struct time{ 37 | int hour; 38 | int minute; 39 | int second; 40 | } ; 41 | 42 | struct time t; 43 | ``` 44 | 45 | 46 | 47 | 如何定义一个int类型的变量? 48 | 49 | ```cpp 50 | int number; 51 | ``` 52 | 53 | 54 | 55 | 实际上来说,结构体变量的定义是跟普通数据类型类似的。 56 | 如,以上两个变量的声明区别,仅在于,一个的类型是struct time 另一个的类型是int 57 | 58 | 59 | 2)声明的同时定义 60 | 61 | ```cpp 62 | struct student{ 63 | char name[256]; 64 | char sex[2]; 65 | int age; 66 | int grade; 67 | } Alan, Tom ; 68 | ``` 69 | 70 | 71 | 72 | 3)使用结构体作为成员 73 | 74 | ```cpp 75 | struct DATE{ 76 | int year; 77 | int month; 78 | int day; 79 | } ; 80 | 81 | struct person{ 82 | char name[256]; 83 | struct DATE birthday; 84 | } ; 85 | 86 | struct time t; 87 | ``` 88 | 89 | 90 | 91 | 92 | 4)匿名结构体 93 | 94 | ```cpp 95 | struct { 96 | int number; 97 | char name[256]; 98 | char sex[2]; 99 | int age; 100 | int grade; 101 | } Alan, Tom ; 102 | ``` 103 | 104 | 105 | 106 | 107 | 结构体的引用与初始化 108 | 109 | 使用“.”成员运算符来获取结构体中的成员 110 | 111 | 112 | ```cpp 113 | #include#include 114 | 115 | struct student{ 116 | int number; 117 | char name[256]; 118 | char sex[2]; 119 | int age; 120 | int grade; 121 | } ; 122 | int main() 123 | { 124 | struct student alan; 125 | alan.number = 001; 126 | strcpy(alan.name, "Allan"); 127 | strcpy(alan.sex, "男"); 128 | alan.age = 18; 129 | alan.grade = 3; 130 | 131 | printf("学号:%d \n姓名: %s \n性别:%s \n年龄:%d\n年级:%d\n", 132 | alan.number, alan.name, alan.sex, alan.age, alan.grade); 133 | } 134 | 135 | ``` 136 | 137 | 138 | 139 | 140 | 结构体数组 141 | 142 | 结构体数组的使用: 143 | 144 | ```cpp 145 | #include 146 | #include 147 | 148 | struct student{ 149 | int number; 150 | char name[256]; 151 | int age; 152 | } ; 153 | int main() 154 | { 155 | struct student class_02[5]; 156 | int k; 157 | 158 | for(k=0; k < 5; k++) 159 | { 160 | printf("Please input number:\n"); 161 | scanf("%d", &class_02[k] .number); 162 | printf("Please input name:\n"); 163 | scanf("%s", class_02[k] .name); 164 | 165 | printf("Please input age:\n"); 166 | scanf("%d", &class_02[k] .age); 167 | 168 | printf("\n"); 169 | } 170 | 171 | printf("Num\tName\tage\n"); 172 | 173 | for(k=0; k < 5; k++) 174 | { 175 | printf("%d\t", class_02[k] .number); 176 | printf("%s\t", class_02[k] .name); 177 | printf("%d\n", class_02[k] .age); 178 | } 179 | } 180 | ``` 181 | 182 | 183 | 184 | 185 | ```cpp 186 | #include 187 | 188 | struct student{ 189 | int number; 190 | char name[256]; 191 | char sex[6]; 192 | int age; 193 | int grade; 194 | } ; 195 | int main() 196 | { 197 | struct student class1[5] = { 198 | { 01, "Alan", "man", 16, 12 }, 199 | { 02, "Bob", "man", 18, 12 }, 200 | { 03, "Cici", "woman", 16, 12 }, 201 | { 04, "David", "man", 11, 12 }, 202 | { 05, "Elis", "woman", 16, 12 }, 203 | }; 204 | for(k = 0; k < 5; k++) 205 | { 206 | printf("\nstudy number: %d \nname: %s \nsex: %s \nage: %d\n grade: %d\n" ,class1[k].number, 207 | class1[k].name, 208 | class1[k].sex, 209 | class1[k].age, 210 | class1[k].grade); 211 | } 212 | } 213 | ``` 214 | 215 | 216 | 217 | 218 | 结构体指针 219 | 220 | 使用分量运算符“->”来获取成员 221 | 222 | 223 | ```cpp 224 | #include 225 | 226 | struct DATE{ 227 | int year; 228 | int month; 229 | int day; 230 | } *date ; 231 | int main() 232 | { 233 | date->year = 2012; 234 | printf("%d", date->year); 235 | } 236 | 237 | ``` 238 | 239 | 240 | 241 | 242 | ```cpp 243 | #include 244 | 245 | struct DATE{ 246 | int year; 247 | int month; 248 | int day; 249 | } date = { 2012, 11, 27 }, *d ; 250 | int main() 251 | { 252 | d = &date; 253 | printf("%d", d->year); 254 | } 255 | 256 | ``` 257 | 258 | 259 | 260 | 用于函数的参数以及返回值: 261 | 262 | ```cpp 263 | #include 264 | 265 | struct time add(struct time now, struct time pass); 266 | 267 | struct time{ 268 | int hour; 269 | int min; 270 | } ; 271 | int main() 272 | { 273 | struct time now = { 3, 55 }, pass = { 1, 33 }, result; 274 | result = add(now, pass); 275 | printf("%d:%d\n", result.hour, result.min); 276 | } 277 | 278 | struct time add(struct time now, struct time pass) 279 | { 280 | struct time rel; 281 | rel.hour = now.hour + pass.hour + (now.min + pass.min)/60 ; 282 | rel.min = (now.min + pass.min)%60; 283 | return rel; 284 | } 285 | ``` -------------------------------------------------------------------------------- /basics/10_string.md: -------------------------------------------------------------------------------- 1 | 字符串处理 2 | ============= 3 | 4 | 字符与字符串的区别 5 | --------------- 6 | 7 | 1)符号 8 | 9 | ```cpp 10 | 字符 ' ' 单引号 11 | 字符串 " " 双引号 12 | ``` 13 | 14 | 2)内容 15 | 16 | ```cpp 17 | 字符 单个字符 18 | 字符串 多个字符 19 | ``` 20 | 21 | 3)输入输出格式 22 | 23 | ```cpp 24 | 字符 %c 25 | 字符串 %s 26 | ``` 27 | 28 | 4)标识 29 | 30 | ```cpp 31 | 字符串 '\0'做结尾 32 | ``` 33 | 34 | 字符串的本质是? 35 | --------------- 36 | 37 | 字符串本质上就是一个字符数组 38 | 39 | "hello world" 这样的字符串,就是包含其中各个元素的,并且结尾为'\0'的一个一维字符数组 40 | 41 | 如: 42 | 43 | ```cpp 44 | char hi[12]={'H','e','l','l','o',' ','w','o','r','l','d','\0'}; 45 | ``` 46 | 47 | 因为一个字符串要有'\0'作为结尾 48 | 所以字符数组的长度要比本身字符数目多一个 49 | 50 | 如上例中,字符串有11个,但是字符数组长度要达到12 51 | 52 | 53 | 字符串的定义与初始化 54 | --------------- 55 | 56 | 字符串面量: 57 | "Hello world" 注意:字面量(双引号引起来的)是常量 58 | 59 | 区别举例: 60 | 61 | ```cpp 62 | "Alan" 常量 63 | char name[20] = "Jack"; // "Jack"是字面量 是常量 name是字符数组, 是变量 64 | ``` 65 | 66 | 注: 67 | 常量不能被赋值,如讲2的值赋给1这样: 68 | 69 | ```cpp 70 | 1 = 2 是不行的,1是常量不能被赋值 71 | ``` 72 | "string" 这样的字符串也是不能被赋值的: 73 | 74 | ```cpp 75 | "string" = "Hello Jack" 这样是错的 76 | ``` 77 | 78 | 79 | 字符数组 80 | --------------- 81 | 82 | 1)数组形式 83 | 84 | ```cpp 85 | char hi[3]={'H', 'i','\0'}; 86 | char hello[]={'H','e','l','l','o',' ','w','o','r','l','d','\0'}; 87 | ``` 88 | 89 | 2)直接赋首地址 90 | 91 | ```cpp 92 | char shool[20] = "第一中学"; 93 | ``` 94 | 95 | 3)省略长度 96 | 97 | ```cpp 98 | char name1[] = "Alan"; 99 | char name2[] = { "Alan" }; 100 | ``` 101 | 102 | 103 | 字符指针 104 | --------------- 105 | 106 | 107 | ```cpp 108 | char *name3 = "Alan"; 109 | char *s = "第一中学"; 110 | ``` 111 | 112 | 思考: 113 | 指针能不能直接赋给数组? 114 | 115 | 116 | 字符串的遍历 117 | --------------- 118 | 119 | 120 | ```cpp 121 | char hi[] = "I am happy" ; 122 | ``` 123 | 124 | 1.for循环遍历 125 | 126 | ```cpp 127 | for(i=0; i<11; i++) 128 | { 129 | printf("%c", hi); 130 | } 131 | ``` 132 | 133 | 2.直接输出 134 | 135 | ```cpp 136 | printf(hi); 137 | ``` 138 | 139 | 3.字符串格式(%s)输出 140 | 141 | ```cpp 142 | printf("%s", hi); 143 | ``` 144 | 145 | 146 | 字符串数组(二维字符数组) 147 | --------------- 148 | 149 | 常见姓名: 150 | 151 | ```cpp 152 | char name1[] = "张三"; 153 | char name2[] = "李四"; 154 | char name3[] = "王五"; 155 | ``` 156 | 157 | 存储多个字符串: 158 | 159 | 1)二维数组 160 | 161 | ```cpp 162 | char name[][256] = { "张三", "李四", "王五" }; 163 | ``` 164 | 165 | 2)一维指针数组 166 | 167 | ```cpp 168 | char *name[] = { "张三", "李四", "王五" }; 169 | ``` 170 | 171 | 172 | 对于printf,最重要的是? 173 | --------------- 174 | 175 | 对于printf和scanf来说,字符串最重要的是其起始地址 176 | 177 | 如打印一个字符串: 178 | 179 | ```cpp 180 | char *text = "hey gays!"; 181 | 182 | 1) pirntf(text); 183 | 2) printf("%s", text); 184 | ``` 185 | 186 | 对于printf这个函数而言,只要知道字符串开头的地址, 187 | 那么就一直打印下去,一直到碰到'\0'的时候停止 188 | 189 | 如: 190 | 191 | ```cpp 192 | printf("Hello \0 world"); \\ hello 193 | ``` 194 | 195 | 196 | 常见的字符串操作函数 197 | --------------- 198 | 199 | stdio.h 200 | 201 | 输入:scanf()、gets()、getchar() 202 | 输出:printf()、puts()、putchar() 203 | 204 | string.h 205 | 206 | 连接:strcat() 207 | 拷贝:strcpy() 208 | 比较:strcmp() 209 | 获取长度:strlen() 210 | 大小写转换:strupr()、strlwr() 211 | 拼接字符串:sprintf() 212 | 213 | 示例: 214 | 215 | ```cpp 216 | #include 217 | #include 218 | int main() 219 | { 220 | char *hi = "hello", s2 = "Alice"; 221 | char str[256], *pstr; 222 | printf("%s \n", strcat(hi, " world"));//连接 223 | printf("%s \n", strcpy(str, "come on")); //拷贝 224 | printf("%s \n", strcmp("你好", "你好")); //比较 225 | printf("%s \n", strlen(str)); //获取长度 226 | printf("%s \n", strupr(str)); //转成大写 227 | } 228 | ``` 229 | 230 | 231 | 学会查询文档: 232 | --------------- 233 | 1.右键查看定义 234 | 2.度娘谷歌 235 | 3.手册 236 | 4.自己撰写自己的文档 237 | 238 | 239 | 关于函数传参数 240 | --------------- 241 | 242 | 243 | ```cpp 244 | 对于:int add(int a, int b); 245 | 调用:add(5, 10); 246 | 247 | add函数中参数初始化时,相当于: 248 | int a = 5; int b = 10 249 | 250 | 对于:int swap(int *x, int *y); 251 | 调用:swap(&i, &j); 252 | 253 | swap函数中参数初始化时 ,相当与: 254 | int *x = &i; int *y = &j; 255 | ``` 256 | 257 | 258 | strlen() 259 | --------------- 260 | 261 | 262 | ```cpp 263 | #include 264 | int mylength(char *aim); 265 | 266 | int main() 267 | { 268 | char *str1 = "hello "; 269 | printf("%d\n", mylength(str1)); 270 | } 271 | 272 | int mylength(char *aim) 273 | { 274 | int count=0; 275 | while(*aim++){ 276 | count++; 277 | } 278 | return count; 279 | } 280 | ``` 281 | 282 | 283 | strcat() 284 | --------------- 285 | 286 | 287 | ```cpp 288 | #include 289 | char * mycat(char *dest, char *src); 290 | 291 | int main() 292 | { 293 | char str1[20] = "hello "; // 要拷贝的话需要有足够的内存 294 | char *str2 = "world"; 295 | printf("%s\n", mycat(str1, str2)); 296 | } 297 | 298 | char *mycat(char *dest, const char *src) 299 | { 300 | char *address = dest; 301 | 302 | while (*++dest) // 加到 '\0' 马上停止 303 | ; 304 | 305 | while (*dest++ = *src++) 306 | ; 307 | 308 | return address; 309 | } 310 | ``` 311 | (感谢 灬蕾依丽雅 君的提醒, 该函数已修正) 312 | 313 |

本讲小结

314 | 315 | 一、字符串的本质,与字符的区别 316 | 1)本质上是结尾为'\0'字符数组 317 | 2)单双引号,书写区别 318 | 3)输出格式"%c"和"%s" 319 | 320 | 二、字符串的定义与初始化 321 | 1)字面量 322 | 2)数组 323 | 3)指针 324 | 325 | 三、常见的字符串操作,及其操作的实现 326 | 连接(strcat)、拷贝(strcpy)、比较(strcmp)、获取长度(strlen)、大小写转换(strupr、strlwr)、拼接字符串(sprintf) 327 | 328 | 以上部分函数的实现跨越在博主的 string.h 的实现中找到 博主的 C标准库 329 | 330 | 课后作业 331 | 332 | 通过自己查找参考,理解并实现以上常见的字符串操作 333 | 注:sprintf()只要掌握,不要求实现 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /math/information-in-computer.md: -------------------------------------------------------------------------------- 1 | 信息存储 2 | ======== 3 | 4 |
    5 |
  1. 计算机数据存储单位
  2. 6 |
  3. 进制转换 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 |
  4. 34 |
  5. 数字与编码 35 |
      36 |
    • ASCII编码
    • 37 |
    • 数字的计算
    • 38 |
    • 计算机中的数字与编码对比
    • 39 |
    40 |
  6. 41 |
42 | 43 | 44 | 计算机数据存储单位 45 | -------------------------------- 46 |
 47 | 1TB (Trillionbyte 万亿字节 太字节 )     = 1024 GB
 48 | 1GB (  Gigabyte   吉字节 又称“千兆” ) = 1024 MB
 49 | 1MB (  Megabyte   兆字节 简称“兆” )   = 1024 KB
 50 | 1KB (  Kilobyte   千字节 )              = 1024 B
 51 | 1B  (    Byte     字节 )                =   8  Bit
 52 | 
53 | 54 | 各位需要注意,内存上最小的单位是字节(byte)没有比这更小的单元了。而我们讨论的位(bit)是比字节还要小的单位,这个单位在计算机上是无法直接查看的(因为字节已经是最小的了),但是实际上而言计算机真正的所有数据都是有一个位一个位的1010之类的二进制数据组成的。而我们要进行C/C++编程的话,很多时候都需要去处理这个比内存最小单位还要小的位,如果是专做底层的话使用位操作就更加频繁了,所以我们必须要了【位级】也就是【二进制层面】的数据形式。 55 | 56 | 进制转换 57 | -------------------------------- 58 | 59 | 60 | ###常见的进制转换 61 | 62 | 生活中常见的进制: 63 | } 64 | 65 | 我们的生活中充斥着各种各样的进制转换,例如每天工作生活的时候,可能很多人都不知道今天几号,但是却一定知道今天星期几,这个星期的概念中就存在着进制转换。满了七天就可以进一位变成一个星期,这是一个很常见的进制转换。 66 | 67 | 上述还列举了好几种其他的进制转换,我们可以很清晰的发现,其实不同的进制在【进位】的时候很明显的体现出一个规律便是:几进制就满几进一。 68 | 69 | 70 | ###二进制简介 71 | 72 | 那么实际上二进制跟上述常见的进制都是类似的,也就很简单的是满 2 进一位,我们可以看如下的式子: 73 | 74 |
 75 | 1 + 1 = 2
 76 | 
77 | 78 | 这在我们十进制中是一个幼儿园的小孩子都懂的加法,但是到了二进制中这个结果会变得不一样了: 79 | 80 |
 81 | 1 + 1 = 10
 82 | 
83 | 84 | 乍一看会觉得很难接受,但是仔细一想这也是可以理解的,因为在二进制中 满2 就会进一位,所以 1+1=2 已经满2了就进了一位结果就是 10 了。不过各位需要注意的是这个 10 是二进制中的 10 : 85 | 86 |
 87 | 10(二进制) = 2(十进制)
 88 | 
89 | 90 | 那么我们的二进制,再加几个数字看看: 91 | 92 |
 93 | 10 + 1 =  11 (等于十进制中的3)
 94 | 11 + 1 = 100 (等于十进制中的4)
 95 | 
96 | 97 | 情况就是这样,我们可以用这样的方式依次类推下来: 98 | 99 |
100 | 二进制   十进制
101 |     1       1
102 |    10       2
103 |    11       3
104 |   100       4
105 |   101       5
106 |   110       6
107 |   111       7
108 |  1000       8
109 |  1001       9
110 |  1010      10
111 |  1011      11
112 |  1100      12
113 |  1101      13
114 |  1110      14
115 |  1111      15
116 | 10000      16
117 | 
118 | 119 | 有些人可能会觉得奇怪,为了为什么这个看起来没有开始七进制那个星期的那样好理解,这里博主解释一下。 120 | 121 | 真正数学意义上的七进制里面是没有7的,因为到了6之后再加一 满 7 就要进一位变成 10 ,这个形式我们不是很熟悉但是换个熟悉的方式就理解了,因为我们平常生活着中把这个七进制的【个位】叫做【天】,【十位】叫做【星期】所以我们的七进制的: 122 |
123 | 10 天
124 | 
125 | 也可以看做 126 |
127 | 1星期 0天
128 | 
129 | 130 | 131 | 132 | 133 | ###进制计算的基本概念 134 | 135 | 首先我们要了解的是进制本身的一个概念: 136 | 137 | 138 | ####七进制计算 139 | 140 | 以星期的七进制举例: 141 | 142 |
143 | 21
144 | 
145 | 146 | 这个值代表的天数到底是多少?我们将其换成我们所熟悉的单位一看: 147 | 148 |
149 | 2 星期 1 天
150 | 
151 | 152 | 这样很直观的就能算出来 这个七进制的 21 所代表的的是十进制的 15 天,为什么呢? 153 | 154 | 很简单,因为一个星期是7天,所以上述的七进制数字转成十进制就是: 155 | 156 |
157 | 7*2 + 1 = 15
158 | 
159 | 160 | 161 | ####六十进制计算 162 | 163 | 以时分秒的六十进制举例: 164 | 165 |
166 | 356
167 | 
168 | 169 | 那么这个六十进制的 356 秒到底是十进制的多少秒?乍一看又有点晕了,不过没关系,换成我们所熟悉的单位来看看: 170 | 171 |
172 | 3小时 5分钟 6秒
173 | 
174 | 175 | 这样看一下一下子就觉得简单了,我们也可以开始算了,答案就是: 176 | 177 |
178 | 3*3600 + 5*60 + 6 = 11106(秒)
179 | 
180 | 181 | 182 | ####十进制计算 183 | 184 | 接下来我们再用十进制来举例: 185 | 186 | 十进制的: 187 | 188 |
189 | 1234
190 | 
191 | 192 | 我想这个大家应该一眼就能看出来这个十进制的值,那么我们要看的是这个十进制的每一位拆开来看的式子: 193 | 194 |
195 | 1*1000 + 2*100 + 3*10 + 4
196 | 
197 | 198 | 199 | 200 | ####进制计算的规律与公式推导 201 | 202 | 相信经过上面三种进制的举例之后,大家的心里已经模糊的有点想法,接下来我们就要把这个模糊的概念变的清晰。 203 | 204 | 首先我们定义一个未知数x(x>=2),那么假设我们所使用的这个进制是 x进制,那么这个 x进制有什么特点? 205 | 206 | 不用多说: 207 | 208 |
209 | ① 满x进一
210 | 
211 | 212 | 相信大家可以理解 213 | 214 | 那么对于这个 x进制 的个位,单位的话一定 1,因为满了 x 就会进一位,所以由 ① 式可得: 215 | 216 |
217 | ② 个位的最大值是 x-1
218 | 
219 | 220 | 那么各位同学想想,由 ①、② 式可以知道什么?那么博主也不卖关子: 221 | 222 |
223 | ③ 第二位的 1 是第一位的 x 倍
224 | 
225 | 226 | 那么接下来的问题就是: 227 | 228 |
229 | x进制的 abcd (abdc 分别是0到x-1的数字) 等于 10进制的多少?
230 | 
231 | 232 | 大家可以停在这里先仔细考虑这个问题,当然草稿纸也是必要的,因为经过思考之后再来看博主的推理绝对会效果更佳! 233 | 234 | 235 | 236 | 那么,如果你已经思考过了我们就继续往下看。 237 | 238 | 由 第①、③式 就可以知道我们想要的结论了: 239 | 240 | 关于x进制的 abcd: 241 | 242 |
243 | 个位数就是  d
244 | 十位数是   x*c
245 | 百位数是  x*x*b
246 | 千位数是 x*x*x*a
247 | 
248 | 249 | 所以最后答案是: 250 | 251 |
252 | ④ 1111(x进制)= a*x^3 + b*x^2 + c*x^1 + d*x^0 (10进制)
253 | 
254 | 255 | 备注: 256 | 257 | 1. x^3 的意思就是 x的3次方 即 x*x*x 258 | 259 | 2. x^0 的意思是 x的0次方 即 1(除0以外,任意数的0次方都是1) 260 | 261 | 262 | 那么这个式子 ④ 是一个通用形的公式,可以计算任意进制转十进制。各位可以摊开草稿纸自行推导,以及套用求,博主这里就不废话了。 263 | 264 | 265 |   266 | 267 | 268 | ###二进制与十进制的转换 269 | 270 | 271 | ####二进制转十进制 272 | 273 | 既然有了公式,那么二进制转十进制自然是可以套用通用公式来计算的: 274 | 275 |
276 | 例如 0100 1011 的十进制计算:
277 | 
278 | 0100 1011(二进制) = 1*2^6 + 1*2^3 + 1*2^1 + 1*2^0 = 75 (十进制)
279 | 
280 | 281 | 或者使用 1248 法,那么什么是 1248 法,额,博主在写的时候才发现其实这个就是公式一种运用方式吧。就是记住2 282 | 的各个次方,依次从0次方开始分别是:1、2、4、8、16、32、64…… 等等 283 | 284 | 然后计算的时候碰到如下情况,直接套用: 285 | 286 |
287 | 如 0001 0101 的十进制值计算:
288 | 
289 | 0001 0101(二进制) = 16 + 4 + 1 = 21
290 | 
291 | 292 | 二进制的话,0就是没有值不用乘,1的话乘的时候可以省略,所以只要记住一些常见的 2 的次方就可以快速的将二进制转成十进制了。博主在视频当中二进制转十进制的时候就是这么做的 =v= 293 | 294 | ####十进制转二进制 295 | 296 | 使用【除二取余法】,例如: 297 | 298 |
299 | 789(十进制) = 1100010101(二进制)
300 | 
301 |  789 / 2 = 商 394 余 1  个位
302 |  394 / 2 = 商 197 余 0  十位
303 |  197 / 2 = 商 98  余 1  百位
304 |   98 / 2 = 商 49  余 0  第..位
305 |   49 / 2 = 商 24  余 1  第..位
306 |   24 / 2 = 商 12  余 0  第..位
307 |   12 / 2 = 商 6   余 0  第..位
308 |    6 / 2 = 商 3   余 0  倒数第3位
309 |    3 / 2 = 商 1   余 1  倒数第2位
310 |    1 / 2 = 商 0   余 1  倒数第1位
311 | 
312 | 313 | 那么我们的余数倒过来就是我们的二进制的值了。 314 | 315 | 316 | #####六十进制中 317 | 318 | 319 | 11106 秒转 六十进制 320 | 321 |
322 | 11106 / 60 = 商 185  余数 6
323 |   185 / 60 = 商 3    余数 5
324 |     3 / 60 = 商 0    余数 3 
325 | 
326 | 327 | 所以 11106 = 3小时 5分 6秒 328 | 329 | 330 | #####十进制中 331 | 332 | 333 |
334 | 1234 / 10 = 商 123 余 4
335 |  123 / 10 = 商 12  余 3
336 |   12 / 10 = 商 1   余 2
337 |    1 / 10 = 商 0   余 1
338 | 
339 | 340 | 341 | 342 | #####除二取余法原理 343 | 344 | 345 | 346 | 设两个未知数 x, y (x>=2) ,假设我们面对的是 x进制,要把十进制数 y 转成 x 进制 347 | 348 | 那么我们一定要清楚的是这个 y 去除以 x 能得到什么 349 | 350 | 假设这个 x进制的数是 abcd (abcd为0~x之间常数) 当然这个x进制的数可能没有4位也可能超过4位,这没有关系我们只是看个示意,那么有了这个示例,根据我们最开始算出来公式可以得出下列等式: 351 | 352 |
353 | abcd(x进制) = a*x^3 + b*x^2 + c*x^1 + d*x^0 (十进制) = y 
354 | 
355 | 356 | 用这个数去除以 x 你会发现: 357 | 358 |
359 | y / x = ( a*x^3 + b*x^2 + c*x^1 + d*x^0 ) / x (十进制)
360 |       = 商 a*x^2 + b*x^1 + c*x 余数 d
361 | 
362 | 363 | 那么获取的这个余数 d 就是我们 abcd 这个 x进制数的【个位】也就是第一位 364 | 365 |
366 | ( a*x^2 + b*x^1 + c*x ) / x = 商 a*x^1 + b*x 余数 c
367 | 
368 | 369 | 再用这个商去除以 x 就能获得 x进制数的 第二位。依次类推,只要商不为0,我们就可以通过这个办法一直求下去。 370 | 371 | 各位可以用摊开草稿纸残念一下,也可以用这个结论反过来看看前几个 二进制、十进制、六十进制 用【除二取余法】的数据,博主就不赘述了,顺便感慨一下,百度百科上面那些进制转换的原理好残念,完全看不懂,不知道写着有什么意思。 372 | 373 |   374 | 375 | 376 | ###二进制与十六进制的转换 377 | 378 | 379 | 如果上面的公式你都有参与推倒,并且有使用公式进行过一定的转换联系,那么这个部分的内容对你而言肯定是小case 380 | 381 |
382 |  二进制   十六进制 十进制
383 | 0000 0000    00      0
384 | 0000 0001    01      1
385 | 0000 0010    02      2
386 | 0000 0011    03      3
387 | 0000 0100    04      4
388 | 0000 0101    05      5
389 | 0000 0110    06      6
390 | 0000 0111    07      7
391 | 0000 1000    08      8
392 | 0000 1001    09      9
393 | 0000 1010    0A      10
394 | 0000 1011    0B      11
395 | 0000 1100    0C      12
396 | 0000 1101    0D      13
397 | 0000 1110    0E      14
398 | 0000 1111    0F      15
399 | 0001 0000    10      16
400 | 0001 0001    11      17
401 | 0001 0010    12      18
402 | 0001 0011    13      19
403 | 0001 0100    14      20
404 | 0001 0101    15      21
405 | 0001 0110    16      22
406 | 0001 0111    17      23
407 | 0001 1000    18      24
408 | 0001 1001    19      25
409 | 0001 1010    1A      26
410 | 0001 1011    1B      27
411 | 0001 1100    1C      28
412 | 0001 1101    1D      29
413 | 0001 1110    1E      30
414 | 0001 1111    1F      31
415 | 0010 0000    20      32
416 | 
417 | 418 | 简单的观察一下就会发现上述二进制的低四位对应十六进制的第一位,上述二进制的高四位对应十六进制的第二位。 419 | 420 | 这其实是一个很简单的事情,因为【一】个【十六进制】的位刚好包含了【四】个【二进制】的位,这是因为十六进制的 x 是 16也就是 2的四次方,而二进制的 x 是 2 即 2的1次方。 421 | 422 | 我们通过观察上述数据也可以发现二进制的 0~1111 对应的刚好就是 十六进制的 0 ~ F 也就是二进制的四个位刚好对应一个十六进制的位。所以二进制与十六进制的转化十分简单: 423 | 424 |
425 | 二进制   :1111 0001 1010 0101 0111 1000
426 | 十六进制 :   F    1    C    5    7    8
427 | 
428 | 429 | 430 | 431 | 432 | 433 | 434 | ###大端法与小端法机器 435 | 436 | 大端法和小端法,指的是数据的两种存储方式,对于一个数据 0x01234567 而言在 437 | 438 | 大端法机器上是 439 | 440 |
441 |       低 ------------------------> 高
442 | 内存地址:0x100 0x101 0x102 0x103
443 |              01    23    45    67
444 | 
445 | 446 | 小端法机器上是 447 | 448 |
449 |       低 ------------------------> 高
450 | 内存地址:0x100 0x101 0x102 0x103
451 |              67    45    23    01
452 | 
453 | 454 | 这是两种计算机存储字节数据的方式(2个十六进制的数表示8个二进制的位也就是1个字节)。大端法和小端法分别代表两种思想,一种是亲【人类直观】另一种是倾向【数学意义】 455 | 456 | 最开始看的时候会举得小端法有些不科学,其实这个是比较符合【数学意义】的,因为 67 是数字 0x01234567 中的个位与十位,是最低的一个字节,那么按照数学意义上来说的话,存储数据的时候从最低的字节开始写入是一种很正常的想法。只不过看起来不是那么直观。 457 | 458 | 而大端法的话,把最高字节的数据放在内存的低位其实就【数学意义】上看来是有些奇怪的,不过我们作为人看来却是比较亲切。 459 | 460 | 二者之间各有优点,各位只要了解即可,这个大小端只是做一个基础知识点。实际上编程时很少会感受到这中间的差别。 461 | 462 | 最后附上博主查看大小端的代码: 463 | 464 | 465 | 466 | #include // 包含 stdio 这个库的头文件 467 | 468 | /* 469 | * main 函数 是程序的入口 470 | * 471 | * int 是程序的返回值类型 472 | * main 是函数名 473 | * int argc 是参数个数 474 | * char const *argv[] 是指向参数的指针数组 475 | */ 476 | int main(int argc, char const *argv[]) 477 | { 478 | int i = 0x01234567; 479 | char *p; 480 | p = (char *)&i; 481 | 482 | printf("%x ", *(p+0)); 483 | printf("%x ", *(p+1)); 484 | printf("%x ", *(p+2)); 485 | printf("%x ", *(p+3)); 486 | 487 | // main 函数的返回值 488 | // return 是返回的关键字 489 | return 0; 490 | } 491 | 492 | 493 | 由于大部分语法尚未开始讲解,所以这个程序的具体含义各位可以留待以后再来探讨。 494 | 495 | 数字与编码 496 | -------------------------------- 497 | 498 | ###ASCII编码 499 | 500 | 在数据的世界里, 实际上是没有任何中英文之类的字符. 所有的数据全都是1010之类的二进制组成的数字. 那么在这样的情况下, 我们要在计算机上使用字符就需要使用硬件上自带的编码才能把这些数字的数据编程我们所需要的文字等字符. 以下是使用范围最广的 ASCII 编码的一部分: 501 | 502 | 503 | 504 | 506 | 508 | 510 | 512 | 513 | 514 | 516 | 517 | 519 | 520 | 521 | 523 | 524 | 526 | 527 | 528 | 530 | 531 | 533 | 534 | 535 | 537 | 538 | 540 | 541 | 542 | 544 | 545 | 547 | 548 | 549 | 551 | 552 | 554 | 555 | 556 | 558 | 559 | 561 | 562 | 563 | 565 | 566 | 568 | 569 | 570 | 572 | 573 | 575 | 576 | 577 | 579 | 580 | 582 | 583 | 584 | 586 | 587 | 589 | 590 | 591 | 593 | 594 | 596 | 597 | 598 | 600 | 601 | 603 | 604 | 605 | 607 | 608 | 610 | 611 | 612 | 614 | 615 | 617 | 618 | 619 | 621 | 622 | 624 | 625 | 626 | 628 | 629 | 631 | 632 | 633 | 635 | 636 | 638 | 639 | 640 | 642 | 643 | 645 | 646 | 647 | 649 | 650 | 652 | 653 | 654 | 656 | 657 | 659 | 660 | 661 | 663 | 664 | 666 | 667 | 668 | 670 | 671 | 673 | 674 | 675 | 677 | 678 | 680 | 681 | 682 | 684 | 685 | 687 | 688 | 689 | 691 | 692 | 694 | 695 | 696 | 698 | 699 | 701 | 702 | 703 | 705 | 706 | 708 | 709 | 710 | 712 | 713 | 715 | 716 | 717 | 719 | 720 | 722 | 723 | 724 | 726 | 727 | 729 | 730 | 731 | 733 | 734 |
二进制 505 | 十进制 507 | 十六进制 509 | 图形 511 |
0100 0000 64 515 | 40 @ 518 |
0100 0001 65 522 | 41 A 525 |
0100 0010 66 529 | 42 B 532 |
0100 0011 67 536 | 43 C 539 |
0100 0100 68 543 | 44 D 546 |
0100 0101 69 550 | 45 E 553 |
0100 0110 70 557 | 46 F 560 |
0100 0111 71 564 | 47 G 567 |
0100 1000 72 571 | 48 H 574 |
0100 1001 73 578 | 49 I 581 |
0100 1010 74 585 | 4A J 588 |
0100 1011 75 592 | 4B K 595 |
0100 1100 76 599 | 4C L 602 |
0100 1101 77 606 | 4D M 609 |
0100 1110 78 613 | 4E N 616 |
0100 1111 79 620 | 4F O 623 |
0101 0000 80 627 | 50 P 630 |
0101 0001 81 634 | 51 Q 637 |
0101 0010 82 641 | 52 R 644 |
0101 0011 83 648 | 53 S 651 |
0101 0100 84 655 | 54 T 658 |
0101 0101 85 662 | 55 U 665 |
0101 0110 86 669 | 56 V 672 |
0101 0111 87 676 | 57 W 679 |
0101 1000 88 683 | 58 X 686 |
0101 1001 89 690 | 59 Y 693 |
0101 1010 90 697 | 5A Z 700 |
0101 1011 91 704 | 5B [ 707 |
0101 1100 92 711 | 5C \ 714 |
0101 1101 93 718 | 5D ] 721 |
0101 1110 94 725 | 5E ^ 728 |
0101 1111 95 732 | 5F _ 735 |
736 | 737 |
738 | 739 | 完整请查看: http://zh.wikipedia.org/wiki/ASCII 740 | 741 | 742 | ASCII('''A'''merican '''S'''tandard '''C'''ode for '''I'''nformation '''I'''nterchange,'''美国信息交换标准代码''')是基于拉丁字母的一套电脑编码系统, 它主要用于显示现代英语. 743 | 744 | 对于 一个数字 65 如果我们告诉计算机我们要将其当做字符来使用, 那么这个数据就会被转换成对应的字符 '''A'''. 当然用 'A' 这样的字符也可以当做数字来计算, 因为虽然看起来它是个字符, 但实际上内存中只会存储 65 这个数字, 所以 'A' + 1 是可以计算的, 而且结果是 66, 转成字符就是 'B'. 745 | 746 | 747 | ###数字的计算 748 | 749 | 数字的计算跟平常数学意义上的计算没有太大的差别, 不过编程中的计算会有某些方便的拓展, 如位运算. 具体细节请参见后面的 CPU 计算章节. 750 | 751 | 752 | ###计算机中的数字与编码对比 753 | 754 | 在计算机当中, 所有的数据都是 1010 的二进制形式, 当你把这个数据当成是字符的时候, 计算机就会查找对应的编码, 当你把这个数据当成是图片时, 计算机就会按照对应的图片格式来加载这个数据. 如果仅仅是当做数字来计算的话, 那么就是普通的数学计算. 755 | 756 | 最开始学习编程基础的时候, 我们最需要了解的就是字符和数字的区别. 字符只是对应编码转换出来的一种符号, 如果编码不同的话字符转换出来的符号也可能不同, 所以并没有很强的数学意义. 而且在 C语言中 用于保存字符的 char 类型单位大小只有 1字节 也就说最多只有 255 种情况. 如果用字符来做计算的话也只能做一些简单的计算, 超过范围的话就会因为单位过小而无法保存运算的结果. 757 | 758 | 而在 C语言中 有 int 类型专门用于做整数的计算, 在 32 位操作系统上 int 759 | --------------------------------------------------------------------------------