I'm working on hash table codes on C language from my lecturer. There are 2 for that I've never seen before:
for(;t!=NULL;t=t->next)
and
for(;*s;s++)
well it's not like an ordinary for I've known before:
for(value first; value last; value ++ / --)
please kindly provide working example of those for.
for(;t!=NULL;t=t->next)
This loop means you have decleared and initialised t somewhere, so you don't need to initialise again.
for(;*s;s++)
This loop exactly does the same except the terminating condition. The value of *s should be zero for the loop to terminate.
Actually the syntax of for loop is:
for(initialization;boolean_condition;updation)
Any field can be left empty and if the boolean condition is false in some step the loop terminates.
For loop is
for(INIT; COND; AFTERTHOUGHT) {
CODE
}
INIT block runs only once at start of the loop
COND block runs after each iteration and check one need to continue this loop or not
AFTERTHOUGHT blocks runs after each iteration to update some values like counters
In your case
for(;t!=NULL;t=t->next)
There is no INIT block. Seems like it was done before this loop like
Node *t = pointerToRootNode;
for(; t!=NULL; t=t->next) {
// deal with t->data i guess
}
In second case
for(;*s;s++)
Also there is no INIT block. In COND block just dereferencing s pointer. Look at this example.
const char* some_str = "ab";
char* s = some_str;
if (*s) {
puts("It will be printed")
s++;
}
if (*s) {
puts("It will be printed too");
s++;
}
if (*s) {
puts("It will never be printed because *s == 0 i.e end of string");
}
for(;t!=NULL;t=t->next) or for(;*s;s++)
=> the initial condition is not required (assuming t is declared somewhere else)
for(int i = 10; i > 0 ; i --)
=> int i = 0; for (; i > 0; i--)
The first one iterates through a linked list until it reaches the very end, which is the place you could add the next node.
The second one does a similar concept, except it's looking for a value of zero when it dereferences the pointer.
Related
My first question here on forum. I'm not sure why the output of the code is "hi" whereas I'm thinking it should be null. I might be missing here something badly. Help appreciated.
#include <stdio.h>
int main(void)
{
int i = 0;
while (i == 0)
{
printf("hi\n");
i++;
}
}
Your while loop will run what you have enclosed in it up until the stopping condition is false. you have int i = 0 as your starting value and your while loop condition says while (i == 0) to print "hi". Since i = 0, your condition is true one time and will print "hi" once before i increments and becomes false on the next pass.
The output of your code is correct, the while loop is entered because i == 0 and then i changes to 1 so the condition is false on the second iteration which makes the loop end and thus the program too.
You are confusing while loops with until loops (which C doesn't have). The while loop will execute its body while a condition is true, not until it is true. So if you want to print "hi" 10 times, you will need to write
int i = 1;
while (i <= 10) {
printf("hi\n");
++i;
}
#include <stdio.h>
int main(void)
{
int i = 0;
while (i == 0)
{
printf("hi\n");
i++;
}
}
while loop works in such a way that the loop executes only if the condition inside the parenthesis is true. In the above code, the value of 'i' is initially set to 0, which satisfies the condition of the while loop. It enters inside the loop, goes on to print 'hi' and then increments the value of 'i'.
Now the condition of while is again checked. Since the condition fails this time ,as the value of 'i' has been incremented, it exits out of the loop and the program terminates. I hope it answers your question.
like #iharob said, i==0 returns 1 which creates an infinite loop running and printing hi hi hi hi hi
if i was to do them, I would put in an if statement inside the while loop to check if i is still 0 or changed. if its 0, print hi, else, return 0;
it is obvious that the syntax that your are looking for is a do ... while loop
because programs run from up to down and left to right, the moment that your program reaches the while checks the i and it is still 0 but for the next loop it won't print anything because i=1.
I am reading a code of my friend an I see this:
#include <stdio.h>
#include <conio.h>
void main()
{
char string1[125], string2 [10];
int i, j;
printf("\nstring 1: ");
gets(string1);
printf("\nNstring2 : ");
gets(string2);
i = 0;
while (string1[i] != 0)
{
j = 0;
while (string1[i++] == string2[j++] &&string1[i-1] != 0 && string2[j-1] != 0)
;//i dont know what it mean and why we can put ;after while loop
if (string1[i-1] != 0 && string2[j-1] == 0)
printf("\nfound at position %d", i-j);
}
getch();
}
why we can put ; after while loop , anyone can help?
The ; is just a null statement, it is a no op but it it the body of the while loop. From the draft C99 standard section 6.8.3 Expression and null statements:
A null statement (consisting of just a semicolon) performs no operations.
and a while statement is defined as follows from section 6.8.5 Iteration statements:
while ( expression ) statement
So in this case the statement of the while loop is ;.
The main effect of the while loop is here:
string1[i++] == string2[j++]
^^^ ^^^
So each iteration of the loop increments i and j until the whole condition:
string1[i++] == string2[j++] &&string1[i-1] != 0 && string2[j-1] != 0
evaluates to false.
Usually, in a while loop, you have initialization, a comparison check, the loop body (some processing), and the iterator (usually either an addition of an index, or a pointer traversal e.g. next), something like this:
index = 0 // initialization
while(index < 4) { // comparison, loop termination check
printf('%c\n', mystring[index]); // Some processing
index += 1; // iterate to next loop
}
Without at least the last item, you won't ever exit the loop, so normally the loop body has more than one statement in it. In this case, they use post-increments like this:
while (string1[i++] == string2[j++]);
This does the comparison (the ==) and the iteration (the post-increment ++) in the comparison statement itself, and has no body, so there's no reason to add any other statements. A blank loop body can be represented by just a semicolon.
Semicolon is like empty instruction. If we don't put any instruction after while or use loop while with {} we must use semicolon to tell compiler that all we want from while loop is doing this empty instruction.
That is called a semicolon. In programming standards, the ; signifies an end of statement, or in this case that it is a null statement. It is effectively a non operation in the body of the while loop, so it is not actually doing anything.
guys i'm new at programming and i was surprised by the result of post increment value, now i'm bound by confusion after i found out and executed the code below, if for loop says
1. initialize
2. check for condition if false terminate
3. incrementation.
where does i++ happens? where does i value is equal to 1?
int main()
{
int i, j;
for (int i =0; i<1; i++)
{
printf("Value of 'i' in inner loo[ is %d \n", i);
j=i;
printf("Value of 'i' in outter loop is %d \n", j);
// the value of j=i is equals to 0, why variable i didn't increment here?
}
//note if i increments after the statement inside for loop runs, then why j=i is equals to 4226400? isn't spose to be 1 already? bcause the inside statements were done, then the incrementation process? where does i increments and become equals 1?
//if we have j=; and print j here
//j=i; //the ouput of j in console is 4226400
//when does i++ executes? or when does it becomes to i=1?
return 0;
}
if Post increment uses the value and add 1? i'm lost... Please explain... thank you very much.
I'm not really sure what you're asking, but sometimes it's easier for beginners to understand if rewritten as a while loop:
int i = 0;
while (i < 1)
{
...
i++; // equivalent to "i = i + 1", in this case.
}
Your loop declares new variable i and it shadows the i declared earlier in main(). So if you assign i to j outside of the loop, you are invoking undefined behaviour because i is not initialised in that context.
Prior to the first iteration, i is initialised to 0. This is the "initialize" phase, as you called it.
The loop condition is then evaluated. The loop continues on a true value.
The loop body is then executed. If there's a continue; statement, that will cause execution to jump to the end of the loop, just before the }.
The increment operator is then evaluated for it's side-effects.
Hence, it is after the first iteration that i changes to 1. i keeps the value 1 for the entirety of the second iteration.
It looks like you have a clash of variable names: i is declared before the loop, and also inside the loop.
The i that is declared in the for statement is the only one that will ever be 1. It will be one just after the body of the loop is executed.
Try setting a breakpoint and using the debugger to step through the loop whilst you watch the value of the variable (here's a video of what I mean by stepping with the debugger).
To remove the ambiguitity of having two variables called i you could change the for loop to:
for (i = 0; i < 1; i++) // remove the `int`
this will ensure that there is only one i in your code.
A comment on #CarlNorum's answer which wouldn't look good as a comment:
The C Standard defines
for ( A; B; C ) STATEMENT
as meaning almost the same thing as
{
A;
while (B) {
STATEMENT
C;
}
}
(where a {} block containing any number of statements is itself a kind of statement). But a continue; statement within the for loop will jump to just before the next statement C;, not to the next test of expression B.
for (i=0; i<x; i++)
Is equivalent to
i=0;
while(i<x) {
// body
i = i + 1;
}
Why does it tend to get into an infinite loop if I use continue in a while loop, but works fine in a for loop?
The loop-counter increment i++ gets ignored in while loop if I use it after continue, but it works if it is in for loop.
If continue ignores subsequent statements, then why doesn't it ignore the third statement of the for loop then, which contains the counter increment i++? Isn't the third statement of for loop subsequent to continue as well and should be ignored, given the third statement of for loop is executed after the loop body?
while(i<10) //causes infinite loop
{
...
continue
i++
...
}
for(i=0;i<10;i++) //works fine and exits after 10 iterations
{
...
continue
...
}
Because continue goes back to the start of the loop. With for, the post-operation i++ is an integral part of the loop control and is executed before the loop body restarts.
With the while, the i++ is just another statement in the body of the loop (no different to something like a = b), skipped if you continue before you reach it.
The reason is because the continue statement will short-circuit the statements that follow it in the loop body. Since the way you wrote the while loop has the increment statement following the continue statement, it gets short-circuited. You can solve this by changing your while loop.
A lot of text books claim that:
for (i = 0; i < N; ++i) {
/*...*/
}
is equivalent to:
i = 0;
while (i < N) {
/*...*/
++i;
}
But, in reality, it is really like:
j = 0;
while ((i = j++) < N) {
/*...*/
}
Or, to be a little more pedantic:
i = 0;
if (i < 10) do {
/*...*/
} while (++i, (i < 10));
These are more equivalent, since now if the body of the while has a continue, the increment still occurs, just like in a for. The latter alternative only executes the increment after the iteration has completed, just like for (the former executes the increment before the iteration, deferring to save it in i until after the iteration).
Your increment of i is after continue, so it never gets executed
while(i<10) //causes infinite loop
{
.........
continue
i++
......
}
In any loop, continue moves execution back to the top of the loop, not executing any other instructions after the continue statement.
In this case, the for loop's definition is always executed (per standard C), whereas the i++; statement is NOT executed, because it comes AFTER the continue statement.
Because the third part of the for is always executed.
continue statement jumps the control to the end of the statements in current iteration of loop i.e. it skips the execution of the statements in the current iteration and moves to the next iteration of the loop.
With while loop, continue statement causes control to reach the end of statements (including increment statement), thus causing loop to continue forever.
With for loop, continue statement jumps the control to end of statement and excutes the increment statement (In for loop, increment statement is considered seperate from the statments written within the body of the loop).
for loop holds condition statements and increment, so when the condition is satisfied it goes to execute the statement inside for loop,but if write continue statement than it will again reached to first line of for loop i.e. increment and checking of condition statement, if satisfied than again comes in for execution.
For while loop it just checks the condition statement and if condition satisfied it goes for the execution of statements in the while loop.
so continue will not execute any line after it.and hence your condition satisfied every time and goes for the infinite loop.
continue bypasses the rest of the block and begins again at the top of the block if the conditional of the loop is met.
The next question is: "What do I do, then?"
There are two answers I can think of.
Example:
void foo ()
{
size_t i = 0;
do
{
/*...*/
if ( /*...*/ )
{
/*...*/
continue;
}
/*...*/
i++;
} while ( /* loop conditional */ );
}
Solution #1: Manually Increment
void foo ()
{
size_t i = 0;
do
{
/*...*/
if ( /*...*/ )
{
/*...*/
i++;
continue;
}
/*...*/
i++;
} while ( /* loop conditional */ );
}
Solution #2: A uniquely valid application of goto*
void foo ()
{
size_t i = 0;
do
{
/*...*/
if ( /*...*/ )
{
/*...*/
goto foo_next;
}
/*...*/
foo_next:
i++;
} while ( /* loop conditional */ );
}
goto is valid in this case because incrementation in two places is technically the same instruction. This solution is especially relevant when the per-iteration-volatile variables are more complex; such as, setting multiple variables or modifying a value with an equation or function.
In the event of a single increment or decrement statement, Solution #1 may prove favorable; however, it should be noted that: if the code is modified after such an implementation, one must remember to update both instances of the statement (which may be prone to bugs, especially if the modifications take place after an extended period of time**). Therefore, I highly reccomend Solution #2.
*Some consider any and all use of goto bad practice. I recommend you decide for yourself, and leave you this: google for "c goto bad"
**A comment reminding of this necessity may suffice, but — if my advice has been followed — the per-iteration-volatile variables in are restricted to a single statement. And I quote:
There is never a reason to comment a single line
-Linus Torvalds (source: http://yarchive.net/comp/linux/coding_style.html)
Here is my code to find substring entered by the user in the given string.
bool find_str(char *str, char const *substr) {
while(*str) {
if(*str++ == *substr) {
char const *a = substr;
while((*str++ == *++a)); /*empty*/
if(*a == '\0')
return true;
}
}
return false;
}
// If match found, then return true, else false
int main(void) {
printf("%d", find_str("ABCDEF", "CDE")); /* Return true in this case */
printf("%d", find_str("ABCDE", "CDE")); /* Return false in this case */
}
As explained in the comment, it returns true whenever it ends with an additional characters. If it is not, then it returns false. I think there is a problem in increment/decrement operator. But I could not find how?
This is because your code decides to stop on finding \0 only after performing the comparison
*str++ == *++a
This condition will be true even when the match happens at the end of the string on null terminators, so the while loop would happily proceed beyond the end of both strings past the null terminator, causing undefined behavior.
Changing the condition to exit when *a is zero should fix the problem:
while((*str++ == *++a) && (*a));
I analysed you piece of code a little bit and based on my analysis,
I think the problem is in here
while((*str++ == *++a)); /*empty*/
perhaps you would like to add another statement like below
while((*str++ == *++a) && ( *a != '\0' ) ) ; /*empty*/
I guess you are missing a null check, what if both pointer are pointing to NULL termination they will still go forward that's exactly whats happening
I was going through your piece of code and found quite a few interesting things
Lets say the memory allocated for CDE is at X
say again the memory allocated for ABCDEF is at X+4 (this was the case in my machine)
and say memory block allocated for ABCDE is at some X+Y or what ever
now when the function is called second time
both pointers a and str point to respective memory locations starting at X+2 where Character C satisfies the condition above, however the condition will still be true even if they reach to end i.e at X+3 and hence a will move forward and point to A which makes your program behave erroneously