C语言基础(L15-L16)

本文详细介绍了编译过程中的预处理步骤,包括宏定义的使用及其特点,并通过实例展示了宏定义的强大功能与注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值