1

这就是C中符号连接的方式。

#define conc(a,b) a ## b

例如:

conc(hello,World)将制作符号helloWorld

我需要知道的有点不同。假设有一个变量n包含一些整数。现在我需要通过将另一个符号 n.

例如:

n = 2
我需要定义一些function(...),以便function(symbol,n)给出symbol1(不symboln)以及何时n = 3function(symbol,n)将给出symbol3等......

我怎么能定义这样的东西?


这是我真正想要实现的。首先,这是用于对微控制器AtmelStudio进行编程。atmega那里有 4 个USART模块,因此有一组单独的寄存器,它们仅根据模块的编号更改名称。

例如,四个模块中的四个波特率寄存器是UBRR0L, UBRR1L, UBRR2L, UBRR3L。(还有更多,见下文)。

在此处输入图像描述

我需要编写一个函数来通过设置相关寄存器的值来初始化给定的模块。由于寄存器名称仅因模块编号而异,如果我可以按照本文中的要求定义一些预处理器指令,我可以编写一个用一些符号表示寄存器名称的函数,因此这些符号将带有相关的寄存器名称和一切都会好起来的。。

例如:

如果我可以定义conc(a,b)做我需要的,一个简单的功能

void init(int no){
    conc(UBRR,no) = 0xF0;
}

将能够用来表示以下所有内容;

UBRR0 = 0xF0;
UBRR1 = 0xF0;
UBRR2 = 0xF0;
UBRR3 = 0xF0;

如果这无法实现,我只知道重新编写四个单独的函数。但希望会有更好的选择..

4

4 回答 4

5

预处理器将在编译之前对您的代码进行操作,并且显然是在运行时之前。因此,没有预处理器指令可以解决您的目的。

最接近的匹配是使用如下开关盒:

switch(n){
case 0: ptr=&symbol0; break;
case 1: ptr=&symbol1; break;
case 2: ptr=&symbol2; break;
case 3: ptr=&symbol3; break;
case 4: ptr=&symbol4; break;
case 5: ptr=&symbol5; break;
//etc... needs to be filled manually.
}

然后操作*ptr...

此外,如果您的变量名称是连续的,为什么不使用一个数组,将名称作为符号 &symbol0更改为symbol[0]

编辑:现在看到问题中的编辑。您可以使用如上所示的 switch case,或创建一个指针数组,该数组将保存UBRR0LUBRR0L,然后将其与索引一起使用。据我所知,它们只是寄存器,将出现在固定地址。

于 2013-01-07T12:21:16.650 回答
4

您不能使用 C 预处理器来执行此操作,因为变量的值是在运行时确定的。但是您可以使用snprintf()在运行时基于数字构建字符串。

于 2013-01-07T12:17:31.383 回答
2

在我看来,寄存器(例如 RXC0、RXC1、RXC2 等)是等距的。如果这个假设成立,您可以计算以下寄存器的地址(只需替换rint为寄存器的类型):

rint *
register_address(rint *first, rint *second, unsigned int n)
{
    size_t diff = second - first;

    return first + diff * n;
}

您的init()函数将如下所示:

void
init(int no)
{
    *register_address(&UBRR0, &UBRR1, no) = 0xF0;
}

此函数调用可以通过宏简化/隐藏:

#define register_value(name, no) *register_address(&conc(name, 0), &conc(name, 1), no)

所以你可以写:

void
init(int no)
{
    register_value(UBRR, no) = 0xF0;
}

这段代码未经测试,我不确定它是否真的有效。如果它有效并且您将使用它,我将通过静态断言测试假设。

于 2013-01-07T21:16:43.703 回答
0

真正的诀窍如下:

#define TIMER_0     0
#define TIMER_1     1
#define TIMER_2     2

#define _SET_TIMER_NORMAL_MODE(val)        TCCR ## val &= ~(1 << WGM ## val ## 0)
#define SET_TIMER_NORMAL_MODE(instance)     _SET_TIMER_NORMAL_MODE(instance)

现在我们可以将其用作:

SET_TIMER_NORMAL_MODE(TIMER_0)

扩展为:

 _SET_TIMER_NORMAL_MODE(0)

此外,这扩展到:

TCCR0 &= ~(1 << WGM00)
于 2020-02-23T13:19:44.930 回答