arabain

宏定义与使用分析

1. 定义宏常量

(1)#define 定义宏常量可以出现在代码的任何地方

(2)#define从本行开始,之后的代码都可以使用这个宏常量

#define ERROR        -1                 //正确
#define    PI      3.1415926      //正确

#define    PATH_2    "D:\Delphi\C\Topic3.ppt"      //正确
#define    PATH_1     D:\Delphi\C\Topic3.ppt       //正确,因为预编译器只是简单的替换
#define    PATH_3     D:\Delphi\C\
Topic3.ppt                                   //正确,这里的\是接续符

2. 定义宏表达式

(1)#define表达式给有函数调用的假象,却不是函数

(2)#define表达式可以比函数更加强大

(3)#define表达式比函数更容易出错

#include <stdio.h>

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

int sum(int a, int b)
{
     return a+b;
}

int min(int a, int b)
{
     return ((a)<(b)? (a):(b));
}

int dim(int array[])
{
      return sizeof(array) / sizeof(*array);  
}

int main()
{
       int i = 1;
       int j = 5;
       int a[] = {1, 2, 3}

       printf("%d\n", SUM(1, 2) * SUM(1, 2));  //相当于(1)+(2) *  (1)+(2),输出为5
       printf("%d\n", sum(1, 2) * sum(1, 2)); 
     
       printf("%d\n", MIN(i++, j));  //相当于((i++)<(j)? (i++): (j)),输出是2
       printf("%d\n", min(i++, j));    //输出是1

       printf("%d\n", DIM(a);   //输出3,数组元素个数;而使用函数比较难实现
       printf("%d\n", dim(a);  //输出为1,因为函数的数组参数会退化为一个指针,那么sizeof(array)就是一个指针所占用空间的大小
}    

【编程实验—宏代码块的定义(宏强于函数的优势)】

#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;
}

3. 宏表达式与函数的对比

(1)宏表达式在预编译期被处理,编译器不知道宏表达式的存在

(2)宏表达式用“实参”完全替代形参,不进行任何运算

(3)宏表达式没有任何的“调用”开销

(4)宏表达式中不能出现递归定义,如:  

#define FAC(n)    ((n>0) ? (FAC(n-1)+1) : 0)
int j = FAC(100);

4. 你见过#undef吗?

  • 宏定义的常量或表达式是否有作用域的限制?
#include <stdio.h>
 
int f1(int a, int b)
{
    #define _MIN_(a,b) ((a)<(b) ? a : b)
     
    return _MIN_(a, b);

#undef _MIN_(a,b) //下面就不可以再使用该宏,用#undef来实现作用域的限制 }
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; }

5. 强大的内置宏

【编程实验—定义日志宏】

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

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


void f()
{
    LOG("Enter f()....");
    LOG("Exit f()....");
}

int main()
{
    LOG("Enter main()....");

    f();

    LOG("Exit main()...");  
}

分类:

技术点:

相关文章: