当前位置:网站首页>标准C语言学习总结11
标准C语言学习总结11
2022-08-03 19:06:00 【c7473168】
一,预处理指令
程序员所编写的代码不是真正的标准C代码,需要一段程序翻译成标准C代码,
才能被编译器编译
翻译的过程叫做预处理,负责翻译的程序叫做预处理器,
被翻译的语句叫做预处理指令,以#开头的都是预处理指令
gcc -E code.c 直接显示预处理后的结果
gcc -E code.c -o code.i 生成预处理文件
二,预处理指令的分类
#include 导入头文件/头文件包含
#include <> 直接从系统指定路径查找头文件并导入头文件
#include "" 先从当前的工作路径查找,找不到再从系统指定路径查找并导入头文件
gcc code.c -I path
编译时指定头文件的加载路径为path,最先从该路径查找
可以通过设置环境变量来修改,增加系统指定头文件加载路径
修改~/.bashrc 终端配置文件
#define 定义宏
宏常量:#define 宏名 常量值
#define MAX 100
其实本质上就是,在代码中出现宏名的地方在预处理时替换为
对应的常量值
优点:提高代码可扩展性,提高了可读性,提高了安全性,还可以用在case后面
注意:一般宏名全部大写,末尾不要加分号
局部变量,函数名全部小写,全局变量首字母大写,数组arr,指针p
二级指针pp 字符串str
预定义好的宏:
__func__ 获取函数名
__FILE__ 获取文件名
__DATE__ 获取当前日期
__TIME__ 获取当前时间
__LINE__ 获取当前行数 上面都是字符串这个是%d
宏函数:其实就是带参数的宏
#define 宏名(参数名) 替换的内容,代码
宏函数不是真正的函数,不检查参数类型,没有传参,
只有表达式的计算结果没有返回值
#define SUM(a,b) a+b
替换过程:
1,先把代码中使用到宏函数的地方替换为宏函数后面的代码 a+b
2,再把宏函数代码中使用到的参数替换为调用者提供的数据 num1+num2
注意:宏函数后面的替换代码不能直接换行,需要使用每一行的末尾
通过续行符\来换行
如果有多行代码,可以使用大括号保护代码
宏的二义性:
由于宏代码所处位置,参数位置,优先级问题,
导致同一个还能干啥有不同的可解释的结果
如何避免宏的二义性:
1,给每个参数加小括号,给整个式子加小括号
2,在使用宏函数时,不要提供带自变运算符的参数
注意:容易出选择题
"常考的笔试面试题:
#define 与 typedef 的区别?
#define INT int 宏定义
typedef int INT; 类型重定义
INT num;
如果是普通类型,它们功能上没有任何区别
#define INTP int*
typedef int* INTPP;
INTP p1,p2,p3; //p1是int* p2 p3 是int
INTPP p1,p2,p3; //p1,p2,p3都是int*
宏函数与普通函数的区别?
它们是什么?
宏函数:带参数的宏替换,只是代码替换,只是使用时像函数而已,
不是真正的函数
函数:是一段具有某项功能的代码集合,会被翻译成二进制指令存储代码段
函数名就是它的首地址,有独立的栈内存,命名空间
有什么不一样:
函数: 返回值 类型检查 安全 内存申请,释放 速度慢 函数跳转
宏函数: 运算结果 通用 危险 替换 速度快 代码冗余
注意:调用频繁,内容简单的功能适合写成宏函数
"
条件编译
根据条件决定哪些代码是否参与最终的编译
版本控制:
#if 条件
#elif 条件
#else
#endif
头文件卫士:
防止头文件被'重复'包含
#ifndef 宏名
#define 宏名
#endif/*宏名*/
宏名:头文件名全部大写,小数点用下划线_代替
注意:头文件中必加头文件卫士
调试,判断:
#ifdef 宏名(DEBUG)
如果宏名定义了,则此处代码参与编译
#else
否则,此处参与编译
#endif
gcc code.c -D宏名
可以在编译时定义宏
定义打印调试信息宏函数,是否打印提示信息,取决于是否定义了DEBUG宏
#ifdef DEBUG
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif
打印错误信息的宏函数
#define error(...) printf("%s:%s %d %s:%m %s %s\n",__FILE__,__func__,__LINE__,__VA_ARGS__,__DATE__,__TIME__)
三,头文件
头文件中应该写什么?
问题:头文件可能会被任意的源文件包含,意味着头文件中的内容会
在多个目标文件中同时存在,因此要满足合并内容不能有冲突
重点:头文件中只能编写声明语句,绝对不能有定义语句
函数声明
全局变量声明
宏常量
宏函数
typedef 类型重定义
结构,联合,枚举的类型声明
头文件的编写原则:
1,为每个.c文件编写一份.h文件,.h文件对.c文件的说明
2,如果需要用到某个.c文件中的全局变量,函数,宏等内容时,
只需要把它的头文件导入即可
3,.c文件也要导入它自己的.h文件,目的是为声明与定义一致
头文件的相互包含:
假设a.h包含了b.h, b.h又包含了a.h此时编译会出错
解决方案:把a.h需要导入b.h的内容和b.h需要导入a.h的内容提取出来
到另一个c.h
错误提示:位置类型名"xxxx",大概率就是头文件相互包含
边栏推荐
猜你喜欢
When does MySQL use table locks and when to use row locks?You should know this
MySQL【变量、流程控制与游标】
Shell编程案例
MD5是对称加密还是非对称加密,有什么优缺点
Solution for no navigation bar after Word is saved as PDF
要想成为黑客,离不开这十大基础知识
基于DMS的数仓智能运维服务,知多少?
【WPS-OFFICE-Word】 WPS中样式的运作原理?样式自动更新、自动改变如何处理?样式的管理方法?
[Notes] Introduction to machine learning
U-Net生物医学图像分割讲解(Convolutional Networks for BiomedicalImage Segmentation)
随机推荐
基于ck+redash构建MySQL慢日志+审计日志展示平台
使用安全浏览器将网页保存为pdf的方法步骤
【ORACLE】什么时候ROWNUM等于0和ROWNUM小于0,两个条件不等价?
力扣刷题之分数加减运算(每日一题7/27)
online 方式创建索引触发trigger怎么办?
ctfshow php features
选出表中的中位数记录[构造左右边界 || 问题转换]
MVC vs MVP
Postgresql-xl global snapshot and GTM code walking (branch line)
MySQL 啥时候用表锁,啥时候用行锁?这些你都应该知道吧
APT级全面免杀与企业纵深防御体系的红蓝对抗
力扣刷题之有效的正方形(每日一题7/29)
【WPS-OFFICE-Word】 WPS中样式的运作原理?样式自动更新、自动改变如何处理?样式的管理方法?
LeetCode 952. 按公因数计算最大组件大小
SQL server 实现触发器备份表数据
图像超分——Real-ESRGAN快速上手
MYSQL误删数据恢复
Web项目中简单使用线程池
Alibaba senior experts create a learning architecture from scratch, including Alibaba's internal technology stack PPT, PFD actual combat
【HCIP】MPLS实验