C语言学习笔记--#和##操作符

1. #运算符

1#运算符用于在预处理期将宏的参数转换为字符串

2#的转换作用是在预处理期完成的,因此只在宏定义中有效,即其他地方不能用#运算符

3)用法:#define STRING(x) #x

    printf("%s ",STRING(Hello World!));//注意,Hello World!不加引号!

#include <stdio.h>
#define STRING(x) #x
int main()
{ 
    //注意宏参数不用加引号,#运算符在宏替换时会自动加上去
    printf("%s
",STRING(Hello World!)); //"Hello World!"
    printf("%s
",STRING(100)); //"100"
    printf("%s
",STRING(while)); //"while"
    printf("%s
",STRING(return)); //"return"
    return 0;
}

#运算符的妙用

#include <stdio.h>
//注意宏后面的为逗号表达式,返回的是第 1 个表达式的值
//该宏最大的用处在于,可以输出被调用的函数的名称
#define CALL(f,p) (printf("Call function %s
",#f),f(p))

int square(int n)
{
    return n*n;
}

int func(int x)
{
    return x;
}

int main()
{
    int iRet = 0;
    //将函数名称作用宏参数,利用#运算符将这个名称转为字符串输出
    //同时,逗号表达式最后一个式子调用相应的函数
    iRet = CALL(square,4);
    printf("result = %d
",iRet);//输出函数名,并调用函数
    iRet = CALL(func,10);
    printf("result = %d
",iRet);//输出函数名,并调用函数
    return 0;
}

2. ##运算符

1##运算符用于在预处理期粘连两个标识符 

2##的连接作用是在预处理期完成的,因此只在宏定义中有效

3)编译器不知道##的连接作用 

4)用法:

#define CONNECT(a,b) a##b 

int CONNECT(a,1); //int a1;

a1 = 2;

#include <stdio.h>
#define NAME(n) name##n
int main()
{
    int NAME(1); //name1;
    int NAME(2); //name2;
    NAME(1) = 1; //name1 = 1;
    NAME(2) = 2; //name2 = 2;
    printf("%d
",NAME(1));
    printf("%d
",NAME(2));
    return 0;
}

##运算符的工程应用

#include <stdio.h>
//该宏可以方便定义结构体,并给结构体命名。
//省去每次在定义结构体时,都要重复地写上
//typedef struct ....之类的相同代码
#define STRUCT(type) 
typedef struct _tag_##type type;
struct _tag_##type
//定义结构体,并命名为 Student
STRUCT(Student)
{
    char* name;int id;
};

int main()
{
    Student s1;
    Student s2;
    s1.name = "s1";
    s1.id = 1;
    s2.name = "s2";
    s2.id = 2;
    printf("s1.name = %s
",s1.name);
    printf("s1.id = %d
",s1.id);
    printf("s2.name = %s
",s2.name);
    printf("s2.id = %d
",s2.id);
    return 0;
}

参考资料:
www.dt4sw.com
http://www.cnblogs.com/5iedu/category/804081.html

原文地址:https://www.cnblogs.com/CoderTian/p/5903314.html