【C语言】程序环境和预处理

目录

程序的编译和链接

预处理详解 

预定义符号

 #define

VS2019查看预编译文件

1.#define定义的标识符常量

 2.#define定义宏

宏的副作用

 宏和函数的比较

宏的参数可以出现类型

#和##

命名约定

#undef

条件编译指令

满足条件进行编译 不满足则不编译

判断是否被定义

头文件包含

 本地文件包含

库文件包含

嵌套文件编译


程序的编译和链接

请大家直接看图:

预处理详解 

预定义符号

_FILE_      -进行编译的源文件

_LINE_      -文件当前的行号

_DATE_     -文件被编译的日期

_TIME_      -文件被编译的时间

_STDC_     -如果编译器遵循ANSI C,其值为1,否则未定义

 VS2019不支持ANSIC

 #define

VS2019查看预编译文件

1.#define定义的标识符常量

那么定义时末尾需要加上分号吗?

答案是不加,容易出错。

  

 2.#define定义宏

申明方式:

#define name(parament - list)  stuff

//#define定义宏
#define BIG(x,y) ((x)>(y)?(x):(y)) 
int main()
{
	printf("%d\n", BIG(7, 9));
	return 0;
}

 例:如下程序运行的结果是什么??

#define MUL(x,y) (x*y)
int main()
{
	printf("%d\n", MUL(4 + 2, 5));
	return 0;
}

答案是 :14

因为宏只是进行机械的替换

宏的副作用

#include<stdio.h>
#define MAX(a, b) ( (a) > (b) ? (a) : (b) )

int main()
{
	int x = 5;
	int y = 8;
	int z = MAX(x++, y++);
	printf("x=%d y=%d z=%d\n", x, y, z);
	return 0;
}

 宏和函数的比较

1.宏比函数的运算速度要快一些,因为函数调用和返回也需要一些时间。

2.宏与类型无关

宏的参数可以出现类型

#define SPACE(type,num) (type*)malloc(num*sizeof(type))
int main()
{
	int* arr = SPACE(int, 7);
	if (arr == NULL)
	{
		perror("malloc");
		return;
	}

	int i = 0;
	for (i = 0; i < 7; i++)
	{
		arr[i] = i;
		printf("%d ", arr[i]);
	}

	free(arr);
	arr = NULL;

	return 0;
}

#和##

1.#

2.## 

##可以把位于两边的符号合并成一个符号,合成后的符号必须是合法的标识符,否则其结果就是未定义的。

#define LINK(a,b) a##b
int main()
{
	int cl999 = 957;
	printf("%d", LINK(cl, 999));
	return 0;
}

命名约定

1.函数名 不全部大写

2.宏名全部大写

#undef

作用:移除一个宏定义

条件编译指令

满足条件进行编译 不满足则不编译

int main()
{
#if 1 //跟一个常量表达式 也可以是 1+2 0  ...
	printf("hehe\n");//表达式为真打印 为假不打印
#endif
	return 0;
}

//#define NUM 9
#define NUM 10
int main()
{

#if NUM == 9
	printf("HaHa\n");
#elif NUM == 7
	printf("HeHe\n");
#else
	printf("无语\n");
#endif
	return 0;
}

这个是不是和if..else语句很像呢?

判断是否被定义

#define MAX 100
#define NUM 0
int main()
{
#if defined MAX  
	printf("Yes\n");
#endif

#ifdef NUM   //这两个判断方法是一样的 且只关心是否被定义 与内容无关
	printf("Yes\n");
#endif
	return 0;
}

//#define MAX 100
//#define NUM 0
int main()
{
#if !defined MAX
	printf("No\n");
#endif

#ifndef NUM
	printf("No\n");
#endif 

	return 0;
}

嵌套指令 

嵌套指令
#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"filename.h"

查找策略:会优先在源目录文件下查找,如果查找不到则编译器像查找库函数头文件一样在标准位置下查找该头文件,如果查找不到则报错

库文件包含

#include<filename.h>

查找策略:仅在标准位置下查找该头文件,如果找不到就提示编译错误 

也可以用" ... "来引头文件,现在源文件目录底下查找,再到标准位置下查找,不过这样效率会变低,不建议。 

嵌套文件编译

假如一个文件中出现重复头文件的引用,这样就造成了内容的重复,那么如何解决呢?

 

#ifndef _BUG_
#define _BUG_ 1 //如果没有定义就定义_BUG_ 如果定义了就不进入 以此来保证内容不重复
int Add(int x, int y);
#endif

 

 

 

 

 OK,至此,我将放弃C语言,投入Java的怀抱!!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值