I'm currently learning C and I'm facing a problem that I can't solve.
It's really simple, I want the numbers from 1 to 20 printed but only if they're even (meaning the output would be 2, 4, 6,...). I know how to do this but the problem is that I want to do it in a way that I put two conditions in a for loop:
int main() {
for (int i = 1; i<=20 && i%2 == 0 ; i++) {
printf("%d\n", i);
}
return 0;
}
It seems that the second condition isn't evaluated, moreover it causes the program not to print anything. How can I do it ?
The second condition is evaluated. It is because it is evaluated the loop does not iterate.
The initial value of i is equal to 1. So the sub-expression i%2 == 0 evaluates to false.
You could use an if statement within the loop like
for (int i = 1; i<=20; i++) {
if ( i % 2 == 0 ) printf("%d\n", i);
}
If you want to place the expression i % 2 == 0 in the condition of the loop then the loop can look for example the following way as it is shown in the demonstrative program
#include <stdio.h>
int main(void)
{
for ( int i = 1; ( i % 2 == 0 ? i : ++i ) <= 20; i++) {
printf("%d\n", i);
}
return 0;
}
The program output is
2
4
6
8
10
12
14
16
18
20
Both conditions are evaluated - that's why the loop never gets going, in fact. When for starts, it sets i to 1, and immediately does the loop termination check: 1<=20 && 1%2==0. This reduces to true && false and finally to false. So the for loop won't do anything else: the very first check fails.
Remember: a failure of the condition check in the for loop terminates the loop!
Instead, you need to write what you meant - it'll be more readable and will work, too! You said:
I want the numbers from 1 to 20 printed but only if they're even
That translates directly to C (the return is unnecessary):
#include <stdio.h>
int main() {
// for all numbers from 1 to 20
for (int i = 1; i<=20; i++) {
// print out only those that are even
if ((i%2) == 0) printf("%d\n", i);
}
}
You can try this out online!.
The loop stops as soon as the condition fails. Since i%2 == 0 fails for i = 1, the loop stops immediately.
You need to put the even check inside the loop, not in the for condition.
int main() {
for (int i = 1; i<=20; i++) {
if (i % 2 == 0) {
printf("%d\n", i);
}
}
return 0;
}
Related
Beginner question on C function here so please bear with me...
#include <stdio.h>
#include <stdlib.h>
int some_function(void);
int result;
result = some_function();
printf("%d", result);
return 0;
}
int some_function(void)
{
int i;
for (i = 0; i < 10; i++)
{
// printf("%d", i);
}
return (i);
}
I commented out the result of running the for loop which is all integers from 0 to 9.
I can not clearly understand why the final result of local int i is increased once more to finally provide a return of 10 out of int some_function(void).
Thank you so much for any help.
for (i = 0; i < 10; i++) says:
Initialize i to zero.
Test whether i < 10 is true. If it is, execute the body of the loop. If it is not, exit the loop.
Increment i and go to step 2.
Therefore, the loop continues executing until i < 10 is false.
When i is nine, i < 10 is true, and the loop does not exit. When i is ten, then i < 10 is false, and the loop exits.
Therefore, when the loop exits, i is ten.
for (i = 0; i < 10; i++) {
...
}
is equivalent to
i = 0
while (i < 10) {
...
i++;
}
When i is 9, the loop body is executed, then i is incremented (and its value is now 10), then the test of the while loop is executed once more, and the loop exits, with i still having the value 10.
try to input 20 numbers with array and to output
the numbers in the double location only but somehow it's print
also the 0 location... please help.
#include<stdio.h>
#define n 20
int main()
{
int num[n]={0},i=0,order=1,double_locaion=0;
for(i=0;i<n;i++)
{
printf("please enter %d number\n",order);
scanf("%d",&num[i]);
order++;
}
for(i=0;i<n;i++)
{
if (i%2==0 && i!=1 && i!=0)
{
printf("%d\n",num[i]);
}
}
}
Try this, start with 2 and increase by 2 every time, the you don't have to deal with 0th element and odd element.
for (i = 2; i < n; i += 2)
{
printf("%d\n",num[i]);
}
First of all there is no way that your code is printing the 0-th location of the array. That's impossible given the condition of the if statement.
Secondly n- you don;t need to use macro expansion for that name.
/* This program takes 20 integer number from input.
* Prints the numbers entered in odd positions.(First,Third,..etc).
*/
#include<stdio.h>
#include<stdlib.h>
#define NUM 20
int main(void)
{
int numArr[NUM];
for(size_t i = 0; i < NUM; i++) {
printf("please enter %zu number\n",i+1);
if( scanf("%d",&numArr[i]) != 1){
fprintf(stderr, "%s\n","Error in input" );
exit(1);
}
}
for(size_t i = 0; i < n; i++)
{
if( i%2 == 0 )// if you want to omit the first number put the
// the condition (i%2 == 0 && i)
{
printf("%d\n",numArr[i]);
}
}
return 0;
}
What you did wrong that your code skipped 0th element?
if (i%2==0 && i!=1 && i!=0)
^^^^
i when 0 makes this condition false - and you never get to print it.
i!=1 ?
If i=1 then i%2 will be 1, so you will not even check the second conditions, the whole conditional expression will become false. So you can safely omit this logic.
Is there a better way?
Sure,
for(size_t i = 0; i < n; i += 2){
printf("%d\n",num[i]);
}
Explanation
If you consider that every time you check the modular arithmetic of 2 the elements which results to 0 remained are
0,2,4,6,8,10,...18
See the pattern? Starts with 0 and increments by 2 each time and when does it stop? Yes before reaching 20 coding it we get
for(size_t i = 0; i < n; i += 2){
/* Initialize with i=0 as first number is 0 (i=0)
* Increments by 2 (i+=2)
* Runs when less than 20 (i<n)
*/
printf("%d\n",num[i]);
}
If you want to omit the 0-th index do initialize properly
for(size_t i = 2; i < n; i += 2){
If you mean you want the numbers from array that are present at even position than you can do like this:
for (i = 2; i < n; i=i + 2) //Initialize i = 0 if 0 is consider as even
{
printf("%d\n",arr[i]);
}
I above code i is initialized to 2 and the increment in each iteration is 2 so it will access elements only at even position (2,4,6...).
#include< stdio.h>
int main()
{
int n,a=0,i=1,b=11;
while(i<=2)
{
while(i>0)
{
a=a+b;
i--;
}
printf("%d",a);
i++;
}
}
but if i make a little change i will get the output..
what is the difference between both the code??
#include< stdio.h>
int main()
{
int n,a=0,i=1,b=11;
while(i<=2)
{
n=i;
while(n>0)
{
a=a+b;
n--;
}
printf("%d\n",a);
i++;
}
}
output-
11
33
while (i <= 2)
{
while (i > 0)
{
a = a + b;
i--; <- out the inner while loop when i = 0
}
printf("%d", a);
i++; <- at here, the i==0 each time, so infinity loop
}
Because your nested loop always restores the value of i to 0,
And 0 <= 2 is always true, thus it keeps on going.
Initially the value of i is 1, the first loop starts by checking i<=2 , which is true for i=1, then the second loop checks i>0, which is also true, then the second loop decreases the value of i to 0 by i--;
This time the test condition for the nested loop fails and the inner loop exits, back in the first loop, the condition is satisfied as i=0 is<= 2 thus i is incremented, now i = 1.
This keeps on going forever.
In the second code, you're copying the current value of i to n, thus, initially i = 1;
Condition for first loop satisfied, then you set n = i,
And check n >0 which is true as n = i = 1
In this loop you are decrementing n and n becomes 0, thus the loop quits, and the outer loop increments i, i now being 2 allows the outer loop to run and then again n = i = 2,
The inner loop runs twice and then exits and i is incremented to 3 failing the outer loop condition and hence quitting the loop. And you get the result.
In the first code your
While(i<=2) never ends because you add 1 to i with i++ and then you subtract 1 from i with i-- and you never get i=3 to end the while loop.
What does for (; --i >= 0; ) mean in C?
How is the counter getting decremented and how is it different from for ( ; i >= 0; --i)?
They are very similar, but not the same! First you have to understand how a for loop in C gets executed:
As an example:
1 2, 5 4
| | |
v v v
for(i = 0; i < 5; i++) {
// Do something <-- 3
}
As you can see 2, 3, 4, 5 is a loop until the condition is false.
Now you should clearly see how the for loop gets executed. The difference now is that in your first example:
int i = 5;
for ( ; --i >= 0; )
printf("%d\n", i);
The output would be:
4
3
2
1
0
Because after the first check of the condition (Point 2), it executes the code block of the for statement and i already gets decremented.
In your second example:
int i = 5;
for( ; i>=0; --i)
printf("%d\n", i);
The output would be:
5 // See here the difference
4
3
2
1
0
Here you get the difference, because it gets decremented in Point 4, so the first time it runs with the value 5.
These constructs are formally equivalent to
while (--i >= 0)
{
Body;
}
and
while (i >= 0)
{
Body;
--i;
}
Do you better see the difference?
In general, we can convert any for loop or while loop into a set of mostly linear statements with a goto. Doing this may be helpful to compare the code.
Case 1
### for (; --i >= 0; ) { statements; }
; // Initializer statement
start:
bool condition = (--i >= 0); // Conditional
if (condition) { // If true, we execute the body as so:
statements; // The statements inside the loop
; // Empty increment statement
goto start // Go to the top of the loop.
}
Case 2
### for( ; i>=0; --i) { statements; }
; // Initializer statement
start:
bool condition = (i >= 0); // Conditional
if (condition) { // If true, we execute the body as so:
statements; // The statements inside the loop
--i; // Increment statement
goto start; // Go to the top of the loop.
}
Let's compare the "simpler" code from those two cases.
In the first case, we decrement i for the first time before each loop body. In the second case, we decrement i after each loop body.
The easiest way to see that is to consider what happens when you enter this loop when i == 0. In the first case, after this block of code, you would have a resulting value of i == -1. In the second case, i wouldn't have changed (that is, i == 0), because we never reached the increment statement.
for (; --i >= 0; ) works like this:
Say if you have i as 10, it will decrement the i value and will compare 9 >= 0 and so on.
So the output would be like 9, 8... till 0.
While the loop for( ; i>=0;--i) would first go to 10, then decrement the value and then it would check i>=0. So the output would be 10, 9, 8... till 0.
The first one decrements i and then checks the condition.
The second one checks the condition first and if true, decrements i after the loop body has been executed.
Well, it is the same as saying for( i=0 or some value; --i <= 0 ; do nothing){}
and --i is an predecrement operator.
That means when this piece of code, i.e., --i, is being read, the value of i will decrease by 1 at the same moment.
There are three main components in a for loop.
Initialization, condition, and afterthought.
Initialization happens once at the start of the entire statement. Condition happens before every cycle. Afterthought comes after every cycle. Consider i starts at 2:
for (; --i >= 0; )
Initialization: i = 2
Condition: i = 1
Afterthought: i = 1
Condition: i = 0
Afterthought: i = 0
Condition: i = -1
Exit
In the other case
for( ; i>=0; --i)
Initialization: i = 2
Condition: i = 2
Afterthought: i = 1
Condition: i = 1
Afterthought: i = 0
Condition: i = 0
Afterthought: i = -1
Condition: i = -1
Exit
You can see that the second version actually lasts one cycle longer!
The three parameters (initialization, condition and increment) in for are optional (but they still requires the semicolon ;). So, you can safely write for(;;) and it's the same as while(1). So, expressions like
for(; x > y; x++) { ... }
for(;1;x++) { if(x > y) break;
for(;;) { if(x++ > y) break;
for(;x++ > y;) { ... }
Are valid and equivalent. In this, the increment occurs in the conditional parameters, just like in your code example.
I have written a small piece of code that would perform Run length encoding kind of stuff on 1-D array but still far from desired result.
main()
{
int a[8]={2,0,0,0,3,0,0,9};
int i,temp,ct=0,flag,m;
int found[90]={0};
for(i=0;i<=7;i++)
{
if(!a[i])
{
ct++;
if(!found[a[i]])
{
flag=i;
found[a[i]]=1;
}
}
}
a[flag]=ct;
m=ct;
for(i=0;i<m;i++)
{
printf("%d",a[i]);
}
}/* end of main*/
Now for above array i would like to have output something below
2 5 0 3 9
But with my piece of code am getting
2 5 0 0 3
Can I have any suggestion on that?
Shouldn't run length encoding turn 2,0,0,0,3,0,0,9 into 2 1 0 3 3 1 2 0 9 1?
1) The first thing I see is wrong is that you aren't looking at the entire array. You're using < to stop before 8, but also stopping at 7, so you only evaluate array items 0 - 6.
2) If ct stands for count it's never reset (ct=0 only on declaration). Also it's assignment is this: a[flag]= ct; which overwrites your original data. It basically tracks the value of i.
This is my version I've just put together:
#define SZ 8
main()
{
int a[SZ]={2,0,0,0,3,0,0,9};
int i; //absolute position
int runningCount = 1; //because we start at array index 1 and not zero
for (i = 1; i <= SZ; i++) {
if (a[i - 1] == a[i]) //value same as one before it...
runningCount++;
else { // new value found. print last one, and the count of the last one.
printf("%d %d ", a[i - 1], runningCount);
runningCount = 1; //reset for next loop
}
}
return 0;
}
The output is 2 1 0 3 3 1 0 2 9 1
Ok based on the comment left below, your algorithm would actually look like this:
#define SZ 8
main()
{
int a[SZ]={2,0,0,0,3,0,0,9};
int i; //absolute position
int zero_count = 0; //target zeros specifically...
for (i = 0; i < SZ; i++) {
if (a[i] == 0)
zero_count++;
}
//now write it out in a bizarre, unparsable format again...
for (i = 0; i < SZ; i++) {
if (a[i] != 0) //write out all non zero values
printf("%d ", a[i]);
if (i == 0) { //this says put the zero count after the first number was printed
printf("%d 0 ", zero_count); //inserting it into a strange place in the array
}
}
return 0;
}
which outputs: 2 5 0 3 9
You need a <= in your for loop:
for(i=0;i<=7;i++)
instead of
for(i=0;i< 7;i++)
Otherwise you miss the last element.
All you appear to be doing is (a) counting the number of times 0 occurs in the array, and (b) replacing the first occurrence of 0 with that count. It's not clear how this is meant to be a useful encoding.
In any case, you're not getting your desired result, at least in part, because you're only modifying one element of the array. I suspect what you want, or at least think you want, is to shift the non-zero elements of the array to the left as you encounter them.
What is the utility of compressing the array in the way you propose? Is some other piece of code going to have to reconstruct the original, and if so how do you expect to do so from your desired result?