I listed some example code below and the question is if there is a way for the function_name to access the value of number from struct_name?
typedef struct struct_name {
int number
void (*func)();
} * struct_name_ptr;
void function_name() {
//access number from struct
}
main() {
struct_name_ptr newobject;
newobject->func=&function_name;
newobject->func(); //can it print the value of the number in the structure above?
}
Uh - no.
A struct can certainly contain a function pointer. But the function you call wouldn't have any knowledge of the struct. Unless you passed a pointer as a function argument, or made the struct global.
With my limited knowledge of programming, I don't think this is possible. Though the struct contains a function pointer, the address of the function assigned to it is different and I don't think there will be anyway for it to access it unless you pass it as an argument.
Well, two things, struct_name->number should have a value, and it either needs to be in the same scope as &function_name or it needs to be explicitly passed. Two ways to do it:
/* Here is with a global calling struct */
#include<stdio.h>
typedef struct struct_name {
int number;
void (*func)();
} * struct_name_ptr;
struct struct_name newobject = { 0 };
void function_name() {
printf("%d",struct_name);
}
void main() {
struct struct_name_ptr newobject;
newobject->func=&function_name;
newobject->func();
}
/* And one with a modified function_name */
#include<stdio.h>
typedef struct struct_name {
int number;
void (*func)();
} * struct_name_ptr;
void function_name(struct_name) {
printf("%d",struct_name);
}
void main() {
struct struct_name_ptr newobject;
newobject.number = 0;
newobject->func=&function_name;
newobject->func(newobject);
}
No, a pizza won't ever know what the pizza delivery guy, who delivered it, looks like.
A regular function is just an address in memory. It can be called using a function pointer like in this case. In any case: The function won't know how it was called. In particular it won't know that it was called using a function pointer that's part of (a piece of memory corresponding to) some struct.
When using a language with classes like C++, member functions will have a hidden argument which is a pointer to the class instance. That's how member functions know about their data.
You can 'simulate' a simple OOP in plain C, for your example like:
typedef struct {
int number;
void (*func)();
} class;
void function_name(class *this) {
printf("%d",this->number);
}
#define CALL(c,f) c.f(&c)
int main() {
class object={12345,function_name};
CALL(object,func); // voilá
}
Related
I declared a struct like this one :
typedef struct s_data {
char buff[2048];
int len;
void *func[10];
struct data *next;
} t_data;
In my code, when passing a *data, I assigned some functions (just giving one so it is more understandable)
void init_data(t_data *data)
{
data->len = 0;
data->func[0] = &myfirstfunctions;
//doing the same for 9 others
}
My first function would be something taking as argument *data, and an int.
Then, I try to use this function in another function, doing
data->func[0](data, var);
I tried this and a couple of other syntaxes involving trying to adress (*func[0]) but none of them work. I kind of understood from other much more complex questions over there that I shouldn't store my function like this, or should cast it in another typedef, but I did not really understand everything as I am kind of new in programming.
void* can only be used reliably as a generic object pointer ("pointer to variables"). Not as a generic function pointer.
You can however convert between different function pointer types safely, as long as you only call the actual function with the correct type. So it is possible to do just use any function pointer type as the generic one, like this:
void (*func[10])(void);
...
func[0] = ((void)(*)(void))&myfirstfunction;
...
((whatever)func[0]) (arguments); // call the function
As you might note, the function pointer syntax in C is horrible. So I'd recommend using typedefs:
typedef void genfunc_t (void);
typedef int somefunc_t (whatever*); // assuming this is the type of myfirstfunction
Then the code turns far easier to read and write:
genfunc_t* func [10];
...
func[0] = (genfunc_t*)&myfirstfunction;
...
((somefunc_t*)func[0]) (arguments);
If all of your functions will have the same signature, you can do this like:
#include <stdio.h>
typedef void (*func)(void *, int);
struct s_data {
char buff[2048];
int len;
func f[10];
struct s_data *next;
};
static void
my_first_function(void *d, int x)
{
(void)d;
printf("%d\n", x + 2);
}
static void
init_data(struct s_data *data)
{
data->len = 1;
data->f[0] = my_first_function;
}
int
main(void)
{
struct s_data d;
init_data(&d);
d.f[0](NULL, 5);
return 0;
}
If your functions have different signatures, you will want to either use a union, or perhaps you will need several different members of the struct to store the function pointers.
The problem is that you haven't actually declared an array of function pointers. What you actually did is an array of pointers to void.
The syntax of declaring a pointer to function is as following:
function_return_type (*pointer_name)(arg1_type,arg2_type,...);
Then you can create an array of pointers to functions:
function_return_type (*arr_name[])(arg1_type, arg2_type,...)
Therefore, the declaration of your structure should look like this:
typedef void (*pointer_to_function)(void *, int);
struct s_data {
char buff[2048];
int len;
pointer_to_function array_of_pointeters[10];
struct s_data *next;
};
Good luck:)
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 one of my applications written in C I have a struct declared as a member of another struct:
struct _test
{
int varA;
//...
struct _small
{
int varB;
//...
} small;
} test;
Now I want to create a function that access varB above, but I don't want it to access the entire structure test, that is, I don't want to do:
#include <relevant_header>
void myFunction()
{
test.small.varB = 0;
}
instead, I want to pass only the small structure as a parameter to that function; something like this:
#include <relevant_header>
void myFunction(struct _test::_small* poSmall)
{
poSmall->varB = 0;
}
The problem is I don't know how to do this, that is, the above code doesn't compile right (I suppose it's C++ syntax only). So how may I do this in a C code - pass a pointer to a struct that was declared inside another struct? I wasn't able to find anything about this both in SO as well as in Google in general.
Just do:
void myFunction(struct _small *poSmall)
{
poSmall->varB = 0;
}
The scope of struct _small is not limited to its outer structure.
Can we have functions in structures in C language?
Could someone please give an example of how to implement it and explain?
No, structures contain data only. However, you can define a pointer to a function inside of a struct as below:
struct myStruct {
int x;
void (*anotherFunction)(struct foo *);
}
The answer is no, but there is away to get the same effect.
Functions can only be found at the outermost level of a C program. This improves run-time speed by reducing the housekeeping associated with function calls.
As such, you cannot have a function inside of a struct (or inside of another function) but it is very common to have function pointers inside structures. For example:
#include <stdio.h>
int get_int_global (void)
{
return 10;
}
double get_double_global (void)
{
return 3.14;
}
struct test {
int a;
double b;
};
struct test_func {
int (*get_int) (void);
double (*get_double)(void);
};
int main (void)
{
struct test_func t1 = {get_int_global, get_double_global};
struct test t2 = {10, 3.14};
printf("Using function pointers: %d, %f\n", t1.get_int(), t1.get_double());
printf("Using built-in types: %d, %f\n", t2.a, t2.b);
return 0;
}
A lot of people will also use a naming convention for function pointers inside structures and will typedef their function pointers. For example you could declare the structure containing pointers like this:
typedef int (*get_int_fptr) (void);
typedef double (*get_double_fptr)(void);
struct test_func {
get_int_fptr get_int;
get_double_fptr get_double;
};
Everything else in the code above will work as it is. Now, get_int_fptr is a special type for a function returning int and if you assume that *_fptr are all function pointers then you can find what the function signature is by simply looking at the typedef.
No, it has to be implemented like this :
typedef struct S_House {
char* name;
int opened;
} House;
void openHouse(House* theHouse);
void openHouse(House* theHouse) {
theHouse->opened = 1;
}
int main() {
House myHouse;
openHouse(&myHouse);
return 0;
}
I'm a new C programmer and I wanted to know how I can pass a struct through to a function. I'm getting an error and can't figure out the correct syntax to do it. Here is the code for it....
Struct:
struct student{
char firstname[30];
char surname[30];
};
struct student person;
Call:
addStudent(person);
Prototype:
void addStudent(struct student);
and the actual function:
void addStudent(person)
{
return;
}
Compiler errors:
line 21: warning: dubious tag declaration: struct student
line 223: argument #1 is incompatible with prototype:
This is how to pass the struct by reference. This means that your function can access the struct outside of the function and modify its values. You do this by passing a pointer to the structure to the function.
#include <stdio.h>
/* card structure definition */
struct card
{
int face; // define pointer face
}; // end structure card
typedef struct card Card ;
/* prototype */
void passByReference(Card *c) ;
int main(void)
{
Card c ;
c.face = 1 ;
Card *cptr = &c ; // pointer to Card c
printf("The value of c before function passing = %d\n", c.face);
printf("The value of cptr before function = %d\n",cptr->face);
passByReference(cptr);
printf("The value of c after function passing = %d\n", c.face);
return 0 ; // successfully ran program
}
void passByReference(Card *c)
{
c->face = 4;
}
This is how you pass the struct by value so that your function receives a copy of the struct and cannot access the exterior structure to modify it. By exterior I mean outside the function.
#include <stdio.h>
/* global card structure definition */
struct card
{
int face ; // define pointer face
};// end structure card
typedef struct card Card ;
/* function prototypes */
void passByValue(Card c);
int main(void)
{
Card c ;
c.face = 1;
printf("c.face before passByValue() = %d\n", c.face);
passByValue(c);
printf("c.face after passByValue() = %d\n",c.face);
printf("As you can see the value of c did not change\n");
printf("\nand the Card c inside the function has been destroyed"
"\n(no longer in memory)");
}
void passByValue(Card c)
{
c.face = 5;
}
The line function implementation should be:
void addStudent(struct student person) {
}
person is not a type but a variable, you cannot use it as the type of a function parameter.
Also, make sure your struct is defined before the prototype of the function addStudent as the prototype uses it.
When passing a struct to another function, it would usually be better to do as Donnell suggested above and pass it by reference instead.
A very good reason for this is that it makes things easier if you want to make changes that will be reflected when you return to the function that created the instance of it.
Here is an example of the simplest way to do this:
#include <stdio.h>
typedef struct student {
int age;
} student;
void addStudent(student *s) {
/* Here we can use the arrow operator (->) to dereference
the pointer and access any of it's members: */
s->age = 10;
}
int main(void) {
student aStudent = {0}; /* create an instance of the student struct */
addStudent(&aStudent); /* pass a pointer to the instance */
printf("%d", aStudent.age);
return 0;
}
In this example, the argument for the addStudent() function is a pointer to an instance of a student struct - student *s. In main(), we create an instance of the student struct and then pass a reference to it to our addStudent() function using the reference operator (&).
In the addStudent() function we can make use of the arrow operator (->) to dereference the pointer, and access any of it's members (functionally equivalent to: (*s).age).
Any changes that we make in the addStudent() function will be reflected when we return to main(), because the pointer gave us a reference to where in the memory the instance of the student struct is being stored. This is illustrated by the printf(), which will output "10" in this example.
Had you not passed a reference, you would actually be working with a copy of the struct you passed in to the function, meaning that any changes would not be reflected when you return to main - unless you implemented a way of passing the new version of the struct back to main or something along those lines!
Although pointers may seem off-putting at first, once you get your head around how they work and why they are so handy they become second nature, and you wonder how you ever coped without them!
You need to specify a type on person:
void addStudent(struct student person) {
...
}
Also, you can typedef your struct to avoid having to type struct every time you use it:
typedef struct student{
...
} student_t;
void addStudent(student_t person) {
...
}
Instead of:
void addStudent(person)
{
return;
}
try this:
void addStudent(student person)
{
return;
}
Since you have already declared a structure called 'student' you don't necessarily have to specify so in the function implementation as in:
void addStudent(struct student person)
{
return;
}