#include <stdio.h>
#define abs(x) (x < 0 ? -x : x)
int x;
int doubleGlobalX()
{
x*=2;
return x;
}
int main()
{
scanf("%d",&x);//5
printf("%d\n",abs(doubleGlobalX()));//20
return 0;
}
When the input is 5 the output of this code is 20. When input is 15 the output is 60. Don't know why it doubles the global twice.
#define abs(x) (x < 0 ? -x : x)
Macros perform textual substitution. Defining an abs() macro like this is a well-known trap because it ends up evaluating x twice. If it were a function it'd be fine, but as a macro it's a problem. abs(doubleGlobalX()) expands to:
doubleGlobalX() < 0 ? -doubleGlobalX() : doubleGlobalX()
It ends up calling doubleGlobalX() twice which causes x to be doubled twice.
Related
I am currently trying to do the CS50 course. I am trying to make a do-while loop for the 1st problem set, but i throws back an error. Help would be great, thanks!
#include <cs50.h>
#include <stdio.h>
int main(void)
{
do
{
printf("Enter a positive integer no greater than 23: \n");
int n = get_int();
}
while ( int n < 0 || int n > 23);
}
$clang mario.c
mario.c:12:13: error: expected expression
while ( int n < 0 || int n > 23);
^
mario.c:12:13: error: expected ')'
mario.c:12:11: note: to match this '('
while ( int n < 0 || int n > 23);
^
2 errors generated.
Declare n only once, outside the do-while loop:
int n = -1;
do
{
printf("Enter a positive integer no greater than 23: \n");
n = get_int();
}
while (n < 0 || n > 23);
we never define a variable inside
expressions like if or while and For loop
this is only possible in other languages like C++ |;
Your problem lies in the fact that you have:
Declared n inside your while loop (This is not allowed in C89, but is grudgingly allowed in later versions)
Declared n twice in the while section.
The idea of declaration is to show the compiler, that the variable name present is not garbage but is actually a variable. The compiler generally follows fixed rules and does not look for variable names within the while/for loops (this is for optimization purposes). Also the second time that you declared n the compiler is now confused as you have stated a variable named n already exists.
PS: I believe you wished to say that n lies within the bounds of 1 and 22 If you wished to say this the correct expression would involve AND (&&) and not OR (||) ie, while ( int n < 0 && int n > 23).
This question already has answers here:
Preprocessor macro in C
(3 answers)
Closed 5 years ago.
I am learning C in depth. But I am not getting this program. Somebody, please tell me how the output of the below program is m=2, n=3
#include <stdio.h>
#define MAX(a,b) a>b ? a:b
int main()
{
int m,n;
m=3+MAX(2,3);
n=2*MAX(3,2);
printf("m=%d, n=%d\n",m,n);
return 0;
}
This is why parenthesis in macro definitions are important.
A macro does simple text substitution. So when you do this:
m=3+MAX(2,3);
It expands to this:
m=3+2>3 ? 2:3
With the implicit parenthesis:
m = ((3+2)>3) ? 2:3
Which is probably not what you want.
You need to put parenthesis around the entire macro as well as around each argument wherever it is used:
#define MAX(a,b) ((a)>(b) ? (a) : (b))
This will then expand to:
m = 3 + ((2)>(3) ? (2):(3))
Also note that with a macro like this you open yourself up to side effects of one of the operands. For example, if you did this:
int a=2, b=3;
m = MAX(a++,b);
You would get:
int a=2, b=3;
m = ((a++) > (b) ? (a++) : (b));
This invokes undefined behavior because it attempts to modify a more than once in an expression without a sequence point.
This is what happens in your case:
int main() {
int m,n;
m=3+2>3 ? 2:3; //(3+2)>3 ? 2 : 3 = 2
n=2*3>2 ? 3:2; //(2*3)>2 ? 3 : 2 = 3
printf("m=%d, n=%d\n",m,n);
return 0;
}
If you rewrite your defined to #define MAX(a,b) ((a)>(b) ? (a):(b))
then you will have desired output as it will be evaluated to:
//Correct way with parenthesis
int main() {
int m,n;
m=3+((2)>(3) ? (2):(3)); //6
n=2*((3)>(2) ? (3):(2)); //6
printf("m=%d, n=%d\n",m,n);
return 0;
}
I am studying how to program and have recently been working on a problem that calculates the total of 2 entered numbers from min to max. For example, if someone entered the numbers 4, 7. The calculation would be 4+5+6+7=22.
I've attempted what i think would be the definition of recSum but obviously it is wrong as I get a segmentation fault. What is wrong with my definition?
/* Define the recursive function */
int recSum (int x, int max)
{
int incrementalSum = 0;
if (x == max)
{
return x; /* Exit if summated lower to upper numbers */
}
else
{
return (x + recSum(x++, max)); /* My recursive call */
}
} /* End of function call */
*new code is shown above, sorry, i used the wrong code.
Your code has 3 important problems
The expression
incrementalSum = x + x++;
is undefined, read this for more information
Your function is not recursive, a recursive function calls it self until a condition happens where it should end.
Also, noting that I am not an irrational "don't ever use goto person", this is precisely why some people advice against using goto.
The reason your code doesn't work is this line:
return x + recSum(x++, max);
x++ increments x but returns the previous value, so in the recursive calls it never increments and you never reach the base case. Like an infinite loop. You have to replace x++ with ++x in order to give any result, even though it won't be correct. ++x is modifying x so it will alter the final sum of x + recSum. You'd better use:
return x + recSum(x + 1, max);
See What is the difference between ++i and i++?
It seems you mean the following
int recSum(int x, int max)
{
return max < x ? 0 : x + recSum( x + 1, max );
}
Or it would be even better to declare the return type of the function like long long int.
long long int recSum(int x, int max)
{
return max < x ? 0 : x + recSum( x + 1, max );
}
The function can be called like
printf( "%lld\n", recSum( 4, 7 ) );
As for your function then it exits in the first call
int recSum(int x, int max)
{
int incrementalSum = 0;
recCall: if (x < max)
return incrementalSum;
^^^^^^^^^^^^^^^^^^^^^
because usually it is called when x is less than max. So the function does not make sense. Moreover the function is not recursive because it does not call itself.
Is there a shorthand way of writing equivalent code to:
if (variable > max){
variable = max;
}else if (variable < -max){
variable = -max;
}
I know I can use ternary operators to get code like this:
variable = variable > max ? max : variable;
variable = variable < -max ? -max : variable;
Question:
But is there an even shorter version of this code?
Note: Not nested ternary operators, either.
P.S.: This isn't necessarily a language-specific question, but I'm writing my code in C so I'd like to have answers that can work in that language.
You could probably use this construct:
if (abs(variable) > max) {
variable = sgn(variable) * max;
}
There is no sgn(x) function in standard C library, but it is easy enough to implement it using arithmetic operations:
#define sgn(x) (((x) > 0) - ((x) < 0))
Here is an working example:
#include <stdio.h>
#include <math.h>
#define sgn(x) (((x) > 0) - ((x) < 0))
int main(void)
{
int variable = -100, max = 20;
if (abs(variable) > max) {
variable = sgn(variable) * max;
}
printf("%d\n", variable);
return 0;
}
Note, that it will not work for INT_MIN on systems, that use two's complement representation, because -INT_MIN cannot be represented as int (kudos for #M.M).
You can nest conditional operators:
variable = variable > max ? max : (variable < -max ? -max : variable);
IMHO this is almost unreadable, so I don't recommend it.
This question already has answers here:
C macros and use of arguments in parentheses
(2 answers)
Closed 4 years ago.
I am new to c language. I just wanted to know why is my macro not working properly. It is giving me output as 13 where as my expected output is 24.?
#include<stdio.h>
#define mult(a,b) a*b
int main()
{
int x=4,y=5;
printf("%d",mult(x+2,y-1));
return 0;
}
mult(x+2,y-1) expands to x +2 * y -1 that is equals to 4 + 2 * 5 -1 gives output: 13.
You might be expecting answer (4 + 2) * (5 -1) = 6 * 4 = 24. To make it expand like this you should write parenthesize macro as #H2Co3 also suggesting:
#define mult(a,b) ((a)*(b))
Read aslo: So, what's wrong with using macros? by Bjarne Stroustrup.
This is because C macros are simple textual substitutions, the macro writer must be sure to insert parentheses around every macro variable when it is substituted, and around the macro expansion itself, to prevent the resulting expansion from taking on new meanings.
If you observe your program: mult(a, b) is defined as a * b
mult(x + 2, y - 1) = x + 2 * y - 1 = 4 + 2 * 5 - 1 = 4 + 10 - 1 = 13
The Correct way would be:
mult(a, b) ((a) * (b))
Use parentheses in the macro definition
#include<stdio.h>
#define mult(a,b) ((a)*(b))
int main()
{
int x=4,y=5;
printf("%d",mult(x+2,y-1));
return 0;
}
This is because different arithmetic operators have different precedence levels. Hence always use parentheses while defining the macro.
Because it replaces the arguments literally:
mult(x+2,y-1) --> mult(4+2,5-1) --> 4 + 2*5 - 1 --> 13
Try changing the define to:
#define mult(a,b) (a)*(b)
In this case the result after pre-processing is this:
int main()
{
int x=4,y=5;
printf("%d",(x+2)*(y-1));
return 0;
}
This will solve the problem but it's still not the best way to do it.
#define mult(a,b) ((a)*(b))
This version is considered as good practice because in other types of situation the first one would fail. See the bellow example:
#include<stdio.h>
#define add(a,b) (a)+(b)
int main()
{
int x=4,y=5;
printf("%d",add(x+2,y-1)*add(x+2,y-1));
return 0;
}
In this case it would give an incorrect answer because it is translated by the pre-processor to the fallowing:
int main()
{
int x=4,y=5;
printf("%d",(x+2)+(y-1)*(x+2)+(y-1));
return 0;
}
printing 34 instead of 100.
For the ((a)+(b)) version it would translate to:
int main()
{
int x=4,y=5;
printf("%d",((x+2)+(y-1))*((x+2)+(y-1)));
return 0;
}
giving a correct answer.