zoukankan      html  css  js  c++  java
  • gnu 扩展之#和##

    转自:http://chongsoft.bokee.com/5816474.html

    今天测试了宏定义中的 "#" 和 "##" 的区别。

    结果如下:

      "#"  代表和一个字符串相连接

     "##"  代表和一个符号连接,符号可以是变量,或另一个宏符号。

    举例如下:

    宏定义如下

    (1)

    #define DEV_FILE_NAME    "/dev/test_kft"

    #define OPEN_FILE(fd, n)   
    {  
        fd = open(DEV_FILE_NAME #n,O_RDONLY);
        if(fd < 0) 
        {
           printf("Open device error "); 
            return 0;
        }  
    }

    如此调用:

        OPEN_FILE(fd1, 1);
        OPEN_FILE(fd2, 2);
        OPEN_FILE(fd3, 3);
        OPEN_FILE(fd4, 4);
        OPEN_FILE(fd5, 5);
        OPEN_FILE(fd6, 6);

    用gcc -E展开后,如下

    2299:    { fd1 = open("/dev/test_kft" "1",00); if(fd1 < 0) { printf("Open device error "); return 0; } };
    2300:    { fd2 = open("/dev/test_kft" "2",00); if(fd2 < 0) { printf("Open device error "); return 0; } };
    2301:    { fd3 = open("/dev/test_kft" "3",00); if(fd3 < 0) { printf("Open device error "); return 0; } };
    2302:    { fd4 = open("/dev/test_kft" "4",00); if(fd4 < 0) { printf("Open device error "); return 0; } };
    2303:    { fd5 = open("/dev/test_kft" "5",00); if(fd5 < 0) { printf("Open device error "); return 0; } };
    2304:    { fd6 = open("/dev/test_kft" "6",00); if(fd6 < 0) { printf("Open device error "); return 0; } };

    如果没有定义DEV_FILE_NAME ,就是

    2299:    { fd1 = open(DEV_FILE_NAME "1",00); if(fd1 < 0) { printf("Open device error "); return 0; } };
    2300:    { fd2 = open(DEV_FILE_NAME "2",00); if(fd2 < 0) { printf("Open device error "); return 0; } };
    2301:    { fd3 = open(DEV_FILE_NAME "3",00); if(fd3 < 0) { printf("Open device error "); return 0; } };
    2302:    { fd4 = open(DEV_FILE_NAME "4",00); if(fd4 < 0) { printf("Open device error "); return 0; } };
    2303:    { fd5 = open(DEV_FILE_NAME "5",00); if(fd5 < 0) { printf("Open device error "); return 0; } };
    2304:    { fd6 = open(DEV_FILE_NAME "6",00); if(fd6 < 0) { printf("Open device error "); return 0; } };

    所以可以很清楚的看出#n 解析出来的是"n" , 用于连接一个已有的字符串。

    (2)  再来看 ## 是什么意思, 宏定义如下:

    #define OPEN_FILE(fd, n)   
    {  
        fd = open(DEV_FILE_NAME ##n,O_RDONLY);
        if(fd < 0) 
        {
           printf("Open device error "); 
            return 0;
        }  
    }

    调用方式相同。

    看宏展开:

    2299:    { fd1 = open(DEV_FILE_NAME1,00); if(fd1 < 0) { printf("Open device error "); return 0; } };
    2300:    { fd2 = open(DEV_FILE_NAME2,00); if(fd2 < 0) { printf("Open device error "); return 0; } };
    2301:    { fd3 = open(DEV_FILE_NAME3,00); if(fd3 < 0) { printf("Open device error "); return 0; } };
    2302:    { fd4 = open(DEV_FILE_NAME4,00); if(fd4 < 0) { printf("Open device error "); return 0; } };
    2303:    { fd5 = open(DEV_FILE_NAME5,00); if(fd5 < 0) { printf("Open device error "); return 0; } };
    2304:    { fd6 = open(DEV_FILE_NAME6,00); if(fd6 < 0) { printf("Open device error "); return 0; } };

    现在看清楚了, ##n 的作用是把n直接连接在了一个符号的末尾. 好, 现在我们定义一个符号看看效果。

    #define DEV_FILE_NAME1    "/dev/test_kft1"

    再展开:


    2299:    { fd1 = open("/dev/test_kft1",00); if(fd1 < 0) { printf("Open device error "); return 0; } };
    2300:    { fd2 = open(DEV_FILE_NAME2,00); if(fd2 < 0) { printf("Open device error "); return 0; } };
    2301:    { fd3 = open(DEV_FILE_NAME3,00); if(fd3 < 0) { printf("Open device error "); return 0; } };
    2302:    { fd4 = open(DEV_FILE_NAME4,00); if(fd4 < 0) { printf("Open device error "); return 0; } };
    2303:    { fd5 = open(DEV_FILE_NAME5,00); if(fd5 < 0) { printf("Open device error "); return 0; } };
    2304:    { fd6 = open(DEV_FILE_NAME6,00); if(fd6 < 0) { printf("Open device error "); return 0; } };

    很显然第一个符号被替换了, 因为是符号是宏的缘故。 这样我们也能把这一扩展特性应用在变量上。

    测试的话,可以用下面的代码来测试。

    #include <stdio.h>
    #define  OPEN(a,b) {a#b}
    
    int main()
    {
        OPEN(cwd,123);
        OPEN(CWD,456);
        return 0;
    }

    把其中的#换成#就是另外一个

    另外注意 gcc -E 的好处

  • 相关阅读:
    Leetcode Binary Tree Preorder Traversal
    Leetcode Minimum Depth of Binary Tree
    Leetcode 148. Sort List
    Leetcode 61. Rotate List
    Leetcode 86. Partition List
    Leetcode 21. Merge Two Sorted Lists
    Leetcode 143. Reorder List
    J2EE项目应用开发过程中的易错点
    JNDI初认识
    奔腾的代码
  • 原文地址:https://www.cnblogs.com/cdwodm/p/4136074.html
Copyright © 2011-2022 走看看