Reputation: 13
I am working on learning to program microcontrollers using C++. NewbieHack.com has a great tutorial but I am stuck on a section dealing with pointers.
In his code, he writes a function called Send_A_String
void Send_A_String(char *StringOfCharacters)
{
while(*StringOfCharacters > 0)
{
Send_A_Character(*StringOfCharacters++);
}
}
In his int main() section of code, he calls the function the following way
Send_A_String("NewbieHack.com");
The use of "NewBieHack.com" is confusing to me because the input to the function is a char type variable. How does using a pointer allow you to assign strings to char type variables?
I apologize if this isn't worded clearly. Any help would be greatly appreciated.
Upvotes: 1
Views: 212
Reputation: 75688
It is not a char type. It is a pointer to char char *
. You can see a pointer as the starting address of an array, so you basically have an array of char, witch is in effect a string.
*StringOfCharacters
here it dereferences the pointer, meaning the char at the address StringOfCharacters
.
*StringOfCharacters++
this must be broken in two: StringOfCharacters++
increments the pointer, so now the pointer points to the next char in array (please note that this is pointer arithmetics), but since it is operator postfix increment, it will return the old pointer value for the next part :*StringOfCharacters
witch again dereferences the pointer, giving you a char. Hope I was clear.
Upvotes: 1
Reputation: 607
What's happening is something like this.
The literal "NewbieHack.com" is really pointer to a 'string' (or array) of characters that is null terminated by the compiler. This resides in a segment of RAM somewhere at a given address, e.g.
0xface0000 = 4E 65 77 64 69 65 48 61 N e w b i e h a
0xface0008 = 63 6B 2e 63 6f 6D 00 c k . c o m \0
when invoking the function in your example
Send_A_String("NewbieHack.com");
the compiler is passing the address to the function. As such, Send_A_String is looping through the characters in the string, printing them out until it encounters the the null character (or 0).
There is a subtle difference in the syntax here that is important. In the function definition that lists the arguments 'char *StringOfCharacters' means that StringOfCharacters is a pointer (an address) to a character. Later, the syntax (*StringOfCharacters > 0) says deference the address contained in the variable StringOfCharacters and use the value there. The use of the '*' does not have the same meaning in both cases. I'll see if I can illustrate:
void Send_A_String(char *StringOfCharacters) /* StringOfCharacters = 0xface0000 */
{
while(*StringOfCharacters > 0)
/* iteration 1 : *0xface0000 = 0x4E or 'N' so print it out below */
/* iteration 2 : *0xface0001 = 0x65 or 'e' so print it out below */
/* iteration 3 : *0xface0002 = 0x4E or 'w' so print it out below */
...
/* iteration 15 : *0xface000e = 0x00 or 0 or NULL so stop */
{
Send_A_Character(*StringOfCharacters++);
/* here the *StringOfCharacters gets done first */
/* the ++ is applied after the function returns */
/* iteration 1 : print 'N' then increment, StringOfCharacters now = 0xface0001 */
/* iteration 2 : print 'e' then increment, StringOfCharacters now = 0xface0002 */
/* iteration 3 : print 'w' then increment, StringOfCharacters now = 0xface0003 */
...
/* iteration 14 : print 'm' then increment, StringOfCharacters now = 0xface000e */
}
}
Hope that helps.
Upvotes: 1
Reputation: 49976
Writing :
Send_A_String("NewbieHack.com");
is actually the same as writing below
const char* sz = "NewbieHack.com";
Send_A_String(sz); // with dangerous conversion const char* -> char*
a more correct version would be:
char sz[] = "NewbieHack.com";
Send_A_String(sz);
at least no warning should be emited. But actually Send_A_String should have its parameter changed to const char*, since its not changing string chars, but only incrementing pointer.
[edit]
if what confuses you is the following line:
Send_A_Character(*StringOfCharacters++);
then you can rewrite it as follows:
StringOfCharacters++; // increment pointer to next char
char c = *StringOfCharacters; // dereference pointer to get char
Send_A_Character(c); // use char
now it should be easy to grasp whats going on
Upvotes: 1
Reputation: 310950
This function is invalid. First of all this call
Send_A_Character(*StringOfCharacters++);
shall not be compiled bacause expression *StringOfCharacters++
is not a pointer.
Moreover there is no any sense to call (if the above call contains a typo)
Send_A_Character(StringOfCharacters++);
because you will get stack overflow.
Also this condition
while(*StringOfCharacters > 0)
should be changed to
while( *StringOfCharacters )
becasue type char can behave as signed char.
I would rewrite the function the following way
void Send_A_String( const char *StringOfCharacters )
{
while ( *StringOfCharacters )
{
Send_A_Character( ++StringOfCharacters );
}
}
EDIT: I am sorry. I did not see that there are two different functions Send_A_String and Send_A_Character.:) so I changed the function the following way
void Send_A_String( const char *StringOfCharacters )
{
while ( *StringOfCharacters )
{
Send_A_Character( *StringOfCharacters++ );
}
}
Upvotes: -1
Reputation: 151
The reason this works is that "NewbieHack.com"
is a null terminated char array which can be visualised as {'N', 'e', 'w', 'b', 'i', 'e', 'H', 'a', 'c', 'k', '.', 'c', 'o', 'm', '\0'}
.
So when you make the Send_A_String("NewbieHack.com")
call, the const string "NewbieHack.com"
will be casted to a const char*
which points to the beginning of the char array ('N' in this case).
In the while loop you will iterate the char array until you hit the end of the char array (which is '\0').
Upvotes: 2
Reputation: 4041
Albeit this is dubious, as per polkadotcadaver's comment, I'll explain.
(Unprefixed) String literals are actually of type const char[], not std::string. char[] actually decays to char* when the function is called. Send_A_String is not const-correct (as it should indeed accept const char*), but that probably only results in a warning from your compiler.
Notice that the input is not a char-type variable but a pointer-to-char-type variable! This makes all the difference. So the const char[] "NewbieHack.com" decays to const char* which is compatible with char*.
Now the pointer points to the first char of the char[], that's 'N'. Since it's a pointer, you need to dereference it using the operator* in order to get to the char.
The loop tests for end-of-string ('\0'), the call then calls Send_A_Character with the dereferenced pointer, i.e. the character the pointer points to, and advances the pointer by one. Hence, the pointer now points to the second character of the char[], 'e'. And so on and so forth until the end is reached.
Upvotes: 1