题
我和高科技型PICC32工作的PIC32MX系列微处理器,但我认为这个问题是一般足够在C.知识渊博的人(这几乎等同于C90,用的sizeof(INT)=的sizeof(长)=的sizeof(浮点)= 4。)
比方说,我读出的数据的4字节字代表一个float
。我可以用快速转换到其实际浮点值:
#define FLOAT_FROM_WORD(WORD_VALUE) (*((float*) &(WORD_VALUE)))
但是,这仅适用于左值。我不能,例如,使用此上的函数返回值,如:
FLOAT_FROM_WORD(eeprom_read_word(addr));
是否有一个短和甜的方式来做到这一点的内联,即没有函数调用或临时变量?说实话,没有巨大的理由让我避免函数调用或额外的变种,但它的烦我。必须有一个办法,我失踪。
补充:我不知道,WORD
竟是一个共同的typedef。我已经改变了宏参数的名称,以避免混淆。
解决方案
您可以返回值运行的伎俩其他方式
float fl;
*(int*)&fl = eeprom_read_word(addr);
或
#define WORD_TO_FLOAT(f) (*(int*)&(f))
WORD_TO_FLOAT(fl) = eeprom_read_word(addr);
或为R塞缪尔Klatchko表明
#define ASTYPE(type, val) (*(type*)&(val))
ASTYPE(WORD,fl) = eeprom_read_word(addr);
其他提示
如果这是海湾合作委员会,你可以这样做:
#define atob(original, newtype) \
(((union { typeof(original) i; newtype j })(original)).k)
哇。可怕。但用法是好的:
int i = 0xdeadbeef;
float f = atob(i, float);
我敢打赌,你的编译器不支持要么typeof
运营商也不是union
流延GCC呢,因为无论是标准的行为,但在休的机会,你的编译器可以做union
铸造,那就是你的答案。改性不使用typeof
:
#define atob(original, origtype newtype) \
(((union { origtype i; newtype j })(original)).k)
int i = 0xdeadbeef;
float f = atob(i, int, float);
当然,这忽略了,当你使用两种不同的尺寸发生了什么问题,但更接近“你想要什么”,也就是一个简单的宏过滤器返回,而不是采取一个额外的参数值。这个版本需要额外的参数仅供一般性。
如果你的编译器不支持union
铸造,这是一个整洁,但不可移植的伎俩,那么有没有办法做到这一点,“你想要的方式,”和其他的答案都已经知道了。
如果使用const引用可以采取一个临时值的地址:
FLOAT_FROM_WORD(w) (*(float*)&(const WORD &)(w))
但不会在C工作:(
(C没有引用的权利?在Visual C ++作品)
正如其他人所说,无论是内联函数或在一个临时一个定义,编译器将优化它。
不是一个真正的答案,更建议。你FLOAT_FROM_WORD宏会更自然,使用更灵活,如果没有它,在端
#define FLOAT_FROM_WORD(w) (*(float*)&(w))
fl = FLOAT_FROM_WORD(wd);
这可能不是你的确切情况是可能的,但升级到C99编译器会过于解决您的问题。
C99具有内联函数其中,而在参数表现得像正常功能和返回值,在完全相同这种情况下与没有宏的缺点得到改善的效率。