C语言学习之宏函数

宏函数: 

 #define 宏名(a,b,c,...) a+b*c

    宏函数不是真正的函数,而是带参数的宏,只是使用方法像函数而已。

    在代码中使用宏函数,预处理时会经历两次替换,第一次把宏函数替换成它后面的一串代码、表达式,第二次把宏函数中的参数替换到表达式中。

    如果宏函数后面的代码有多行,可以使用大括号包括,进行保护。

    #define 宏名(a,b,c,...) {代码1; 代码2; ...}

    宏函数后面的代码不能直接换行,如果代码确定太长,可以使用续行符换行。

    #define 宏名(a,b,c,...) {   \

        代码1; \

        代码2; \

        ...    \

}

普通函数与宏函数的优缺点:

宏函数的优点:

            1、执行速度快,它不是真正的函数调用,而是代码替换,不会经历传参、跳转、

            返回值。

            2、不会检查参数的类型,因此通用性强。

        宏函数的缺点:

            1、由于它不是真正的函数调用,而是代码替换,每使用一次,就会替换出一份代码,会造成代码冗余、编译速度慢、可执行文件变大。

            2、没有返回值,最多可以有个执行结果。

            3、类型检查不严格,安全性低。

            4、无法进行递归调用。

        函数的优点:

            1、不存在代码冗余的情况,函数的代码只会在代码段中存储一份,使用时跳转过去执行,执行结束后再返回,还可以附加返回值。

            2、安全性高,会对参数进行类型检查。

            3、可以进行递归调用,实现分治算法。

        函数的缺点:

            1、相比宏函数它的执行速度慢,调用时会经历传参、跳转、返回等过程,该过程耗费大量的时间。

            2、类型专用,形参什么类型,实参必须是什么类型,无法通用。

宏函数如何使用:

什么样的代码适合封装成宏函数?

            1、代码量少,即使多次使用也不会造成代码段过度冗余。

            2、调用次数,但执行次数多。

            3、对返回值没有要求。

    设计宏时要注意的问题:

        1、末尾不要加分号。

        2、多加小括号防止产生二义性。

        3、不要使用自加、自减的变量给宏函数提供参数。

封装一个malloc、free函数

        my_malloc 它要记录my_malloc的调用位置,申请到的内存地址

        my_free 它要记录my_free的调用位置,释放到的内存地址


    void* _my_malloc(size_t size,const char* file,const char* func,size_t line)
    {
        void* ptr = malloc(size);
        printf("%s %s %d 申请了%d字节的内存,地址是%p\n",file,func,line,size,ptr);
        return ptr;
    }
    // 由于my_malloc必须有返回值,所以只能使用这种方式中转一下
    #define my_malloc(size) _my_malloc(size,__FILE__,__func__,__LINE__)

    #define my_free(ptr) {\
        free(ptr);\
        printf("%s %s %d 释放了内存 %p\n",__FILE__,__func__,__LINE__,ptr);\
    }

猜你喜欢

转载自blog.csdn.net/m0_62480610/article/details/125927958