#define C中参数的值?

时间:2013-11-22 22:24:05

标签: c-preprocessor

我想知道是否有可能通过参数的值替换指令#define中的参数,它们实际上在程序中。这是代码:

typedef struct {
uint8_t b0 : 1;
uint8_t b1 : 1;
uint8_t b2 : 1;
uint8_t b3 : 1;
uint8_t b4 : 1;
uint8_t b5 : 1;
uint8_t b6 : 1;
uint8_t b7 : 1;
} BIT_FIELD;
#define _PORTD (*( volatile BIT_FIELD*)&PORTD)
#define kupa(s) _PORTD.b##s
void SentByteTo74HC595 (uint8_t val){
    for(int i = 7 ; i >=0 ; i--) {
        DS = kupa(i);
        SHCPpulse() ;
    }

问题在于kupa让_PORTD.bi对_PORTD.b0,PORTD.b1等进行了注意。我正在尝试用#或##进行不同的方式但是我不确定它是否可能实现我想要实现的目标

3 个答案:

答案 0 :(得分:0)

因为预编译器(扩展宏的东西)甚至在编译器之前运行。你想要的是在运行时访问struct字段的名称,这是不可能的,因为字段的名称不会被保留。 C不是动态语言,也没有反射。

但是,您可以将迭代编写为单独的定义,并将其调用8次。不过,这不是最佳解决方案 - 在您的情况下,我会使用位移而不是位字段。它更容易支持,使用和阅读。

答案 1 :(得分:0)

在处理(即编译)之前处理和应用预处理器指令。 kupa是一个预处理器宏,因此编译器永远不会看到它。所以不,你不能这样做。

您尝试做的事情是不可移植的,比特的存储方式取决于编译器。

您可能更好地使用位操作,例如定义指定给定位的枚举

enum {
    b0 = 0x001,
    b1 = 0x002,
    b3 = 0x004,
...
};

您可能仍需要对值进行(例如)字节序转换,具体取决于您的交换方式。

答案 2 :(得分:0)

typedef struct {
uint8_t b0 : 1;
uint8_t b1 : 1;
uint8_t b2 : 1;
uint8_t b3 : 1;
uint8_t b4 : 1;
uint8_t b5 : 1;
uint8_t b6 : 1;
uint8_t b7 : 1;
} BIT_FIELD;

union u_ToSend {
uint8_t ui8val;
BIT_FIELD BFval;
} ;


    void SentByteTo74HC595 (uint8_t val){
union u_ToSend tmp;
tmp.ui8val = val;
for (int i = 7; i >=0; i--){
    DS = tmp.BFval.b7 ;
    tmp.ui8val <<= 1 ;
    SHCPpulse() ;
}

还有其他方法可以编写它,以便程序消耗更少的RAM和闪存吗?