C语言基础(十)----预处理



来源:微信公众号「编程学习基地」

宏定义

作用:文本替换 提高代码的可读性

//示例 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”)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeRoy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值