16-macro

来源:互联网 发布:opt算法c语言代码 编辑:程序博客网 时间:2024/06/05 18:41


定义宏常量
#define定义宏常量可以出现在代码的任何地方;
#define从本行开始,之后的代码都可以使用这个宏常量

#define ERROR    -1
#define PI        3.14
#define PATH_0 "D:\delphi\c.ppt"

#define PATH_1 D:\delphi\c.ppt
#define PATH_3 D:\delphi\
c.ppt

以上宏定义都是没有语法错误的;
PATH_3等价于 D:\delphic.ppt

定义宏表达式
#define表达式给函数调用的假象,却不是函数
#define表达式可以比函数更强大
#define表达式比函数更容易出错

#define SUM(a, b)    (a)+(b)
#define sum(a, b)    ((a)+(b))
#define MIN(a, b)    ((a) < (b) ? (a) : (b))
#define DIM(array)    {sizeof(array) / sizeof(*array)}

宏只是单纯的展开替换
printf("%d\n", SUM(1,2) * SUM(1,3)); //1 + 2 * 1 + 3 ==5
printf("%d\n", sum(1,2) * sum(1,3)); //(1 + 2) * (1 + 3) == 12
int i = 1, j = 5;
printf("%d\n", MIN(i++, j)); //返回1,而不是2
int i = 1, j = 5;
printf("%d\n", MIN(++i, j)); //返回3,而不是2
int a[] = {1, 2, 3};
printf("%d\n", DIM(a));

前面三个宏都可以找到替代的函数,最后一个宏是找不到对应的函数的;

宏强于函数的优势

宏可以用来扩展C语言的关键字和用法
#include <stdio.h>
#include <malloc.h>

#define MALLOC(type, x) (type*)malloc(sizeof(type)*x)
#define FOREVER() while(1)

#define BEGIN {
#define END   }
#define FOREACH(i, m) for(i=0; i<m; i++)

int main()
{
    int array[] = {1, 2, 3, 4, 5};
    int x = 0;
    int* p = MALLOC(int, 5);
    
    FOREACH(x, 5)
    BEGIN
        p[x] = array[x];
    END
    
    FOREACH(x, 5)
    BEGIN
        printf("%d\n", p[x]);
    END
    
    FOREVER();
    
    free(p);
    
    printf("Last printf...\n");
    
    return 0;
}

宏表达式与函数的对比
宏表达式在预编译期被处理,编译器不知道宏表达式的存在;
宏表达式用"实参"完全替代形参,不进行任何运算;
宏表达式没有任何的"调用"开销
宏表达式中不能出现递归定义
#define FAC(n) ((n>0) ? (FAC(n-1)+n) : 0)
int j = FAC(10);
通过单步编译,查看预编译的结果可知,替换后的结果为:
int j = FAC(9) + 10;

宏定义的常量或表达式是否有作用域限制?
int f1(int a, int b) {
    #define _MIN_(a, b)    ((a) < (b) ? (a) : (b))
    return _MIN_(a, b);
    #undef _MIN_
    // 有了宏,可以定义类似局部函数的概念
}
int f2(int a, int b, int c) {
    return _MIN_(_MIN_(a, b), c);
}
int main() {
    printf("%d\n", f1(2, 1));
    printf("%d\n", f2(5, 3, 2));
    return 0;
}

强大的内置宏
__FILE__ 被编译的文件名
__LINE__ 当前行号
__DATE__ 编译时的日期
__TIME__ 编译时的时间
__STDC__ 编译器是否遵循标准C语言规范


例子
定义日志宏

#include <stdio.h>
#include <time.h>

/* #defien LOG(s) printf("%s:%d %s ...\n", __FILE__, __LINE__, s) */
#define LOG(s)    do {                \
    time_t t;                        \
    struct tm* my_tm;                \
    time(&t);                        \
    my_tm = localtime(&t);            \
    printf("%s[%s:%d] %s\n", asctime(my_tm), __FILE__, __LINE__, s);    \
} while(0)

void f(){
    printf("Enter f() ...\n");
    printf("End f() ...\n");
}
int main(){
    LOG("Enter main() ...");
    f();
    LOG("Exit main() ...");
}

#define f (x) ((x) - 1)
上面的宏代表什么意思?
宏定义对空格敏感吗?宏"调用"对空格敏感吗?


0 0