我通过做微控制器项目自学C++。我目前的项目是使用一对Adafruit Feather分组收音机。无线电数据包的库函数需要一个C风格的字符串(我相信(,我认为它是一个char数组。
我已经设置了一个枚举来反映接收器的各种操作,并希望将该状态发送回发射器。所以我想把一个枚举变成一个char数组。
在谷歌上搜索将enum转换为字符数组的方法中,最简单的(对我来说很容易理解(是将enum变量传递给一个带有switch语句的函数,该语句将返回一个字符字符串。但当我试图将返回值放入我的char数组时,我会得到错误";从"char*"到"char"的转换无效[-fpermisive]";。我也一直在努力了解数组和指向数组的指针,这在我的脑海中仍然很模糊。
以下是我的一些代码片段,我希望这些片段能充分展示我正在尝试做的事情
从我的主要功能
BLINKING_RIGHT, //0
BLINKING_LEFT, //1
FLASHING, //2
SHOWING_BATTERY,//3
NONE //4
};
以及处理枚举以发送的两个函数
void SendStatus()
{
char data[20] {EnumToString(currentAction)}; //This is the line showing the error
//itoa (data,static_cast<int>(currentAction),10);
//data[0]=static_cast<uint8_t>(currentAction);
//data[1]=0;
rf69.send(data, sizeof(data));
rf69.waitPacketSent();
Serial.println("Sent a reply");
}//end_function SendStatus()
char* EnumToString(CurrentAction inputEnum)
{
char *statusString;
switch(inputEnum)
{
case 0:
statusString = "BLINKING_RIGHT"; //0
return statusString;
break;
case 1:
statusString = "BLINKING_LEFT"; //1
return statusString;
break;
case 2:
statusString = "FLASHING"; //2
return statusString;
break;
case 3:
statusString = "SHOWING_BATTERY";//3
case 4:
statusString = "NONE"; //4
return statusString;
break;
default:
return "EnumToString: Invalid enum";
}
}
我想帮助解决这个问题,更重要的是,帮助理解char*类型和char类型之间的区别。
此行:
char data[20] {EnumToString(currentAction)};
是错误的,因为它使用数组初始化来用字符串(char*
(初始化char
的数组的第一个元素(第一个类型为char
的元素(。你想做的是这样的事情:
char data[20];
strcpy(data, EnumToString(currentAction));
或者简单地说:
char *data = EnumToString(currentAction);
后者不涉及任何形式的复制,并且在微控制器上效率很重要。
当我们讨论效率问题时,将顺序枚举值映射到字符串的规范方法是使用数组,这比重复分支的效率高几个数量级:
// stored as read-only data in the .hex file
static char *names[] = { "BLINKING_RIGHT", "BLINKING_LEFT", "FLASHING", "SHOWING_BATTERY", "NONE" };
// later
const char *data = names[currentAction];
char和char*之间的差异
char
是一个字符对象。字符是数字。数值对一些文本字符进行编码(在固定宽度字符编码中;在可变宽度unicode编码中,C++字符表示一个"代码单元"(。
char*
是指针对象。它特别是指向char
对象的指针。指针对象指向内存中的另一个对象,如果为null则不指向任何对象,如果指针无效则指向对象所在的内存。指针也是迭代器,递增指针使其指向数组的连续元素。
char data[20] {EnumToString(currentAction)}; //This is the line showing the error
data
是一个由20个类型为char
的对象组成的数组。{expr}
使用表达式初始化数组的第一个元素。在您的情况下,表达式是对EnumToString
的调用。因此,您正试图使用函数返回的char*
对象初始化char
对象。C++的类型系统保护您不受这个明显错误的影响。
假设您可以选择发送少于20个字节的数据,一个潜在的简单解决方案是避免完全使用本地阵列:
std::string_view str = EnumToString(currentAction);
rf69.send(str.data(), str.size());
char *statusString; statusString = "BLINKING_RIGHT"; //0
这在C++中是不正确的。字符串文字是const char
的数组,并且它们不能转换为指向非常量char
的指针(因为C++11(。
简单的修复方法是将变量和返回类型更改为const char*
。也就是说,使用std::string_view
可能更可取,因为这样调用者就不需要在运行时通过搜索null终止符来计算字符串的长度。
char
(或任何T(是一个值。
char*
(或任何T*(是指针(指向另一个值,即地址的值(。
请记住指针指向第0个元素的数组(char[]
或任何T[]
(。char*
的变量可以指向数组的一个元素(在特殊情况下指向第一个元素(。