I have been going through some exercises from a recommended book I found on this website. I came across this following basic piece of code, which I could not fully understand.
#include <stdio.h>
int main(void)
{
int i;
for (i = 10; i >= 1; i /= 2)
printf("%d ", i++);
return 0;
}
This is my reasoning behind this program fragment:
Variable i is initialised to 10.
i is tested to see if greater or equal to 1, (which is always the case).
The third expression reads: i = i / 2, thus i is divided by 2 and its value stored in i.
In the printf statement i is incremented after each printf statement.
I simply cannot understand why the output of this program is:
1 1 1 1 1 1 1 1 ...
I get that the condition statement is always true, however shouldn't the first values be:
5 3 2 1 1 1 1 1?
Basically I cannot seem to understand why the value of i is straight away being stored as 1. Any corrections regarding my reasoning and/or insight on the matter will be appreciated. Please do excuse the basic nature of this question.
As #abelenky pointed out, the correct output is 10 5 3 2 1 1 1 .... The only mistake you made in your reasoning is that the statement i /= 2 gets evaluated after the body of the for loop, before testing the condition again. Another way to write the same loop would therefore be
for(i = 10; i >= 1; i = (i + 1) / 2)
printf ("%d ", i);
If you are running on Windows, try paging the output through more: myprog | more. This should allow you to see the beginning of the output of this infinite loop. On a linux machine, you could acheive the same result using more or less: myprog | less. Thanks to #EugeneSh for making the suggestion that this could be the issue.
Another way that I have found to view the initial output for programs like this is to hit Ctrl+C immediately after starting the program with Enter. This is not a "standard" method and may require very quick reflexes to get any results for a quick loop like yours.
A final suggestion is to limit the output you produce from the program directly:
int i, count;
for(i = 10, count = 0; i >= 1 && count < 100; i /= 2, count++)
printf("%d ", i++);
This will add a counter that will stop your output after 100 numbers have been printed and allow you to see the first numbers.
On the second line, you have 'i++'.
Thus at each iteration of the loop, it will also increment i by 1.
So supposing i = 1 when you start the loop. First it will be divided by 2 (i /= 2). Since i is an integer, it will become 0. Then, on the second line, you have 'i++', thus incrementing i.
So by the end of the loop iteration, i will be back to being equal to 1 (thus making this loop infinite).
Related
I am rather new to coding and need some help with creating an array that will move to the next index every 30 seconds in C using byte operators. The goal is to be able to iterate to the next index and then loop back to the first index in 3000 second intervals. Im sort of stuck on how to proceed but any luck or direction would be greatly appreciated. Thank you to anyone willing to help.
array[3] = {var1|var2, var1|var2, var1|var3};
msleep(3000);
array[i++];
printf("The array is currently this: %d\n", array[i]
If your array has 3 elements, you can increment the index modulo 3:
#include <unistd.h>
#define ARRAY_SIZE 3
int array[ARRAY_SIZE] = {var1|var2, var1|var2, var1|var3};
unsigned i = 0;
while(true)
{
printf("The array is currently this: %d\n", array[i]);
i = (i + 1) % ARRAY_SIZE;
sleep(3);
// when to break is up to you.
}
EDIT: Addressing your comment
It's perfectly valid to use an if statement to reset the array index, however, I'm not quite following your logic in the comment. Don't forget, in C, arrays begin at index 0, not 1. You do not need to use an if statement and modular division. Using an if statement would go something like
while(true)
{
printf("The array is currently this: %d\n", array[i]);
if (i + 1 >= ARRAY_SIZE)
{
i = 0;
}
else
{
i++;
}
sleep(3);
// when to break is up to you.
}
This may even squeak out some better performance, but considering a 3 second sleep is acceptable, probably negligible (you'd have to benchmark it to know for sure).
Another thing to consider when using the modulo approach, and rightly so, is wrap around. An unsigned int on your system is most likely 4 bytes, meaning it has a max value of 232 - 1, or 4294967295. It turns out this is evenly divisible by 3, so consider what happens when you get to the upper limits of an unsigned int:
4294967293 % 3 == 1
4294967294 % 3 == 2
4294967295 % 3 == 0 // <== MAX UNSIGNED INT, +1 wraps it back to 0
0 % 3 == 0
1 % 3 == 1
// etc
This means, that if you were to wrap around, you would get index 0 twice in a row. If that's unacceptable, you definitely want to use the "if statement" method. However, there will be 4294967295 / 3 == 1431655765 iterations before wrap around, and considering your 3 second sleep, that will take more than 136 years to occur, according to my math. There's not a computer system that's ever been conceived expected to run for that long, so you're perfectly safe using the modulo approach for all practical purposes.
array[3] = {var1|var2, var1|var2, var1|var3};
while (1)
{
array[++i % 3]; /* answer */
printf("The array is currently this: %d\n", array[i]);
msleep(3000);
}
The ++ must precede the variable to be performed before expression is evaluated.
When ++ precedes the variable, it is being used as a "prefix operator".
I have a piece of code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
for (int i = 0; i < 3; i++)
{
int j = 3;
while (j)
{
do
{
printf("%d %d\n", i, j);
j--;
} while (j == 2);
printf("Bang\n");
}
printf("Pop\n");
}
}
I am a new programming student, and this was one of the pieces of code the professor put on the board to see if we could walk through it. I understand the how this would compile, or so I thought.
Apparently the output for the code an endless loop, but forms a pattern as such:
i j
0 3
0 2
0 1
Bang
0 1
Bang
Pop
1 3
1 2
1 1
Bang
1 1
Bang
Pop
The part that is confusing to me is that, the do while loop claims to only do the loop if while(j ==2), yet at no point does the value of j seem to matter regarding the output of the loop. I am confused as to why j would go to from 1, before the bang, be subtracted with the j--; output Bang, then go back to 1. Also I dont understand why at one point it prints just Bang, but at another points Bang and Pop, i understand its exiting different scopes of loops, but I dont understand why it does that.
I input the code into visual studio 2013 and got a alternative output:
i j
0 3
0 2
bang
0 1
bang pop
1 3
1 2
bang
1 1
This makes more sense as printing Bang is adhering to the while(j == 2) loop, yet it still do not know why it prints bang and pop when j gets to 1.
I am confused as to why j would go to from 1, before the bang, be subtracted with the j--; output Bang, then go back to 1.
You're right when you say that j is 1 before the bang, and being 1 allows it to print "bang". But then it goes back into the while loop, prints 1 again (because it is still 1) goes down to zero (which you don't see because it doesn't print) and then prints "bang" again. Because j is 0 (which you never saw) it gets to exit the while loop and print "pop". The pattern repeats, but now i is 1.
You first need to understand that there is a fundamental difference between while and do-while.
The former checks the condition before entering the loop body so the loop body may execute zero or more times.
The latter checks after the loop body so is guaranteed to execute that body at least once. Hence the code snippet:
int j = 99;
do {
puts ("Hello");
while (j == 42);
will output Hello despite the fact j is nowhere near 42.
One thing I find very helpful to starters is to actually get a pen and paper and track every single line of code, evaluating it in your head, and keeping records of the current variable values:
i j Output
===== ===== ======
This will greatly assist your learning process.
In addition, you can (temporarily) change your bang/pop lines to provide more information:
printf("Bang %d %d\n", i, j);
printf("Pop %d %d\n", i, j);
and this will also make it clearer as to why you're seeing them together.
Taking all that information above into account, the reason you're seeing your particular output is because, whenever you exit the inner loop with j == 0 (having just banged), you also exit the middle loop because j being zero is equivalent to j being false. That will cause you to pop as well.
This can only happen if j started the inner loop at 1 - being do-while, it will execute at least once and j will drop to zero.
The situations where you bang without popping are limited to those situations where you exit the inner loop when j is not zero.
Has j started the inner loop at any other value than 1, it would have exited at 1 and you would have banged but not popped.
I cannot understand how the code is giving output of the prime factors of input..and what is the use of temp variable in this code?another question is what is the purpose of i=1 in the code fragment?
#include<stdio.h>
int main()
{
int number,i,temp;
scanf("%d",&number);
if(number<0)
{
printf("%d = -1 x ",number); //just printing
number=number*-1; //multiplication by -1
}
else
{
printf("%d = ",number); //just printing
}
for(i=2;i*i<=number;i++)
{
if(number%i==0)
{
printf("%d x ",i);
number=number/i;
temp=i;
i=1;
}
}
printf("%d\n",number);
return 0;
}
sample input:100
sample output:100 = 2 x 2 x 5 x 5
sample input:20
sample output:20 = 2 x 2 x 5
As previously mentioned, temp is unused.
The way this prints the prime numbers is by trying over and over to divide the number by the smallest number possible. That is the purpose of i=1.
So take 175.
First, the loop is initialized at 2. It then increments i until 175 % i == 0. When this happens, it means that i is a factor of 175. So it prints i and divides 175 by i. This ensures you won't double-count the factor. Here, this will happen first for i == 5. So now, num = 175/5 = 35.
At this point, i is reset to 1. The first thing that happens at the end of the loop block is that i is incremented to 2. So now again, it looks for the smallest factor. Again, it finds 5.
If i was not set to 1, the program would keep going up and it would miss the fact that 5 is a factor of 175 twice.
Eventually, when i > number, the program knows that it has found all the factors. This is because factors have to be less than the number they are factors of.
Hope this helps.
temp isn't used. i=1 resets the checking for factors at 1 once a factor is found
Here in this code..
i = 1
resets i as you want the prime factors.. else if it let to increment you will get values like 4 and 6 also.. which would be wrong.
no use of
temp = i;
Here temp variable is not used at all. You may remove it from pgm.
i=1 is done, so that checking of remainder if(number%i==0) can be started from value 2 again.
I recently started reading Hacking: The Art of Exploitation by Jon Erickson. In the book he has the following function, which I will refer to as (A):
int factorial (int x) // .......... 1
{ // .......... 2
int i; // .......... 3
for (i = 1; i < x; i++) // .......... 4
x *= i; // .......... 5
return x; // .......... 6
} // .......... 7
This particular function is on pg. 17. Up until this function, I have understood everything he has described. To be fair, he has explained all of the elements within (A) in detail, with the exception of the return concept. However, I just don't see how (A) is suppose to describe the process of
x! = x * (x-1) * (x-2) * (x-3)
etc which I will refer to as (B). If someone could take the time to break this down in detail I would really appreciate it. Since I am asking for your help, I will go through the elements I believe I understand in order to potentially expose elements I believe I understand but actually do not but also to help you help me make the leap from how (A) is suppose to be a representation of (B).
Ok, so here is what I believe I understand.
In line 1, in (int x), x is being assigned the type integer. What I am less sure about is whether in factorial (int x), int x is being assigned the type factorial, or if even factorial is a type.
Line 3 is simple; i is being assigned the type integer.
Line 4 I am less confident on but I think I have a decent grasp of it. I'm assuming line 4 is a while-control structure with a counter. In the first segment, the counter is referred to as i and it's initial value is established as 1. I believe the second segment of line 4, i < x, dictates that while counter i is less than x, keep looping. The third segment, i++, communicates that for every valid loop/iteration of this "while a, then b" situation, you add 1 to i.
In line 5 I believe that x *= i is suppose to be shorthand for i * x but if I didn't know that this function is suppose to explain the process of calculating a factorial, I wouldn't be able to organically explain how lines 4 and 5 are suppose to interact.
'I humbly ask for your help. For any one who helps me get over this hump, I thank you in advance. '
I think the program given in the book is wrong. Theoretically, the for-loop will never terminate, as x is growing in every iteration, and much faster than i.
In practice, x will overflow after some time, thus terminating the loop.
Forget about why this calculates the factorial for a moment. First let's figure out what it does:
int factorial (int x) // .......... 1
{ // .......... 2
int i; // .......... 3
for (i = 1; i < x; i++) // .......... 4
x *= i; // .......... 5
return x; // .......... 6
} // .......... 7
Line 1:
Ignoring the part in the parenthesis for now, the line says int factorial (...) - that means this is a function called factorial and it has a type of int. The bit inside the parenthesis says int x - that means the function takes a parameter that will be called x and is of type int. A function can take multiple parameters separated by commas but this function takes only one.
Line 3:
We are creating a variable which we will call i of type int. The variable will only exist inside these curly braces so when the function is finished i will not exist any more.
Line 4:
This is indeed a looping control that uses the variable i created on line 3 to keep the count. At the start of the loop, the i=1 makes sure the count starts at 1. The i<x means it will keep looping as long as i is less than x. The i++ means each time the loop finishes the stuff in the curly braces the variable i will be incremented. The important part of this line is that the loops stops when i gets to x - which, as we will see, never happens.
Line 5:
The x*=i means the value of x will be updated by multiplying it by i. This will happen each time the loop iterates. So, for example, if x was equal to 5 the loop will make i equal to the values 1, 2, 3 and 4 (the numbers from 1 up but less than x) and the value of x will be updated by multiplying it by 1, 2, 3 and 4, making it larger and larger. But now that x is larger, the loop doesn't end here as expected - in fact, it contines looping making x larger and larger until the value of x no longer fits into an int. At that point, the program has undefined behaviour. Because compilers assume no one would want undefined behaviour, the program can do absolutely anything at that point including crashing or looping infinitely or even rewriting the whole program so it doesn't do any calculations at all.
Line 6:
We need to get that value of x back to the outside world and that is what the return command does - if the program gets to here the return statement gives the factorial function the value of x (which is the value of the factorial of 5 in the example we just used).
Then somewhere else in your program you might do this:
int f;
f = factorial(5);
Which will make the parameter called x have an initial value of 5 and will make f have the final value of the function.
So what does it return? Well, there is undefined behaviour so anything could happen - but because x gets larger and larger it definitely will NOT return the factorial. Anything could happen, but in my tests factorial(5) returns a huge negative number.
Try it online!
So how do we fix it? Well, as #JonathanLeffler said, we can't change the value of x so we need a new variable to hold the result. We will call that variable r:
int factorial (int x)
{
int r = 1;
for (int i = 1; i < x; i++)
r *= i;
return r;
}
So this program changes the value of r and doesn't change the value of x. So the loop works properly now. But it still doesn't calculate the factorial of the value passed in - if x is 5 it multiplies all the values up to but not including x.
Try it online!
So how do we fix it? The factorial has to include all the values including x, so this actually calculates the factorial:
int factorial (int x)
{
int r = 1;
for (int i = 1; i <= x; i++)
r *= i;
return r;
}
And this works as long as the value of x you pass in is small enough that the factorial can fit into a signed int.
Try it online!
You could get more range by using an unsigned long long but there is still a maximum value that can be calculated.
The program loops through integers 1 thru N-1. (Assume the input value is 'N')
Before loop starts, x=N.
After one iteration, x=N*1.
After 2 iterations, x=N*1*2.
After N-1 iterations, x=N*1*2*....(N-1).
Which is N factorial.
So N! is returned.
The fifth line is : x *= i;
You should understand here : x = x * i;
The loop will execute while i < x. Which means until reaches x - 1;
Knowing that i begins at 1 you will get this sum : x * 1 * 2 * 3 * ... * ( x - 1)
You can rearrange this so you get : 1 * 2 * 3 * ... * (x - 1) * x
This program outputs 1. I could not understand how it outputs 1 as the for loop will fail at a[2][3] which contains the value 12. So 12 will get assigned to k and the output will have to be 12.
#include<stdio.h>
int main()
{
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int i,j,k=99;
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
if(a[i][j]<k)
{
k=a[i][j];
printf("%d\n",k);
}
}
}
printf("Res:%d\n",k);
return 0;
}
The first time through the loop the if is evaluated as a[0][0] < k which is 1 < 99 which is true.
The second time through he loop if the if is a[1][0] < k which is 2 < 1 which evaluates as false thus the value of k is not updated
k is never reassigned another value, thus at the end k=1.
In this line you are changing the K value
k=a[i][j];
And the first itteration you run would change k to 1, that's why the second itteration would fail. On every itteration your k would be one unit less than it should be for if statement to work
Some comments:
Calling a variable k tells us nothing about what you are using it for. Had you called it arrayMin then it would have been clearer to us. Using i and j for loop indexes is fine, that is expected.
Assigning k=99 makes assumptions about the contents of the array and hence makes for fragile code. Better not to make assumptions and to start by assigning arrayMin = a[0][0]
Your program is small and simple enough that you could run through it yourself on paper. Doing that would have helped you see what was going on. Using a debugger to single-step through it would have helped as well.