Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Friday, December 18, 2015

For loop with pointer in C

For loop with pointer in C


I'm learning C and I have a question about a for loop with a pointer in it.

The teacher showed me this code and asked me to explain it to him during the following week, but [...]

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?

He said we will add to the code next week, but I need to understand for loop in this case.

Answer by Joe for For loop with pointer in C


It takes advantage of the fact that the terminator to the string (eventually found by that for loop) will be a NUL, which is a zero, which also happens to evaluate to false, thus terminating the loop.

It's worth noting the difference and similarity between 0, false, NULL and ASCII NUL. See this question: What is the difference between NULL, '\0' and 0

Answer by errikos for For loop with pointer in C


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.

Answer by KeylorSanchez for For loop with pointer in C


This could be rewritten like this

for (p = str; *p != '\0'; p++)  {      // Code  }  

In C, a string must always be terminated by a null character, which is the same as '\0' or 0.

Answer by Manos Nikolaidis for For loop with pointer in C


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"

Answer by J. Sy for For loop with pointer in C


String in str

As you can see from the picture, for loop starts with *p where p points the str. At this point *p has S.

When continuously looping the for, it finally reaches to str[9] which has '\0' which means NULL.

At this point the condition statement *p in for (p = str; *p; p++) is equal to NULL so the code will break from the for loop.

Answer by Zaibis for For loop with pointer in C


Lets analyze it the dry but depth way!

Or as D. Ritchie would say: Let's do it with the power of assembly language and the convenience of ? assembly language.


I'll try to explain all necessary aspects by referencing the ISO/IEC:9899 (emphasis mine)- C99 standard. (The post style is motivated by Donald Knuth's phrase "Science is what we understand well enough to explain to a computer. Art is everything else we do. ")

First of all, lets inspect what exactly is the for-loop supposed to do!

Referring to ISO/IEC:9899 6.8.5 "Iteration statements"

Semantics

4 An iteration statement causes a statement called the loop body to be executed repeatedly until the controlling expression compares equal to 0.

So far nothing new I guess, so lets get it on:

6.8.5.3 The for statement

1 The statement for ( clause-1 ; expression-2 ; expression-3 ) statement

behaves as follows: The expression expression-2 is the controlling expression that is evaluated before each execution of the loop body. ...

So we now know the body (in your case // Code) will be executed as long the beforehand evaluated value of your *p is not zero.

... The expression expression-3 is evaluated as a void expression after each execution of the loop body.[...]

So now we know, (I assume digging up p++'s definition is not necessary?!) that for each iteration p increments, so there may be a change in *p.

The following point is not related, but I'm adding it since this makes the Semantic part of for complete and its well to know since its the reason, why for(;;) is a inf-loop.

2 (---) Both clause-1 and expression-3 can be omitted. An omitted expression-2 is replaced by a nonzero constant.

Ok, that's the dry but information-enriched part of what the for loop does in your case.

Now lets get over to pointer arithmetic:

6.5.6 Additive operators

Constraints

2 For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to an object type and the other shall have integer type. (Incrementing is equivalent to adding 1.)

So in your case you are adding 1 (integer) to the "pointer to an object"-type.

What is equivalent to increasing the Address by the sizeof its pointed to type like shown in this picture:

enter image description here

Now lets see what *p actually does.

6.5.3.2 Address and indirection operators

Constraints

[...]

2 The operand of the unary * operator shall have pointer type.

Semantics

[...]

4 The unary * operator denotes indirection. If the operand points to a function, the result is a function designator; if it points to an object, the result is an lvalue designating the object. If the operand has type ??pointer to type??, the result has type ??type??. If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined.

This is a bit dry again1 but for better understanding this can be reverse engineered by:

6.5.2.1 Array subscripting

[...]

Semantics

2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))).

So *((p)+(0)) what is(since p+0 is same as p... obvious) is equal to p[0], is doing nothing else as evaluating p's object.

And since we know, expression-2 of a for loop is interrupting the iteration if it is evaluating 0, we can say it is the same as p[0] != 0.

Now the final step

Lets just look onto the C-Coder's Friend; JSSCA... No, wait...our friend was called... ASCII Now as that's clarified, we can figure out what the 0 is representing.

It is the NULL-token that in C is designating the end of a string.


So conclusive:

All, this is doing is:

Iterating the body of that for-loop, until p is actually pointing to the address, where the object evaluates to the "end of string"-token.

Or:

Let p go through the string until the end is reached.


And now just to cite my self; Something you never should forget:
(emphasis mine.....)

A variable is declared through a declarator(type-specifier) that precedes the identifier which names an lvalue object that can be evaluated to its value

It is neither more nor less!


1That is, what I promised! ;)

Answer by terence hill for For loop with pointer in C


What does the *p do in the loop?

enter image description here

Following the imaginary advice of Jessica (who is actually citing D. Knuth (1)), we will try in this answer to actually see what *p means in the following loop:

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

About the unary operator

?The unary operator * is the indirection or deferencing operator; when applied to a pointer, it access the object the pointer points to.? (B. Kernighan and D. Ritchie (2))

So *p is the value pointed by p:

enter image description here

What the for loop actually do

Looking at the for loop we have 3 instructions:

  1. p = str
  2. *p
  3. p++

In 1. we assign the pointer to the array str to p. In fact, in C: ?By definition, the value of a variable or expression of type array is the address of element zero of the array? (K & R (2)). Which means that str is the address of element zero of the array and:

p = &str[0] and p = str

The above equalities are explained in the following: ?In evaluating a[i], C converts it to *(a+i) immediately. ?. it follows that &a[i] and a+i are identical? (K & R (2)). We conclude that, at the beginning of the loop, p points to the first element of str.

The core of the question

Let's move to the second point, the core of your question: the instruction ?*p? . This is equivalent to *p != 0 (as pointed out by @errikos in his answer) so that the loop exit condition is simply: when the value pointed by p is zero, exit. Here, we also point out that str has been initialised:

char str[128] = "Some Text";  

and that: ?all string constants contain a null termination character (\0) as their last character? (gnu-manual).

The instruction p++ (point 3.) advances the pointer p to the next element of the str array, thus, at the 9-th iteration *p became 0 (or \0, NULL, NUL, see the answer from @Joe) and the loop exits.

See to believe

A picture is worth a thousand words, here is a graphical representation of the loop:

enter image description here

The same usage of *p in a different example

In the following snippet *p is used the same way but in a while loop:

#include   int main() {      char str[128] = "We all scream for ice cream!";      char *p = str;      // here we see again the loop exit condition *p == '\0'      while(*p) {          printf("%c", *p);          p++;      }      printf("\n");  }  

Short poetry

Poetically, I tried to represent the struggling of *p in the loop:

Brave C *p(rogrammers)

In the loop of whilederness

The NUL will stop them

This is an haiku poem, it consists of three lines, with the first and last line having 5 syllable, and the middle line having 7.


May the for(;*C;)e be with you!


References

(1) Vol. I, Fundamental Algorithms, Section 1.1 (1968)

(2) The C Programming Language Pg 94-99

Answer by machine_1 for For loop with pointer in C


It can be explained as follows :

for( initialization ; Conditional Expression ; expression3)  {      Code here will execute while 2nd Expression(Conditional Expression) is true      true means non-zero value      '\0' is equivelant to 0,so when *p equal '\0' : loop will terminate  }  

Answer by chqrlie for For loop with pointer in C


A long time ago, in a PDP far, far away, resources were scarce, names got short: i for index, p for pointer would please early Jedi programmers.

Implicit tests told the truth in for condition space. A single * was all they typed, trusting p and pushing it to the end of strings.

To this day, they use the for(e = s;*e;e++) most familiar and elegant loop to defy the C++ empire and its cohorts of ctors, dtors and vile iterators. Bare bits and bytes against templates, exceptions and obscure types, only the brave still dare for C to fight, and uncast the void *.

Answer by Elyasin for For loop with pointer in C


That is the condition part of the loop.
If that condition is not met then the loop is not executed anymore.
*p dereferences the pointer p and returns the character pointed at in the string str.
The C-style string str is terminated by the value \0.
The loop iterates over each character (using p) until the condition is not met.

In C a value of 0 or \0 is like the meaning offalse, i.e. condition is not met.
Any other value is like the meaning of true, i.e. condition is met.

In short, p iterates over each character in str and stops as soon as it hits the string termination character \0.

Why not using p instead of *p?
Because p is a pointer and contains an address. It's sometimes hard or even not possible to use address arithmetic only. It's not good practice and makes code hard to read.
*p is the dereferenced pointer and contains the value that p points to. In this case it is easy to use the values that p points to, because you know the string is terminated by a \0. As a condition (if, while, etc.) *p is equivalent to *p != '\0'.


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 71

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.