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