user3097206
user3097206

Reputation: 13

Using pointers with char type variables

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

Answers (6)

bolov
bolov

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

maha
maha

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

marcinj
marcinj

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

Vlad from Moscow
Vlad from Moscow

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

ali
ali

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

FRob
FRob

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

Related Questions