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 :
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
- 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. - 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 of0x74
. After that you have the string's null character0x00
. 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) - 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
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:
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
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.....)
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?
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:
What the for loop actually do
Looking at the for loop we have 3 instructions:
- p = str
- *p
- 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:
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