函数与宏:

 

 

示例:

 1 #include <stdio.h>
 2 
 3 #define RESET(p, len)          \
 4     while( len > 0 )           \
 5         ((char*)p)[--len] = 0
 6 
 7 void reset(void* p, int len)
 8 {
 9     while( len > 0 ) 
10         ((char*)p)[--len] = 0;
11 }
12 
13 int main()
14 {
15     int array[] = {1, 2, 3, 4, 5};
16     int len = sizeof(array);
17     int i = 0;
18     
19     for(i=0; i<5; i++)
20     {
21         printf("array[%d] = %d\n", i, array[i]);
22     }
23     
24     return 0;
25 }

运行结果如下:

 

第19行加上重置为0的宏,结果如下:

 

我们再次修改第19行,第一个参数使用6,先用宏,再用函数调用,结果如下:

 

使用宏时,编译器不会报任何警告,而在运行时出现段错误。使用函数在编译阶段就会报警告。

编译器对于函数会有更严格的检查。可以帮助我们发现更多的错误,能用函数的地方不用宏。宏的副作用巨大。

 

 

宏的副作用:

 1 #include <stdio.h>
 2 
 3 #define _ADD_(a, b) a + b
 4 #define _MUL_(a, b) a * b
 5 #define _MIN_(a, b) ((a) < (b) ? (a) : (b))
 6 
 7 int main()
 8 {
 9     int i = 1;
10     int j = 10;
11     
12     printf("%d\n", _MUL_(_ADD_(1, 2), _ADD_(3, 4)));
13     printf("%d\n", _MIN_(i++, j));
14     
15     return 0;
16 }

运行结果如下:

 

这是不符合我们的预期的,这就是宏的副作用。

宏的妙用:

 

示例:

 1 #include <stdio.h>
 2 #include <malloc.h>
 3 
 4 #define MALLOC(type, x)   (type*)malloc(sizeof(type)*x)
 5 #define FREE(p)           (free(p), p=NULL)
 6 
 7 #define LOG_INT(i)        printf("%s = %d\n", #i, i)
 8 #define LOG_CHAR(c)       printf("%s = %c\n", #c, c)
 9 #define LOG_FLOAT(f)      printf("%s = %f\n", #f, f)
10 #define LOG_POINTER(p)    printf("%s = %p\n", #p, p)
11 #define LOG_STRING(s)     printf("%s = %s\n", #s, s)
12 
13 #define FOREACH(i, n)     while(1) { int i = 0, l = n; for(i=0; i < l; i++)
14 #define BEGIN             {
15 #define END               } break; } 
16 
17 int main()
18 {
19     int* pi = MALLOC(int, 5);
20     char* str = "D.T.Software";
21     
22     LOG_STRING(str);
23     
24     LOG_POINTER(pi);
25     
26     FOREACH(k, 5)
27     BEGIN
28         pi[k] = k + 1;
29     END
30     
31     FOREACH(n, 5)
32     BEGIN
33         int value = pi[n];
34         LOG_INT(value);
35     END
36     
37     FREE(pi);
38     
39     LOG_POINTER(pi);
40     
41     return 0;
42 }

运行结果如下:

 

 

单步编译,FOREACH如下:

 

 

小结:

 

posted on 2018-08-30 22:27  周伯通789  阅读(189)  评论(0编辑  收藏  举报