Macros print output - c

#include <stdio.h>
#define N 100
void f(void);
int main(void)
{
f();
#ifdef N
#undef N
#endif
return 0;
}
void f(void){
#if defined(N)
printf("N is %d\n",N);
#else
printf("N is undefined\n");
#endif // defined
}
Why does this output print N is undefined shouldn't it print N is 100 because of the function call on f before it reaches the undef that removes the value 100?

Preprocessor directives and macros are processed at a very early stage of compilation, they have no existence at runtime.
Running your code just through the preprocessor (cpp -P -- warning: remove the #include first) shows the actual C code that is being compiled.
void f(void);
int main(void)
{
f();
return 0;
}
void f(void){
printf("N is undefined\n");
}
As to why this expansion is chosen rather than the alternate message, consider these lines in your source.
#ifdef N
#undef N
#endif
Regardless of whether it's defined or not initially, it will not be defined after these lines are (pre-)processed.

Related

How can i use printf in a function with checking a variable?

I want to print output if OUT is 1. So i think that code.
#define OUT 1
void d_printf(char *text){
if(OUT)
printf("%s", text);
}
int main(void){
d_printf("%d\n", 5);
return 0;
}
But my parametre is char*, i can't send %d, 5. How can i solve this?
You can use a simple macro:
#include <stdio.h>
#define OUT 1
#define d_printf OUT && printf
int main(void) {
d_printf("%d\n", 5);
return 0;
}
If you get compiler warnings about an unused expression, you can use a more elaborate macro:
#include <stdio.h>
#define OUT 1
#define d_printf(...) do { if (OUT) printf(__VA_ARGS__); } while(0)
int main(void) {
d_printf("%d\n", 5);
return 0;
}

C Language - different definitions of function due to global variables

Can I have a function that gets defined differently due to value of some global variable -for example called "s"?
It should accept two integers if s equals 0, and one character otherwise.
I've tried using C preprocessor, but it seems that global variables cannot be accessed while preprocessing is being done.
# include <stdio.h>
int s = 1;
# if (s == 0)
void f(int x, int y);
# else
void f(char x);
#endif
int main(){
if (s == 0) f(0, 1);
else f('z');
return 0;
}
Surprisingly, in the above code f will be defined to accept two arguments, which logically is not expected.
I also do not want to change the main function.
You can do it in this way
# include <stdio.h>
#define S
# ifdef S
void f(int x, int y);
# else
void f(char x);
#endif
int main(){
# ifdef S
f(0, 1);
# else
f('z');
#endif
return 0;
}
And if you want to run the "else" version you just put the definition of S in a comment //#define S

C: Include a file which includes a file that also needs to be included in the main program

I have a header file (generalfunctions.h):
#ifndef GENERALFUNCTIONS_H
#define GENERALFUNCTIONS_H
//functionsdeclartion for example
int getInt(char* text);
#endif /* GENERALFUNCTIONS_H */
and a C file generalfunctions.c where I include this headerfile (so I can use some of the functions within each other and don't have bother with their order) and code out the functions.
generalfunctions.c:
#include "generalfunctions.h"
#include <stdlib.h>
#include <stdio.h>
//functions implentaion for example
int getInt(char* text){
int i;
printf("%s\n", text);
if(scanf("%d", &i)==EOF){
printf("INT_ERROR\n");
exit(1);
}
while (fgetc(stdin) != '\n');
return i;
}
//...
Now I need some of these functions in a file called project_objects.c that together with project_objects.h defines a couple of structs, unions, variables and functions with these things I need for my project.
project_objects.h:
#ifndef POINT_H
#define POINT_H
typedef struct point{
int x;
int y;
} point;
point create_point(void);
void print_point(point *p);
//...
#endif /* POINT_H */
project_objects.c:
#include <stdlib.h>
#include <stdio.h>
#include "project_objects.h"
#include "generalfunctions.h"
point create_point(void){
point p;
p.x=getInt("Give my a x");
p.y=getInt("Give my a y");
return p;
}
void print_point(point *p){
printf("x: %d\n", p->x);
printf("y: %d\n", p->y);
}
//..
However I also need some of the functions described in generalfunctions.h directly in my main program:
#include "generalfunctions.c"
#include "project_objects.c"
#include <stdlib.h>
#include <stdio.h>
int main(void){
int i=getInt("How many points would you like to create?");
while(i<1){
i=getInt("Cannot create a negative number of points. How many points would you like to create?");
}
point pointarray[i];
for(int j=0; j<i; j++){
pointarray[j]=create_point();
}
for(int k=0; k<i; k++){
printf("Point %d:\n", k+1);
print_point(pointarray+k);
}
return EXIT_SUCCESS;
}
This seems to work. If I just include the h-files than I get the error that getInt() isn't defined when I link. And before when I included the C file for general functions in project_object.c I got errors for duplication. But now the files seem more dependent on each other than I planned. I also don't understand why this works.
Do not include .c-files. Write function protytypes in .h-files and include them.
project_object.h
typedef int faa;
foo.h
include "project_object.h"
faa foo( faa x ); // prototype for function "foo"
foo.c
#include "foo.h"
faa foo( faa x ) // implementation of function "foo"
{
return x + 666;
}
main.c
#include "project_object.h"
#include "foo.h" // include .h-file with prototype of function "foo"
int main( void )
{
faa x;
x = foo(0); // call function "foo"
return 0;
}

#define not working as expected after #undef using #ifndef

I wrote a simple program to change addition to multiplication
#include<stdio.h>
#define ADD(X,Y) X+Y
void fun()
{
#ifndef ADD(X,Y)
printf("entered #ifndef");
#define ADD(X,Y) X*Y;
#endif
int y=ADD(3,2);
printf("%d",y);
}
int main()
{
#undef ADD(X,Y)
fun();
return 0;
}
The output I expect is 3*2 but the code still outputs 3+2 i.e. 5 .
The code doesn't output : "entered #ifndef", that means #undef is not working?
What is wrong here?
Edit :
Thanks to #deviantfan
Here is the correct code:
#include<stdio.h>
#define ADD(X,Y) X+Y
void fun();
int main()
{
#undef ADD(X,Y)
fun();
return 0;
}
void fun()
{
#ifndef ADD(X,Y)
printf("entered #ifndef");
#define ADD(X,Y) X*Y;
#endif
int y=ADD(3,2);
printf("%d",y);
}
The preprocessor (which processes eg #define) doesn´t know about
functions or things like that. It processes the file strictly from top to bottom,
independent how the actual code execution would jump around at runtime.
As soon as it hits your #undef, the #ifndef is long forgotten and won´t be evaluated again.
The actual solution to this problem is to use function pointers.
Here is a direct translation from your current code to function pointers.
Note the similarities and differences.
#include <stdio.h>
int actual_add(int X, int Y) {
return X+Y;
}
int actual_multiply(int X, int Y) {
return X*Y;
}
int (*ADD)(int,int) = actual_add;
void fun()
{
if (!ADD)
{
printf("entered #ifndef");
ADD = actual_multiply;
}
int y=ADD(3,2);
printf("%d",y);
}
int main()
{
ADD = NULL;
fun();
return 0;
}
The #ifdef, #ifndef and #undef preprocessor directives expect an identifier, not an expression.
#ifndef ADD(X,Y) is meaningless.
It should read: #ifdef ADD.
The same goes for #undef ADD

initializing global variables from a text file in C

I have a beginner question in C. I'm having trouble in reading a file with values that initialize global variables to be shared in different C files. My true project has many variables to be used and changed across multiple files. My file that reads the parameters is:
#include <stdio.h>
#include <stdlib.h>
#include "parameters.h"
#include "prototypes.h"
#define MAX_LENGTH 100
int ReadParameters(void)
{
char line[MAX_LENGTH];
FILE *fp = fopen("parameters.in", "r");
if (! fp)
return EXIT_FAILURE;
int numread = 0;
while (fgets(line, MAX_LENGTH, fp)) {
numread += sscanf(line, "x = %d", &x);
numread += sscanf(line, "y = %d", &y);
numread += sscanf(line, "z = %d", &z);
}
fclose(fp);
return numread;
}
I defined the variables x, y, and z as external in a header file:
#ifndef PARAMETERS_H
#define PARAMETERS_H
extern int x;
extern int y;
extern int z;
#endif
The prototype of ReadParameters.c is in the header prototype.h and the values in x, y, and z are used in main.c:
#include <stdio.h>
#include <stdlib.h>
#include "parameters.h"
#include "prototypes.h"
int main()
{
ReadParameters();
printf("The value of x: %d\n", x);
printf("The value of y: %d\n", y);
printf("The value of z: %d\n", z);
x += 15;
y -= 5;
z -= 20;
printf("Now the value of x: %d\n", x);
printf("Now the value of y: %d\n", y);
printf("Now the value of z: %d\n", z);
return EXIT_SUCCESS;
}
When I compile I get the error of undefined reference to x, y, and z which I believe its because I only declared the variables not defined them. If I remove extern from the header file I get no errors and it runs but I read its not good practice to define variables in header files. If I make a another .C file and defined the variables there:
#include "parameters.h"
int x, y, z;
it works but is this ok to do? I'm new to programming and any suggestions would be appreciated. Thanks
extern means that the variables are available in some other compilation unit (ie. .c file). Typically you have one .h file for each .c file that "exposes" anything to other units.
So for something like this, I would probably have:
parameters.c
int x, y, z;
parameters.h
#ifndef PARAMETERS_H
#define PARAMETERS_H
extern int x;
extern int y;
extern int z;
#endif
main.c
#include "parameters.h"
int foo() {
x = 4; // setting x from parameters.c
}
extern tells the compiler that the definition of the variables lies else where( special case would be where variables are defined in the same compilation unit ). But linker should find these definitions. So, declare them extern in a header file(s) and include the header file in source files intended to use them. But don't forget to define them in exactly one source file. What you are doing seems ok to me.
it works but is this ok to do?
It is indeed regarded as bad practice, since it leads to "tight coupling" and spaghetti code.
The preferred way is this:
//parameters.h
void set_x (int x);
//parameters.c
#include "parameters.h"
static int private_x; // static means: only visible/accessible from parameters.c
void set_x (int x)
{
private_x = x;
}
// main.c
#include "parameters.h"
set_x (something);

Resources