C语言的宏定义,字符串连接

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言的宏定义,字符串连接相关的知识,希望对你有一定的参考价值。

#define ADC_SPI 5
#define COMB_SPI_INFO(name) "SPI/"#name

想得到这种效果调用 COMB_SPI_INFO(ADC_SPI) 得到 "SPI/5" 这个字符串
下次要修改的时候,如把5改成6,#define ADC_SPI 6,调用 COMB_SPI_INFO(ADC_SPI) 得到 "SPI/6" 这个字符串

上面第二个宏定义,只会得到“SPI/ADC_SPI”,请问一下怎么实现?

(一)宏定义中的##
连接符与#

##
连接符号由两个井号组成,其功能是在带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串。但它不可以是第一个或者最后一个子串。所谓的子串(token)就是指编译器能够识别的最小语法单元。具体的定义在编译原理里有详尽的解释,但不知道也无所谓。同时值得注意的是#符是把传递过来的参数当成字符串进行替代。下面来看看它们是怎样工作的。这是MSDN上的一个例子。
假设程序中已经定义了这样一个带参数的宏:
#define
paster(
n
)
printf(
"token"
#n
"
=
%d",
token##n
)
同时又定义了一个整形变量:
int
token9
=
9;
现在在主程序中以下面的方式调用这个宏:
paster(
9
);
那么在编译时,上面的这句话被扩展为:
printf(
"token"
"9"
"
=
%d",
token9
);
注意到在这个例子中,paster(9);中的这个”9”被原封不动的当成了一个字符串,与”token”连接在了一起,从而成为了token9。而#n也被”9”所替代。
可想而知,上面程序运行的结果就是在屏幕上打印出token9=9
(二)"\"与一个较长占多行的宏
宏定义中允许包含两行以上命令的情形,此时必须在最右边加上"\"且该行"\"后不能再有任何字符,连注释部分都不能有,下面的每行最后的一定要是"\","\"后面加一个空格都会报错,更不能跟注释。
#define
exchange(a,b)
\
int
t;\
t=a;\
a=b;\
b=t;\
参考技术A #define ADC_SPI 5
#define COMB_SPI_INFO(name) "SPI/"##name

用##替换#追问

这样的话,编译都过不了

追答

#define ADC_SPI 5
#define COMB_SPI_INFO(name) TEMP(name)
#define TEMP(x) "SPI/"#x

本回答被提问者采纳

C语言学习笔记--C语言中的宏定义

1. C 语言中的宏定义

1#define 预处理器处理的单元实体之一(因此,预处理器只是简单的进行替换,并
2#define 定义的宏可以出现在程序的任意位置(包括函数体的内部)
3#define 定义之后的代码都可以使用这个宏

2. 定义宏常量 

1#define 定义的宏常量可以直接使用
2#define 定义的宏常量本质为字面

3. 宏定义表达式

1#define 表达式的使用类似函数调用
2#define 表达式可以比函数更强大
3#define 表达式比函数更容易出错

#include <stdio.h>
#define _SUM_(a, b) (a) + (b)
#define _MIN_(a, b) ((a) < (b) ? (a) : (b))
#define _DIM_(a) sizeof(a)/sizeof(*a)
int main()
{
    int a = 1;
    int b = 2;
    int c[4] = {0};
    int s1 = _SUM_(a, b); //(a)+(b)
    int s2 = _SUM_(a, b) * _SUM_(a, b); //(a)+(b)*(a)+(b)
    int m = _MIN_(a++, b); //((a++)<(b)?(a++):(b))
    int d = _DIM_(c); //sizeof(c)/sizeof(*c);
    printf("s1 = %d\n", s1); // 3
    printf("s2 = %d\n", s2); // 5
    printf("m = %d\n", m); // 2
    printf("d = %d\n", d); // 4
    return 0;
}

4. 宏表达式与函数的对比

1)宏表达式被预处理器处理,编译器不知道宏表达式的存在
2)宏表达式用实参完全替代形参,不进行任何运算

3)宏表达式没有任何的调用开销

4)宏表达式中不能出现递归定义
内置宏

技术分享

技术分享

#include <stdio.h>
#include <malloc.h>
#define MALLOC(type, x) (type*)malloc(sizeof(type)*x)
#define FREE(p) (free(p), p=NULL)
#define LOG(s) printf("[%s] {%s:%d} %s \n", __DATE__, __FILE__,__LINE__, s)
#define FOREACH(i, m) for(i=0; i<m; i++)
#define BEGIN {
#define END }
int main()
{
    int x = 0;
    int* p = MALLOC(int, 5); //以 int 类型作为参数!
    LOG("Begin to run main code...");FOREACH(x, 5)
    BEGIN
    p[x] = x;
   END
    FOREACH(x, 5)
    BEGIN
    printf("%d\n", p[x]);
    END
    FREE(p);
    LOG("End");
    return 0;
}

 

以上是关于C语言的宏定义,字符串连接的主要内容,如果未能解决你的问题,请参考以下文章

C宏定义中的连接符"##"和字符串化操作符"# "及变参宏"..."

预定义宏,C语言预定义的宏详解

C语言中的宏定义怎么用?

C语言的宏定义问题

C语言的宏定义问题

C语言中的宏定义如何使用?