char和char*之间的区别



我通过做微控制器项目自学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*的变量可以指向数组的一个元素(在特殊情况下指向第一个元素(。

最新更新