Author Topic: C string  (Read 273 times)

0 Members and 1 Guest are viewing this topic.

Offline PerranOak

  • Frequent Contributor
  • **
  • Posts: 329
  • Country: gb
C string
« on: May 05, 2020, 02:05:00 pm »
This code calls a function to send a text string to an LCD display:

      lcdputs( "LCD test " );

other code

       void lcdputs(const char *s)
       {
         while( *s )
           lcdwrite( *s++ );
       }

Am I right to interpret this as:

1. pass the string "LCD test " to the function lcdputs.
2. lcdputs receives not the string but the address of the string and represents this as *s.
3. while the character contained in the address *s is not zero ...
4. pass the character contained in the address *s to the function lcdwrite and after returning...
5. increment the address pointer (correct term?) by one to get the next character in the string.
6. the final character is a space which triggers the while loop to end somehow.

Cheers.
Some light can never be seen!
RJD
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 7400
  • Country: us
Re: C string
« Reply #1 on: May 05, 2020, 02:15:46 pm »
while (*s) loops for every character that is non-zero.  By definitions, C strings are terminated with a NULL character which is \0 or zero.  The while expression fails when *s points to the NULL character.

This is a very common construct in C.

The string "LCD test " is actually 10 bytes long with a trailing NULL.  Whether the space after 'test' is required depends on what is to be written next but it is still a non-NULL character so it will get displayed.  You just won't see it.

You might want to have the space if you were going to append another string on the same line.  Otherwise, it serves no purpose.
« Last Edit: May 05, 2020, 02:18:28 pm by rstofer »
 

Online HwAoRrDk

  • Frequent Contributor
  • **
  • Posts: 739
  • Country: gb
Re: C string
« Reply #2 on: May 05, 2020, 02:25:43 pm »
3. while the character contained in the address *s is not zero ...
...
6. the final character is a space which triggers the while loop to end somehow.

You had the correct answer for the termination condition in step 3. :)

To add to what rstofer said:

Whenever you write a string literal in C (e.g. "a string") it implicitly contains a terminating NUL character at the end. So if you were to look at a hex dump of the memory where your example string is stored, it would look like:

Code: [Select]
L  C  D     t  e  s  t   
4C 43 44 20 74 65 73 74 20 00
 

Offline PerranOak

  • Frequent Contributor
  • **
  • Posts: 329
  • Country: gb
Re: C string
« Reply #3 on: May 05, 2020, 03:04:28 pm »
Brill, cheers both.

BTW is the rest of what I said a correct interpretation?
Some light can never be seen!
RJD
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 1598
  • Country: us
  • Formerly SiFive, Samsung R&D
Re: C string
« Reply #4 on: May 05, 2020, 03:27:12 pm »
All correct except point 6. It's the 0 character the compiler adds to the end of your string that makes the loop end, not the space. The space will be printed.

As for point 1 ... strings in C are just arrays of characters. Your constant string is an array of 10 characters which the compiler stores somewhere in the program.

C can't copy an array from one variable to another, or pass an array as a function argument. Any time you use an array it is actually just the address of the first item in the array.

If you want to copy an array from one place to another you need to write a loop to copy it item by item (characters in this case), or call a function such as strcpy() or memcpy() which has a loop inside it.

The compiler *will* copy a struct from one variable to another, including  any arrays contained inside it. Weird huh?
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 5439
  • Country: fr
Re: C string
« Reply #5 on: May 05, 2020, 06:56:04 pm »
This code calls a function to send a text string to an LCD display:

      lcdputs( "LCD test " );

other code

       void lcdputs(const char *s)
       {
         while( *s )
           lcdwrite( *s++ );
       }

Am I right to interpret this as:

1. pass the string "LCD test " to the function lcdputs.

Yes. Well, to be precise, not the "string" as an object, but a pointer to it.

2. lcdputs receives not the string but the address of the string and represents this as *s.

As per 1. lcdputs() receives as its only argument a pointer to the string. 'const char *' represents a pointer to a char. Could be a single char, or a consecutive buffer of several chars.
The 'const' qualifier has two purposes: gives an hint to the developer that the function WILL NOT modify the "string" that is pointed to (so you can consider this as a "read-only" qualifier here), and effectively prevents modifying the content of the string inside the lcdputs() function. If you attempt to write code that does, the compiler will complain.

3. while the character contained in the address *s is not zero ...

Yes. Although I prefer saying "pointer" than "address". Whereas pointers in C are often effectively addresses, they could be anything really. Just call them pointers.
'*s' represents a dereference, thus the object pointed to by the pointer 's'. (Which is effectively the corresponding char here.)

4. pass the character contained in the address *s to the function lcdwrite

The address (again I prefer pointer) is not '*s', it's 's'. You really need to get that if you want to understand pointers in C. '*s' is not a pointer, it's a dereference of a pointer.
What may confuse you (or beginners in general) is that declarations of pointers use the '*' symbol (to indicate they are pointers), but in any expression using pointers, '*' is the dereference operator.
Two different things.

5. and after returning... increment the address pointer (correct term?) by one to get the next character in the string.

Not really. The pointer's post-incrementation here is guaranteed in C to be executed AFTER the dereference (so '*s++' effectively corresponds to the same char as '*s'), but it's not guaranteed to be incremented AFTER the function call here (as it's passed as a parameter). Not that it really matters here, but do not expect expressions in function arguments to be evaluated in any particular order.

6. the final character is a space which triggers the while loop to end somehow.

No, here the only character that will end the loop is 0. 0 is not a space. It's just conventionally the marker of the end of a - you guessed it - zero-terminated string (which is the convention with C strings.)

And there is no "somehow". ;)
The loop will end upon a nul (0) character because 0 as a condition in C is considered false. That's all there is to it.

To make the intent a bit more clear, I tend to prefer writing this as: while (*s != 0). But it's strictly equivalent in C.
« Last Edit: May 05, 2020, 07:00:37 pm by SiliconWizard »
 
The following users thanked this post: PerranOak

Offline PerranOak

  • Frequent Contributor
  • **
  • Posts: 329
  • Country: gb
Re: C string
« Reply #6 on: May 06, 2020, 03:59:11 pm »
Wow cheers mate! I think I'm really beginning to get pointers now.
Some light can never be seen!
RJD
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf