This question already has answers here:
Printing 1 to 1000 without loop or conditionals
(106 answers)
Closed 8 years ago.
i see the question on a c++ programming context, i check for a solution and one of my friend give me this code its works perfect but i can't understand it's logic and also how it's works. i asked to him about it but he also don't know how the program is actually works, i think he is also take this solution from somewhere. Anybody can explain the logic behind this i mean in the line
(&main + (&exit - &main)*(j/1000))(j+1); ?
#include <stdio.h>
#include <stdlib.h>
void main(int j) {
printf("%d\n", j);
(&main + (&exit - &main)*(j/1000))(j+1);
}
Thanks in advance
It works as follows:
Performs the int division j/1000, which will return 0 always while j is smaller than 1000.
So the pointer operation is as follows:
&main + 0 = &main, for j < 1000.
Then it calls the resulting function pointed by the pointer operations passing as parameter j+1.
While j is less than 1000, it will call main recursively with parameter one more than the step before.
When the value of j reaches 1000, then the integer division j/1000 equals to 1, and the pointer operation results in the following:
&main + &exit - &main = &exit.
It then calls the exit function, which finishes the program execution.
I go with the explanation already given but it would be easier to understand if written as below:
void main(int j) {
if(j == 1001)
return;
else
{
printf("%d\n", j);
main(j+1);
}
}
The above code does the same as already written code.
Related
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Order of operations for pre-increment and post-increment in a function argument? [duplicate]
(4 answers)
function parameter evaluation order
(5 answers)
Closed 4 months ago.
I'm new to C and I'm writting some simple stuff to get familiar. I just tried pre-increment on an array index and what I got was really not what I was expecting.
The code in question:
#include <stdio.h>
int main()
{
int array[5] = {1,2,3,4,5};
int i = 0;
printf("%d %d",array[i], array[++i]);
return 0;
}
which should display elements of array[0] and array[1], right?
But it doesn't, as the output is 2 2
What am I missing?
Here's the thing: You can't guarantee what order function arguments are evaluated in.
What this means is, in your printf call, there's no way to tell whether array[i] or array[++i] will be evaluated first. In your case it appears that array[++i] won, so what happens is that you end up printing array[1] twice.
That's not a good use of pre-increment.
If you want to look at array[i] and array[i+1], just do that:
printf("%d %d\n", array[i], array[i+1]);
Remember, i++ does not just take i's old value and add 1 to it. It takes i's old value, and adds 1 to it, and stores the new value back into i. When you were printing array[i] and array[i+1], did you really want to change the value of i?
If you did want to change the value of i — or, in any case, since that mention of array[i++] did change the value of i — you introduced undefined behavior. Once you've got an expression that's modifying the value of i, how do you know what array[i] will print? How do you know that array[i] won't end up using the new value of i? You probably assumed that things are evaluated from left to right, but it turns out that's not necessarily true. So weird, weird things can happen.
Here's an example that helps show how ++ works, and that's well-defined:
#include <stdio.h>
int main()
{
int array[5] = {1,2,3,4,5};
int i = 1;
array[i++] = 22;
array[++i] = 44;
for(i = 0; i < 5; i++)
printf("%d: %d\n", i, array[i]);
return 0;
}
Or, as you suggested in a comment, if you did want to modify i's value, perhaps to advance the variable i along the array, you sometimes have to take care to move the i++ into a separate statement. The simple rule is, if you're applying ++ or -- to a variable, you can only use that variable once in the same statement. So you can't have i++ + i++, since that has two i's in it and they're both modified. But you also can't have i + i++, or f(a[i], a[i++]), since those have a spot where you modify i, and a spot where you use i, and there's no way to know whether you use the old or the new value of i. (And, again, in C there's not a general left-to-right rule that helps you here.)
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
While performing recursion to find the sum of first 25 natural numbers, to see which all numbers getting added I used printf to see but it shows 25 only once.
#include <stdio.h>
int sum_of_numbers(int);
int main(){
int sum, num1 = 1;
sum = sum_of_numbers(num1);
printf("\nSum of first 25 natural numbers is %d.", sum);
}
int sum_of_numbers(int n1){
int sum;
if(n1 <= 25){
printf("%d ", n1);
sum = n1 + sum_of_numbers(++n1);
}
else
return 0;
}
Let's begin by looking at this function:
int sum_of_numbers(int n1){
int sum;
if(n1 <= 25){
printf("%d ", n1);
sum = n1 + sum_of_numbers(++n1);
}
else
return 0;
}
For the moment, ignore the fact that this is a recursive function. In fact, let's replace the recursive call with one that isn't recursive:
int sum_of_numbers(int n1){
int sum;
if(n1 <= 25){
printf("%d ", n1);
sum = n1 + some_other_mystery_function(++n1);
}
else
return 0;
}
Based on experience, when you're first learning recursion, it's often helpful to pretend the recursive calls are to different functions. Many errors in recursion are really simpler errors in function call and return that get overlooked because you're focusing too much on the recursive bit.
With that change made - do you notice anything unusual about this function? Specifically, what value gets returned if you pass in a value n1 that's less than or equal to 25? In that case, the function reaches the end without ever returning anything. Specifically, we enter the if statement, execute the printf, make the call to some_other_mystery_function, then fall off the end of the function with nothing returned. In C, that's undefined behavior, and the value that gets returned is essentially up to the whim of the compiler, the OS, and the alignment of the planets.
This leads to general transferable skill 1: make sure, when writing recursive functions, that you always return a value. That's true about most functions, but especially in the case of recursion.
There's also something else a bit suspicious here. Notice that you set the sum variable equal to some value, but sum is a local variable that's never referenced later in the function. That should trigger some alarm bells - why are we setting a local variable without reading it?
I think what you meant was something more like this:
int sum_of_numbers(int n1){
if(n1 <= 25){
printf("%d ", n1);
return n1 + some_other_mystery_function(++n1);
}
else
return 0;
}
This always returns a value, and never writes to a local variable that isn't read.
There's another issue here, though. Look at this line:
return n1 + some_other_mystery_function(++n1);
Here, you're reading from n1 at one point in the expression, and writing ++n1 in another. That's a Bad Thing, because there isn't a way to guarantee whether the first use of n1 evaluates to "what n1 used to be before the ++n1 was evaluated" or "the new value of n1 after we did ++n1." Then again, notice that this statement is a return statement, so after this line executes there's never going to be another chance to touch n1 again. I think you meant something like this?
return n1 + some_other_mystery_function(n1 + 1);
This more clearly means "pass n1 + 1 as the argument to the function."
That leads to general, transferable skill number 2: avoid using ++, +=, -=, etc. as parameters to functions. In some cases this will work correctly, but in many cases it introduces errors. Instead, pass value + 1, value + 137, value - 271, etc.
And finally, transferable skill number 3 - the compiler can warn you about all of these issues. Most compilers these days, when you crank the warning settings up, will warn you about writing to local variables that aren't read, or falling off the end of a function without returning anything, or incrementing a variable used elsewhere in an expression. I would recommend enabling those settings, since that would likely have tipped you off that something wasn't quite right here. You might not have understood what the warnings were all about, and that's fine! If that happens, feel free to post your code and the warning message in a separate question on the site, and other folks can take a look at it.
Two problems.
In the event n is less than or equal to 25, you never explicitly return. This can cause weird things to happen.
Also, there's no reason to use ++n1 in this case when you can just use n1 + 1 since you're passing by value. The ++ operators can be useful, but the prefix ++ isn't doing what you probably think it is in this case.
First of all, you are not returning the value from the body of the recursive function, though my GNU g++ compiler is not complaining about it and doing the work, but you cannot assume it to work.
Second, you are incrementing the variable ++n1 which is also increasing the value for n1 in the calling statement. So what you are actually doing is adding 2 to 26, not 1 to 25. You can use n1 + 1 instead, you don't need to change the variable and you should not. You can change your code to following to address the issues:
#include <stdio.h>
int sum_of_numbers(int);
int main() {
int sum, num1 = 1;
sum = sum_of_numbers(num1);
printf("\nSum of first 25 natural numbers is %d.", sum);
}
int sum_of_numbers(int n1){
int sum;
if (n1 <= 25) {
printf("%d ", n1);
sum = n1 + sum_of_numbers(n1 + 1);
return sum;
}
else {
return 0;
}
}
Here Is my code:
#include <stdio.h>
int mul(int,int);
int main()
{
int sum,m,n;
scanf("%d%d",&m,&n);
sum=mul(10,mul(m,n));
printf("%d",sum);
}
int mul(int x,int y)
{
int sum;
sum=x+y;
return(sum);
}
Input
10
5
Output
25
Can someone tell me why I get 25 as output? Was the function called 2 times?
One during parameters and other time during sum?
It's perfectly simple:
sum=mul(10,mul(m,n));
You're calling mul() with 10 as the first argument, and the return value of mul(m, n) as the second argument.
m and n are 10 and 5, so mul(10, 5) returns 15. The statement in your main function then evaluates to this:
sum = mul(10, 15);
Which is 25.
TL;DR: yes, mul() is called twice. Once with m and n as arguments. The second time with the sum of m and n, adding 10
Using a debugger, or even looking at the assembler output generated by the compiler would've told you there were 2 successive calls to mul.
And yes, as others have rightfully pointed out: reading the help section (in particular how to ask) would be a good idea. It explains that you're expected to do the sensible debugging/diagnostic steps yourself. Only if that didn't solve the problem should you post a question here:
Explain how you encountered the problem you're trying to solve, and any difficulties that have prevented you from solving it yourself.
You merely state that, given input X, you get output Y, and you don't know why.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 9 years ago.
i begin Why the output produce 002?
Thanks for the edit and the answers but I'm still confused.
Here is the code:
#include <stdio.h>
int t[3],i;
int main()
{
for(i=0;i<3;i++)
t[i]=i++;
for(i=0;i<3;i++)
printf("%d",t[i]);
}
002
Can anyone help me understand why it is so?
It's because you incremented your i counter twice in your for-loop (once at t[i] = i++, once at the end statement of your for-loop, i++). That way, the for-loop is executed twice (not three times), once for i = 0 and once for i = 2. Hence your output.
To convince yourself, try adding prints as in
for(i=0;i<3;i++) {
printf("%i ", i);
t[i]=i++;
}
and see how many times your for loop gets executed and for which values of i it does.
Download a copy of the C standard (for example, google for N1570, that will give you the latest freely available version). In that document, look for "sequence point" and read what it says.
In short: Your program is rubbish and could do whatever it likes, for the reasons explained in this document. (Basically, the statement t [i] = i++; invokes undefined behaviour. This is a very special case of a general rule set in the C Standard. C++ and Objective-C have the same rule).
You are incrementing i twice in each iteration. In first iteration i = 0, so t[0] = 0 then you are doing i++ twice. In second iteration i=2 so t[2] = 2 and now loop is ending. t[1] is uninitialized.You are getting 002 because:the first 0 from t[0]the second 0 is garbage value or null value from where t[1] is stored in the memory (in your case it is 0 )and the last 2 from t[2]
I wonder if I can at the same time assign a value and check if it changed in a C conditional expression without introducing new examples. Consider the function test as fixed in the following example (I don't want to change its parameters or return values). I search for a variation of the conditional in the main routine which prints "works" because the value of n is incremented by 1 by the test routine. I.e. I want a comparison with the old value of nsing. At the same time it should print "works not" if n would not be incremented by test. I wonder if this could be possible exploiting rules for the order of evaluation or something, i.e. without introducing new variables which store the value of n.
#include <stdlib.h>
#include <stdio.h>
int test(int n)
{
return n + 1;
}
int main()
{
int n;
if ((n = test(n)) == n) {
printf("works not\n");
} else {
printf("works\n");
}
return 0;
}
short answer: no you cannot. For a longer explanation have a look at sequence points
No, you can't do that and that's undefined behaviour, because there's no sequence point between the assignment and the comparison.