I don't understand what a pointer does in the for loop. What does the *p do in the following loop?

char str[128] = "Some Text";
char *p;

for (p = str; *p /*what does this mean?*/; p++)
{
    // Code
}

I do understand the rest, but why isn't *p like p > 3 or something like that?
Why is it alone?
Why is it written that way?


Solution 1:

In a Boolean context such as the condition of a for loop, each expression in C evaluates to true (non-zero) or false (zero).

You want the for loop to terminate, when it reaches the end of the string.

In C, each string is terminated with the character '\0', which is practically 0. So, when the for loop reaches the end of string, *p evaluates to '\0', which is 0, which evaluates to false, which terminates the for loop.

Solution 2:

The for loop will terminate if whatever lies between the two ; in the statement is zero (false). *p dereferences p and returns the char, p points to. According to Dennis Ritchie "C treats strings as arrays of characters conventionally terminated by a marker". That marker is the null character with (ASCII) value of zero. So, this for loop :

for (p = str; *p; p++)

is equivalent to these

for (p = str; *p != '\0'; p++)
for (p = str; *p != 0; p++)
for (p = str; p[0] != '\0'; p++)

Another name for the null terminating character is sentinel or according to Donald Knuth "dummy value" (Art of Computer Programming, Volume 1). Here is a diagram of the str string, the indexes (offsets from the start) of each character and the values at each index :

enter image description here

For completeness and after a request at the comments here is what the debugger sees in the memory block that str occupies :

0x00007fffffffe6a0:
  0x53 0x6f 0x6d 0x65 0x20 0x54 0x65 0x78 0x74 0x00 0x00 0x00 0x00 0x00 0x00 0x00
     S    o    m    e         T    e    x    t
  1. The hex value at the first line is the address (64bit) of this memory block. That's where p points to at the start of the for loop.
  2. On the 2nd line you see the hex values of the letters in your string. You can see an ASCII table here. The last char in your string is t with hex value of 0x74. After that you have the string's null character 0x00. Then you see a few more null characters because I built in debug mode and the compiler zero-initialized. Normally you would see garbage (seemingly random values)
  3. On the 3rd line I added the chars of your string for reference

I understand you are on precipitous learning curve at the moment with pointers in C, but eventually you'll be able to say "I C the point"

Solution 3:

Before diving in, I would like to state a simple rule in C regarding an expression

When C requires the Boolean value of an expression, a false value is inferred when the expression compares equal to zero, and a true value otherwise. That is, whenever one writes

if(expr)

where expr is any expression at all, the compiler essentially acts as if it had been written as

if((expr) != 0)  

Now coming to your question:

What does the *p do in the following loop?

In C, strings are terminated by a null character '\0'.

enter image description here

Every character has a decimal equivalent. This '\0' is an ASCII escape character. The decimal equivalent of '\0' is 0.

So, the expression *p in loop just check that the decimal equivalent of character at the memory address pointed by p is either a zero or non-zero. When p reaches the end of the string and finds the first '\0' character, the expression *p returns1 a zero value. A zero means false in C. This is equivalent to testing *p != '\0' or *p != 0 as stated above.

This is how it works:

enter image description here


1 When *p evaluates then the value of *p is fetched from memory. This value is the value of expression *p.