C语言---条件编译、文件包含、.h头文件书写

条件编译

如果我们在代码编写过程中,有一段代码弃之可惜,保留无用你会如何做呢?是直接删除还是大面积注释?当学习了解条件编译以后,就可以条件编译来“装b”的注释掉了。那么,让我们来看看什么是条件编译!

条件编译,顾名思义,就是有条件的进行编译。举个例子:

#include 
#define DEBUG

int main()
{
	int i = 0;
	int arr[10] = { 0 };
	for (i = 0; i < 10; i++)
	{
		arr[i] = i;

#ifdef DEBUG         //如果定义了 DEBUG 就编译下面的代码
		
		printf("%d\n", arr[i]);//为了观察数组是否赋值成功。 

#endif   //结束条件编译
	}
	return 0;
}

在上面的代码中,我们使用printf函数只是为了调试观察数组是否赋值成功,但是对整个程序的功能是多余的。此时我们就可以使用条件编译,当满足条件时编译该条语句,不满足条件时则不编译该条语句。

#ifdef DEBUG的意思就是如果定义了 DEBUG 就编译下面的代码。那么这个条件何时结束呢?就是直到遇到了#endif 就结束条件编译。

常见的条件编译指令:

1.比较直接简单的条件编译:

1.最简单的条件编译:
#if (常量表达式)
 //...
#endif
//常量表达式由预处理器求值。
如:
#define __DEBUG__ 1
#if __DEBUG__
 //..
#endif

注意:这里#if后面应该是常量表达式。
使用举例:

int main()
{
	//3==5为假,所以不打印”哈哈“
#if 3==5
	printf("哈哈\n");
#endif

	//3是真,所以打印”呵呵“
#if 3
	printf("呵呵\n");
#endif
	return 0;
}

2.多个分支的条件编译:

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

使用举例:

int main()
{
	//3==5为假,所以不打印”哈哈“
#if 3==5
	printf("哈哈\n");

	//5>2是真,所以打印”嘿嘿“
#elif 5>2
	printf("嘿嘿\n");
    
    //上一个elif是真,所以这里不打印“呵呵”
#else 
	printf("呵呵\n");
#endif
	return 0;
}

可以看到,多个分支的条件编译#if … #elif … #else …的使用和if-else语句是很相似的。


3.根据是否被定义来判断:

3.判断是否被定义:
//如果定义了则编译的两种写法:
#if defined(symbol)
#ifdef symbol

//如果没定义则编译的两种写法:
#if !defined(symbol)
#ifndef symbol

使用举例

#define DEBUG 100
int main()
{

#ifdef DEBUG    //如果定义了 DEBUG 就编译下面的代码
		printf("定义了DEBUG\n"); 
#endif   //结束条件编译

#ifndef TEST   //如果没定义TEST,就编译下面的代码
		printf("没定义TEST\n");
#endif   //结束条件编译
	
	return 0;
}

4.嵌套指令:

4.嵌套指令:
#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

目前作为初学者,我们可能用不到这些东西,但是了解了可以让我们能够阅读别人的代码。在以后编写复杂程序代码的时候,条件编译将会满足很多需求!


文件包含

我们已经知道, #include 指令可以使另外一个文件被编译。就像它实际出现于 #include 指令的地方一样。 这种替换的方式很简单: 预处理器先删除这条指令,并用包含文件的内容替换。 这样一个源文件被包含10次,那就实际被编译10次。

头文件被包含的方式

1.本地头文件的包含

#include "filename.h"

如果是我们自己创建的.h头文件需要被包含,就使用"“来包含。
使用”"包含时,当系统编译的时候,会先去我们项目的文件夹中寻找该头文件,如果找不到,就去库文件的目录下寻找。如果还找不到就报错。


2.库函数文件的包含

#include 

我们要包含库函数所在的头文件,需要用<>来包含。
使用<>包含时,当系统编译的时候,直接就去库文件目录寻找头文件了。

因此,对于库函数头文件,两种方式均可。但是还是用<>更好,寻找的效率更高。
对于本地头文件,就只能用""包含!


嵌套文件包含 (.h文件该怎么写)

我们知道,包含头文件在编译时会将该头文件中的东西完整复制一遍。如果我们的程序多次调用同一个头文件,那么调用时也会多次调用,使得编译代码十分冗余,那么我们该如何防止这种情况呢?

1. #pragma once
在头文件开头加上这个预处理指令,它表示该头文件只会被引用一次,即使在多个文件中被包含。

2.条件编译
我们介绍了条件编译,那么如何利用条件编译来达到头文件只被包含一次的目的呢?

#ifndef __TEST_H__
#define __TEST_H__

//头文件的内容

#endif   

在头文件中加入上述预处理指令,将头文件中的内容写在中间。
这是什么逻辑呢?

因为#ifndef __TEST_H__表示如果没有定义__TEST_H__这个东西才会执行下面的代码,当第一次包含该头文件时,TEST_H__确实没有被定义,于是执行该头文件中的所有代码。但是第一次执行后,因为下一句就是定义#define TEST_H,所以第一次执行该头文件中的代码后,下一次再用#ifndef判断时,因为第一次包含头文件时已经定义了__TEST_H,那么下面的代码就不会再执行了。

由此达到了只包含一次头文件的目的!

你可能感兴趣的:(C语言学习笔记,c语言)