• C语言中函数名称和宏名称同名


      C语言中,函数名称和宏名称可以相同。可以参考下面的示例程序。
    ///////////////////////////////////////////test.cpp
    #include <stdio.h>


    void print(int value) {
    printf("%d\n", value);
    }


    #define print(x) printf("hello"); \
    print(x)


    int main() {
    print(23);


    return 0;
    }
      上面的程序在vc和gcc下都可以运行,输出结果是:hello23。
      究其原因,我们知道编译器编译C语言程序时,先执行预编译,然后再执行编译、汇编和链接等步骤。预编译阶段质主要处理宏,而编译阶段同名的宏已经被替换掉了,故而此时是不存在标识符冲突的。
    但是,函数名称和宏名称同名是有前提的,同名的宏定义必须在同名函数实体之下。再请参考下面示例程序。
    /////////////////////////test.cpp
    #include <stdio.h>

    #define print(x) printf("hello"); \
    print(x)


    void print(int value) {
    printf("%d\n", value);
    }


    int main() {
    print(23);


    return 0;
    }
      这个程序是编译不过去的,因为宏定义在同名函数定义之前,预编译到print函数时,其名称也被当做宏进行处理,预编译完毕后,编译器编译是程序显然是不对的。如果程序的文件名称是test.c,则linux环境可以通过命令gcc -E test.c > test.i,可以看到预编译结果,有心者可以自己分析下,仔细看看print函数的预编译结果。
    如果要定义一个与函数名同名的函数,我们须在函数定义之后再定义宏,似乎不太优雅,没有别的方法么?有的,多文件实现之。有多文件及其源码如下:
    /////////////////////////print.h
    #ifndef __PRINT_H__
    #define __PRINT_H__


    void print(int value);


    #endif


    /////////////////////////print.cpp
    #include "print.h"
    #include <stdio.h>


    void print(int value) {
    printf("%d\n", value);
    }


    /////////////////////////print_inf.h
    #ifndef __PRINT_INF_H__
    #define __PRINT_INF_H__


    #include "print.h"


    //print macro
    #define print(x) printf("hello"); \
    print(x) //print function


    #endif


    /////////////////////////test.cpp
    #include "print_inf.h"
    #include <stdio.h>

    int main() {
    print(23);


    return 0;
    }
      编译程序命令是gcc test.c print.c -o test,运行程序test,输出是hello23。
      okay,问题又一次解决。此时,可能有一个疑问,宏与函数同名,有什么用?还是仅仅为了炫耀?
      考虑如下场景,如果程序库print版本更新,我觉得print.h中的print函数功能有限,需要扩充一下,实现一个print_ex函数,而此时我没有定义一个print宏,调用这个print函数的地方改怎么办?
      当然可以把调用旧版本print函数的代码都更新为print_ex函数,当然,你得费力费心。
      但是,如果旧版本库做的比较好,而且考虑周全,已经定义了一个与print函数同名的print宏呢?我是不是仅仅把print宏中的print函数更改为print_ex就可以了?是不是很方便?而且,不管新版本的函数名称如何更改,因为一个宏的存在,调用print库用户不必关心新版本更新了那些内容,也无需更改代码,仅仅重新编译程序即可。新的示例代码如下:
    /////////////////////////print.h
    #ifndef __PRINT_H__
    #define __PRINT_H__


    void print(int value);
    void print_ex(int value);


    #endif


    /////////////////////////print.cpp
    #include "print.h"
    #include <stdio.h>


    void print(int value) {
    printf("%d\n", value);
    }


    void print_ex(int value) {
    printf("%d\n", value + 10);
    }


    /////////////////////////print_inf.h
    #ifndef __PRINT_INF_H__
    #define __PRINT_INF_H__


    #include "print.h"


    //print macro
    #define print(x) printf("hello"); \
    print_ex(x) //print function


    #endif


    /////////////////////////test.cpp
    #include <stdio.h>
    #include "print_inf.h"


    int main() {
    print(23);


    return 0;
    }
      上面编译程序命令同样是gcc test.c print.c -o test,运行程序test,输出是hello33。




  • 相关阅读:
    php数组的使用
    php数组的定义、php数组的类型
    小米手机安卓手机微信里出现意外的边框线,border:0也没用
    php实现WEB在线文件管理器
    安装了https ssl证书,但浏览器显示并非完全安全(此页面内容部分不安全)
    thinkphp无限分类模块实现
    常见的移动web问题,终端触摸交互,各种bug坑如何解决
    现代都市风 移动端可折叠导航菜单
    电器类电商网站分类大菜单,配色超舒服~
    帮助中心模板框架--简约小清新风格
  • 原文地址:https://www.cnblogs.com/menggucaoyuan/p/2832822.html
Copyright © 2020-2023  润新知