预处理
作用:文本替换 提高代码的可读性
1//示例 1
2#define PI 3.1415926
没有参数类型 也没有返回值类型 可以接受任意类型的参数 本质是替换 没有任何检查
1//示例 2
2#define ADD(A,B) A+B
在示例 2 中需要考虑优先级问题
1#include<stdio.h>
2#define ADD(A,B) A+B
3int main()
4{
5 printf("%d\n",2*ADD(2,-3)); //输出结果为1
6 return 0;
7}
带参宏定义的时候加()
1//示例 3
2#define ADD(A,B) (A)+(B)
在某些特定的情况下加()也会出错
1//示例 4
2//c++面试题:#define MIN(A,B) ( (A) <= (B) ? (A) : (B) )
3#include<stdio.h>
4#define MIN(A,B) ((A)<=(B)?(A):(B))
5int main()
6{
7 int a=1,b=2;
8 int *p=&a;
9 printf("%d\n",MIN(*p++,b)); //结果是一个随机值
10 return 0;
11}
解释一下:
1MIN(*p++,b) = ((*p++)<(b))?(*p++):(b)
2这个表达式会产生副作用,指针p会作二次++自增操作
3开始p指向a,后来就不知道指向的是那个地址
需要注意的几点:
编译器内置的宏定义
1__LINE__ // 在源代码中插入当前源代码行号
2__FILE__ // 在源文件中插入当前源文件名
3__DATE__ // 在源文件中插入当前的编译日期
4__TIME__ // 在源文件中插入当前编译时间
这些宏定义不仅可以帮助我们完成跨平台的源码编写,灵活使用也可以巧妙地帮我们输出非常有用的调试信息
1//示例5
2#include <stdio.h>
3int main()
4{
5 printf("__FILE__:%s\n", __FILE__); //该.c文件路径
6 printf("__DATE__:%s\n", __DATE__); //编译日期
7 printf("__TIME__:%s\n", __TIME__); //编译时间
8 printf("__LINE__:%d\n", __LINE__); //当前源代码行号
9 return 0;
10}
输出结果:
1__FILE__:D:\test\test.c
2__DATE__:Dec 22 2019
3__TIME__:00:37:15
4__LINE__:7
5Press any key to continue
使用库函数之前,应该用
#include
引入对应的头文件。这种以#
号开头的命令称为预处理命令。 #include<> #include" "
区别:
先去系统目录中去找头文件 找不到 报错
先去项目文件夹找头文件 找不到 在去系统目录找 都找不到 报错
使用注意:
系统头文件stdio.h用<>更快
自己编写的头文件用" "
条件编译指令 | 说 明 |
---|---|
#if | 如果条件为真,则执行相应操作 |
#elif | 如果前面条件为假,而该条件为真,则执行相应操作 |
#else | 如果前面条件均为假,则执行相应操作 |
#endif | 结束相应的条件编译指令 |
#ifdef | 如果该宏已定义,则执行相应操作 |
#ifndef | 如果该宏没有定义,则执行相应操作 |
#if 条件表达式1 程序段 1 #elif 条件表达式2 程序段 2 #else 程序段3 #endif
写注释的时候可以这样注释,当条件为0时代码段不编译
1#if 0
2 //代码段
3#endif
#ifndef 标识符 #define 标识符 //… #endif 作用:防止头文件重复包含
多文件编程
1//test.h 文件
2#pragma once //这个头文件只包含一次
3#ifndef _TEST_H_ //防止头文件重复包含
4#define _TEST_H_
5
6//类型定义 函数声明 宏定义 ....
7#include<stdio.h>
8#define N 10
9struct student //结构体定义
10{
11 int data;
12};
13void fun(); //函数声明
14
15#endif
同名.c文件
1//test.c
2#include"test.h" //包含同名.h
3//函数定义.... 放同名.c文件当中
4void fun()
5{
6 //如果要在这个里面使用其他函数 头文件放summer.h
7 printf("hello world!\n");
8}
在多文件编程,.h文件开头加上这段代码防止头文件重复包含
1#pragma once
用n个字节作为对齐单位 n是2的x次方 1 2 4 8 16
1//示例 6
2#include<stdio.h>
3typedef struct test
4{
5 double x;
6 float y;
7}TEST;
8int main()
9{
10 printf("size:%d\n",sizeof(TEST));
11 return 0;
12}
根据对齐规则,输出结果为:size:16
1//示例 7
2#include<stdio.h>
3#pragma pack(4) //设置结构体对齐单位为4
4typedef struct test
5{
6 double x;
7 float y;
8}TEST;
9int main()
10{
11 printf("size:%d\n",sizeof(TEST));
12 return 0;
13}
由于设置了对齐单位,所以输出结果为:size:12