程序环境和预处理

程序环境和预处理

  • 程序的翻译环境
  • 程序的执行环境
  • C语言程序的编译+链接
  • 预定义符号介绍
  • 预处理指令 #define
    • #define 定义标识符
    • #define 定义宏
  • 宏和函数的对比
  • 预处理操作符#和##的介绍
  • 命令定义
  • 预处理指令 #undef
  • 条件编译

程序环境和预处理_第1张图片

程序的翻译环境

程序环境和预处理_第2张图片

  1. 预处理 选项 gcc -E test.c -o test.i
    预处理完成之后就停下来,预处理之后产生的结果都放在test.i文件中
  2. 编译 选项 gcc -S test.c
    编译完成之后就停下来,结果保存在test.s中
  3. 汇编 gcc -c test.c
    汇编完成之后就停下来,结果保存在test.o中

程序的执行环境

  1. 程序必须载入内存中,在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成
  2. 程序的执行便开始,接着便调用main函数
  3. 开始执行程序代码,这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回
    地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值
  4. 终止程序,正常终止main函数;也有可能是意外终止

C语言程序的编译+链接

预定义符号介绍

FILE //进行编译的源文件
LINE //文件当前的行号
DATE //文件被编译的日期
TIME //文件被编译的时间
STDC //如果编译器遵循ANSI C,其值为1,否则未定义

printf("file:%s line:%d\n", __FILE__, __LINE__);

预处理指令 #define

#define 定义标识符

#define MAX 1000
#define reg register      //为 register这个关键字,创建一个简短的名字
#define do_forever for(;;)   //用更形象的符号来替换一种实现
#define CASE break;case     //在写case语句的时候自动把 break写上。
// 如果定义的 stuff过长,可以分成几行写,除了最后一行外,每行的后面都加一个反斜杠(续行符)。
#define DEBUG_PRINT printf("file:%s\tline:%d\t \
             date:%s\ttime:%s\n" ,\
             __FILE__,__LINE__ ,    \
             __DATE__,__TIME__ ) 

#define 定义宏

#define name( parament-list ) stuff
其中的 parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中

所以用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏时由于参数中的操作符或邻近操作符之间不可预料的相互作用

宏和函数的对比

程序环境和预处理_第3张图片

预处理操作符#和##的介绍

使用 # ,把一个宏参数变成对应的字符串

int i = 10;
#define PRINT(FORMAT, VALUE)\
printf("the value of " #VALUE "is "FORMAT "\n", VALUE);
PRINT("%d", i+3);

代码中的 #VALUE 会预处理器处理为:
“VALUE” .
最终的输出的结果应该是:

the value of i+3 is 13

##可以把位于它两边的符号合成一个符号
它允许宏定义从分离的文本片段创建标识符

#define ADD_TO_SUM(num, value) \
sum##num += value;
...
ADD_TO_SUM(5, 10);//作用是:给sum5增加10

命令定义

#include 
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

预处理指令 #undef

这条指令用于移除一个宏定义

#undef NAME
//如果现存的一个名字需要被重新定义,那么它的旧名字首先要被移除

条件编译

在编译一个程序的时候我们如果要将一条语句(一组语句)编译或者放弃是很方便的,因为我们有条件编译指令

1.
#if 常量表达式
//...
#endif
//常量表达式由预处理器求值
如:
#define __DEBUG__ 1
#if __DEBUG__
//..
#endif
2.多个分支的条件编译
#if 常量表达式
//...
#elif 常量表达式
//...
#else
//...
#endif
3.判断是否被定义
#if defined(symbol)
#ifdef symbol
#if !defined(symbol)
#ifndef symbol
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

你可能感兴趣的:(windows)