我有一个库驱动结果存储为int16_t值(它是一个负数,我可以使用它的绝对值)和另一个需要此值的库函数,稍后以uin8_t *的形式出现。不使用String怎么办?
以下代码有效,但是使用了可怕的字符串。是否可以在不调用String或std :: string的情况下做到这一点?
void setup() {
Serial.begin(9600);
}
void loop() {
delay(5000);
String initialVal= String(-fetchInt());
Serial.print("Initial value is: ");Serial.println(initialVal);//prints "76"
uint8_t medianVal[sizeof(initialVal);
medianVal.getBytes(medianVal, sizeof(initialVal));
Serial.print("median value is: ");Serial.println(medianVal);//prints "76"
uint8_t* finalVal = medianVal;
Serial.print("final value is: ");Serial.println((char*)finalVal);//prints "76"
}
int16_t fetchInt(){
return -76;
}
那么,如何将 int16_t 转换为 uint8_t * ?
下面的评论中指出:
Serial.println(static_cast<unsigned>(*finalVal));
可以工作,但是此解决方案将uint8_t转换为无符号int,并且该方法需要uint8_t *。
我来自Java之类的人,而且很难将整数转换为字符串。
答案 0 :(得分:5)
类型uint8_t
的指针不能指向类型int16_t
的对象;您需要复制firstVal
的值,但是因此需要一个单独的对象来使用该值。
uint8_t firstValAbs = firstVal >= 0 ? firstVal : -firstVal;
uint8_t* secondVal = &firstValAbs;
注意:uint8_t x = -34
不会不会给您-34
的绝对值,即不会产生34
。您宁愿得到-34
的二进制补码,即255-34+1 == 222
。
答案 1 :(得分:3)
int16_t
使用16位(-32,768至32,767)存储带符号的数值。
uint8_t
使用8位(0到255)存储无符号数字值。
如果确定更改符号后int16_t
的值适合uint8_t
,则可以对其进行分配:
int16_t firstVal = -76;
uint8_t secondVal = -firstVal;
现在,如果您需要一个指向第二个值的指针,则只需创建它即可。您无法直接指向firstVal
,因为您需要存储更改后的值。
uint8_t* secondValPointer = &secondVal;
此uint8_t*
可以解释为指向库中字符的指针。通常,您应该为此使用char(也使用8位,但it is implementation defined if it is signed or unsigned)。您可以将此指针强制转换为c har*
,尽管您需要使用reinterpret_cast告诉编译器要在指针之间强制转换:
char *secondValAsChar = reinterpret_cast<char*>(secondValPointer);
现在,您可以将此指针视为指向字符的指针。例如,以下代码将打印“ L”,因为L的ASCII码为76:
std::cout << *secondValAsChar << std::endl;
但是,您必须非常小心使用此指针,因为secondValAsChar不是以null终止的字符串,因此您不能使用像strcat
这样的旧通用方法。