C preprocessor #定义C中参数的值?
我想知道是否有可能将指令C preprocessor #定义C中参数的值?,c-preprocessor,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*)&P
#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等。我尝试了不同的方法来使用#或###,但我不确定它是否能够实现我想要实现的目标。因为预处理器(扩展宏的东西)甚至在编译器之前就已经运行了。您想要的是在运行时访问struct字段的名称,这是不可能的,因为字段的名称不会被保留。C不是一种动态语言,没有反射
但是,您可以将for迭代编写为一个单独的定义,并调用它8次。但这不是最好的解决方案——在您的情况下,我会使用位移位而不是位字段。它更易于支持、使用和阅读。预处理器指令在处理(即编译)之前进行处理和应用
kupa
是一个预处理器宏,因此编译器永远不会看到它。所以不,你不能这样做
您试图做的是不可移植的,位的存储方式取决于编译器
您可以更好地使用位操作,例如定义指定给定位的枚举
enum {
b0 = 0x001,
b1 = 0x002,
b3 = 0x004,
...
};
您可能仍然需要对值执行(例如)endian转换,具体取决于您交换值的方式。typedef struct{
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() ;
}
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;
}位场;
托森工会{
uint8_t ui8val;
位字段BFval;
} ;
无效发送至74HC595(uint8_t val){
联合托森tmp;
tmp.ui8val=val;
对于(int i=7;i>=0;i--){
DS=tmp.BFval.b7;
tmp.ui8val