Reputation: 31
I have a piece of code that has the following lines:
char* someString = "Blah"
char* someOtherString = someString;
if (someString) {
while (*someOtherString) {
printf("%d\n",someOtherString);
++someOtherString;
}
--someOtherString;
}
This prints out:
4206692
4206693
4206694
4206695
How does it even work? I get that it goes through the if statement as true because someString can be interpreted as a true condition, but how does it exit the while loop?
When I type the while loop by itself like so, I the loop goes infinitely:
while (*someOtherString) {
printf("%d\n",someOtherString);
++someOtherString;
}
Thanks for help in advanced!
Upvotes: 1
Views: 3433
Reputation: 22477
The while loop exits when it finds the NUL
character at the end of the "string".
In C, declaring and assigning constant strings inside double-quotes declares a null-terminated string. Memory equal to the
number of characters in side the double-quotes + 1 (for the trailing NUL
character) is allocated. Each of the characters is stored sequentially in the memory block and a NUL
character is automatically assigned to the end of the memory block.
Thus "Blah" is stored in memory as
B
L
A
H
\0
Intially someOtherString
and someString
both point to B
.
someOtherString
is incremented to point to the next character in each iteration of the while loop. So after 4 iterations it ends up pointing to the null character.
A while loop running on un-initialised data could run for a large number of iterations as there is no guarantee that it will encounter a
NUL
character (byte =0x00
).
Finally a list of popular functions and extensions for processing strings in C.
Upvotes: 3
Reputation: 61910
This is just a technique to scan through a string.
When you just tell char *string1 = "hello"
the starting address of the string will be stored inside the variable char *string1
and not the string. One practice is to assign a pointer to NULL
when it is not used, instead allowing the old address values in it, which now is not valid. Therefore if at some point we did string1 = NULL
, then the if (string1)
will be false, becaues NULL
evaluates to 0.
a1 a2 a3 a4 a5 a6
+-----+-----+-----+-----+-----+-----+
string1 = | h | e | l | l | o | \0 |
+-----+-----+-----+-----+-----+-----+
Whereas when we do *string1
it is basically in the form *(string + x)
. Depending on the type of the pointer string1
, x
elements will be skipped first, then *
will do the dereferencing at the location, x
elements away from the address what is stored in string1
.
a1 a2 a3 a4 a5 a6
+-----+-----+-----+-----+-----+-----+
string1 = | h | e | l | l | o | \0 |
+-----+-----+-----+-----+-----+-----+
^
|
+-------------+
|
*(string1 + 3) same as string1[3]
Therefore doing *string1
will fetch the value pointed by the address stored in string1
.
Therefore
if (string1)
{
while (*string1)
{
count++;
string1++;
}
}
This will enter the if
iff the address stored in the string is not NULL, ie some valid address is assigned (if we follow the convention to assign NULL to unused). *string
will be true until the address stored in string1
in a specific iteration points to a non-zero value. C strings are terminated with a NUL character which is '\0'
and has an ASCII value 0
. In each iteration we do string1++
, this will increment the address value stored, and after each increment the value of string1
will point to the next element adjacent (first a1
then a2
etc). When it points to the address where '\0'
is stored, *string1
will be 0 and while (*string1)
is false thus breaks out of the loop.
Upvotes: 2
Reputation: 54796
Your string literal is stored in memory like:
{'B', 'l', 'a', 'h', '\0'}
...where '\0' is the null character (i.e. a character with a value of 0 when interpreted as an integer).
So eventually (after 4 increments), *someOtherString
will evaluate to 0, which will be interpreted as false
and end the loop.
I'm not sure how you're getting the infinite loop. Your cut-down versions works just fine in ideone: http://ideone.com/4fTDJb
Upvotes: 0