1

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.

4
  • 1
    Please link to the tutorial in question. If it claims to be for C++, and is using a char* as a string, it sounds a little fishy to me. Commented Dec 12, 2013 at 21:38
  • Please find a good book, this tutorial doesn't sound that great - stackoverflow.com/q/388242/1496443 Commented Dec 12, 2013 at 21:40
  • "the input to the function is a char type variable" - which function are you talking about? Send_A_String or Send_A_Character? Commented Dec 12, 2013 at 21:40
  • You aren't modifying the string. Therefore, there's absolutely no reason to use a non-const char *. In C++, there's little enough reason to use a const char *, let alone that. Commented Dec 12, 2013 at 21:42

6 Answers 6

2

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').

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

1

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

Comments

1

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.

Comments

1

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.

Comments

-1

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++ );
   }
}

4 Comments

Send_A_Character( *++StringOfCharacters ); Are you sure?
What makes you think Send_A_Character should expect a pointer? And why the pre-increment? That just leaves out the first character, only to send the final NUL byte at the end instead.
There are two functions here, not sure how you can see a stack overflow without seeing the Send_A_Character implementation.
Ah i did not see that Send_a_String and Send_A_Character are two different function.:) I am sorry. I will uodate my post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.