C语言宏的使用分析

#define

#define定义的宏可以出现在程序的任何位置

#define定义之后的代码都可以使用这个宏

#define定义的宏常量本质为字面量

#define表达式不能出现递归定义

C语言中的内置宏

ANSI C 规定了以下几个预定义宏,它们在各个编译器下都可以使用:

LINE:表示当前源代码的行号;

FILE:表示当前源文件的名称;

DATE:表示当前的编译日期;

TIME:表示当前的编译时间;

STDC:当要求程序严格遵循ANSI C标准时该标识被赋值为1;

__cplusplus:当编写C++程序时该标识符被定义。

__WIN32:当在window平台下编写程序时被定义

linux:当在linux平台下编写程序时被定义

条件编译使用分析

条件编译在行为上类似c语言中的if…else…;

条件编译在预处理期进行分支判断;

我们可以通过命令行来定义宏

格式:gcc –Dmacro=value file.c 或者 gcc –Dmacro file.c

#include

include将已经存在的文件内容嵌入到当前文件中来;间接包含同样会嵌入文件内容;多次包含了同一文件会嵌入多次,出现重复定义,程序出错。

现代软件工程涉及到的文件众多,为了避免重复调用头文件,防止程序出错,一般在头文件前使用如下语句:

#ifndef headname_h     

#define headname_h

//头文件体 

#endif

#error

#error用于生成一个编译错误消息

用法:#error message message是我们要输出的语句,但不需要双引号

类似的:#warning用于生成编译警告

例如:

#ifndef __cplusplus
      #error This file should be processed with C++ compiler.
#endif
//__cplusplus是c++内置的宏,在C语言中没有定义,如果使用c编译,则#error执行,编译无法完成。

#line

#line用于强制自定义新的行号和编译文件名,并对源程序的代码进行重新编号。

用法:#line number filename //filename可省略

#line编译指示字的本质是重定义_LINE_和_FILE_

#pragma

#pragma用于指示编译器完成一些特定的动作

#pragma所带有的指示字很多是编译器特有的,不可移植

编译器将忽略不认识的#pragma指令

#pragma message 用于在编译时输出消息到编译输出窗口

#pragma pack(number) 用于指定内存以number字节对齐

内存对齐

不同类型的数据在内存中按照一定的规则排列

下面是以4字节对齐的例子:

在这里插入图片描述

需要进行内存对齐的原因:CPU对内存的读取不是连续的,而是分成块读取的,块的大小只能是1、2、4、8、16…字节;当被读取的数据元素未进行内存对齐时,需要2次总线周期访问内存,性能上有影响;同时对于一些硬件平台而言,只能从规定的相对地址读取特性类型的数据,否则会产生硬件异常。

编译器在默认情况下进行4字节内存对齐。

#标识符

#标识符用于在预处理期将宏参数转换成字符串;

#的转换作用是在预处理期完成的,因此只在宏定义中有效。

例如:

#define Call(f, p) (printf(“Call function %s\n”, #f), f(p))

int square(int n){return n* n;}

int main()
{
      printf(“result = %d\n”, Call(square, 4));

      return 0;
}

## 标识符

##用于在预处理期粘连两个标识符

#的转换作用是在预处理期完成的,因此只在宏定义中有效

例如:

#define STRUCT(type) typedef struct _tag_##type type;\
                     struct _tag_##type

STRUCT(student)
{
      char* name;
      int id;
};

int main()
{
      student std;

      return 0;
}
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页