zoukankan      html  css  js  c++  java
  • 2015-11-5 宏定义使用分析听课笔记·

    注:基础的宏定义注意事项及概念不再赘述。

    1、可以在预编译之后的.i文件中查看宏替换之后的代码。

    2、可以利用宏定义求数组求数组元素个数。

    #define DIM(array)  (sizeof(array)/sizeof(*array))

    思考:这个功能可以利用函数来实现吗?

    int dim(int array[])

    {

    return sizeof(array)/sizeof(*array);

    }

    我们在VS2005下对两种方法都进行了实验,利用宏定义的代码如下:

     1 #include<stdio.h>
     2 
     3 #define DIM(arr)  (sizeof(arr)/sizeof(*arr))
     4 
     5 int num[]={1,2,4,5,67,78,5};
     6 
     7 void main()
     8 {
     9 printf("%d
    ",DIM(num));
    10 getchar();
    11 }

    程序运行结果为7,是正确的。

    接下来我们采用函数的方法,看能否实现相同的效果:

     1 #include<stdio.h>
     2 
     3 
     4 
     5 int num[]={1,2,4,5,67,78,5};
     6 
     7 int dim(int arr[])
     8 {
     9 return sizeof(arr)/sizeof(*arr);
    10 }
    11 
    12 void main()
    13 {
    14 printf("%d
    ",dim(num));
    15 getchar();
    16 }

    实验结果为1,显然这不是我们预期的结果。那么问题出在哪里呢?

    这是由于在C语言中,函数的数组参数会退化成一个指针。

    这样就可以解释为什么结果为1了,因为在函数中arr是一个指针,在32位系统下,一个指针占4个字节,一个整数也是占4个字节,所以结果为1。

    通过这个例子可以说明,宏定义还是有其用武之地的。

    3、宏定义与函数的对比:

    a、宏定义在预编译期被处理,编译器不知道宏定义的存在。

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

    c、宏表达式没有任何的调用开销

    d、宏表达式中不能出现递归的定义。

    4、关于#undef,宏定义的常量或者表达式是否有作用域限制?

    先来看这样一段代码:

     1 #include<stdio.h>
     2 
     3 
     4 
     5 int f1(int a,int b)
     6 {
     7   #define _MIN_(a,b) ((a)<(b)?a:b)
     8   return _MIN_(a,b);
     9 }
    10 
    11 int f2(int a,int b ,int c)
    12 {
    13 return _MIN_(_MIN_(a,b),c);
    14 }
    15 
    16 void main()
    17 {
    18 printf("%d
    ",f1(5,11));
    19 printf("%d
    ",f2(5,3,2));
    20 getchar();
    21 }

    代码运行的结果是5,2,由此我们可以发现,我们在函数f1中定义的宏,在函数f2中还可以使用。
    那么假如我们把f2移到f1之前呢?我们这样试了一下,结果编译器报错,说_MIN_未定义在f2中。

    这就说明,宏定义的作用域是从它定义之处开始到文件最后都可以使用,那么我们有没有什么办法来限制我们宏定义的作用域呢?这里就用到了我们的#undef关键字。

    还是上面的代码,我将f1修改成这样:

     1 #include<stdio.h>
     2 
     3 
     4 
     5 int f1(int a,int b)
     6 {
     7   #define _MIN_(a,b) ((a)<(b)?a:b)
     8   return _MIN_(a,b);
     9   #undef _MIN_
    10 }
    11 
    12 int f2(int a,int b ,int c)
    13 {
    14 return _MIN_(_MIN_(a,b),c);
    15 }
    16 
    17 void main()
    18 {
    19 printf("%d
    ",f1(5,11));
    20 printf("%d
    ",f2(5,3,2));
    21 getchar();
    22 }

    编译器同样报错说,在f2中_MIN_未定义,这就说明我们可以通过#undef关键字来人为地限定宏定义的作用域。

    5、强大的内置宏:

      宏名                      意义                           示例

    _FILE_             被编译的文件名                    file.c

    _LINE_                当前行号                         25

    _DATE_           编译时的日期                  Jan 31 2012

    _TIME_            编译时的时间                   17:01:01

    _STDC_   编译器是否遵循标准C规范                1

    我们可以利用上述宏定义打印日志:

    #define LOG(s) printf("%s:%d %s ",_FILE_,_LINE_,s)

    6、课后思考题:

    下面的宏定义是什么意思?宏定义对空格敏感吗?宏“调用”对空格敏感吗?

    #define f  (x)   ((x)-1)

  • 相关阅读:
    16. 3Sum Closest
    17. Letter Combinations of a Phone Number
    20. Valid Parentheses
    77. Combinations
    80. Remove Duplicates from Sorted Array II
    82. Remove Duplicates from Sorted List II
    88. Merge Sorted Array
    257. Binary Tree Paths
    225. Implement Stack using Queues
    113. Path Sum II
  • 原文地址:https://www.cnblogs.com/wan0807/p/4938734.html
Copyright © 2011-2022 走看看