Reputation: 395
for (i = 0; *(str+i); i++)
{
//some code;
}
What is meant by the second condition in this syntax? Can we write it like this?
Upvotes: 3
Views: 191
Reputation: 311068
Such loops usually used for arrays that have a sentinel value that can be converted to a bool value. For example for strings. (Strings are terminated by zero character)
For example this loop calculates length of string literal "Hello"
const char *str = "Hello";
size_t i = 0;
for ( ; *( str + i ); i++ )
{
/* empty body of the loop */
}
std::cout << "The length of string literal " << str
<< " is equal to " << i << std::endl;
Or in C you can use printf
printf( "The length of string literal %s is equal to %zu\n", str, i );
Expression *( str + i )
is equivalent to str[i]
In the for loop this expression used like the condition is equivalent to
*( str + i ) != 0
That is it is just converted to type bool
( bool ) *( str + i )
So if the expression is equal to 0 then it yields false
otherwise true
.
Another example. If you want to output program parameters then you can write the following way
#include <iostream>
int main( int argc, char *argv[] )
{
while ( *argv ) std::cout << *argv++ << std::endl;
}
Ot in C
while ( *argv ) puts( *argv++ );
Because the last element of the array with program parameters argv[] is always equal to NULL.
The while loop in the program is equivalen to the following for loop
for ( int i = 0; *( argv + i ); i++ )
Or
for ( int i = 0; argv[i]; i++ )
From the C++ Standard (5.2.1 Subscripting)
1 A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall have the type “array of T” or “pointer to T” and the other shall have unscoped enumeration or integral type. The result is of type “T.” The type “T” shall be a completely-defined object type.65 The expression E1[E2] is identical (by definition) to *((E1)+(E2))
The same is valid in C.
Upvotes: 5
Reputation: 362
The statement is correct. Yes, we can use it as *(str+i) it will run until the end of the string. Where as *provide value at particular address.
Example:
char str[5]={"test"};
cout<<*str; // it will always give default first index value
cout<<*(str+1) // it will display first character of string
So when it gets to the end of the string it will become null. The end of the string is always a null character. So then Loop will terminate.
Upvotes: 2
Reputation: 73394
Yes it is. str
is a pointer, thus when the string null terminator ('\0'
) is reached, the condition will be false, making the loop stop from executing its body.
Imagine that the string will be something like this:
str: 'a'|'b'|'\0'
i: 0 | 1 | 2
So when i
gets the value 2, then this *(str+i)
will give 0, thus your loop will be like this at that time:
for (i = 0; 0; i++)
since the pointer arithmetic will result in *(str+i)
to point to the last entry of the string.
Upvotes: 3
Reputation: 134356
Just to add clarity, the for
loop construct
for (i = 0; *(str+i); i++)
can be re-written as
for (i = 0; str[i]; i++) //pointer arithmetic
which can be re-written as
for (i = 0; (str[i] != 0); i++) //condition checking
so, essentially, the *(str+i)
is a condition checking statement (similar to the most-widely used condition checking statements involving <
/ >
operators), which is perfectly valid and legal.
The purpose it serves is, looping until the i
th element is not null.
A null
has a decimal value of 0, FWIW.
Upvotes: 1
Reputation: 206697
In its most generic form, the for
loop contains the following elements:
for ( init-statement; condition-statement; iter-statement ) statement
What goes in each of those elements is very open. In your case, the condition-statement is just *(str+i)
. If it evaluates to a non-zero value, the statement part of the loop will be exeucted. If it evaluates to a zero value, the loop will be terminated.
When you want to execute statement a given number of times, you can use:
for ( i = 0; i < count; ++i ) { ... }
Assuming str
in your code points to null terminated string, you are executing statement for all the characters in str
. Your for
loop is equivalent to:
for (i = 0; str[i] != '\0'; i++)
Upvotes: 2
Reputation: 8839
The second statement in the loop checks for a condition to be true. If the condition is true, the loop continues; if it is false, the loop is terminated. Additionally, C considers 0
to be false
and anything non-zero to be true
. So, *(str+i)
evaluates to true
if it is non-zero and false
if it is zero. Since each string in C is a character array that is terminated by \0
(or zero which evaluates to false
), looking at the string terminating character evaluates to false
and hence, the statement is legal and valid.
For more on why it happens like this in C, it is a side effect of loading something in the accumulator of the Arithmetic Logic Unit (ALU) which results in setting of some flags (such as whether ACC is zero).
Upvotes: 1
Reputation: 106092
*(str+i)
is equivalent to str[i]
provided that str
is a pointer to some data type. This is a valid syntax.
It seems that str
is a null terminated string. This condition will false
when *(str+i)
will be equal to '\0'
.
Upvotes: 2