Reputation:
Consider the following simple code fragement:
void SetCommand( const unsigned char *cmd )
{
iHeader[4] = *cmd;
}
...
const unsigned char *test = "\x72";
unsigned char iHeader[32];
hdrSetCommand(test);
What I wanna do is pretty straighforward: I have a 32 character array and the SetCommand should set me the 4th byte to "\x72". The code as it is here works fine, but what I do not understand is why I do have to write
iHeader[4] = *cmd /* instead of */ iHeader[4] = cmd ?
And furthermore, when declaring
unsigned char *test = "\x72";
I also get an error message that test needs to be declared as constant? How come?
Upvotes: 0
Views: 662
Reputation: 881443
Because cmd
is a pointer. It points to the actual characters in memory and it's likely to be a weird value like 0xbf001234
. The following diagram may illustrate:
Memory address
+------------------+
0xef001214: | cmd (0xbf001234) |
(on stack) +------------------+
| +----+----+
0xbf001234: +---------------> |\x72|\x00|
(in read-only +----+----+
memory)
When you de-reference cmd
(with *cmd
), it actually gets the character at the memory location where cmd
points to, which is the \x72
that you want. The basic difference is:
"\x72"
is a pointer to a constant char array { '\x72', '\0' }
.'\x72'
is the single character.What you were probably looking for was something along the lines of:
#define CMD_POS 4
#define CMD_TEST '\x72'
...
unsigned char iHeader[32];
void hdrSetCommand (unsigned char cmd) {
iHeader[CMD_POS] = cmd;
}
...
unsigned char test = CMD_TEST;
hdrSetCommand (test);
This passes the character '\x72'
rather than a pointer to the string containing that character.
Also note the judicious use of #define
s - these usually make the code a lot more readable and less prone to errors (since, for example, CMD_POS is only defined at one point rather than scattered throughout the code as the magic number 4). You should look carefully at the use of all magic numbers other than zero or one.
As to the reason why you got the error stating that your string variable needs to be defined constant, this is because you cannot change the contents of a const char
array (which is what "\x72" is, a two-element character array) - the compiler is free to place it into read-only memory and/or share it such as the two strings:
const char *x = "Hello there";
const char *y = "there";
being allowed to overlap as follows:
Memory location
+---+---+---+---+---+---------+
0xbf005678 (x): | H | e | l | l | o | <space> |
+---+---+---+---+---+---------+
0xbf00567e (y): | t | h | e | r | e | \0 |
+---+---+---+---+---+---------+
By attempting to treat a constant string as non-constant, you break your contract with the compiler.
Upvotes: 6
Reputation: 51711
"\x72" is a string, therefore you need a pointer to point to all the characters in that string, so after
const unsigned char *test = "\x72";
test points to the frist of two characters '\x72' and a null terminator '\x0'
You can rewrite this as
const unsigned char test = '\x72';
test is now a character, and you can then write your function as
void SetCommand( const unsigned char cmd )
{
iHeader[4] = cmd;
}
You no longer need *cmd, because cmd is not a pointer, therefore you do not need to dereference it to get it's value
Hope this helps.
Upvotes: 1
Reputation: 99234
Should be something along the lines of :
void SetCommand( unsigned char cmd ) {
iHeader[4] = cmd;
}
const unsigned char test = '\x72';
unsigned char iHeader[32];
you're trying to assign a point to a single byte, which won't work.
Upvotes: 2
Reputation: 13028
Because you are passing a pointer to character string, not a single character. *cmd
dereferences the first character in the array.
Because static strings are in a read-only data segment. Thus any pointers to them should be read only.
Upvotes: 0
Reputation: 170499
You need *cmd
because in order to retrieve the char
value you need to dereference the char*
pointer and that requires using the * operator.
You need to declare test
as const
because you make it point to a constant string literal - assigning an address of a constant literal to a pointer to non-const (char*, not const char*) violates const-correctness and is prohibited,
Upvotes: 4