目录
一、程序的运行过程
二、每个步骤的任务
三、预处理详解
一、程序的运行过程

二、每个步骤的任务
预处理
头文件的展开
条件编译
#define定义的符号的替换
删除注释
编译
把C语言代码转化成汇编代码
1.语法分析
2.词法分析
3.语义分析
4.符号汇总
汇编
把汇编代码转化成二进制指令(机器指令)
形成符号表
链接
合并段表
符号表的合并和重定位
三、预处理详解
预定义符号
__FILE__ //进行编译的源文件
__LINE__ //文件当前的行号
__DATE__ //文件被编译的日期
__TIME__ //文件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义(VS不支持)

#define
定义标识符

定义宏
宏的本质是替换

选择第一种宏是更保险的,第二种和第三种都可能会得不到预期的结果
#define替换规则
在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先 被替换
替换文本,随后**入到程序中原来文本的位置。对于宏,参数名被他们的值替换
最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程
注意:
宏不能递归,可以作参数,如:ADD(ADD(2,3),8)
当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索
如下图,双引号内的MAX不会被搜索

#和

# 把一个宏参数变成对应的字符串
如下图,"#n" 如果参数是a就会转化成 "a"

可以把位于它两边的符号合成一个符号
它允许宏定义从分离的文本片段创建标识符

注意:连接必须产生一个合法的标识符。否则其结果就是未定义的
带副作用的宏参数

注意:宏的参数是不计算直接替换的

注意:函数的参数是计算后再传参的
宏和函数对比
优势:
宏比函数在程序的规模和速度方面更胜一筹

宏是类型无关的
劣势:
每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度
宏是没法调试的
宏由于类型无关,也就不够严谨
宏可能会带来运算符优先级的问题,导致程序容易出现错误
宏参数可以传类型

命名约定
把宏名全部大写
函数名不要全部大写
#undef
用于移除一个宏定义


条件编译
#if 常量表达式
//...#
endif
//常量表达式由预处理器求值


多个分支的条件编译
#if 常量表达式
//...
#elif 常量表达式
//...
#else
//...
#endif

判断是否被定义
判断符号是否定义了
#if defined(symbol)
#ifdef symbol


判断符号是否没定义
#if !defined(symbol)
#ifndef symbol


嵌套指令
#if defined(OS_UNIX)
#ifdef OPTION1
unix_version_option1();
#endif
#ifdef OPTION2
unix_version_option2();
#endif
#elif defined(OS_MSDOS)
#ifdef OPTION2
msdos_version_option2();
#endif
#endif
头文件被包含
" " 自定义函数文件的被包含
先在源文件所在目录下查找,如果该头文件未找到,编译器就像查找库函数头文件一样在标准路径查找头文件
< >库函数文件的被包含
查找头文件直接去标准路径下去查找,如果找不到就提示编译错误
库文件也能用""包含,但查找效率会低些,也不容易区分库函数文件和自定义函数文件
防止头文件被多次包含
法一:
#ifndef __TEST_H__
#define __TEST_H__
//头文件的内容
#endif
法二:
#pragma once

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/122899.html