
C语言进阶剖析学习记录
-出发-
学生一个,正处于学习阶段,希望与大家多多交流
展开
-
C语言进阶剖析--学习目录
【C语言进阶剖析】1、基本数据类型【C语言进阶剖析】2、有符号数与无符号数【C语言进阶剖析】3、浮点数的秘密【C语言进阶剖析】4、类型转换【C语言进阶剖析】5、变量属性【C语言进阶剖析】6、分支语句【C语言进阶剖析】7、循环语句【C语言进阶剖析】8、goto 和 void 分析【C语言进阶剖析】9、const 和 volatile 分析【C语言进阶剖析】10、struct 和...原创 2020-01-07 22:48:17 · 1532 阅读 · 0 评论 -
【C语言进阶剖析】48、函数设计原则(完结)
到这里 C 语言进阶剖析就要结束了,在本系列博客的最后,给大家简单说一下函数的设计原则函数设计原则函数从意义上应该时一个独立的功能模块函数名要一定程度上反应函数的功能函数参数名要能体现参数的意义避免在函数中使用全局变量(可能同样的输入,输出不一样了)如下两个函数:...原创 2020-01-07 22:41:11 · 482 阅读 · 0 评论 -
【C语言进阶剖析】47、递归函数分析
递归的数学思想递归是一种数学上分而治之的思想,将大型问题转化为与原问题小童但规模较小的问题进行处理。递归需要有边界条件,满足边界条件时,递归停止。递归函数内部自己调用自己,递归函数必有要有出口,否则将无限递归而使得程序栈溢出而崩溃。下面通过实例来分析递归。汉诺塔问题:// 47-3.c#include<stdio.h>void han_move(int n, char* ...原创 2020-01-07 20:06:31 · 375 阅读 · 0 评论 -
【C语言进阶剖析】46、函数与宏分析
1 函数与宏看下面这两段代码有什么区别与联系。上面这两段代码的功能都是将指针 p 所指的数组元素置为 0,一个是用宏实现的,一个用函数实现的。宏是由预处理期直接替换展开的,编译器不知道宏的存在,函数是由编译器直接编译的实体,调用行为由编译器决定多次使用宏会导致最终可执行程序的体积增大函数是跳转执行的,内存中只有一份函数体存在宏的效率比函数高,因为宏是世界展开,无调用开销函数调用时...原创 2020-01-06 22:03:50 · 509 阅读 · 1 评论 -
【C语言进阶剖析】45、C语言中的可变参数
文章目录1 可变参数2 实例分析3 小结我们都用过 printf() 函数,函数的参数个数是不确定的,第一个参数一定是字符串。这种可变参数是如何实现的呢,我们今天就来学习下。1 可变参数首先,要实现可变参数必须依赖于头文件 stdarg.h。其次,实现函数可变参数需要使用以下几个标示符:va_list:参数集合va_arg:取具体参数值va_start:标识参数访问的开始va_e...原创 2020-01-05 20:08:41 · 362 阅读 · 0 评论 -
【C语言进阶剖析】44、函数参数的求值顺序与程序中的顺序点
1 函数的参数函数参数在本质上与局部变量相同在栈上分配空间函数参数的初始值是函数调用时的实参值如下图所示,函数调用时,函数参数就被压入栈中,函数返回时,栈中数据弹出。函数参数的求值顺序依赖于编译器的实现下面看一个实例分析,看一下函数参数的求值顺序到底是怎样的。// 44-1.c#include<stdio.h>int func(int i, int j){...原创 2020-01-05 11:36:26 · 2113 阅读 · 0 评论 -
【C语言进阶剖析】43、函数的声明和定义
1 声明和定义声明的意思在于告诉编译器程序单元的存在,定义则明确指示程序单元的意义C 语言中通过 extern 进行程序单元的声明一些程序单元在声明时可以省略 extern注意:在 C 语言中,当有多个源文件的时候,编译器编译文件的顺序是不确定的。所以不能编写依赖于编译顺序的代码。2 实例分析// 43-1.c#include<stdio.h>#include&...原创 2020-01-02 20:04:26 · 467 阅读 · 0 评论 -
【C语言进阶剖析】42、内存操作的经典问题分析(二)
1 常见内存错误结构体成员指针未初始化结构体成员指针未分配足够的内存内存分配成功,但未初始化内存操作越界我们记得定义一个指针的时候要初始化,却容易忘记定义结构体变量时初始化指针成员。指针未分配足够的内存会导致越界操作的问题。内存分配成功,但未初始化,这个可能回造成字符串方面的错误。内存操作越界可能会操作不因该操作的内存,比如字符串没有结尾的 ‘\0’,复制的时候没有发现结尾的 ‘\0...原创 2019-12-30 21:14:23 · 402 阅读 · 0 评论 -
【C语言进阶剖析】41、内存操作的经典问题分析(一)
文章目录1 野指针1.1 认识野指针1.2 野指针的由来1 野指针1.1 认识野指针指针变量中的值是非法的内存地址,进而形成野指针野指针不是 NULL 指针,是指向不可用内存地址的指针NULL 指针并无危害,很好判断,也很好调试C 语言中无法判断一个指针所保存的地址是否合法1.2 野指针的由来局部指针变量没有初始化:局部变量没有初始化就是随机值,局部指针没有初始化就随机赋值...原创 2019-12-29 16:26:44 · 487 阅读 · 0 评论 -
【C语言进阶剖析】40、程序的内存布局
写完的 .c 文件是源文件。也叫源代码。将源代码编译后,会生成可执行文件程序(Linux下是.out,windows下是.exe)。这个文件就是程序。也叫作可执行代码。源代码与可执行文件的对应如下,也就是程序文件的布局:可以看到,程序被编译器编译过后:初始化的全变量和静态局部变量在 .data 段,未初始化的全局变量和静态局部变量在 .bss 段,函数等代码在 .text 段。局部非...原创 2019-12-28 21:41:32 · 486 阅读 · 0 评论 -
【C语言进阶剖析】39、栈、堆和静态存储区
文章目录1 程序中的栈1 程序中的栈原创 2019-12-27 11:13:04 · 655 阅读 · 0 评论 -
【C语言进阶剖析】38、动态内存分配
文章目录1 动态内存分配的意义2 malloc 和 free2.1 malloc(0) 探究2.2 内存漏泄检测模块3 calloc 和 realloc1 动态内存分配的意义C 语言中的一切操作都是基于内存的变量和数组都是内存的别名内存分配由编译器在编译期间决定定义数组的时候必须指定数组的长度数组长度是在编译期就必须确定的可能除了在编译之前就确定数组的大小,还有别的需求:程...原创 2019-12-22 11:26:07 · 436 阅读 · 0 评论 -
【C语言进阶剖析】37、指针阅读技巧分析
文章目录1 笔试中的问题2 右左法则3 复杂指针阅读4 小结1 笔试中的问题2 右左法则3 复杂指针阅读4 小结原创 2019-12-19 23:23:07 · 450 阅读 · 0 评论 -
【C语言进阶剖析】36、函数与指针分析
文章目录1 函数类型2 函数指针3 回调函数1 函数类型C 语言中的函数有自己特定的类型函数的类型由返回值,参数类型和参数个数共同决定int add(int i, int j) 的类型为 int (int, int)C 语言中通过 typedef 为函数类型重命名typedef type name(parameter)例如:typedef int f(int, int...原创 2019-12-18 21:00:44 · 398 阅读 · 0 评论 -
【C语言进阶剖析】35、数组参数和指针参数分析
文章目录1 数组参数退化为指针1.1 退化的意义1.2 二维数组参数1.3 被忽略的知识点2 实例分析3 小结1 数组参数退化为指针我们知道 C 语言中的数组参数会退化为指针,可是为什么会退化为指针呢?1.1 退化的意义C 语言中只会以值拷贝的方式传递参数C 语言在诞生的时候是为了开发 Unix 操作系统,这样要求 C 语言的效率必须很高,在设计向函数传递数组时,有两个方案;将整...原创 2019-12-08 23:12:23 · 417 阅读 · 0 评论 -
【C语言进阶剖析】34、多维数组和多维指针
文章目录1 指向指针的指针1 指向指针的指针指针的本质是变量,会占用一定的内存空间可以定义指针的指针来保存指针变量的地址指针的指针没有什么了不起的,它还是一个指针,只不过这个指针所指向的内存空间的元素又是一个地址。可以这么理解,你的狗狗丢了,要去找狗狗,现在你有一个门牌号,你拿着这个门牌号去找对应的房子,到了对应的屋子以后,没找到狗狗,找到的还是一个门牌号,然后你拿着这个新找到的门牌号...原创 2019-12-08 18:59:40 · 404 阅读 · 0 评论 -
【C语言进阶剖析】33、main 函数与命令行参数
文章目录1 main 函数的概念main 函数的本质1 main 函数的概念C 语言中 main 函数成为主函数一个 C 程序是从 main 函数开始执行main 函数的本质main 函数是操作系统调用的函数操作系统总是将 main 函数作为应用程序的开始操作系统将 main 函数的返回值作为程序的退出状态思考:为什么 C 编译器支持这么多不同的 main 函数类型?...原创 2019-12-06 16:56:48 · 578 阅读 · 0 评论 -
【C语言进阶剖析】32、数组指针和指针数组
文章目录1 数组类型在开始之前我们先提出一个问题?下面的声明合法吗?1 数组类型C 语言中的数组有自己特定的类型数组的类型由元素类型和数组大小共同决定例如:int array[5] 的类型为 int[5]我们经常会碰见这样的情景:问:这定义的数组是什么类型的?答:int 型。。。这样的回答就是概念不清晰了,数组的类型包括元素类型和数组大小,回答int 型只回答了元素类型,正确...原创 2019-12-05 20:47:20 · 398 阅读 · 0 评论 -
【C语言进阶剖析】25、# 和 ## 操作符使用分析
文章目录1 #运算符2 # 运算符的妙用3 \## 运算符1 #运算符# 运算符用于在预处理期将宏参数转换为字符串# 的转换作用是在预处理期完成的,因此只在宏定义中有效编译器不知道 # 的转换作用用法如下:看段简单的代码,对 # 运算符有个直观的了解,了解 # 运算符的基本用法// 25-1.c#include<stdio.h>#define STRING(x)...原创 2019-11-27 17:25:01 · 822 阅读 · 0 评论 -
【C语言进阶剖析】31、字符串典型问题分析
文章目录1 snprintf 函数2 strlen 和 sizeof3 比较两字符串相等4这一篇博客我们分析四个典型的字符串问题。1 snprintf 函数下面的代码会输出什么?函数 snprintf 的功能和 printf 类似,只不过 printf 是将输出到终端,snprintf 是输出到第一个参数中。这里就是输出到 buf 中。这里就是将字符串 src 复制到 buf 中,再将...原创 2019-12-04 00:26:12 · 459 阅读 · 0 评论 -
【C语言进阶剖析】30、C语言中的字符串
文章目录1 字符串的概念1.1 字符数组与字符串1.2 小秘密2 字符串字面量3 字符串的长度4 小结1 字符串的概念字符串是有序字符的集合字符串是程序的基本元素之一C 语言中没有字符串的概念C 语言中通过特殊的字符数组模拟字符串C 语言中的字符串是以 ‘\0’ 结尾的字符数组1.1 字符数组与字符串在 C 语言中,双引号引用的单个或多个字符是一种特殊的字面量存储于程...原创 2019-12-02 23:16:20 · 526 阅读 · 0 评论 -
【C语言进阶剖析】29、指针和数组分析(下)
文章目录11原创 2019-12-01 17:44:12 · 420 阅读 · 0 评论 -
【C语言进阶剖析】28、指针和数组分析(上)
文章目录1 数组的本质2 指针的运算3 指针的比较4 小节1 数组的本质数组是一段连续的内存空间数组的空间大小为sizeof(array_type) * array_size数组名可看作指向数组第一个元素的常量指针现在有两个问题:a + 1 的意义是什么?结果是什么?指针运算的意义是什么?结果又是什么?下面我们实际用编译器实现一下,看下 a + 1 的结果是什么?// 2...原创 2019-11-30 10:09:43 · 382 阅读 · 0 评论 -
【C语言进阶剖析】27、数组的本质分析
1 数组的概念数组是相同类型的变量的有序集合数组的大小数组在一片连续的内存空间中存储元素数组元素的个数可以显示或隐式指定如下定义两个数组 a 和 b有两个问题?a[2],a[3],a[4] 的值是多少?b 包含了多少个元素?下面我们就来实际操作一下:// 27-1.c#include<stdio.h>int main(){ int a[...原创 2019-11-29 20:53:09 · 440 阅读 · 0 评论 -
【C语言进阶剖析】26、指针的本质分析
文章目录1 *号的意义2 传值调用与传址调用3 常量与指针4 小结在本系列第一篇博客中讲到变量的本质是一段存储空间的别名,那么是不是必须通过我们先看一个问题?下面的程序输出什么,为什么?我们来实际编译运行一下:#include<stdio.h>int main(){ int i = 5; int* p = &i; printf("%d, ...原创 2019-11-27 23:46:16 · 432 阅读 · 0 评论 -
【C语言进阶剖析】24、#pragma 使用分析
今天学习一个非常的预处理指示字 #pragma,在实际工程开发中这个预处理指示字用的非常多,我们以前却接触的非常少,为什么呢,因为 #pragma 是 C 语言留给编译器生产厂商对 C 语言进行扩展了一个特殊的预处理指示字。这也就导致了一个问题,#pragma 在不同的编译器之间可能是语法移植的,这里我们学习几个常用的功能。1 #pragma 简介#pragma 用于指示编译器完成一些特定...原创 2019-11-25 21:42:03 · 3926 阅读 · 0 评论 -
#pragma once 和 #ifndef 的区别
功能:#pragma once 和 #ifdef 都可以避免同一个文件被 include 多次。1 #pragma once方式#pragma once 是编译器相关,移植型差,有些编译器支持,有些编译器不支持,比如:gcc,vs 编译器支持,bcc 编译器不支持。由编译器提供保证,同一个文件不会被包含多次。这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。不用像使用 ...原创 2019-11-25 10:32:31 · 2937 阅读 · 0 评论 -
【C语言进阶剖析】23、#error 和 #line 使用分析
1 #error 的用法#error 用于生成一个编译错误消息用法如下:#error 编译指示字用于滴定仪程序员特有的编译错误消息,类似的,#warning 用于生成编译警告...原创 2019-11-21 23:16:45 · 1029 阅读 · 0 评论 -
【C语言进阶剖析】22、条件编译使用分析
1 基本概念条件编译的行为类似于 C 语言中的 if…else…条件编译是预编译指示命令,用于控制是否编译某段代码先来看段代码,对条件编译有个直观的概念// 22-1.c#include<stdio.h>#define C 1int main(){ const char* s; #if (C == 1) s = "This is fi...原创 2019-11-20 16:21:55 · 524 阅读 · 0 评论 -
【C语言进阶剖析】21、宏定义与使用分析
C 语言中的宏定义#define 是预处理器处理的单元实体之一#define 定义的宏可以出现在程序的任意位置#define 定义之后的代码都可以使用这个宏定义宏常量#define 定义的宏常量可以直接使用#define 定义的宏常量本质为字面量看一下下面定义的宏正确吗?宏定义不占内存空间,因为宏在预处理阶段就会被替换掉,到了编译的阶段是没有宏存在的,它自然到不了可执行文...原创 2019-11-18 21:47:48 · 1003 阅读 · 0 评论 -
【C语言进阶剖析】20、链接过程简介
问题原创 2019-11-09 21:34:17 · 397 阅读 · 0 评论 -
【C语言进阶剖析】19、编译过程简介
1 隐藏的事实编译器是由几部分组成的,包括预处理器,编译器,汇编器,链接器。我们写的代码经过预处理器,变成 .i 文件,再经过编译器处理,变成 .s 文件,再经汇编器,生成 .o 文件,最后经链接器,变成可执行文件。预处理器,编译器,汇编器,链接器都做了什么呢,我们接着看2 预编译处理所有的注释,以空格代替将所有的 #define 删除,并且展开所有的宏定义处理条件编译指令 #...原创 2019-11-09 11:53:58 · 416 阅读 · 0 评论 -
【C语言进阶剖析】18、三目运算符和逗号表达式
1 三目运算符三目运算符 (a ? b : c) 可以作为逻辑运算的载体规则:当 a 的值为真时,返回 b 的值,否则返回 c 的值下面看一下例子,初识三目运算符?// 18-2.c#include<stdio.h>void hello(){ printf("Hello!\n");}int main(){ int a[3][3] = { ...原创 2019-11-09 00:00:36 · 1151 阅读 · 0 评论 -
【C语言进阶剖析】17、++ 和 --操作符分析
1 ++ 和 – 操作符的本质++ 和 – 操作符对应两条汇编指令如下:前置:先对变量自增(减)1,再取变量值后置:先取变量值,再对变量值自增(减)1,取的是临时变量的值下面看一个令人头疼的问题:int i = 0;(i++) + (i++) + (i++);(++i) + (++i) + (++i);...原创 2019-11-08 10:53:06 · 881 阅读 · 1 评论 -
【C语言进阶剖析】16、位运算符分析
C 语言中的位运算符直接对 bit 位进行操作,其效率最高位运算符含义&按位与|按位或^按位异或~取反<<左移>>右移1 位运算符分析...原创 2019-11-06 20:29:42 · 464 阅读 · 0 评论 -
【C语言进阶剖析】15、逻辑运算符分析
一提到逻辑运算符,第一印象就是经常用在条件判断中,挺简单的。其实逻辑运算符确实在条件判断中用的比较多,但是真的很简单吗?下面来看一个例子1 初探逻辑运算符逻辑运算符有 &&,|| 和 !,他们真的很简单吗,下面看一个例子?// 15-1.c#include<stdio.h>int main(){ int i = 0; int j = 0; ...原创 2019-11-06 20:29:31 · 416 阅读 · 0 评论 -
【C语言进阶剖析】14、单引号和双引号
C 语言中的单引号用来表示字符字面量C 语言中的双引号用来表示字符串字面量举例说明:‘a’ 表示字符自变量,在内存中占 1 字节,‘a’ + 1 表示 ‘a’ 的 ASCII 码加 1,结果为 ‘b’“a” 表示字符串字面量,在内存中占 2 个字节,“a”+1 表示指针运算,结果指向 “a” 结束符 ‘\0’1 实验一:单引号和双引号的本质//14-1.c#include<...原创 2019-11-02 19:16:13 · 750 阅读 · 0 评论 -
【C语言进阶剖析】13、接续符和转义符
1 接续符1.1 接续符的意义C 语言中的接续符(\)是指示编译器行为的利器下面通过一个例子感受一下接续符//13-1.c#in\clud\e<st\dio.h>in\t m\ain(\){pri\ntf\ (\ "Helo world!\n" )\ ;ret\urn 0;}上面的代码是合法的代码吗?我们编译一下...原创 2019-11-02 00:33:58 · 514 阅读 · 0 评论 -
【C语言进阶剖析】12、注释符号
1 注释的第一印象一提起注释,第一印象总觉得注释没有必要深究,注释太简单了,对程序也没什么影响,其实注释是 C 语言的重要工具。下面看一下下面的注释正确吗?//12-1.c#include<stdio.h>int main(){ int/*...*/i; char* s = "abcdefg //ijkmn"; // Is it a\ ...原创 2019-11-01 20:06:28 · 542 阅读 · 0 评论 -
【C语言进阶剖析】11、enum,sizeof 和 typedef 分析
1 枚举类型的使用方法enum 是 C 语言中的一种自定义类型enum 值是可以根据需要自定义的整数值默认情况下第一个定义的 enum 值为 0,其他的值是在前一个值的基础上加 1enum 类型的变量只能取定义时的离散值枚举类型的特殊意义:enum 中定义的值是 C 语言中真正意义上的常量,在工程中 enum 多用于定义整型常量,其值不能再修改。下面通过一个例子来说明 enum...原创 2019-10-31 00:20:36 · 449 阅读 · 0 评论