Case 1: structure declared outside main() working fine
#include<stdio.h>
#include<conio.h>
struct prod
{
int price,usold;
};
int main()
{
struct prod *p,a;
int billamt(struct prod *);
int bill;
printf("enter the values \n");
scanf("%d%d",&p->price,&p->usold);
bill=billamt(p);
printf("bill=%d",bill);
getch();
}
int billamt(struct prod *i)
{
int b;
b=(i->price*i->usold);
return b;
}
Case 2: declared inside main() giving error
[Error] type 'main()::prod' with no linkage used to declare function 'int billamt(main()::prod*)' with linkage [-fpermissive]*
#include<stdio.h>
#include<conio.h>
int main()
{
struct prod
{
int price,usold;
};
struct prod *p,a;
int billamt(struct prod *);
int bill;
printf("enter the values \n");
scanf("%d%d",&p->price,&p->usold);
bill=billamt(p);
printf("bill=%d",bill);
getch();
}
int billamt(struct prod *i)
{
int b;
b=(i->price*i->usold);
return b;
}
where to declare structures, inside main() or outside main()?
First thing, I think you meant "define", not "declare".
Second, there is no rule as such, You can define wherever you want. It is all about the scope of the definition.
If you define the structure inside main(), the scope is limited to main() only. Any other function cannot see that definition and hence, cannot make use of that structure definition.
If you define the structure in a global scope, (i.e., outside main() or any other function, for that matter), that definition is available globally and all the functions can see and make use of the structure definition.
It have to do about scoping, when you define the structure inside the main function then it's only defined in the scope of the main function, so the billamt function can't know about it.
Structure are a like array only the main difference in Array can hold only same type of values but a structure can have different types of values so if you need to implement structure globally(by globally i mean it can be used in any other function too) define it outside the main and if you want to use your structure only in the main function define it inside it.
Happy Coding :-)
Related
The following link says that structs defined in main don't have the scope to be called by functions because they are local so you should define your structs globally. However with variables, it's preferred to declare variables locally and pass to functions with pointers instead of declaring global variables.
Is there a way in pure C using pointers etc to pass a struct defined in main to a function? If you don't mind, please use the example program to demonstrate the method. Thanks.
where to declare structures, inside main() or outside main()?
This code works but is not what I want. I want to define the structure within main. Is this possible?
#include <stdio.h>
#include <SDL2/SDL.h>
void function();
struct hexColour
{
Uint32 red;
}hc;
int main(void)
{
hc.red = 0xFFFF0000;
function(hc);
return 0;
}
void function(struct hexColour hc)
{
printf("red is %x\n", hc.red);
}
What I want is:
int main(void)
{
struct hexColour
{
Uint32 red;
}hc;
hc.red = 0xFFFF0000;
function(hc);
return 0;
}
First of all you should really use proper prototypes that matched the function definitions.
Secondly, your example do pass a structure into the local variable hc in the function.
When function is running there are two distinct and separate structures in memory: The one in the main function, and the local in the function function.
To cover my bases, here are two answers for two other question that maybe is asked:
You want to define the structure itself inside the main function, and then be able to use it in other functions.
Something like
int main(void)
{
struct hexColor
{
uint32_t white;
// Other members omitted
};
struct hexColour hc;
hc.white = 0xff;
func(hc); // Assume declaration exist
}
void func(struct hexColour my_colour)
{
printf("White is %u\n", my_colour.white);
}
This is not possible. The structure hexColour is defined inside the main function only. No other function can use that structure. It doesn't matter if you pass a pointer or not, the structure hexColour still will only exist inside the main function only.
Emulate pass-by-reference by passing a pointer to a structure object. Like
struct hexColor
{
uint32_t white;
// Other members omitted
};
int main(void)
{
struct hexColour hc;
hc.white = 0xff;
// Assume declaration of function exists
func(&hc); // Emulate pass-by-reference by passing a pointer to a variable
}
void func(struct hexColour *colourPointer)
{
colourPointer->white = 0x00;
}
This is possible, because then the structure hexColour exists outside the main function, in the global scope. All functions declared and defined after the structure definition may use the structure and its members.
If you pass by value a copy is made (expensive, modifications are not reflected outside). If you want to pass a pointer to a struct just go with, but this doesn't mean you are passing a struct by reference (C doesn't have references), you are passing a pointer to a struct by value instead.
void function(struct hexColour* hc) {
printf("red is %x", hc->red);
}
int main() {
...
functon(&hc);
...
}
See:
Signature of the function changes from struct hexColor to struct hexColor* so that you are passing a pointer (by value)
To access field of the struct when dealing with pointers you use -> instead that .
You need to take the address to the struct when invoking the function, function(hc) becomes function(&hc)
Now since you are passing the address the the struct any modification is done to the real value.
You seem to have understood your linked question and its answers incompletely. You write,
The following link says that structs defined in main don't have the
scope to be called by functions because they are local so you should
define your structs globally.
The ambiguity here is between struct types, such as your struct hexColour, and objects having those types, such as your hc. Both struct types and struct objects should be declared so that they are in scope at all the places where they are needed, but that plays out differently for these two different kinds of entities and in various different situations.
However with variables, it's preferred to declare variables locally
and pass by reference instead of declaring global variables.
It is usually best to use block-scope variables instead of file-scope variables, yes, but C has only pass by value, not pass by reference. There are plenty of circumstances where it is advantageous to pass pointers (by value) instead of the objects to which they point, and this is close to pass by reference, but there is certainly no rule or general practice that passing pointers is universally better than passing the objects to which they point.
Is there
a way in pure C using pointers etc to pass a local struct to a
function?
Both the caller and the callee have to agree about the type of each argument, and there are many ways to achieve this. But there are some conventions that have grown up along with C for how to approach problems such as these in an effective way. Large among them is this:
Any function and any non-builtin type that is to be used in multiple translation units should be declared in a header file, and that header included in every translation unit that needs it.
That's a generalization of the rule you couched in terms of "global" definitions. Example:
colour.h
#ifndef COLOUR_H
#define COLOUR_H
struct hexColour {
Uint32 white;
Uint32 black;
Uint32 red;
Uint32 pink;
Uint32 grey;
}; // Note that only the type is declared here, not any objects
void function(struct hexColour hc);
#endif
Note that the declaration of type struct hexColour appears before the declaration of function function that has a parameter of that type.
You can then use those types and functions with appropriate locality, for example:
main.c:
#include "colour.h"
int main(void) {
struct hexColour hc = {
.white = 0xFFFFFFFF, .black = 0xFF000000, .red = 0xFFFF0000,
.pink = 0xFFFF9999, .grey = 0xFFA0A0A0 };
function(hc);
return 0;
}
void function(struct hexColour hc) {
printf("red is %x\n", hc.red);
}
Note that the declaration of function that forms part of its definition here matches the declaration in the header. That definition function() could as easily be defined in a different source file, instead, as long as the caller has the header file to tell it how that function is declared. You can #include coulour.h into as many different source files as needed.
Do note, however, that in this case, the struct is passed by value. That's well-defined and perfectly acceptable, but inasmuch as the function receives only a copy, it cannot effect changes to the caller's original copy. If you wanted the function to be able to do that, then you would need to pass a pointer to the struct (by value) instead of the struct itself:
void function(struct hexColour *hc) {
// ...
}
int main(void) {
// ...
function(&hc);
// ...
}
You can take a locally-defined struct and pass it to another function:
void f1(struct s);
int main()
{
struct s s1;
f1(s1);
}
You can take a locally-defined struct and pass a pointer to it to another function:
void f2(struct s *);
int main()
{
struct s s2;
f2(&s2);
}
You can return a locally-defined struct:
struct s f3()
{
struct s ret;
/* ... */
return ret;
}
You can not return a pointer to a locally-defined struct:
struct s *f4()
{
struct s ret;
/* ... */
return &ret; /* WRONG */
}
If you declare a struct within a function, it is not a global variable, so you can not refer to it in another function to which you did not pass the structure or a pointer:
void f5();
int main()
{
struct s s1;
f5();
}
void f5()
{
int x = s1.field; /* WRONG */
}
Finally, if you declare the struct type itself inside a function, you end up with a struct which you can't properly refer to elsewhere:
void f1(struct s);
int main()
{
struct s { int a, b; } s1;
f1(s1);
}
void f1(struct s arg) /* error: this struct s might not be the same as the previous one */
{
int x = arg.b; /* error: compiler might not know that struct s contains a and b */
}
Looked at the previous answers. Suggest you wrap your mind around the 'C' difference between a declaration and a definition. Note that earlier versions of 'C' would NOT allow passing a copy of a structure on the stack, only a pointer to a struct..
in my university our teacher taught us "we define function prototype before main function. Like:
#include<stdio.h>
void findmax(float, float);
int main()
{
//code goes here
}
But today my friend showed me they learned they put prototype inside main function. Like:
#include<stdio.h>
int main()
{
void findmax(float, float);
float firstnum, secondnum;
printf("Enter first:");
scanf("%f", &firstnum);
printf("Enter second:");
scanf("%f", &secondnum);
findmax(firstnum, secondnum);
}
void findmax(float x, float y)
{
float maxnum;
if(x>y)
{
maxnum=x;
}
else
{
maxnum=y;
}
printf("The max is %f", maxnum);
}
They both works.I wonder if there are differences between them. Thanks.
Can we define function prototype in main function in C?
Yes.
I wonder if there are differences between them
The difference is that in first snippet prototype is global while in second it is local to main. findmax will be visible after its declaration and/or definition.
#include<stdio.h>
void foo();
int main()
{
void findmax(float, float);
foo();
findmax(10, 20); // It knows findmax by the prototype declared above
}
void findmax(float x, float y)
{
float maxnum;
if(x>y)
maxnum=x;
else
maxnum=y;
printf("The max is %f", maxnum);
}
void foo(){ // foo is using findmax after its definition.
findmax(12, 30);
}
If foo is declared in outside a function, it can be called from any function in the same file:
void foo(); // <-- global declaration
int main() {
foo(); // <-- works, foo() is declared globally
}
void otherfunc() {
foo(); // <-- works, foo() is declared globally
}
However, if foo is declared inside a function, it can only be used within the same scope:
int main() {
void foo(); // <-- scoped declaration
foo(); // works, foo() is declared in same scope
}
void otherfunc() {
foo(); // ERROR: foo() is not declared in scope of otherfunc()
}
In either case, foo must be declared before it is used.
If you declare the function in main() it is scoped in the main() and you cannot access it in another function. But if you declare it at the start of the file or in a header file you can use it in any function.
A straightforward answer to your question would simply be a YES. But when it comes to the scope, I'd like to add more.
What others suggest is right -- if you declare a function inside another function, the first one's scope is usually limited to the second one. For the example you provided, it is perfectly safe to say so. But that may not be the case always. Consider the following code:
#include <stdio.h>
/* Can be accessed from anywhere in this file
* because defined before anything else.
*/
void print_hello() {
puts("Hello!");
}
int main() {
void print_hello(); /* Not needed actually */
void print_namaste();
void print_hi();
print_namaste();
print_hi();
}
/* The following two functions cannot be
* accessed from within the above two functions
* unless these two are declared inside them
* or at the starting of this file
*/
void print_namaste() {
puts("Namaste!");
print_hello();
}
void print_hi() {
puts("Hi!");
}
Here you can see that print_hello() is declared inside main(). But that is redundant. print_hello() has already been introduced into the compiler. There is no need of declaration to use it inside this file (if you use it inside other files and compile them independently, then you'll have to declare it inside those files or write a header file to do so). What my point is, declaring print_hello() inside main() has not rendered it local, at least in this example. You can see print_namaste() calling it successfully without any additional declaration.
But that is not the case with print_namaste() and print_hi(). They require declaration to be used from within main() because they are introduced to the compiler only after main() has been defined.
print_namaste() will only be visible to the functions inside which we declare it, and to those functions which are defined after print_namaste(). In this example, print_namaste() is not visible to print_hello() (unless declared inside it or before it), but visible to main() because declared inside it, and visible to print_hi because its definition comes only after the definition of print_namaste().
In VC2008 the following is valid:
int main(void)
{
void foo(void);
//...
}
void test(void)
{
foo();
}
My believe was that prototype declarations are valid anywhere and their scope is at least from the point of declaration to the end of file.
Looking at the C99 standard:
6.2.1 Scope of Identifiers
An identifier can denote an object; a function; a tag or a member of a structure, union, or
enumeration; a typedef name; a label name; a macro name; or a macro parameter... For each different entity that an identifier designates, the identifier is visible (i.e., can be
used) only within a region of program text called its scope... identifier has scope determined by the placement of its declaration (in a
declarator or type specifier). If the declarator or type specifier that declares the identifier
appears outside of any block or list of parameters, the identifier has file scope, which
terminates at the end of the translation unit. If the declarator or type specifier that
declares the identifier appears inside a block or within the list of parameter declarations in
a function definition, the identifier has block scope, which terminates at the end of the
associated block.
This would mean that VC2008 is wrong.
suppose I have the following code:
#define SIZE 5
### FIRST OPTION ###
int main(int argc , char** argv){
### SECOND OPTION ###
return 0;
}
I have checked online and couldn't really understand what will be the difference between those three code statements (on compile and runtime) when I write them instead of first option line and second option line (each statement will be wrote individually) :
struct my_struct array[SIZE]
static struct my_struct array[SIZE]
struct my_struct** array = (struct my_struct**)malloc(SIZE*sizeof(struct my_struct*))
Michael
Option '1' can be used to define your array in a global scope or in a scope of a function, like main. In the following example 'array' is declared in the global scope and is potentially visible to any other module in at link time (if such a module declares it as 'extern'. There is only one copy of this array in the program.
file1.c
struct my_struct array[SIZE];
int main() {
...
array[0] = ...;
}
this file can access the declaration in file1.c
file2.c
extern struct my_struct array[SIZE];
void foo() {
...
array[1] = array[0];
}
Now, if you declare it inside a function, than a new copy of the array will be allocated (in stack) every time the function is called.
int foo() {
struct my_struct array[SIZE];
....
}
It will be visible inside of the function only. 'main' is a normal function and the rule works there as well.
using static (#2) changes the meaning of allocation. If used outside, there will be only one copy of the data associated with this particular file. It will be visible from inside the file, but not from outside.
static struct my_struct array[SIZE];
int main() {
...
array[0] = ...;
}
if you use it inside the function, than it will be only a single copy of it associated with this function. It will not change between calls to the same function and will keep previous values. It also be visible from inside the function only.
int foo() {
static struct my_struct array[SIZE];
....
array[0].counter++;
}
for #3 all the global/static rules stay the same, but just for the pointer. The pointer contains an address of the memory where you dynamically allocated the array.
In this code I am trying to pass a pointer to the structure and then use this pointer to work on the structure members, but why is the output always showing 0?
#include<stdio.h>
#include<string.h>
struct student
{
int go;
} s;
void m();
void main()
{
m(&s);
printf("%d",s.go);
}
void m(struct student *ptr)
{
ptr->go;
}
struct student
{
int go;
}s;
creates a global variable. Global variables are zero initialized unless they are initialized explicitly. That statement is equivalent to:
struct student
{
int go;
};
struct student s = {0};
Hence the value of s.go is 0. The call to m does not change the values of any variables. It has no effect on the output. The output will be 0 even if the call to m(&s) is removed.
The global variable s is initialized with all members 0.
Nothing changes the value of s.go, so the output is 0.
Your question has all sorts of errors, here they are, in no particular order:
you don't need #include <string.h> if you aren't using any "string" functions
you shouldn't use global variables (if you did, it would eliminate the need to pass the pointer to s to functions to access the struct); you should remove the global variable (i.e., make it local) and continue to pass the pointer-to-struct as you are to m() in order to be able to access it outside of main() (where you should declare it)
your signature for main() is incorrect as I pointed out in a comment to OP, and naturally you are missing the return 0; statement in main() because of this
you are missing a newline in your printf()
you aren't actually doing anything with ptr->go in m(); you aren't assigning anything to it or otherwise using it. It is printing zero because, as others have pointed out, global variables (because they are static,) are (default-)initialized
Here is an example with corrections (note you can initialize s as described by others if you wish to use it's value before you modify/set it):
#include <stdio.h>
struct student
{
int go;
};
void m();
int main(void)
{
struct student s;
m(&s);
printf("%d\n", s.go);
return 0;
}
void m(struct student *ptr)
{
ptr->go = 5;
}
When you declare your structure as global , their members are always initialize with its default value, if int than '0' and if char or string than '\0' . So you are getting Value 0.
struct student
{
int go;
} s;
#include <stdio.h>
#include <conio.h>
typedef arrChoice[10] /*is this a global variable?*/
int main() {};
getch();
return 0;
}
its not done yet, but this is what i meant.
typedef is not a global variable, it's simply an alias for another type. I usually use them for function pointers when I'm passing those around because writing them out every time is annoying.
typedef int (*function)(int, int);
I also use them to define a structure, union, or enumeration as a type
typedef struct {
int x;
int y;
int z;
} Point;
typedef declares the new type not variable.
This might help you. In the code you posted here, there is a error. There are no statements in side main function. getch and return statements should be inside main function. I feel your code should be like this.
#include <stdio.h>
typedef int arrChoice; /* arrChoice is alias to int */
arrChoice a[10] ;/* array a is a global variable of integers*/
int main()
{
getch();
return 0;
}
please note that the purpose of typedef is to assign alternative names to existing types(int,float,double,etc.). The following statements are similar.
typedef arrChoice[10] is similar to typedef int[10];
When you try to refer arrChoice, then you get an error message
expected expression before 'arrChoice'.