简体   繁体   中英

Difference between char and char*

I am teaching myself C++ by doing microcontroller projects. My current project is using a pair or Adafruit Feather packet radios. The library functions for the radio packets require a C-style string (I believe) which I understand to be an array of char's.

I have already set up an enum to reflect the various actions of the receiver and would like to send that status back to the transmitter. So I want to turn an enum into an array of char's.

In googling ways to convert enum to array of chars, the easiest (for me to understand) was passing the enum variable to a function with a switch statement that would return a char string. But when I try to put the return into my char array, I get the error "invalid conversion from 'char*' to 'char' [-fpermisive]". I've also been struggling to get my head around arrays and pointers to arrays which is still pretty fuzzy in my head.

Here are some snippets of my code which I hope will show enough of what I'm trying to do.

...from my main function

  BLINKING_RIGHT, //0
  BLINKING_LEFT,  //1
  FLASHING,       //2
  SHOWING_BATTERY,//3
  NONE            //4
};

...and the two functions that process the enum to send

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";
  }
}

I would like help fixing the problem, and, more importantly, help understanding the difference between the type char* and the type char.

This line:

char data[20] {EnumToString(currentAction)};

Is wrong because it uses array-initialization to initialize the first element of the array of char (first element which is of type char ) with a string ( char* ). What you want to do is something like this:

char data[20];
strcpy(data, EnumToString(currentAction));

Or simply:

char *data = EnumToString(currentAction);

The latter doesn't involve any kind of copying, and efficiency is important on a micro-controller.

While we're on the point of efficiency, the canonical way of mapping sequential enum values to strings is using an array, which is orders of magnitude more efficient than repeated branching:

// 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];

Difference between char and char*

char is a character object. Characters are numbers. The number value encodes some textual character (in fixed width character encodings; A C++ character represents one "code unit" in variable width unicode encoding).

char* is a pointer object. It is specifically a pointer to a char object. A pointer object points to another object in memory - or points to nothing if null or points to memory where an object was if the pointer is invalid. Pointers are also iterators, and incrementing a pointer makes it point to a successive element of an array.


 char data[20] {EnumToString(currentAction)}; //This is the line showing the error

data is an array of 20 objects of type char . {expr} initialises the first element of the array with the expression. In your case, the expression is a call to EnumToString . Thus, you're attempting to initialise a char object using the char* object returned by the function. The type system of C++ protects you from this obvious mistake.

Assuming you have the option of sending less than 20 bytes, a potential simple solution is to avoid using the local array entirely:

std::string_view str = EnumToString(currentAction);
rf69.send(str.data(), str.size());

 char *statusString; statusString = "BLINKING_RIGHT"; //0

This is ill-formed in C++. String literals are arrays of const char , and they are not convertible to pointer to non-const char (since C++11).

As simple fix is to change the variable and the return type to be const char* . That said, using std::string_view may be even more preferable because that way the caller doesn't need to calculate the length of the string at runtime by searching for the null terminator.

char (or any T) is a value.

char* (or any T*) is a pointer (a value poining to another value, ie address).

Keep in mind what arrays ( char[] or any T[] ) presented by pointer to 0-th element. Variable of char* can point to an element of an array (to the first element in a special case).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM