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

1、翻译环境

在代码执行前,会将源文件转化为可执行的机器指令

2、预处理详解

2.1 预定义符号

预定义符号是语言内置的符号可以直接使用

__FILE__ //进行编译的源文件
__LINE__ //文件的当前行
__DATE__ //文件被编译的日期
__TIME__ //文件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义

一般在写日志的时候会用到

2.2 #define

2.2.1 #和##

#:把一个宏参数变成对应的字符串

#include <stdio.h>
#define PRINT(n) printf("the value of "#n" is %d\n",n )
int main()
{
	int a = 10;
	PRINT(a);
	int b = 20;
	PRINT(b);
	return 0;
}

##: 把位于它两端的符号合成一个符号

#include <stdio.h>
#define CAT(s,num) s##num
int main()
{
	int sum5 = 2;
	int b = CAT(sum, 5);//sum5
	printf("%d", b);
	return 0;
}

 2.2.2 宏与函数

1、代码长度

宏:每次使用时,宏代码都会被插入到程序中。除了非常小的宏之外,程序的长度会大幅度增长

函数:函数的代码只出现与一个地方;每次使用这个函数时调用的是同一份代码

2.执行速度:

宏:更快

函数:函数的调用和返回需要额外开销,相对来说会慢一点

3.操作符优先级

宏:宏使用的时候是直接替换,如果没加括号的话,可能会因为优先级问题参数预料之外的结果

函数:函数在传参前先求值

4.带有副作用的参数(自加自减) 

宏:参数可能被替换到宏体的多个位置

比如:

#include <stdio.h>
#define MAX(x,y) (x)>(y)?(x):(y)
int main()
{
	int a = 2;
	int b = 3;
	int m = MAX(a++, b++);
	return 0;
}

a、b会进行多次自增操作

函数:只在传参的时候计算一次

5.参数类型

宏:宏的参数与类型无关,只要对参数的操作是合法的,它就可以使用于任何参数类型

#include <stdio.h>
#define MALLOC(type,size) (type*)malloc(sizeof(type)*size);
int main()
{
	int* p = MALLOC(int, 5);
	return 0;
}

函数:传参的参数需要与定义是的参数对应

6.调试

宏:宏是预处理阶段的操作,不便于调试

函数:可以逐句调试

7.递归

宏:不能递归

函数:可以递归

2.3 #undefine

移除一个宏定义

2.4 命令行定义

许多C 的编译器提供了一种能力,允许在命令行中定义符号。用于启动编译过程。

#include <stdio.h>
int main()
{
    int array [ARRAY_SIZE];
    int i = 0;
    for(i = 0; i< ARRAY_SIZE; i ++)
   {
        array[i] = i;
   }
    for(i = 0; i< ARRAY_SIZE; i ++)
   {
        printf("%d " ,array[i]);
   }
    printf("\n" );
    return 0;
}

编译指令

//linux 环境演示
gcc -D ARRAY_SIZE=10 programe.c

 2.5 条件编译

一些调试性的代码,删除可惜,保留又碍事,所以我们可以选择性的编译。

#include <stdio.h>
#define __DEBUG__
int main()
{
 int i = 0;
 int arr[10] = {0};
 for(i=0; i<10; i++)
 {
 arr[i] = i;
 #ifdef __DEBUG__
 printf("%d\n", arr[i]);//为了观察数组是否赋值成功。 
 #endif //__DEBUG__
 }
 return 0;
}

多分支条件编译

#include <stdio.h>
#define M 150
int main()
{
#if M<100
	printf("less\n");
#elif M==100
	printf("==\n");
#elif M>100
	printf("more\n");
#else 
	printf("hehe\n");
#endif
	return 0;
}

判断是否被定义

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define M 150
int main()
{
#if defined(M)//如果定义了为真
	printf("hehe\n");
#endif
#ifdef m//如果定义了为真
	printf("haha\n");
#endif

#if !defined(m)//如果没定义为真
	printf("wangwang~\n");
#endif
#ifndef M//如果没定义为真
	printf("miaomiao~\n");
#endif 

}

 嵌套指令

#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

2.6 文件包含

" ":先在源文件所在目录下查找,如果该头文件未找到,编译器就会在标准位置查找头文件,如果找不到就报错

<>:直接在标准路径下查找,如果找不到就报错

解决当多次包含同一个头文件时只包含一次

1.

#ifndef __TEST_H__
#define __TEST_H__
//头文件的内容
#endif

 2.

#pragma once

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值