前言:
就在前几天,C语言入门到进阶部分的专栏——《维生素C语言》终于完成了。全文共计十八个章节并附带三张笔试练习篇,美中不足的是,第一章和第二章是以截图形式展现的。由于本人一开始是在有道云笔记上写的初稿,当时想方便省事(有道云排版个人感觉确实比较美观)就直接以截图的形式完成了第一章和第二章。本人考虑到因为是截图,不能复制文中出现的代码,不方便读者进行复制粘贴,所以我打算重新写一下第一章和第一章的内容,并且重新进行了排版。
本章从如何写主函数开始讲起,对C语言基础知识点进行蜻蜓点水地介绍,想看详细讲解教学请订阅专栏!专栏连接:《维生素C语言》
一、如何写代码
0x00 首先写主函数
❓ 何为main函数?
main函数,又称主函数,是程序执行的起点。
1. 主函数是程序的入口
2. 主函数有且只有一个
📚 一个工程中可以有多个“.c文件”,但是多个“.c文件”中只能有一个“main 函数”
20000
0x01 然后写代码
💬 "你好,世界!"
#include <stdio.h> //头文件int main(){printf("hello world!\\n");return 0;}
0x02 最后运行程序
🔨 编译 + 链接 + 运行代码
快捷键: Ctrl + F5( VS2013 )
[调试] -> [选择' 开始执行(不调试)']
❓ “是不是有什么一闪而过了?”
因为程序执行得太快,所以没有看到结果。
为了看到结果,我们需要设置一下 VS2013 的属性 ( VS2019不需要设置项目属性 )
[解决方案资源管理器] -> [右键项目名称] -> [属性] -> [链接器] -> [系统]-> [子系统] -> [选择' 控制台(/SUBSYSRTEM:CONSOLE) ']
🚩 运行结果如下:
二、数据类型
0x00 基本类型
📚 这里先做些简单的介绍:
💬 基本数据类型的使用方法:
int main(void){char ch = 'a';int age = 20;float weight = 50.8;double d = 0.0;return 0;}
0x01 格式说明
📚 格式说明由“%”和格式字符组成:
💬 演示:
int main(){printf("%d\\n", 100);printf("%c\\n", 'a');float foo = 5.0;printf("%f\\n", foo);double pi = 3.14;printf("%.2lf\\n", pi); // .xf(x为小数点保留几位数)char str1[] = "hello";printf("%s\\n", str1);int a = 10;printf("%p\\n", &a);return 0;}
🚩 运行结果: 100 a 5.000000 3.14 hello 0000000000061FE04
0x03 数据类型的大小
📺 32位系统下:
📚 sizeof 函数:获取数据在内存中所占用的存储空间,以字节为单位计数
💬 使用方法演示:
int main(void){char a = 'A';printf("%d\\n", sizeof(a))printf("%d\\n", sizeof a) //求变量时可省略括号 ✅printf("%d\\n", sizeof(char));printf("%d\\n", sizeof char); //error!但是求字符类型时不可省略 ❌return 0;}
🚩 运行结果:1
💬 使用 sizeof 求元素个数:
int main(void){int arr[] = {1,2,3,4,5,6,7,8,9,10};printf("%d\\n", sizeof(arr)); //计算的是数组的总大小,单位是字节printf("%d\\n", sizeof(arr[0])); //计算的是数组首字符大小int sz = sizeof(arr) / sizeof(arr[0]);printf("%d\\n", sz);return 0;}
🚩 运行结果: 40 4 10
📚 计算机中的单位: bit – 比特位
计算机中识别二进制:1&0 8进制:0-7 10进制:0-9
三、变量与常量
0x00 创建变量
💬 代码演示:
#include <stdio.h>int main(void){int age = 20;double weight = 62.5;age = age + 1;weight = weight - 10;printf("%d\\n", age);printf("%lf\\n", weight);return 0;}
0x01 全局变量和局部变量
💬 局部变量和全局变量的名字相同时,局部变量优先,对局部影响:
int var = 100;int main(void){int var = 10;printf("%d\\n", var);return 0;}
🚩 运行结果: 10
0x02 scanf 函数
💬 使用方法演示:
int main(void){int a = 0;scanf("%d", &a);printf("%d", a);return 0;}
0x03 变量的使用
💬 使用方法演示:写一个代码求两个变量的和
int main(void){int a = 0;int b = 0;int sum = 0;scanf("%d %d", &a, &b);sum = a + b;printf("sum = %d\\n", sum);return 0;}
❗ 如果编译器发出了警告,说 scanf 不安全,在代码前面添加
#define _CRT_SECURE_NO_WANRINGS 1
即可,当然还有其他方法可以解决,这里就不细说了。
🚩 运行结果如下:(假设输入了 1 2)
sum = 3
0x04 作用域和生命周期
📚 作用域(scope)
程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用 的 而限定这个名字的可用性的代码范围就是这个名字的作用域。
全局变量的作用域是整个工程。
局部变量的作用域是变量所在的局部范围。
📚 生命周期:
变量的生命周期:变量的创建和销毁之间的时间段
局部变量的生命周期:进入作用域生命周期开始,出作用域生命周期结束。
全局变量的生命周期:整个程序的生命周期。
💬 局部变量的生命周期:
int main(){{int a = 10;printf("%d\\n", a);}printf("%d\\n", a); //error 生命周期结束了}
💬 全局变量的生命周期
//声明一下变量extern int g_val;int main(){printf("%d", g_val);}
0x05 常量
📚 定义:C语言中常量和变量的定义的形式有所差异
C语言的常量分为以下几种:
① 字面常量:直接写
② const 修饰的常变量:用 const 定义
③ #define 定义的标识符常量:宏定义
④ 枚举常量:可以一一列举的常量
💬 字面常量:
int main(void){3.14;10;'a';"abcdef";}
💬 const 修饰的常量:
int main(void){const int num = 10;num = 20; //error, 不能修改printf("num = %d\\n", num);}
🚩 运行结果: 10
💬 #define 定义的标识符常量:
#define MAX 10000 // 不写=,不加分号!int main(void){int n = MAX;printf("%d\\n", n);}
🚩 运行结果:10000
💬 枚举常量:
//性别enum Sex {//这种枚举类型的变量的未来可能取值//枚举常量MALE = 3, //赋初值FEMALE,SECRET};int main(void){enum Sex s = MALE;printf("%d\\n", MALE);// MALE = 3 error 不可修改printf("%d\\n", FEMALE);printf("%d\\n", SECRET);return 0;}
📌 注意事项:
const 只是一个有常属性的变量,本质上仍然为变量!arr[], 数组的大小必须是常量!
int main(){const int n = 10; //n是变量,但是又有常属性,所以我们说n是常变量int arr = {0}; // 仍然不可以,因为n是变量,只是有常属性而已return 0;}
💬 #define 定义的可以,宏定义用得最多的地方是在数组中用于指定数组的长度:
#define N 10int main(){int arr = {0};return 0;}
📌 注意事项:
枚举常量虽然是不能改变的,但是通过枚举常量创造出来的变量是可以改变的!
enum Color{// 枚举常量RED,YEELOW,BULE};int main(void){enum Color c = BULE; //我们创建一个变量c,并将BULE赋给它c = YEELOW; //这时将YEELOW赋给它,完全没有问题 ✅BULE = 6; //error!枚举常量是不能改变的 ❌return 0;}
四、字符串&转义字符&注释
0x00 字符串
📚 定义:
"hello world."
这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal)
📚 关于斜杠零:
字符串的结束标志是一个 \\0 转义字符。
在计算字符串长度的时候 \\0 是结束标志,不算字符串的内容!
💬 下面代码,打印的结果是什么?为什么?
int main(void){char arr1[] = "abc"; //数组// "abc" -- 'a' 'b' 'c' '\\0'// 这里面,'\\0' 字符串的结束标志char arr2[] = {'a', 'b', 'c'};char arr3[] = {'a', 'b', 'c', '\\0'};printf("%s\\n", arr1);printf("%s\\n", arr2);printf("%s\\n", arr3);return 0;}
🚩 打印结果如下:
0x01 计算字符串长度
📚 strlen 函数:返回字符串的长度
📜 使用时需引入头文件 <string.h>
💬 代码演示:
#include <stdio.h>#include <string.h>int main(){char arr1[] = "abc";char arr2[] = {'a', 'b', 'c'};printf("%d\\n", strlen(arr1));printf("%d\\n", strlen(arr2));return 0;}
🚩 运行结果如下: 3 随机值
0x02 ASCII 码值
📚 ASCII (American Standard Code for Information Interchange)
“是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准ISO/IEC 646。ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符”
0x03 转义字符
📚 转意字符顾名思义就是转变字符的意思。
💬 让斜杠就是斜杠:
int main(){printf("c:\\\\test\\\\32\\\\test.c"); //再加一个斜杠,规避转义字符检测return 0;}
🚩 运行结果: c:\\test\\32\\test.c
💬 三字母词、输出单引号、ddd、xdd:
int main(){printf("(are you ok?\\?)\\n"); // ??) -- ] - 三字母词printf("%c\\n", '\\''); //输出一个单引号printf("%s\\n", "\\""); //输出一个双引号printf("%c\\n", '\\130');//8进制的130是10进制的多少呢?//X - ASCII码值是88printf("%c\\n", '\\101'); // A- 65 - 8进制是:101printf("%c\\n", '\\x30'); //48 - '0'return 0;}
🚩 运行结果: (are you ok??) ' " X A 0
❓ 下列代码打印的结果是什么?
int main(){printf("%d\\n", strlen("c:\\test\\328\\test.c"));return 0;}
💡 答案:14
0x04 注释
📚 代码中有不需要的代码可以直接删除,也可以注释掉
代码中有些代码比较难懂,可以加一下注释文字
有两种风格:
① C语言风格的注释 /* xxxxxx */
缺陷:不能嵌套注释
② C++风格的注释 //xxxxxxxxx
优点:可以注释一行也可以注释多行
快捷键:Ctrl + /?
💬 演示:
/* C语言风格注释int Add(int x, int y) {int z = 0;z = x + y;return z;}*/int Add(int x, int y) {return x + y;}int main(void){// C++注释风格// int a = 10;printf("%d\\n", Add(1,2)); //调用Add函数return 0;}
五、分支和循环
0x00 if 语句
📚 定义:if 语句是指编程语言(包括c语言、C#、VB、java、汇编语言等)中用来判定所给定的条件是否满足,根据判定的结果(真或假)决定执行给出的两种操作之一。
💬 选择语句代码演示:
int main(void){int a = 10;int b = 20;if(a>b) {printf("a比b大\\n") ;} else {printf("b比a大\\n");}return 0;}
🚩 运行结果: b比a大
❓ C语言中如何实现循环呢?
1. while 语句
2. for 语句
3. do … while 语句
这里我们着重先了解下 while 语句。
📚 while 循环的基本概念:while是计算机的一种基本循环模式。当满足条件时进入循环,进入循环后,当条件不满足时,跳出循环。
💬 演示代码:敲三万行代码
#include <stdio.h>int main(void){int line = 0;while(line < 30000) {printf("敲代码: %d\\n", line);line++;}if(line == 30000) {printf("恭喜你敲满30000行代码!\\n");}return 0;}
六、函数
❓ 什么是函数?
数学中的函数 f(x) = 2×x+5,C语言中的函数也是一样的。
📚 函数的特点就是:简化代码,代码复用。
💬 代码演示:
int Add (int x, int y) {int z = 0;z = x + y;return z;}int main(void){int num1 = 0;int num2 = 0;scanf("%d%d", &num1, &num2);// int sum = num1 + num2;// 函数的方式解决int sum = Add(num1, num2);printf("%d\\n", sum);return 0;}
七、数组
📚 要存储1-10的数字,怎么存储?
“C语言给了数组的定义:一组相同类型元素的集合”
定义一个整型数组,最多放十个元素:
💬 代码演示:
int main(){int a = 0;int b = 0;int c = 0;int d = 0;//...// 10个整型1-10存起来int arr[10] = {1,2,3,4,5,6,7,8,9,10};char ch[5] = {'a', 'b', 'c'}; // 不完全初始化,剩余的默认为0// 用下标就可以访问元素printf("%d\\n", arr[0]);// 打印整个数组int i = 0;while(i<10) {printf("%d ", arr[i]);i++;}return 0;}
八、操作符简单介绍
0x00 算数操作符
❓ 什么是算数操作符?
📚 算术运算符即算术运算符号。是完成基本的算术运算 (arithmetic operators) 符号,就是用来处理四则运算的符号。
💬 代码演示:
int main(){int add = 1 + 1;int sub = 2 - 1;int mul = 2 * 3;float div = 9 / 2.0; //只要有浮点数出现,执行的就是浮点数除法int mod = 123 % 10;return 0;}
0x01 移位操作符
❓ 什么是移位操作符?
📚 移位运算符在程序设计中,是位操作运算符的一种。移位运算符可以在二进制的基础上对数字进行平移。
💬 代码演示:
int main(){// 移位操作符 移动的是它的二进制位// << 左移// >> 右动int a = 1;// 整形1占4个字节-32bit位// 0000000000000000000000000000001int b = a<<1;// 0000000000000000000000000000010 左边丢弃,右边补0printf("%d\\n", b);printf("%d\\n", a);return 0;}
🚩 运行结果: 2 1
0x02 位操作符
❓ 什么是位操作符?
📚 位操作是程序设计中对位模式按位或二进制数的一元和二元操作
💬 代码演示:
#include <stdio.h>int main(){//位操作 依然是二进制位// & 按位与 都为真,则返回真,只要出现假,就返回假int a = 3; //真int b = 5; //真int c = a&b; //按位与// 011// 101// 001// R→ 1 //真printf("%d\\n", c);int d = a|b;// 按位或 有真则为真,无则假,只要出现真,就返回真// 011// 101// 111// R→ 7printf("%d\\n", d);int e = a^b;// 按位异或 相同为假,相异为真 11\\ 00-> 0 10 -> 1//异或的计算规律//对应的二进制位相同,则为0//对应的二进制位相异,则为1// 011// 101// 110// R→printf("%d\\n", e);return 0;}
0x03 赋值操作符
❓ 什么是赋值操作符?
📚 赋值运算符是双目运算符,用在赋值表达式中。赋值运算符将值存储在运算符左边操作数指定的变量中。
💬 代码演示:
#include <stdio.h>int main(){int a = 10;a = 20; // “=” 赋值 “==” 判断相等a = a+10; //1a += 10; // 2a = a-20;a -= 20;a = a & 2;a &= 2;//这些操作叫做 复合赋值符return 0;}
0x04 单目操作符
❓ 什么是单目操作符?
📚 单目操作符,也就是只接受一个操作数的操作符。
💬 逻辑反操作 !
int main(){//0表示假,非0就是真int a = 5;printf("%d\\n", !a);if(a) {//如果a为真,做事}if(!a) {//如果a为假,做事}while(a); //a != 0,做事while(!a); //a=0,做事return 0;}
💬 按位取反 ~
int main(){int a = 0;printf("%d\\n", ~a);// ~ 按(二进制)位取法//把所有二进制位的数字,1变成0,0变成1//整数a// 0// 00000000000000000000000000000000// 11111111111111111111111111111111 ~a// 数据在内存中存储的是补码// 一个整数的二进制表示有三种: 原码 反码 补码// 负数的计算 -1:// 10000000000000000000000000000001 (原码)// 11111111111111111111111111111110 (反码)// 11111111111111111111111111111111 (补码) -> 在内存中存的// 正的整数: 原码、反码、补码相同return 0;}
💬 前置++
int main(){int a = 10;int b = ++a; //前置++, 先++后使用printf("%d\\n", b); //11printf("%d\\n", a); //11return 0;}
💬 后置++
int main(){int a = 10;int b = a++; //后置++,先使用再++printf("%d\\n", b);printf("%d\\n", a);return 0;}
💬 强制类型转换:
int main(){int a = (int)3.14; //强制类型转换printf("%d\\n", a);return 0;}
0x05 逻辑操作符
📚 逻辑运算符或逻辑联结词把语句连接成更复杂的复杂语句
逻辑与:两个都为真即为真(and)
逻辑或:一个为真即为真(or)
💬 逻辑与 &&
int main(){int a = 3;int b = 5;int c = a && b;printf("%d\\n", c); //1return 0;}
💬 逻辑或 ||
int main(){int a = 3;int b = 0;int c = a||b;printf("%d\\n", c); //1return 0;}
0x06 条件操作符
📚 条件操作符就是三目操作符
exp1成立,exp2计算,整个表达式的结果是:exp2的结果。
exp1不成立,exp2计算,整个表达式的结果是:exp3的结果。
💬 条件操作符的用法:
int main(){//exp1成立,exp2计算,整个表达式的结果是:exp2的结果//exp1不成立,exp3计算,整个表达式的结果是exp3的结果int a = 0;int b = 3;int max = 0;/* 等价于if(a>b) {max = a;} else {max = b;}*/max = a>b ? a : b;return 0;}
0x07 逗号表达式
📚 逗号表达式:逗号隔开的一串表达式。
逗号表达式是从左向右依次计算的。
整个表达式的结果是最后一个表达式的结果。
💬 逗号表达式的用法演示:
int main(){(2, 3+5, 6);int a = 0;int b = 3;int c = 5;// a=5 c=5-4 b=1+2int d = (a=b+2, c=a-4, b=c+2);printf("%d\\n", d); // 3return 0;}
0x08 下标引用操作符
📚 [] 就是下标引用操作符。
💬 演示:
int main(){int arr[10] = {1,2,3,4,5,6,7,8,9,10};printf("%d\\n", arr[5]); // 6return 0;}
0x09 函数引用操作符
📚 调用函数时,函数名后面的()就是函数调用操作符
💬 演示:
int main(){printf("hehe\\n");printf("%d", 100);return 0;}
九、关键字
0x00 常见关键字
📚 C语言提供的关键字:
1. C语言提供的,不能自己创建关键字
2. 关键字不能做变量名
这里我们来简单地介绍几个:
💬 auto – 自动的
int main(){{int a = 10; //自动创建,自动销毁的 - 自动变量// auto省略掉了auto int a = 10;// auto新的C语言中也有其它用法 - 暂时不考虑}return 0;}
💬 register – 寄存关键字
int main(){// 大量/频繁使用的数据,想放在寄存器中,提升效率register int num = 100; //建议num的值存放在寄存器中//是不是最终放到寄存器中是编译器说的算// 其实现在编辑器已经很聪明了,// 就算你不主动加register,它也会帮你存到寄存器中。return 0;}
💬 typedef – 类型重命名
// 这种罗里吧嗦的变量我们可以把它重命名一下typedef unsigned int u_int;int main(){unsigned int num = 100;u_int num2 = 100; //和上面是等价的return 0;}
📚 static – 静态的
1. static修饰局部变量
2. static修饰全局变量
3. static修饰函数
💬 static修饰局部变量
函数中局部变量:
声明周期延长:该变量不随函数结束而结束
初始化:只在第一次调用该函数时进行初始化
记忆性:后序调用时,该变量使用前一次函数调用完成之后保存的值
存储位置:不会存储在栈上,放在数据段
void test() {static int a = 1; //不销毁,生命周期变长了a++;printf("%d ", a);}int main(){int i = 0;while(i<10) {test();i++;}return 0;}
🚩 运行结果: 2 3 4 5 6 7 8 9 10 11
💬 static修饰全局变量
改变该变量的链接属性,让该变量具有文件作用域,即只能在当前文件中使用。
① Global.c:
static int g_val = 2021;// static 修饰全局变量,// 使得这个全局变量只能在自己所在的源文件(.c)内部可以使用// 其他的源文件不能使用!// 全局变量,在其他原文件内部可以被使用,是因为全局变量具有外部链接属性// 但是被static修饰之后,就变成了内部链接属性,// 其他的源文件就不能链接到这个静态的全局变量了!
② test.c:
extern int g_val;int main(){printf("%d\\n", g_val);return 0;}
🚩 运行结果: test.obj : error LNK2001: 无法解析的外部符号 _g_val
💬 static修饰函数
改变该函数的链接属性,让该函数具有文件作用域,即只能在当前文件中使用。
① Add.c:
//static修饰函数,static int Add(int x, int y) {return x + y;}
💬 test1.c:
extern int Add(int, int); //声明外部函数int main(){int a = 10;int b = 20;int sum = Add(a, b);printf("sum = %d\\n", sum);return 0;}
🚩 运行结果:
test.obj : error LNK2019: 无法解析的外部符号 _Add,该符号在函数 _main 中被引用
0x01 define
📚 define 是一个预处理指令:
1. define 定义标识符常量
2. define 定义宏
💬 define 定义标识符常量:
#define MAX 1000int main(){printf("%d\\n", MAX);return 0;}
💬 define 定义宏:
#define ADD(X, Y) X+Y#define ADD1(X, Y) ((X)+(Y))int main(){printf("%d\\n", 4*ADD(2, 3));// 4*2+3 = 11printf("%d\\n", 4*ADD1(2, 3));// 4*(2+3) = 20return 0;}
十、指针初探
0x00 指针介绍
❓ 什么是指针?
指针就是地址,地址就是指针。
指针,是C语言中的一个重要概念及其特点,也是掌握C语言比较困难的部分。指针也就是内存地址,指针变量是用来存放内存地址的变量,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。
💬 变量都有地址,取出变量的地址如下:
int main(){int a = 10; // a在内存中要分配空间 - 4个字节&a; // 取出num的地址printf("%p\\n", &a); //%p - 以地址的形式打印return 0;}
🚩 打印出来的是a的地址
💬 定义指针变量,存储地址
* 说明 pa 是指针变量
int 说明 pa 执行的对象是 int 类型的
int main(){int a = 10;int* pa = &a; // pa是用来存放地址的,在C语言中叫pa的是指针变量char ch = 'w';char* pc = &ch;return 0;}
0x01 解引用操作
如果把定义指针理解为包装成快递,那么“解引用操作”就可以理解为是拆包裹
拆出来的值就是那个变量的值,甚至还可以通过“解引用”来修改它的值。
💬 解引用操作用法:
int main(){int a = 10;int* pa = &a;*pa = 20; // * 解引用操作 *pa就是通过pa里边的地址,找到aprintf("%d\\n", a); //20return 0;}
0x02 指针的大小
📚 指针的大小
“指针的大小是相同的”
❓ 为什么相同?
“因为指针是用来存放地址的,指针需要多大空间,取决于地址的存储需要多大空间”
📺 指针是一种复合数据类型,指针变量内容是一个地址,因此一个指针可以表示该系统的整个地址集合,故按照32位编译代码,指针占4个字节,按照64位编译代码,指针占8个字节(注意:不是64位系统一定占8个字节,关键是要按照64位方式编译)。
32位 – 32bit – 4byte
64位 – 64bit – 8byte
💬 sizeof 计算指针的大小:
int main(){printf("%d\\n", sizeof(char*));printf("%d\\n", sizeof(short*));printf("%d\\n", sizeof(int*));printf("%d\\n", sizeof(long*));printf("%d\\n", sizeof(long long*));printf("%d\\n", sizeof(float*));printf("%d\\n", sizeof(double*));return 0;}
32位下都是 4 64位下都是 8
十一、结构体
0x00 什么是结构体
📚 结构体可以让C语言创建出新的类型
“结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂的类型”
💬 使用结构体描述学生 / 描述书:
// 创建一个学生的类型struct Stu {char name[20]; // 姓名int age; // 年龄double score; // 分数}; // ← 不要忘了加分号// 创建一个书的类型struct Book {char name[20];float price;char id[30];};
💬 结构体的初始化:
点操作符和箭头操作符
. 结构体变量.成员
-> 结构体指针->成员
struct Stu {char name[20]; // 姓名int age; // 年龄double score; // 分数};struct Book {char name[20];float price;char id[30];};int main(){struct Stu s = {"张三", 20, 85.5}; // 结构体的创建和初始化// 点操作符printf("1: %s %d %lf\\n", s.name, s.age, s.score);struct Stu* ps = &s;printf("2: %s %d %lf\\n", (*ps).name, (*ps).age, (*ps).score); // ❎// 箭头操作符printf("3: %s %d %lf\\n", ps->name, ps->age, ps->score); // ✅return 0;}
参考文献 / 资料
Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .
俞甲子 / 石凡 / 潘爱民. 《程序员的自我修养》[M]. 电子工业出版社, 2009-4.
百度百科[EB/OL]. []. https://baike.baidu.com/.
比特科技. C语言基础[EB/OL]. 2021[2021.8.31]. .
本章完。