
C语言技术体系
完整的C语言学习道路,相信你学完所有文章一定会有意想不到的收获!
程序员懒羊羊
记录c/c++学习过程
编译器:Visual Studio2019
展开
-
《C语言技术体系》 学习路线总目录 + 思维导图
本篇文章是对专栏《C语言技术体系》中所有文章及知识点进行总结归档,C语言是最底层也是最核心的语言,要想走上程序员这条道路应该都绕不开它吧。那么这篇超详细C语言目录就奉上了,同学们可以直接根据需要点击连接查看呦!那么有已经学完C语言,开始进阶C++方向的同胞们也可以查看现在正在更新的专栏《C++进阶之路》,希望对你能有所帮助。3.2.1【C语言】 typedef以上就是C语言技术体系的全部内容了,希望对你的学习有帮助,我们山顶见!原创 2023-05-03 16:19:17 · 4576 阅读 · 0 评论 -
【C语言】 知识点汇总--基础知识点梳理(超全超详细)
目录一、从源代码到exe二、基本数据类型三、字符在屏幕上的显示原理四、溢出现象五、类型转换规律六、短路问题七、指针变量类型的作用 八、指针类型的扩展——多级指针九、指针类型的扩展——指针数组十、指针类型的扩展——数组指针十一、一维数组-名-特性十二、二维数组-名-特性十三、大端存储-小端存储十四、函数在源代码中的三种状态十五、堆区与栈区的区别十六、函数的执行原理十七、枚举类型十八、typedef二十、const二十一、全局/局部变量生命周期与作用域二十二、static静态变量二十三、extern二十四、宏d原创 2023-05-02 20:11:23 · 20831 阅读 · 2 评论 -
C语言 通讯录系统
至此,C语言的学习告一段落,以一个不完整的通讯录结束,但大体框架已经搭建,一些功能没有写,感兴趣的可以自行参透。原创 2023-04-05 13:10:31 · 706 阅读 · 1 评论 -
【C语言】 printf格式化打印
printf("固定+可变",可变数据);原创 2023-01-23 16:23:03 · 569 阅读 · 0 评论 -
【C语言】 初识C语言--面向过程的语言
我们在日常写代码时一定要注意这两点,我相信在不久的将来,能够写一手好的代码一定会在面试过程中受到面试官的青睐!模块化思维:#include 打开模块 std 标准的 io 输入输出 .h 头文件。在编写代码时,我们难免会出现一些bug,那么这些bug的根源就只有两种:1.原理不通 2.习惯不好。步入C语言,当然要从Hello World开始了!结构内写代码: 面向过程。原创 2023-01-23 13:54:37 · 519 阅读 · 0 评论 -
C语言 封装静态库/动态链接库
静态库需要放到项目中,他会跟随项目一同打包为exe文件,所以如果exe用到的组件较多,那么他的文件体积会很大,并且每个程序的代码区都会有一份静态库,会造成空间浪费。动态链接库是独立在exe外边的,它属于资源共享,谁想用谁就调用它即可,并且升级也很简单,只要更新自己就行,因为不需要打包在exe文件内,所以文件体积也会较小。将.lib文件加入到测试项目中,可以观察到动态链接库的lib比静态库的lib要小很多。.h是开发用的,.lib是引导调用的,.dll是真正的程序。在头文件中加入头文件,源文件中加入源代码。原创 2023-04-04 22:36:39 · 2407 阅读 · 1 评论 -
C语言 文件操作
将被复制文件的数据先一点一点保存到buffer数组中,再将buffer数组中的数据写入到目标文件,直至被复制文件中的光标到达尾部。用文件指针打开被复制文件和目标文件的缓冲区,再建立一个buffer数组充当中间缓冲区。这里的文件名后缀虽然是txt文本文件,但不能通过拓展名看文件本质。修改前 需要用fseek()函数 重新定位。也可以用rewind() 使光标回到开头。关闭文件流的函数:fclose()从当前位置偏移0,然后改为'8'。打开文件流的函数:fopen()原创 2023-04-04 13:06:40 · 611 阅读 · 0 评论 -
C语言 共用体
char b;union aa h;h.a=65;printf("共用体大小%d\n",sizeof(union aa));原创 2023-04-03 19:30:30 · 277 阅读 · 3 评论 -
C语言 链表
先要根据数据找到下标,在根据下标删除节点。这里我们建的是一个单向链表。进去的是数据,出来的是节点。原创 2023-04-01 22:26:51 · 352 阅读 · 2 评论 -
C语言 结构体
目录定义一个结构体 定义一个结构体 用typedef重命名结构体数组: 结构体指针 结构体对齐 结构体与堆内存结构体位域使用 结构体的嵌套先温习一下之前学过的#define和enum枚举类型:创建结构体变量:创建结构体变量并赋初值:存取结构体成员值 用.操作符:注:不能直接给数组名赋值,因为数组名是一个地址常量,要通过strcpy来赋值。输入 输出:定义一个结构体 用typedef重命名结构体数组:创建结构体数组变量:排序:打印:直接封装BOOK原创 2023-03-31 22:29:04 · 442 阅读 · 1 评论 -
C语言 看图说话-静态库与动态链接库
静态库需要放到项目中,他会跟随项目一同打包为exe文件,所以如果exe用到的组件较多,那么他的文件体积会很大,并且每个程序的代码区都会有一份静态库,会造成空间浪费。他还不宜更新,在更新时要将所有程序都更新一遍,他的优点就是移植方便。动态链接库是独立在exe外边的,它属于资源共享,谁想用谁就调用它即可,并且升级也很简单,只要更新自己就行,因为不需要打包在exe文件内,所以文件体积也会较小。原创 2023-03-30 16:03:04 · 323 阅读 · 1 评论 -
C语言 看图说话-文件复制原理
文件复制我们先用fopen函数打开被复制文件和目标文件的缓冲区,在创建from和to两个文件类型的指针指向他们,我们还需创建一个buffer数组来当作中间的缓冲区。而后我们通过fread函数将在被复制文件中的数据先读到buffer数组中,然后再通过fwrite函数将buffer数组中的数据写入到目标文件,直至被复制文件内的光标到达尾部。原创 2023-03-30 15:55:24 · 383 阅读 · 0 评论 -
C语言 字符串-字符串键盘输入
getchar输入一个字符 (以回车结束输入回车会进入键盘缓冲区,在再次输入输出是不会让你继续输入,会直接打印回车)输入一个字符 输入完立刻结束 但是显示出你的输入字符。输入一个字符 不显示 不用回车结束 输入完立刻结束。原创 2023-03-30 12:44:09 · 1976 阅读 · 1 评论 -
C语言 字符串-字符串类型转换
atof():将字符串转换为双精度浮点型值。itoa():将整型值转换为字符串。atoi():将字符串转换为整型值。原创 2023-03-30 12:32:26 · 515 阅读 · 1 评论 -
C语言 字符串-字符串的匹配
搜索字符串在另一个字符串中首次出现的位置。原创 2023-03-29 22:12:58 · 2029 阅读 · 0 评论 -
C语言 字符串-字符串的比较
ASCII码值的比较 从头到尾一次比较。原创 2023-03-29 22:04:34 · 721 阅读 · 0 评论 -
C语言 字符串-字符串的拼接
strcat追加拷贝,追加到目标空间后面,目标空间必须足够大,能容纳下源字符串的内容。原创 2023-03-29 22:00:14 · 1526 阅读 · 0 评论 -
C语言 字符串-字符串的复制
strncpy_s(目标字符串的首地址,缓冲长度,被复制的字符串的首地址,,复制的长度)strcpy_s(目标字符串的首地址,缓冲长度,被复制的字符串的首地址)strncpy(目标字符串的首地址,被复制的字符串的首地址,复制的长度)strcpy(目标字符串的首地址,被复制的字符串的首地址)仿真字符串复制函数 strncpy。仿真字符串复制函数 strcpy。,这种复制方式更像是覆盖。原创 2023-03-29 21:48:30 · 3386 阅读 · 0 评论 -
C语言 字符串-得到字符串长度
这里字符串长度是5,字符数组长度是6 原因是\0也占空间、首先这里引进一个新的头文件,那就是。,这里包含了很多有关字符串的函数。原创 2023-03-29 21:31:52 · 452 阅读 · 0 评论 -
C语言 字符串存储原理
第一行打印的是字符串在常量区的首地址;第二行打印的是字符串中的第四个成员;第三行打印的是从第三个成员开始打印。字符串常量 特点:exe加载时就被创建在常量区,而且只有一份。字符串常量:代码中代表其所在常量区的地址 是个地址常量。指针指向的是常量区的地址,所以不可以修改。str的是常量区的复制品,因此可以修改。在栈区创建指针指向常量区的字符串常量。原创 2023-03-29 21:18:49 · 257 阅读 · 0 评论 -
C语言 字符、字符数组、字符串
要想让字符数组变为字符串,那么字符数组的结尾一定要有'\0',如果字符数组不完全初始化时,剩余的成员会自动识别为'\0',但是如果字符数组未进行初始化,那么在对成员赋值时结尾成员一定要手动赋值'\0'。因为只有结尾有'\0'时,字符数组才能称之为字符串。就是遍历字符数组的每一个成员直到成员为'\0'截至。遍历可以通过数组下标遍历也可以通过指针的方式遍历。字符串:第一个\0之前的字符为有效字符串(\0称为:字符串结束标记)字符数组:存放连续字符的空间。字符原理:影像 与 编码。原创 2023-03-29 21:05:08 · 385 阅读 · 0 评论 -
C语言 看图说话-文件处理模型
答:fopen函数在内存中开辟一个文件处理缓存区,我们可以定义一个文件类型的指针(FILE*)来指向缓存区,通用对缓存区的操作实现对内存中文件的读写和修改。我们通过fopen函数打开文件流,再通过fclose函数关闭文件流。答:包括二进制文件和文本文件,二进制文件是按照数据在内存中存储的原样存放的,而文本文件时通过字符编码进行存储。答:内存存储属于临时存储,如果不保存就会丢失,存储速度较快但存储容量较小,而外存存储属于长期存储,存储速度较慢但是容量较大。1.内存存储与外存存储的差异是什么?原创 2023-03-29 19:55:17 · 409 阅读 · 0 评论 -
C语言 看图说话-链式存储与顺序存储
答:链式存储又称为链表,他用一组任意存储单元存储线性表中的数据元素,包括数据域和指针域,数据域存数据,指针域指示其后继的信息。他的优点是插入和删除很方便,只需要修改数据邻节点的指向即可,缺点是查询代价较高,在查询任一元素时都需要从头节点开始遍历。答:顺序存储就是把线性表中的所有元素按照某种逻辑顺序,依次存储到从指定位置开始的一块连续的存储空间,比如我们学过的数组就是顺序存储。他的优点是可以快速的查找出表中任意位置的元素,缺点是插入和删除操作中需要移动大量的元素,那么效率就会很低。1.什么是线性表数据结构?原创 2023-03-29 19:14:31 · 475 阅读 · 0 评论 -
C语言 看图说话-struct与union结构体联合体
答:在结构体创建时会有一个对齐不齐的准则,他会选出所使用的数据类型中字节数最大的类型作为标准,并以它的字节数为一个单位,在创建空间时,如果某类型小于单位剩余字节数,那可以直接将这个类型在该单位的空间中创建,如果大于剩余字节数,那么就会再创建一个单位空间对其进行存储。比如图中这个,这些数据类型最大字节数为4,所以一个单位空间就是四个字节,那么我们可以看到第二排剩余一个字节的空间,而最后一排只使用一个字节,如果将最后一排的char类型放在第二排进行创建,那么就会节省四个字节的空间。1.扩展类型包括那些?原创 2023-03-28 19:36:16 · 432 阅读 · 0 评论 -
C语言 函数递归调用原理
例2:递归实现:两个正整数的最大公约数。例3:用递归算法实现斐波那契数列。一定要有终止条件,否则会出现。函数递归就是函数自己调用自己。例5:递归判断是否回文数组。终止条件,递推公式。例1:用递归思想实现n!原创 2023-03-26 21:42:10 · 279 阅读 · 0 评论 -
C语言 看图说话-全局/局部变量生命周期与作用域
全局变量是在函数外定义的变量,它会被分配到全局/静态区,它的作用域是整个项目内,在项目内任何位置都可以通过extern来对它进行引用,但切记不可以二次赋值,它的生命周期是整个项目 开始到结束。局部变量就是定义在函数内的变量,它会存放在栈区,它的生命周期是从函数入栈到弹出,作用域是所在函数内。当全局变量与局部变量重名时,不会出现重定义的语法错误,而是会将全局变量屏蔽,这里遵循一个临近原则。原创 2023-03-22 15:59:39 · 479 阅读 · 0 评论 -
C语言 看图说话-函数的执行原理
从微观来看,在我们执行一个程序时,main函数会首先入栈,之后调用哪个函数哪个函数就入栈,执行完毕后就会pop弹出。函数名实际就是个地址, 也就是说他代表函数在代码区上的地址,既然是个地址,那么我们就可以创建一个指针来指向它、调用它。所以我们在栈区创建一个要指向函数类型的指针,并指向它,在这里我们要注意的是,我们在指向它时有两种方式,一种是。因为第二种方式比较简洁明了,所以在调用执行函数时我们通常选择隐式方式。从宏观来看,函数的执行就像阿拉丁神灯一样,在我们调用执行的时候他就会出现,执行完毕就会消失。原创 2023-03-17 22:55:52 · 639 阅读 · 0 评论 -
C语言 看图说话-堆区与栈区的区别
答:从空间大小来看,堆区的空间较大,栈区的空间较小。分配方式和管理方式:栈区是自动分配和自动回收的。从分配效率来看,栈区是在调用函数的时候直接自动分配出来的;而堆区是要执行malloc或calloc时分配的,也就相当于手动分配,所以栈区的效率更高。答:会产生碎片,在堆积到一定程度时可能会导致程序崩溃,所以我们通常会在栈区创建一个指针,来指向堆区中内容的地址。答:一般是临时性的局部变量,再调用函数时会在栈中创建出临时变量,在执行完毕后会自动回收掉。通常来讲,代码区是低地址的,栈区是高地址的。原创 2023-03-17 22:38:21 · 516 阅读 · 0 评论 -
C语言 看图说话-函数在源代码中的三种状态
要定义一个函数,他首先需要有返回值类型,然后加上函数名和括号,括号中写上要定义的形参,再加上{},最后在{}中写入流程结构。在声明函数时,就是将{}和其中的内容去掉,再加上;,如果函数没有进行前置声明,那么就会出现重定义的语法错误。再调用函数时,我们只需在()中写入实参,就可以将实参传入形参,即可进行函数的调用。在我们自定义函数时,最佳的顺序就是先对我们设计好的函数进行声明,然后将调用函数写入到程序中,看逻辑是否正确,最后按照我们的需求对函数进行定义,书写函数的流程结构。原创 2023-03-17 18:47:37 · 581 阅读 · 0 评论 -
C语言 static静态变量
static所定义的是静态唯一变量,他所定义的变量会被存放在全局/静态区。static变量的值只能初始化一次,如果未进行初始值,系统会自动为其赋值0。当我们在调用函数时,函数内的变量会随着执行结束弹出而被栈区自动回收掉,但如果定义的变量为static变量,他将不会被回收。它的作用域是定义所在的位置,如果是在项目中定义,它的作用域就是整个项目;比如说我们在定义一个全局变量时,在前面加上了static,使其成为了静态全局变量,那么他就是当前源代码的全局变量,不可以在其他源代码中通过extern来引用。原创 2023-03-17 18:09:52 · 800 阅读 · 3 评论 -
C语言 extern
extern就是外部变量链接,它用于声明来自外部的变量,它可以将全局/静态区中的全局变量在外部进行声明,然后所声明的位置就可以使用被声明的变量了,在声明时要注意的是只能声明,不能赋值定义,否则就会出现重定义的语法错误。所以他的格式是extern 数据类型 变量名;切记extern声明的变量不能赋值,有extern没赋值,有赋值没extern。原创 2023-03-03 18:22:46 · 457 阅读 · 1 评论 -
C语言 宏define
define就是宏替换,宏是整体的意思,那么宏替换就是整体替换,它发生在预处理期,它有两种替换方式。一种是#define 宏名 替换内容,这是内容没有可变部位的方式,而如果内容中有可变的部位,他就是#define 宏名(可变部位) 内容模板,其中包括可变部位和不变内容,可变的一般为数组名或数据类型。它也可以进行宏的嵌套定义,将D替换为C,将C替换为B,再将B换成A。1:预处理期: 在这一阶段,源码中的所有预处理语句得到处理例如:#include语句所包含的文件内容替换掉语句本身,所有已定义的宏被展开。原创 2023-03-03 12:10:35 · 854 阅读 · 0 评论 -
C语言 const
const在指针上的用法有三种,如果在*和p前面都加上const,就相当于将指针锁住并且将它指向的地址也锁住,也就是指向不可改,内容也不可改。//----------指向不可改 内容可改---------------////----------指向不可改 内容不可改---------------//--结论:const放到谁的前面,谁就不可改---------------//------指向可改 内容不可改------------//但是防君子不防小人,仍然可以通过指针对其进行修改。原创 2023-03-03 11:30:56 · 370 阅读 · 0 评论 -
C语言 枚举类型enum
枚举类型的全称是enumeration,我们在使用的时候就用enum,它是一种扩展类型,在这之前我们学习过数组,并且在以后还会学到struct结构体以及union联合体。enum可以对数据类型进行扩展,创建自定义的类型,但这个类型的值一定是固定有限的。比如生肖、血型或是方向。他的格式是enum 枚举名称 {内容1,内容2......};方式2: enum 枚举名称 { 内容1=整数, 内容2=整数, 内容3=整数, ...};方式1: enum 枚举名称 { 内容1, 内容2, 内容3,... };原创 2023-03-03 10:38:53 · 486 阅读 · 0 评论 -
C语言 typedef
type是类型的意思,define是定义,那么typedef就是对类型的重新命名,定义一个新的类型。那么什么是嵌套定义呢,比如说我们先将int类型重定义为Integer,再将Integer重命名为Integer INT,然后还可以将Integer INT在重命名为INT MYint,但是无论多少次重命名,这些自定义类型的本质都是int类型。不加typedef 括号中就是变量名,加typedef 括号中就是再命名 typedef:封装了指针类型的描述过程,简化了变量声明。对已经封装的类型再次封装命名。原创 2023-03-03 10:23:27 · 769 阅读 · 0 评论 -
C语言 函数指针
因为函数名本质上就是个地址,所以这里指针指向的就是函数名本身,因此在调用时可以直接用指针进行调用,这种方式比较简洁且清晰,所以在我们使用函数指针是通常使用这种方式。既然是个地址,那么就可以通过指针来指向它,定义指向函数的指针变量 就可以调用内存中的函数代码。指针指向函数名的地址,那么在调用时就需要通过*操作来得到函数名的空间,所以此时*p==函数名。函数名字的本质: 代表函数在内存中的地址。说白了,我们可以将函数当作数据来看!原创 2023-03-03 10:01:00 · 284 阅读 · 1 评论 -
C语言 看图说话-二维数组·名·特征
如果是访问三维数组中某一成员的空间,那么就是三层嵌套,第一层先利用数组名加偏移找到某一个平面的地址,对他*操作后得到这个平面的空间,再利用这个空间加偏移找到这个平面中某一行的地址,*操作后得到这行的空间,最后利用得到的这个行空间加偏移找到某一个成员的地址,对整体*操作后就可以得到这个三维数组中某个成员的空间了。答:二维数组名+1是二维数组中的行偏移,找到的是后面一行的地址,而&二维数组名+1属于是二维数组的偏移,找到的是二维数组后面的地址。3.二维数组名+1与&二维数组名+1的区别?答:代表第0行的地址。原创 2023-02-14 23:06:10 · 696 阅读 · 2 评论 -
C语言 看图说话-一维数组·名·特性
先来看这张图,我们定义了一个一维数组,在这个数组中,他的数组名本质上就是个地址,是这个数组的首地址,我们也可以理解为这个数组第0个元素的地址,那么在这个地址上加上2意思就是向后移动两列,找到的就是这个数组第2各成员的地址。最后要说的是arr与&arr的区别,虽然他们两个的值相同,但是代表的意义不同,arr代表的是数组第0列的地址,向后偏移1位找到的是第1列的地址,而&arr找到的是这个数组的地址,向后偏移1位找到的就是数组后边的地址。答:刚才说到了,数组名+1是在数组中列的移动找到的就是第1列的地址;原创 2023-02-14 22:50:47 · 668 阅读 · 1 评论 -
C语言 看图说话-指针类型的扩展——数组指针
答:我们知道,p指向的是数组的地址,也就是取地址符加上数组名,那么*p就是对取地址后的数组名再*操作,因为&与*为互逆操作,所以此时*p就等同于数组名,所以通过数组指针访问数组成员空间时,只要将数组名替换为*p即可。答:在这个图片中,第一行就为基本类型的指针,不难看出,数组指针所指向的空间更大,再看后两行,前边为指针数组,后边为数组指针,因为如果*p不加括号,int就会先与*结合变为int型指针,再通过后边的方括号进行扩展,最终命名为怕,而数组指针是int与方括号结合成为数组,再通过*p指向它。原创 2023-02-14 22:40:17 · 813 阅读 · 2 评论 -
C语言 函数
return 关键词的意思就是结束并返回值,如果打算中途结束函数执行,return需要与if结合使用。如果返回类型不是void 则函数结束必须返回定义函数的类型。看如下代码,这其中的int a[]其实是给调用者的暗示 实际上是个指针 并且[]中的长度无意义,所以要通过传参的方式将长度传进来。正常来讲,在设计一个函数的过程,先声明,再调用最后再定义。void 是指空·无 无类型占位符,可以出现在函数的声明和定义中。函数的执行原理:调用时执行,执行完消失,也就是从栈中弹出(pop)在函数中的参数为形参。原创 2023-02-11 23:43:24 · 385 阅读 · 0 评论