How to declare parameters in C - c

I have a bunch of parameters (integers and floats); I want to write a C code where both the main program and the functions refer to the same parameters so that if I change one of them the whole code knows the new value I set. My code is formed by a main.c file which calls a function.c file; right now I declared the parameters both in the main and in the function but I think that is not robust (if I change one parameters in the main and I forget to change it also in the function I get wrong results). So here is the question: How can declare the parameters in order to change it just once and not to change it everywhere I have defined?
PS: i don't want to use #define because it doesn't allow me to specify whether it's an integer or not.

You can use a global variable, define it at the top of the main.c file and refer it at the top of the other .c file using the declaration "extern".
main.c
#include
...
int a;//global variable
function.c
include ...
extern int a;//global variable

You can use global variables.
Create a .h files -- let's call it globals.h. Put declarations of the global variables in the file.
extern int var1;
extern float var2;
extern double var3;
Create a .c file -- let's call it globals.c. Define the variables in the file.
#include "globals.h"
int var1 = 0;
float var2 = 10.0f;
double var3 = 200.0;
Use #include "globals.h" in any .c file in which you want to access the global variable.
#include "globals.h"
int main()
{
printf("var1 : %d\n", var1);
printf("var2 : %f\n", var2);
printf("var3 : %lf\n", var3);
}
If you change the values of var1, var2, or var3 anywhere in the program, the change will take effect for all the functions that access them.

You could use static consts, to all intents and purposes your effect will be achieved.
myext.h:
#ifndef _MYEXT_H
#define _MYEXT_H
static const int myx = 245;
static const unsigned long int myy = 45678;
static const double myz = 3.14;
#endif
myfunc.h:
#ifndef MYFUNC_H
#define MYFUNC_H
void myfunc(void);
#endif
myfunc.c:
#include "myext.h"
#include "myfunc.h"
#include <stdio.h>
void myfunc(void)
{
printf("%d\t%lu\t%f\n", myx, myy, myz);
}
myext.c:
#include "myext.h"
#include "myfunc.h"
#include <stdio.h>
int main()
{
printf("%d\t%lu\t%f\n", myx, myy, myz);
myfunc();
return 0;
}

Related

Please can anyone explain me this warning while writing a c program(use of extern keyword)

file name :- next.c
extern int global_var = 2;
file name :- try.c
#include <stdion.h>
#include "next.c"
void main()
{
printf("%d", global_var);
}
The waring that I am getting
In file include form try.c:2:0:
next.c.1.12: warning: 'globl_var' initialized and declared 'extern'
extern in global_var = 22;
^~~~~~~~~
The warning itself tells you that your code is wrong. The messages can be "translated" into something like: "Declaring a variable as extern and at the same time assigning a value, is wrong.
It seems you have misunderstood the normal way to use include files. You don't do:
#include "next.c"
What you do is
#include "next.h"
That is... a c-file contains source code for a unit. The corresponding h-file contains information about the unit that you want to share with other units (aka c-files).
Try this:
next.h:
extern int global_var; // Tell other c-files that include next.h
// that a int-variable with name global_var
// exists
next.c:
int global_var = 2; // Define and initialize global_var
and in try.c do:
#include "next.h" // Include next.h to know what the unit next.c
// makes available for use in try.c
The above is for a global variable defined by the unit next.c. For functions is pretty much the same.
Assume that next.c implements a function foo that you want try.c to call... Then you do the same, i.e. you write the functions source code in next.c and use next.h to tell other units that the function is available. Like:
next.h:
extern int global_var; // Tell other c-files that include next.h
// that a int-variable with name global_var
// exists
void foo(int a, int b); // Tell other c-files that include next.h
// that a function with name foo
// exists
next.c:
int global_var = 2; // Define and initialize global_var
void foo(int a, int b) // Define foo
{
... source code ...
}
and in try.c use it like:
#include "next.h" // Include next.h to know what the unit next.c
// makes available for use in try.c
#include "next.h" // Include next.h to know what the unit next.c
// makes available for use in try.c
int bar()
{
int x = 0;
int y = 42;
foo(x, y); // Call function foo in unit next.c
....
}
extern is used to tell compiler that variable is declared out of scope.
first.c
#include <stdio.h>
#include "second.h"
int main(){
extern const float pi;
printf("pi : %f\n" , pi);
return 0;
}
second.h
const float pi = 3.148;
output
pi : 3.148000
why to use extern?
to prevent local redeclaration of variable and make code more readable and understandable
example error
first.c
#include <stdio.h>
#include "second.h"
int main(){
extern const float pi;
const float pi;
printf("pi : %f\n" , pi);
return 0;
}
output
first.c: In function 'main':
first.c:7:17: error: redeclaration of 'pi' with no linkage
7 | const float pi;
| ^~
In file included from first.c:2:
second.h:1:13: note: previous definition of 'p
' with type 'float'
1 | const float pi = 3.148;
| ^~
extern tells the compiler that the extern declared symbol is defined in a different source file or rather translation unit .
When you assign a value to an extern symbol, you basically say " the definition is somewhere else, but the definition is [x]"
To fix that, you should "define" the variable somewhere without "extern".

need a workaround for a "multiple definition" error

A toy code illustrating my problem is as follows:
stuff.h:
#ifndef STUFF
#define STUFF
int a;
int testarr[]={1,2,3};
#endif
fcn.h:
#include "stuff.h"
int b[]={5,6,7};
void fcn();
main.h:
#include "stuff.h"
#include <stdio.h>
fcn.c:
#include "main.h"
void fcn() {
printf("Hello\n");
}
main.c:
#include "main.h"
#include "fcn.h"
int main() {
fcn();
printf("HI\n");
}
An attempt to compile fails with:
/g/pe_19976/fcn_2.o:(.data+0x40): multiple definition of `testarr'
/g/pe_19976/main_1.o:(.data+0x40): first defined here
After doing some reading, I realize that defining the array testarr in the header file is a problem. But the thing is, in my real code, several files need access to testarr and it needs to have the same assigned values everywhere. I guess I could put it in main.h (?) but even if that would work, in my real code it logically belongs in stuff.h. How do I solve this conundrum?
BTW, based on something else I found, I tried defining testarr as extern but got the same problem.
When you put a variable definition into a header file, any .c file that includes it will have a copy of that variable. When you then attempt to link them, you get a multiple definition error.
Your header files should contain only a declaration of the variable. This is done using the extern keyword, and with no initializer.
Then in exactly one .c file, you put the definition along with an optional initializer.
For example:
main.c:
#include "main.h"
#include "fcn.h"
int a;
int testarr[]={1,2,3};
int main() {
fcn();
printf("HI\n");
}
stuff.h:
#ifndef STUFF
#define STUFF
extern int a;
extern int testarr[];
#endif
fcn.h:
#include "stuff.h"
extern int b[];
void fcn();
fcn.c:
#include "main.h"
int b[]={5,6,7};
void fcn() {
printf("Hello\n");
}
It is not clear why you are using so many global variables. The array
int testarr[]={1,2,3};
is defined as many times as there are compilation units (in your example there are at least two compilation units) that include the corresponding header.
Declare the array in a header like
extern int testarr[3];
and define it in a cpp module.
int testarr[]={1,2,3};
The same is valid for other global variables that have external linkage.
As for this remark
BTW, based on something else I found, I tried defining testarr as
extern but got the same problem.
Then the array with the specifier extern shall not be initialized in a header. Otherwise it is a definition of the array.

Functions and variables scope in C

Why we don't use extern when using function from one .c file in another .c file , but we must do extern for variables case? Is it related to linker?
Functions are extern qualified by default (unless you change it to internal with static). For example,
int func(void) {
}
extern int func2(void) {
}
Both func and func2 are external. The extern keyword is optional for external functions.
Actually, function names act just like variable names, but function prototypes are extern by default.
From cpprerefence:
If a function declaration appears outside of any function, the identifier it introduces has file scope and external linkage, unless static is used or an earlier static declaration is visible.
you can create a .hfile,declare functions you want to use in the other .c files and #include the .hfile in the other .c files.
Demo program,
one.c
#include "one.h"
void func1() //defination
{
//code
}
one.h
void func1(); //declaration
main.c
#include <stdio.h>
#include "one.h"
int main()
{
func1();
}
Then compile program in Gcc Linux : gcc main.c one.c
Yes, Let consider you have one .c file as process.c and you declared it in process.h . Now if you want to use the function from process.c to suppose tools.c then simply #include "process.h" in tools.c and use ther function. The process.h and process.c file should be in your project.
process.c file
#include<stdio.h>
#include<conio.h>
#include "process.h"
unsigned int function_addition(unsigned int a, unsigned int b)
{
unsigned int c = 0;
c = a + b;
return c;
}
process.h:
<bla bla bla >
unsigned int function_addition(unsigned int a, unsigned int b);
<bla bla bla >
tools.c file:
#include<stdio.h>
#include<conio.h>
#include "process.h"
my_tools()
{
unsigned int X = 1, Y = 9, C = 0;
C = function_addition(X,Y);
}
All these files are in one project.

How to define variables in a header file, C

I want to declare and define (with a default value) a variable in a .h file.
When I do that I get
/tmp/cc19EVVe.o:(.data+0x0): multiple definition of `car_name'
/tmp/cc3twlar.o:(.data+0x0): first defined here
collect2: error: ld returned 1 exit status
How do I achieve my goal? Namely, to declare and define with default values a variable in a .h file and use that variable in multiple .c files?
Here is the A.h file
char * car_name = "Volkswagen";
void execute();
Here are the first file that uses the variable car_name defined in A.h: (The file is called execute.c)
#include "A.h"
#include <stdio.h>
#include <string.h>
void execute(){
int len = sizeof(car_name) + 2;
char car_name_with_new_line[len];
strncat(car_name_with_new_line, car_name, sizeof(car_name));
strncat(car_name_with_new_line, "\n", 1);
printf(car_name_with_new_line);
}
That's the other .c file: (It's called main.c)
#include "A.h"
int main(int argc, char ** argv){
execute();
return 0;
}
The answer is simple: Define your variables in exactly one compilation unit (.c file). Declare them in the header file associated with that .c file.
foo.h
extern char *g_name; // Declare that g_name exists
foo.c
#include "foo.h"
char *g_name; // Define g_name in one place
static char *m_private; // Private to foo.c, not "exported" via foo.h
main.c
#include "foo.h"
void somefunc(void)
{
// use g_name
}
1) define the variable in a single file, do not add a static modifier
2) place an extern statement for that variable in the header file.
then only one instance of the variable exists anyone that includes the header file can access the variable.
Note: it is poor programming practice to have global variables.
Good programming practice is to write accessor functions and hide the variable within a file. similar to the following:
static int myVariable = 0;
void setMyVariable( int myVariableParm )
{
myVariable = myVariableParm;
}
int getMyVariable( void )
{
return myVariable;
}

how do i avoid this linking error?

if i have defined a global variable(with initialization) in header file, and included this file in two file and try to compile and link, compiler gives linking error
headers.h:
#ifndef __HEADERS
#define __HEADERS
int x = 10;
#endif
1.c:
#include "headers.h"
main ()
{
}
2.c:
#include "headers.h"
fun () {}
The linker complains because there will be multiple definitions of x once it puts all the object files together to create the executable. You have two different source files including the same header file, and that header file defines a variable x having a value of 10, so you end up with two definitions of x (one in 1.c and another in 2.c).
To avoid multiple definition linker errors, put this in a header file (for example globals.h):
#ifndef GLOBALS_H
#define GLOBALS_H
/*
* The "extern" keyword means that this variable is accessible everywhere
* as long as this declaration is present before it is used. It also means
* that the variable x may be defined in another translation unit.
*/
extern int x;
#endif
Then put this in one source file:
#include "globals.h"
int x = 10;
This is a classic case where you want either the variable declared or declared-and-defined.
If you define it in both source files, you will get a double-definition linker error. One way to handle this is to only set __HEADERS for one of the source files so that it is the one where the variable is defined.
All other source files get the declaration only.
>>headers.h
#ifndef __HEADERS
int x = 10;
#else
extern int x;
#endif
>>1.c
#define __HEADERS
#include "headers.h"
int main (void) {
return 0;
}
>>2.c
#include "headers"
void fun (void) {
}
Of course, it's best to leave definitions out of header files altogether in case you accidentally define __HEADERS in two source files. Try:
>>headers.h
extern int x;
>>1.c
#include "headers.h"
int x = 10;
int main (void) {
return 0;
}
>>2.c
#include "headers"
void fun (void) {
}
#include works exactly the same as if you copied and pasted the text from the header file.
Consider it in that way and you will see that you have therefore put the line int x=10 into both your source files.
A fixed version is below:
>>headers.h
#ifndef __HEADERS
#define__HEADERS
extern int x; // extern tells the compiler it will be linked from another file
#endif
-----------------
>>1.c
#include "headers.h"
int x = 10; // must have it in ONE file for linking purposes
main ()
{
}
---------------------
>>2.c
#include "headers"
fun () {}
Define __HEADERS in the ifndef.
Put declarations, not definitions, in your headers:
// header
extern int x;
// implementation
int x = 10;
3. 2.c has the include wrong.
So:
// headers.h
#ifndef __HEADERS
#define __HEADERS
extern int x;
#endif
// 1.c
#include "headers.h"
int x = 10;
main ()
{
}
// 2.c
#include "headers.h"
fun () {}
You can define x anywhere. Just make it one place.

Resources