摘要: 《C语言进阶剖析》学习笔记 本文总结自狄泰软件学院唐佐林老师的《C语言进阶剖析》课程,在此推荐给想深入学习C语言的同学! 狄泰软件学院QQ群:199546072 课程代码已上传到github:https://github.com/shuaiwangshi/C_Course 阅读全文
posted @ 2019-11-13 23:30 Hengs 阅读(2360) 评论(0) 推荐(2)
摘要: 第48课 - 函数设计原则(完结) 1. 函数从意义上应该是一个独立的功能模块 2. 函数名要在一定程度上反映函数的功能 3. 函数参数要能够体现参数的意义 4. 尽量避免在函数中使用全局变量 5. 当函数参数不应该在函数体内部修改时,应加上const声明 6. 如果参数是指针,且仅作输入参数,则应 阅读全文
posted @ 2019-11-13 23:26 Hengs 阅读(473) 评论(0) 推荐(0)
摘要: 第47课 - 递归函数分析 阅读全文
posted @ 2019-11-13 23:23 Hengs 阅读(225) 评论(0) 推荐(0)
摘要: 第46课 - 函数与宏分析 1. 函数与宏 (1)宏是由预处理器直接替换展开的,编译器不知道宏的存在,因此参数无法进行类型检查 函数是由编译器直接编译的实体,调用行为由编译器决定 (2)多次使用宏会增大代码量,最终导致可执行程序的体积增大,对于嵌入式设备而言,设备资源有限,这个还是比较重要的 函数是 阅读全文
posted @ 2019-11-13 23:22 Hengs 阅读(358) 评论(0) 推荐(0)
摘要: 第45课 - 函数参数的秘密(下) 阅读全文
posted @ 2019-11-13 23:19 Hengs 阅读(243) 评论(0) 推荐(0)
摘要: 第44课 - 函数参数的秘密(上) 1. 函数的参数 (1)函数参数在本质上与局部变量相同,都在栈上分配空间 (2)函数参数的初始值是函数调用时的实参值 (3)C标准只规定了 必须要将每个实参的具体值求出来之后才能进行函数调用,并没有规定函数参数的求值顺序,求值顺序依赖于编译器的实现 比如 void 阅读全文
posted @ 2019-11-13 23:17 Hengs 阅读(350) 评论(0) 推荐(0)
摘要: 第43课 - 函数的意义 1. C语言中的函数 追溯一下C语言发展的历史,我们知道C语言在早期是用在科学计算上的,而科学计算就是使用各种算法处理数据。 在C语言中就是使用函数实现算法。 2. 函数的意义 (1)模块化程序设计 (2)C语言中的模块化 ==> 使用函数完成模块化编程 3. 面向过程的程 阅读全文
posted @ 2019-11-13 23:14 Hengs 阅读(815) 评论(0) 推荐(0)
摘要: 第42课 - 内存操作经典问题分析二 1. 常见内存错误 (1)结构体成员指针未初始化 (2)结构体成员指针未分配足够的内存 (3)内存分配成功但并未初始化 (4)内存操作越界 【常见内存错误1】 1 #include <stdio.h> 2 #include <malloc.h> 3 4 void 阅读全文
posted @ 2019-11-13 23:10 Hengs 阅读(365) 评论(0) 推荐(0)
摘要: 第40课 - 程序的内存布局 阅读全文
posted @ 2019-11-13 23:09 Hengs 阅读(220) 评论(0) 推荐(0)
摘要: 第41课 - 内存操作经典问题分析一 1. 野指针 (1)野指针指的是 指针变量的值是非法的内存地址,操作野指针会导致程序运行出错。 野指针不是NULL指针而是指向了非法地址;NULL指针并没有危害而且很好判断和调试。 (2)C语言中无法判断一个指针所保存的地址是否合法 (3)野指针产生的原因 ※  阅读全文
posted @ 2019-11-13 23:09 Hengs 阅读(322) 评论(0) 推荐(0)
摘要: 第38课 - 动态内存分配 1. 动态内存分配的意义 (1)C语言中的一切操作都是基于内存的 (2)变量和数组都是内存的别名 内存分配由编译器在编译期间决定 定似数组的时候必须指定数组长度 数组长度是在编译器就必须确定的 需求 : 程序运行的过程中,可能需要使用一些额外的内存空间 2. malloc 阅读全文
posted @ 2019-11-13 23:08 Hengs 阅读(293) 评论(0) 推荐(0)
摘要: 第39课 - 程序中的三国天下 1. 程序中的栈 1 2. 函数调用过程 1 2. 程序中的堆 1 3. 程序中的静态存储区 1 阅读全文
posted @ 2019-11-13 23:08 Hengs 阅读(209) 评论(0) 推荐(0)
摘要: 第37课 - 指针阅读技巧分析 阅读全文
posted @ 2019-11-13 23:07 Hengs 阅读(166) 评论(0) 推荐(0)
摘要: 第36课 - 函数与指针分析 1. 函数类型 (1)C语言中的函数有自己特定的类型,函数的类型由返回值、参数类型和参数个数共同决定 比如,int add(int i, int j) 的类型为 int(int, int) (3)C语言中通过typedef为函数类型重命名,typedef return_ 阅读全文
posted @ 2019-11-13 23:06 Hengs 阅读(294) 评论(0) 推荐(0)
摘要: 第35课 - 数组参数和指针参数分析 1. 数组参数和指针参数 阅读全文
posted @ 2019-11-13 23:05 Hengs 阅读(208) 评论(0) 推荐(0)
摘要: 第33课 - main函数与命令行参数 阅读全文
posted @ 2019-11-13 23:04 Hengs 阅读(175) 评论(0) 推荐(0)
摘要: 第34课 - 多维数组和多维指针 阅读全文
posted @ 2019-11-13 23:04 Hengs 阅读(171) 评论(0) 推荐(0)
摘要: 第32课 - 数组指针和指针数组分析 1. 数组的类型 C语言中的数组有自己特定的类型,数组的类型由 元素类型 和 数组大小 共同决定。比如 int array[5] 的类型就是 int[5];float farray[10] 的类型就是 float[10]。 2. 定义数组类型 C语言中通过typ 阅读全文
posted @ 2019-11-13 23:03 Hengs 阅读(354) 评论(0) 推荐(0)
摘要: 第31课 - 字符串典型问题分析 阅读全文
posted @ 2019-11-13 23:02 Hengs 阅读(180) 评论(0) 推荐(0)
摘要: 第30课 - C语言中的字符串 1. 字符串的概念 (1)字符串是有序字符的集合 (2)字符串是程序中的基本元素之一 (3)C语言中没有字符串的概念 C语言中通过特殊的字符数组模拟字符串 C语言中的字符串是以 '\0' 结尾的字符数组 // 回忆前面学过的转义符 \ ,'\0' 即八进制的0表示的字 阅读全文
posted @ 2019-11-13 23:01 Hengs 阅读(485) 评论(0) 推荐(0)
摘要: 第28课 - 指针和数组分析(上) 1. 数组的本质 (1)数组是一段连续的内存空间 (2)数组的大小为 sizeof(array_type) * array_size (3)数组名可以看作指向数组第一个元素的指针常量 思考下面两个问题: ① a + 1的意义是什么?结果又是什么? ② 指针运算的意 阅读全文
posted @ 2019-11-13 23:00 Hengs 阅读(295) 评论(0) 推荐(0)
摘要: 第29课 - 指针和数组分析(下) 1. 数组的访问方式 (1)访问数组元素有两种方式:以下标的形式访问数组中的元素 和 以指针的形式访问数组中的元素。 (2)下标形式 VS 指针形式 指针以固定增量在数组中移动时,效率高于下标形式 指针增量为1且硬件具有硬件增量模型时效率更高 下标形式与指针形式的 阅读全文
posted @ 2019-11-13 23:00 Hengs 阅读(272) 评论(0) 推荐(0)
摘要: 第27课 - 数组的本质分析 1. 数组的概念 数组是相同类型的变量的有序集合。 下图是一个包含5个int类型数据的数组的示意图: 2. 数组的大小 (1)数组在一片连续的内存中间存储元素 (2)数组元素的个数可以显示的或隐式的指定 观察下面两个数组,思考两个问题:① a[2],a[3],a[4] 阅读全文
posted @ 2019-11-13 22:59 Hengs 阅读(353) 评论(0) 推荐(0)
摘要: 第26课 - 指针的本质分析 1. 变量回顾 程序中的变量只是一段存储空间的别名,那么是不是必须通过这个别名才能使用这段内存空间? 2. * 号的意义 (1)在指针声明时,*号表示所声明的变量为指针 (2)在指针使用时,*号表示取指针所指向的内存空间中的值 3. 传值调用与传址调用 (1)指针是变量 阅读全文
posted @ 2019-11-13 22:58 Hengs 阅读(219) 评论(0) 推荐(0)
摘要: 第24课 - #pragma 使用分析 1. #pragma简介 (1)#pragma 是一条预处理器指令 (2)#pragma 指令比较依赖于具体的编译器,在不同的编译器之间不具有可移植性,表现为两点: ① 编译器A支持的 #pragma 指令在编译器B中也许并不支持,如果编译器B碰到这条不认识的 阅读全文
posted @ 2019-11-13 22:57 Hengs 阅读(710) 评论(0) 推荐(0)
摘要: 第25课 - # 和 ## 操作符使用分析 1. # 运算符 (1)# 运算符用于在预处理期将宏参数转换为字符串,即加上双引号 (# 运算符的操作对象是宏参数) (2)# 的转换作用是在预处理期完成的,因此只在宏定义中有效;编译器并不知道 # 的转换作用 (3)在有参宏中,# 只能和宏参数连用,不能 阅读全文
posted @ 2019-11-13 22:57 Hengs 阅读(872) 评论(0) 推荐(0)
摘要: 第23课 - #error 和 #line 使用分析 1. #error 的用法 (1)#error 是一个预处理器指示字,用于生成一个编译错误消息,这个消息最终会传递到编译器(gcc) 在思考这一点的过程中,领悟到了两个点: ① 使用 gcc 编译代码,输出的错误(警告)信息,是由预处理器、编译器 阅读全文
posted @ 2019-11-13 22:56 Hengs 阅读(875) 评论(0) 推荐(0)
摘要: 第22课 - 条件编译使用分析 这节课我们介绍如何使用C语言中的条件编译。 市面上的电子产品一般有低配版、中配版、高配版,那相应的软件也要开发三个版本吗?显然不是这样的,我们一般在同一套代码中使用条件编译区分不同的版本。 1. 基本概念 (1)c 程序的编译一般经过如下四个过程 条件编译是在预处理阶 阅读全文
posted @ 2019-11-13 22:55 Hengs 阅读(643) 评论(0) 推荐(0)
摘要: 第20课 - 链接过程简介 1. 思考一个问题 在具体工作中,每个软件项目都有很多个.c源文件,每个.c源文件经过编译后生成.o格式的目标文件,那么这些.o文件如何生成最终的可执行程序呢? 这里就要引入C语言的链接器了。 2. 链接器的作用 链接器的主要作用就是处理各个模块(目标文件和库文件)之间的 阅读全文
posted @ 2019-11-13 22:54 Hengs 阅读(280) 评论(0) 推荐(0)
摘要: 第21课 - 宏定义与使用分析 阅读全文
posted @ 2019-11-13 22:54 Hengs 阅读(187) 评论(0) 推荐(0)
摘要: 第18课 - 三目运算符和逗号表达式 1. 三目运算符 (1)三目运算符(a ? b : c)可以作为逻辑运算的载体 (2)规则:当a的值为真时,返回b的值;否则返回c的值 三目运算符的本质就是 if...else... 语句,只不过三目运算符格式更加方便优雅。 【三目运算符初探】 (3)三目运算符 阅读全文
posted @ 2019-11-13 22:53 Hengs 阅读(409) 评论(0) 推荐(0)
摘要: 第19课 - 编译过程简介 1. 初识编译器 我们通常所说的编译器其实是一个广义的概念,其实它里面包含了多个子模块,编译的过程由这些子模块协作完成。 编译器的工作过程 2. 编译器做了什么? 2.1 预处理 预处理由预处理器完成,预处理指令示例:gcc -E file.c -o file.i (1) 阅读全文
posted @ 2019-11-13 22:53 Hengs 阅读(317) 评论(0) 推荐(0)
摘要: 第17课 - ++和--操作符分析 1. ++和--操作符对应的两条汇编指令 (1)前置++/--对应的两条汇编指令:变量自增(减)1;然后取变量值 (2)后置++/--对应的两条汇编指令:先取变量值;然后变量自增(减)1 上面两条规则很简单,那 ++ 和 -- 操作符是不是就不需要研究了呢?我们使 阅读全文
posted @ 2019-11-13 22:52 Hengs 阅读(549) 评论(0) 推荐(0)
摘要: 第15课 - 逻辑运算符分析 阅读全文
posted @ 2019-11-13 22:51 Hengs 阅读(155) 评论(0) 推荐(0)
摘要: 第16课 - 位运算符分析 1. C语言中的位运算符 C语言中的位运算符直接对 bit 位进行操作,其效率最高。 2. 左移和右移运算符的注意点 (1)左操作数必须为整型类型即char、short、int,其中char和short被隐式转换为int后进行移位操作。其它的数据类型,如float等不能进 阅读全文
posted @ 2019-11-13 22:51 Hengs 阅读(381) 评论(0) 推荐(0)
摘要: 第14课 - 单引号和双引号 阅读全文
posted @ 2019-11-13 22:50 Hengs 阅读(457) 评论(0) 推荐(0)
摘要: 第12课 - 注释符号 1. 下面的注释正确吗? 在现代软件开发中,代码量动辄几十万行,这么庞大的程序非常需要注释,否则代码可能看的一头雾水。 先检验一下大家对注释的掌握程度,下面这个程序中的注释都正确吗? 怎么验证上面的注释是否正确呢?因为注释是由预处理器处理的,我们使用 gcc -E命令 预处理 阅读全文
posted @ 2019-11-13 22:49 Hengs 阅读(924) 评论(0) 推荐(0)
摘要: 第13课 - 接续符和转义符 1. 接续符 (1)接续符的意义:C语言中的接续符(\)是指示编译器行为的利器 /********** 额外的思考发现: ① 接续符由预处理器在预处理阶段处理 ② 接续符在读取后面的数据时,应该是根据"贪心法则"读取的,可以参考gcc -E的结果,接续符后面一行并没有全 阅读全文
posted @ 2019-11-13 22:49 Hengs 阅读(452) 评论(0) 推荐(0)
摘要: 第11课 - enum, sizeof, typedef 分析 1. enum介绍 (1)enum是C语言中的一种自定义类型,和struct、union地位相同,格式如下: (2)enum定义的第一个值默认情况下为0,后一个的值在前一个值的基础上加1 (3)enum在程序中有两种用法: ① 定义常量 阅读全文
posted @ 2019-11-13 22:48 Hengs 阅读(589) 评论(0) 推荐(0)
摘要: 第10课 - struct和union分析 1. 空结构体 在C语言中,结构体表示一系列变量的的集合,那编译器如何处理空结构体呢? 一类编译器认为,既然你是空结构体,内部没有成员变量那结构体大小就为0,但是可以正常编译;另一类编译器认为,空结构体有悖于结构体设计的初衷,既然结构体是变量的集合但空结构 阅读全文
posted @ 2019-11-13 22:47 Hengs 阅读(402) 评论(0) 推荐(0)
摘要: 第8课 - goto和void分析 1. 遭人嫌弃的goto (1)高手潜规则:禁用goto (2)项目经验:程序质量与goto的出现次数成反比;c语言是一门结构化语言,goto会破坏C语言的结构化特性。 (3)最后的判决:将goto打入冷宫 【goto副作用分析】 2. void的意义 2.1 v 阅读全文
posted @ 2019-11-13 22:46 Hengs 阅读(315) 评论(0) 推荐(0)
摘要: 第9课 - const和volatile分析 1. const只读变量 (1)const修饰的变量是只读的,本质上还是变量,并不是真正意义上的常量 ※※ const只是告诉编译器该变量不能出现在赋值符号的左边 (2)const修饰的局部变量在栈上分配空间;const修饰的全局变量在全局数据区分配空间 阅读全文
posted @ 2019-11-13 22:46 Hengs 阅读(430) 评论(0) 推荐(1)
摘要: 第6课 - 分支语句 1. if 语句分析 (1)if 语句用于根据条件选择执行语句 (2)else 不能独立存在且总是与它最近的 if 相匹配,else 语句后可以连接其它if语句 (3)if 语句中零值比较的注意点,这个考点频繁出现在C语言笔试中!!! bool类型 ==> bool型变量应该直 阅读全文
posted @ 2019-11-13 22:44 Hengs 阅读(289) 评论(0) 推荐(0)
摘要: 第7课 - 循环语句 1. 循环语句分析 (1)循环语句的基本工作方式 通过条件表达式判定是否执行循环体 条件表达式遵循 if 语句表达式的原则 (2)do、while、for的区别 do 语句先执行后判断,循环体至少执行一次 while 语句先判断后执行,循环体可能不被执行 for 语句先判断后执 阅读全文
posted @ 2019-11-13 22:44 Hengs 阅读(318) 评论(0) 推荐(0)
摘要: 第5课 - 变量属性 1. C语言变量的属性 C语言中的变量可以拥有自己的属性。在定义变量时可以加上属性关键字,用来指明变量的特有意义。 语法: property type var_name; 示例: 2. auto关键字 (1)auto属性关键字将被修饰的变量存储在栈上 (2)C编译器默认所有的局 阅读全文
posted @ 2019-11-13 22:42 Hengs 阅读(483) 评论(0) 推荐(0)
摘要: 第4课 - 类型转换 1. 类型之间的转换 C语言的数据类型之间可以进行转换,包括以下两种: 强制类型转换 ==> 程序员人为的将数据类型进行转换 隐式类型转换 ==> 编译器主动进行的数据类型转换 【类型之间的转换】 2. 强制类型转换 (1)强制类型转换的语法 (Type)var_name (T 阅读全文
posted @ 2019-11-13 22:41 Hengs 阅读(456) 评论(0) 推荐(0)
摘要: 第3课 - 浮点数的秘密 1. 浮点数在内存中的存储方式 float与double类型的数据在计算机内部的表示法是相同的,但由于所占存储空间的不同,其分别能够表示的数值范围和精度不同。 2. 浮点数的转换 2.1 浮点数的转换方法 如何将十进制的浮点数转换为内存中二进制表示的浮点数呢?按照下面三个步 阅读全文
posted @ 2019-11-13 22:36 Hengs 阅读(582) 评论(0) 推荐(0)
摘要: 第2课 - 有符号数与无符号数 1. 有符号整型的符号位 有符号整型有正数和负数,那在内存中是如何区分它们的呢?最高位用来标识数据的正负。 最高位为1,表明这个数为负数 最高位为0,表明这个数为正数 【有符号数的符号位】 2. 有符号整型的表示法 在计算机内部用补码表示有符号整型 正数的补码为正数本 阅读全文
posted @ 2019-11-13 22:35 Hengs 阅读(683) 评论(0) 推荐(0)
摘要: 第1课 - 基本数据类型 1. 数据类型 1.1 什么是数据类型? 在汇编时期,没有数据类型的概念。汇编程序中经常需要申请1byte、2byte、4byte大小的内存空间,程序员需要记住内存的起始地址,非常麻烦。。。。。 (1)数据类型可以理解为固定内存大小的别名 (2)数据类型是创建变量的模子 1 阅读全文
posted @ 2019-11-13 22:34 Hengs 阅读(694) 评论(0) 推荐(1)