C preprocessor conditional statement output - c

I have this code but not able to understand the output. Can someone help out to know the behaviour
#include<stdio.h>
int main(){
int a =1;
#if(a==0)
printf("equal");
#else if
printf("unequal");
#endif
return -1;
}
Output comes out to be equal. Strange for me.
Also if i change the if condition to a==2, the output comes unequal
If i try to print value of 'a' inside 'if' block something like
#if(a==0)
printf("value of a: %d",a);
output comes out to be value of a: 1
Please some one explain the output.

The a in the preprocessor directive refers to preprocessor definitions, not variables in your program. Since a is not #defined, its value is effectively 0 for the purposes of #if.

The preprocessor directives (the lines starting with #) are dealt with at compile time, not at runtime. The a in that #if is not the same as the a variable you declared. The preprocessor just replaces it with 0, since there is no #define a statement anywhere. The variable a is unused in your program. If you do use it, like in the printf statement you show, it will get printed as expected - a value of 1 that you assigned to it.

#include<stdio.h>
int main(){
int a =1;
#if(a==0)
printf("equal");
#else if
printf("unequal");
#endif
return -1;
}
which you pass to the compiler will first go through the preprocessor whose output is then sent as an input to the compiler; the preprocessor will send
#include<stdio.h>
int main(){
int a =1;
printf("equal");
return -1;
}
to the compiler, which is the reason you see equal always. The reason is since a as a macro is undefined, the first condition is true, there by leading to only passing that statement on to the compiler. If you try adding #define a 1 next to the include directive, then you'll always see unequal as an output; but these changes affect only the compile time macro a and not the runtime variable a (both are entirely different).
All this because preprocessor is concerned only with compile-time constructs. What you really need may be
#include<stdio.h>
int main(){
int a =1;
if(a == 0)
printf("equal");
else
printf("unequal");
return 0;
}
Aside: Return 0 when you're program is successful, returning negative values from main usually means some error state termination of your program.

Related

Creating a Fibonacci sequence in C

Consider a Fibonacci sequence whose values do not exceed four million. Find the sum of the even-valued terms. Your answer must be 4613732.
#include <stdio.h>
int main()
{
int a =0,b=1,c=0,sum=0;
while (c<=10){
int c=a+b;
a=b;
b=c;
if(c%2==0){
sum=sum+c;
}
}
printf("%d",sum);
return 0;
}
The output comes out to be blank. I tried 10 for smaller calculation time and the answer should be 2+8=10. I don't know what to do.
int c=a+b;
This doesn't modify the variable c that was declared outside the loop; it creates a new variable, whose scope is only the body of the loop. You just want c=a+b; here.
You have another bug in that on the iteration of the loop which increases c beyond its limit value, that value may still be added to the sum, even though it should not. For instance, if you replace the loop test with while (c <= 7), you will still get 10 as the answer, instead of the correct 2. Think about how to restructure the loop body to fix this.
The main problem is here:
int c = a + b;
You have redefined the variable c that shadows the original variable on each iteration. Remove the int declaration from there.
Also, note that you want to iterate up to 4 million to obtain your desired results. So, change the iteration limit from 10 to 4000000.*
* It is recommended declaring a macro constant on the top of the program to avoid magical numbers
int a = b+c is the main problem in your code. That line of code re defines the entire variable declaration. So instead u want to put c = a+b
#include <stdio.h>
int main()
{
int a =0,b=1,c=0,sum=0;
while (c<=4000000){
c=a+b; // just remove the `int` and this should fix it
a=b;
b=c;
if(c%2==0){
sum=sum+c;
}
}
printf("%d",sum);
return 0;
}
outputs: 4613732
In this question
int c=a+b;
You are not using the value declared outside of the method Insted you are defining a new variable that only works on inside of your method. Try removing the int decleration inside the while loop and It should work

C macros using enum

I am trying to use #if macros by defining the type of operation to invoke the right code, So i made a very simple example similar to what I am trying to do:
#include <stdio.h>
enum{ADD,SUB,MUL};
#define operation ADD
int main()
{
int a = 4;
int b = 2;
int c;
#if (operation == ADD)
c = a+b;
#endif
#if (operation == SUB)
c = a-b;
#endif
#if (operation == MUL)
c = a*b;
#endif
printf("result = %i",c);
return 0;
}
But unfortunately that does not work I get the following result = 8... if I replace The operation with numbers it works fine .... But i want it to work as it is described above.
Any help
The preprocessor is a step that is (in a way) done before the actual compiler sees the code. Therefore it has no idea about enumerations or their values, as they are set during compilation which happens after preprocessing.
You simply can't use preprocessor conditional compilation using enumerations.
The preprocessor will always consider that as false:
#if IDENT == IDENT
It can only test for numeric values.
Simplify your code and feed it to the preprocessor:
enum {ADD,SUB,MUL};
#define operation ADD
int main()
{
(operation == ADD);
}
The result of the preprocessor output is:
enum {ADD,SUB,MUL};
int main()
{
(ADD == ADD);
}
As you see, the enumerate value hasn't been evaluated. In the #if statement, that expression is just seen as false.
So a workaround would be to replace your enumerate by a series of #define:
#define ADD 1
#define SUB 2
#define MUL 3
like this it works. Output of preprocessor output is now:
int main()
{
int a = 4;
int b = 2;
int c;
c = a+b;
# 28 "test.c"
printf("result = %i",c);
return 0;
}
the solution is:
either rely at 100% on the preprocessor (as the solution above suggests)
or rely at 100% on the compiler (use enums and real if statements)
As others have said, the preprocessor performs its transformations at a very early phase in compilation, before enum values are known. So you can't do this test in #if.
However, you can just use an ordinary if statement. Any decent compiler with optimization enabled will detect that you're comparing constants, perform the tests at compile time, and throw out the code that will never be executed. So you'll get the same result that you were trying to achieve with #if.
But i want it to work as it is described above.
You seem to mean that you want the preprocessor to recognize the enum constants as such, and to evaluate the == expressions in that light. I'm afraid you're out of luck.
The preprocessor knows nothing about enums. It operates on a mostly-raw stream of tokens and whitespace. When it evaluates a directive such as
#if (operation == SUB)
it first performs macro expansion to produce
#if (ADD == SUB)
. Then it must somehow convert the tokens ADD and SUB to numbers, but, again, it knows nothing about enums or the C significance of the preceding code. Its rule for interpreting such symbols as numbers is simple: it replaces each with 0. The result is that all three preprocessor conditionals in your code will always evaluate to true.
If you want the preprocessor to do this then you need to define the symbols to the preprocessor. Since you're not otherwise using the enum, you might as well just replace it altogether with
#define ADD 1
#define SUB 2
#define MUL 3
If you want the enum, too, then just use different symbols with the preprocessor than you use for the enum constants. You can use the same or different values, as you like, because never the twain shall meet.
Another solution would be to have the enum in an included header file.

Working of these two pieces of code [duplicate]

This question already has answers here:
Scope of #define preprocessor in C
(6 answers)
Closed 8 years ago.
Here are two pieces of C code, but I don't understand how they work:
Program 1 :
#include<stdio.h>
#define s 10
fun() {
#undef s
#define s 20
}
int main(){
printf("%d\n",s);
fun();
printf("%d\n",s);
return 0;
}
Output: 20
20
Program 2:
#include<stdio.h>
#define s 10
int main(){
printf("%d\n",s);
fun();
printf("%d\n",s);
return 0;
}
fun() {
#undef s
#define s 20
}
output: 10
10
What I know is preprocessor works before starting of main() and replaces all of its variables.
Here fun() is called after one printf(), so how are both program are outputting different values by changing the position of fun()?
Macro will be replaced in compile time itself. so code will be like this after preprocessing,
Case 1:
#include<stdio.h>
fun() {
}
int main(){
printf("%d\n", 20);//latest definition of s will be considered.
fun();
printf("%d\n",20);
return 0;
}
Case 2:
#include<stdio.h>
int main(){
printf("%d\n",10); //replaced with 10 only, because in this instance, there is no change in s
fun();
printf("%d\n",10);
return 0;
}
fun() {
//#undef s
//#define s 20 //no use in ur code.
}
fun_extra() { //Added for demo
printf("%d\n",s);//will be replaced by 20.
}
The preprocessor doesn't care about scope. It just goes through the file line by line, in order from top to bottom, and makes textual replacements. If something is #defined or #undefined, it takes effect from that line until the bottom of the file (or another preprocessor statement overrides it).
Preprocessor statements are not executable. They are... well, preprocessed. This means that the compiler will perform an initial, single pass and resolve all preprocessing definitions. If a preprocessing definition is located inside a C control structure, it will be executed regardless of the meaning of the C control structure. In other words, from the point of view of the preprocessor there is no C code. Just text (and other preprocessor statements).
In your case, in this first pass:
#include<stdio.h> // File stdio.h is included/copied
#define s 10 // Preprocessor symbol s is defined as 10
fun() { // Copied literally
#undef s // Preprocessor symbol s is undefined
#define s 20 // Preprocessor symbol s is defined as 20
} // Copied literally
int main(){ // Copied literally
printf("%d\n",s); // Copied with s substituted, ie. printf("%d\n",20);
fun(); // Copied literally
printf("%d\n",s); // Copied with s substituted, ie. printf("%d\n",20);
return 0; // Copied literally
} // Copied literally
So, the input that really gets compiled is:
// Empty line originally corresponding to #include
// Empty line originally corresponding to #define
fun() {
// Empty line originally corresponding to #undef
// Empty line originally corresponding to #define
}
int main(){
printf("%d\n",20);
fun();
printf("%d\n",20);
return 0;
}
In particular, note that the fun function does not contain any C instruction. Before pre-processing it did contain 2 pre-processing instructions, but:
They disappeared after pro-processing
They never really belonged to a function fun because at that point there was no function fun or any other C code. Just text and preprocessor statements.
This work is usually done silently and internally by C compilers. However, many of them have options to save the pre-processed source files. You should obtain a result like the above (except that #include<stdio.h> would expand into many blank lines, and some C code, which here I sinthesized as a single empty line).
The second case is left as an exercise to the OP.

Passing parameters evaluation direction in macro

As I know in C, passing of actual parameters of a function evaluation starts from rightmost and directed to left.
What is the case for a macro definition with parameter? I made a code to make the sense clear but output confused me...
Here is the code.,
#define parsing(a,b) a*b
int parsefun(int a, int b)
{
return a*b;
}
int main()
{
int i=10;
printf("%d\n",parsing((i++),i));
i=10;
printf("%d\n",parsing(i,(i++)));
i=10;
printf("%d\n",parsefun((i++),i));
i=10;
printf("%d\n",parsefun(i,(i++)));
system("PAUSE");
return 0;
}
This code outputs,
100
100
100
110
I hoped same output for macros as function. But where is the crucial point here?
parsing of actual parameters of a function starts from rightmost and directed to left
I think you mean "evaluation" rather than "parsing". But that's not true, the C standard does not specify an order.
So the behaviour you're getting for the functions is unspecified by the C standard.
I hoped same output for macros as function
Macro arguments are not evaluated, they're simply substituted. So you end up with this:
int i=10;
printf("%d\n", (i++) * i);
i=10;
printf("%d\n", i * (i++));
After which, you're simply seeing undefined behaviour, as explained in this question: Why are these constructs (using ++) undefined behavior?.

C exit function not doing what I thought it would

When I use a debugger I can tell the exit is not exiting the function. Am I using the exit function wrong? (i must be) how do I fix this?
int is_prime(int x,char array[]){
int divider = (x-1);
float test;
while(x>-1){
test = isdigit((x % divider)); //isdigit returns !0 if digit
if(divider == '1'){
return(1); //if divider reaches 1 then the number is prime
exit;
}
if(test == '0'){
return (0);//not prime
exit;
}
divider--;
}
}
The name of a function by itself (with no parenthesis after it) just gives you the address of a function without calling it. In C the most basic statement is an expression which is evaluated for its side effects, with the resulting value of the expression ignored. So a statement like exit; or 3; which has no side effects is legal but doesn't actually do anything and might as well be deleted. Some compilers will give you warnings about such meaningless statements, though you may have to turn on extra diagnostic warnings to get them. Using such options (such as -Wall for gcc) is a very good idea and will help you avoid some pitfalls like this.
You must call it:
exit(0);
Also, if you put it after return, it will never be called, since return returns from the function.
EDIT: And, as others have said, exit exits the program, so you probably don't want to use exit here.
Besides the bugs of returnand exit you have a bug also in the way you use ints and characters. isdigit is a function that is only applied to characters, giving true if a character is between '0' and '9', but one should know that the character notation in C is only a fancy way of writing a codepoint (ASCII most of the time). So when you write '1' in a C program, the compiler will see 49, if you write 'a' the compiler sees in reality 97. This means that isdigit return true for the values 48 to 57, probably not what you intended. In the line where you compare divider with '1', in reality you're comparing it with 49 (except on IBM mainframe, where '1' is 241)
Your loop is infinite, it depends on the value of x, but x isn't changed in the loop, so the condition in the while can never change.
EDIT: Here the corrected code
int is_prime(uint_t x)
{
uint_t divider;
if(x <= 3)
return 1;
for(divider = x-1; ; divider--) {
if(x % divider == 0)
return 0; //not prime
if(divider == 1)
return 1; //if divider reaches 1 then the number is prime
}
}
Read exit(3)'s manual.
The statement:
exit;
gives the following warning with GCC:
C:\temp\test.c:71: warning: statement with no effect
What happening is that you have an expression that evaluates to the address of the exit() function - but that expression doesn't actually do anything with that address. it's similar to if you had a statement like:
1 + 2;
It's valid C, but it has no effect on anything.
To call the function, as Thomas Padron-McCarth said, you have to have the argument list (even if they're empty for some functions):
exit(0);
exit exits the process, not the function. You want return.

Resources