vgoshat:
Why when I change the: char *message = "Hello"; to char message = "Hello"; the compiler gives me this error: invalid conversion from 'const char*' to 'char' ? What is the purpose of the '*' sign?
OK...
char message; assigns the name "message" to a one byte area in memory. That one byte area is pointed to by either a 16, 32 or 64 bit pointer (pointer size depends on the processor and compiler).
But, only one byte of memory is allocated, so, ALL you can do is something like this:
char message = 'A';
That is, you can only store one byte in it. If you try this:
char message = "Hello there";
The compiler gives you an error because it cannot put a whole string in one byte.
Now look at this (note the * character)
char *message = "Hello there";
What this does is tell the compiler to assign storage space for 12 bytes ("Hello there" plus a null terminator). The * character means that now the variable name "message" points to the memory address of the first character (i.e. the letter "H").
The compiler counted how many characters were in the string, reserved memory for them and finally returned a pointer to it for you to use.
Here's an example of what the memory map would look like:
char *message = "Hello there";
ADDR DATA
0x0120 H
0x0121 e
0x0122 l
0x0123 l
0x0124 o
0x0125 <space>
0x0126 t
0x0127 h
0x0128 e
0x0129 r
0x012A e
0x012B 0x00H
....
....
....
message
0x0150 0x20
0x0151 0x01
You see? The STRING "message" is stored starting at address 0x0120. The variable that points to it is stored at address 0x0150 and 0x0151 (a 16 bit location, and "little endian" backwards) and it contains the value "0x0120" (the start address of the string).
Now check this code out. I did it in Linux, but you can also do it in Arduino. Just change the "fprintf" calls to "Serial.print()".
If you do this, note the differences in:
- The size of the pointers
- The addresses things are stored at
#include <stdio.h>
#include <string.h>
int main (void)
{
char *message = "Hello there";
unsigned long str_len = (strlen (message) + 1); // grab the null too
unsigned long ptr_siz = sizeof (message);
unsigned long ptr_to_ptr_siz = sizeof (&message);
unsigned long char_siz = sizeof (char);
unsigned long char_ptr_siz = sizeof (char *);
int x;
fprintf (stdout, "The length of the string (including the null) is %lu\n", str_len);
fprintf (stdout, "The string is %s\n", message);
fprintf (stdout, "The string starts at 0x%08X\n", message);
fprintf (stdout, "The address of the pointer to 'message' is 0x%08X\n", &message);
fprintf (stdout, "The pointer to 'message' uses %lu byte%s\n", ptr_siz, (ptr_siz == 1) ? "" : "s");
fprintf (stdout, "The pointer to the address of 'message' uses %lu byte%s\n", ptr_to_ptr_siz, (ptr_to_ptr_siz == 1) ? "" : "s");
fprintf (stdout, "The size of a char in memory is %lu byte%s\n", char_siz, (char_siz == 1) ? "" : "s");
fprintf (stdout, "The size of a char POINTER in memory is %lu byte%s\n", char_ptr_siz, (char_ptr_siz == 1) ? "" : "s");
fprintf (stdout,
"\n"
"Address\t\tData\tChar\n"
"=======\t\t====\t====\n"
);
for (x = 0; x < str_len; x++) {
fprintf (stdout, "0x%08X\t0x%02X\t %c\n", (message + x), message[x], message[x]);
}
fprintf (stdout, "\nBye!\n");
return 0;
}
And running it produces:
The length of the string (including the null) is 12
The string is Hello there
The string starts at 0x004009B8
The address of the pointer to 'message' is 0xE2395968
The pointer to 'message' uses 8 bytes
The pointer to the address of 'message' uses 8 bytes
The size of a char in memory is 1 byte
The size of a char POINTER in memory is 8 bytes
Address Data Char
======= ==== ====
0x004009B8 0x48 H
0x004009B9 0x65 e
0x004009BA 0x6C l
0x004009BB 0x6C l
0x004009BC 0x6F o
0x004009BD 0x20
0x004009BE 0x74 t
0x004009BF 0x68 h
0x004009C0 0x65 e
0x004009C1 0x72 r
0x004009C2 0x65 e
0x004009C3 0x00
Bye!
Notice that my test shows 8 byte (64 bit) pointers. I'm using 64 bit linux. You will probably see 2 byte (16 bit) pointers if you run this on an Arduino.
Hope this helps explain pointers........ 
-- Roger