服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言 操作符#与##使用方法详解

C语言 操作符#与##使用方法详解

2022-11-11 14:36清风自在 流水潺潺 C/C++

在类函数宏中(带参数的宏),#号作为一个预处理运算符,可以把记号转换成字符串。##相当于连接符,它会将两边的内容连接起来,形成新的标识符,下面请看详细的教程

一、# 运算符

  • # 运算符用于在预处理期将宏参数转换为字符串
  • # 的转换作用是在预处理期完成的,因此只在宏定义中有效
  • 编译器不知道 # 的转换作用
  • 用法:
#define STRING(x) #x
printf("%s\n",STRING(Hello World!));

下面通过一个示例感受一下:

test.c:

#include <stdio.h>

#define STRING(x) #x

int main()
{
  
  printf("%s\n", STRING(Hello world!));
  printf("%s\n", STRING(100));
  printf("%s\n", STRING(while));
  printf("%s\n", STRING(return));

  return 0;
}

输出结果如下:

C语言 操作符#与##使用方法详解

为了直观看预处理期间的变化,下面进行单步编译,输入 gcc -E test.c-o test.i,下面为部分输出结果:

test.i:

# 2 "test.c" 2



int main()
{

  printf("%s\n", "Hello world!");
  printf("%s\n", "100");
  printf("%s\n", "while");
  printf("%s\n", "return");

  return 0;
}

可以看到宏参数在预处理阶段转换为字符串。

下面再来看一下运算符的妙用,动态打印当前调用的函数名

test.c:

#include <stdio.h>

#define CALL(f, p) (printf("Call function %s\n", #f), f(p))
 
int square(int n)
{
  return n * n;
}

int func(int x)
{
  return x;
}

int main()
{
  int result = 0;
  
  result = CALL(square, 4);
  
  printf("result = %d\n", result);
  
  result = CALL(func, 10);
  
  printf("result = %d\n", result);

  return 0;
}

下面为输出结果:

C语言 操作符#与##使用方法详解

同样,可以进行单步编译,输入 gcc -E test.c-o test.i,看看预处理后的结果,下面为部分输出结果:

test.i:

# 2 "test.c" 2
int square(int n)
{
  return n * n;
}

int func(int x)
{
  return x;
}

int main()
{
  int result = 0;

  result = (printf("Call function %s\n", "square"), square(4));

  printf("result = %d\n", result);

  result = (printf("Call function %s\n", "func"), func(10));

  printf("result = %d\n", result);

  return 0;
}

 

二、## 运算符

  • ## 运算符用于在预处理期粘连两个标识符
  • ## 的连接作用是在预处理期完成的,因此只在宏定义中有效
  • 编译器不知道 ## 的连接作用
  • 用法
#define CONNECT(a, b) a##b
int CONNECT(a,1);   //int a1;
a1 = 2;

下面通过一个示例,看看运算符的基本用法:

test.c:

#include <stdio.h>

#define NAME(n) name##n

int main()
{    
  int NAME(1);
  int NAME(2);
  
  NAME(1) = 1;
  NAME(2) = 2;
  
  printf("%d\n", NAME(1));
  printf("%d\n", NAME(2));

  return 0;
}

输出结果如下:

C语言 操作符#与##使用方法详解

可以进行单步编译,输入 gcc -E test.c-o test.i,看看预处理后的结果,下面为部分输出结果:

test.i:

# 2 "test.c" 2
int main()
{

  int name1;
  int name2;

  name1 = 1;
  name2 = 2;

  printf("%d\n", name1);
  printf("%d\n", name2);

  return 0;
}

再来看一个 ## 运算符的工程应用:

test.c:

#include <stdio.h>
#define STRUCT(type) typedef struct _tag_##type type;\
                   struct _tag_##type
STRUCT(Student)
{
  char* name;
  int id;
};

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

  return 0;
}

输出结果如下:

C语言 操作符#与##使用方法详解

这么做的好处就是在需要定义很多结构体时,可以尽量少写 struct 和 typedef,提高工作效率,另外使得代码更加美观。

可以进行单步编译,输入 gcc -E test.c-o test.i,看看预处理后的结果,下面为部分输出结果:

test.i:

# 2 "test.c" 2
typedef struct _tag_Student Student; 
struct _tag_Student
{
  char* name;
  int id;
};

int main()
{

  Student s1;
  Student s2;

  s1.name = "s1";
  s1.id = 0;

  s2.name = "s2";
  s2.id = 1;

  printf("s1.name = %s\n", s1.name);
  printf("s1.id = %d\n", s1.id);
  printf("s2.name = %s\n", s2.name);
  printf("s2.id = %d\n", s2.id);

  return 0;
}

 

三、小结

  • # 运算符用于在预处理期将宏参数转换为字符串
  • ## 运算符用于在预处理期粘连两个标识符
  • 编译器不知道 # 和 ## 运算符的存在
  • # 和 ## 运算符只在宏定义中有效

到此这篇关于C语言 操作符#与##使用方法详解的文章就介绍到这了,更多相关C语言 #与##内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_43129713/article/details/123549421

延伸 · 阅读

精彩推荐
  • C/C++关于C++ string和c类型字符数组的对比

    关于C++ string和c类型字符数组的对比

    下面小编就为大家带来一篇关于C++ string和c类型字符数组的对比。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    C++教程网10552021-04-12
  • C/C++C语言之结构体(struct)详解

    C语言之结构体(struct)详解

    本文主要介绍C语言 结构体的知识,学习C语言肯定需要学习结构体,这里详细说明了结构体并附示例代码,供大家参考学习,有需要的小伙伴可以参考下...

    最后一球给我投6852022-01-20
  • C/C++C++中strstr函数的实现方法总结

    C++中strstr函数的实现方法总结

    这篇文章主要介绍了C++中strstr函数的实现方法总结的相关资料,希望通过本文能帮助到大家,让大家掌握这部分内容,需要的朋友可以参考下...

    默伊清风6402021-06-08
  • C/C++C++获得文件状态信息的方法

    C++获得文件状态信息的方法

    这篇文章主要介绍了C++获得文件状态信息的方法,包括文件状态信息、文件所在磁盘盘符、文件创建时间、访问时间及修改日期等,需要的朋友可以参考下...

    鉴客11832021-03-03
  • C/C++深入理解结构体中占位符的用法

    深入理解结构体中占位符的用法

    本篇文章是对结构体中占位符的用法进行了详细的分析介绍,需要的朋友参考下...

    C语言教程网3902020-12-10
  • C/C++C语言时间处理实例分享

    C语言时间处理实例分享

    这篇文章主要介绍了C语言时间处理实例分享的相关资料,需要的朋友可以参考下...

    C语言教程网7492021-03-02
  • C/C++QT实现五子棋游戏

    QT实现五子棋游戏

    这篇文章主要为大家详细介绍了QT实现五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    466015436322021-09-26
  • C/C++C++设计模式之抽象工厂模式

    C++设计模式之抽象工厂模式

    这篇文章主要介绍了C++设计模式之抽象工厂模式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面...

    鬼谷子com8422021-09-16