C语言基础(L15-L16)

L15 :编译过程

预处理

  • 处理注释,以空格代替
  • 将所有#define删除,并且展开所有的宏定义
  • 处理 #if #ifdef等
  • 处理#include,展开被包含的文件
  • 保留编译器需要使用的#pragma指令
    预处理命令:
    gcc -E file.c -o hello.i

编译

语法分析,语义分析,产生汇编代码
gcc -S file.c -o hello.s

链接

  1. 静态链接
    在编译期完成
  2. 动态链接
    在运行期完成

L16 :宏定义与使用分析

特点:强大但是容易出错

#define DIM(array) (sizeof(array)/sizeof(*array))
//获得数组的元素个数

宏表达式与函数的对比:

  • 宏表达式只在预编译期被处理,编译器不知道宏表达式的存在
  • 宏表达式用“实参”完全替代形参,不进行任何运算
  • 宏表达式没有任何的“调用”开销
  • 宏表达式中不能出现递归定义

宏定义的作用域?
在一个函数中定义的一个宏 能否在另一个函数中调用 -》可以
如果想要确保一个函数中定义的宏只能在一个函数中被调用,
可以用 #undef来取消这个宏的定义

    #include <stdio.h>
    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;
    }

强大的内置宏:

利用内置宏实现日志宏


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

    void f()
    {
        LOG("ENTER f()...");
        LOG("EXIT  f()...");    
    }
    int main()
    {
         LOG("ENTER main ...");
         f();
         LOG("ENTER main ...");
         return 0;
    }

猜你喜欢

转载自blog.csdn.net/shouzhoudd/article/details/45972667