C++报错无效的预处理命令include_预处理

6063fd21b3d0c23b043b1586a9bd2f36.png

宏定义

作用:文本替换 提高代码的可读性
 //示例 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("%dn",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("%dn",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__:%sn", __FILE__);  //该.c文件路径
     printf("__DATE__:%sn", __DATE__);  //编译日期
     printf("__TIME__:%sn", __TIME__);  //编译时间
     printf("__LINE__:%dn", __LINE__);  //当前源代码行号
     return 0;
 }

输出结果:

__FILE__:D:testtest.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:%dn",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:%dn",sizeof(TEST));
    return 0;
}

由于设置了对齐单位,所以输出结果为:size:12

  • 添加库 #pragma comment(lib,"winmm.lib")

预处理​mp.weixin.qq.com
3d4d78c052b9f8346408dd621532e792.png

C语言从入门到精通:

C语言集合​mp.weixin.qq.com