I wanted to create a function for my struct. I searched on the internet and found this two helpful links:
Can I define a function inside a C structure?
Define functions in structs
Most of the answers defined this:
typedef struct Point
{
int x;
int y;
void (*Print)(Point* p);
} Point;
Meaning that if you wanted to call the Print function on a struct you will have to pass the same point again. In other words you would do something like this:
somePoint.Print(&somePoint);
That works but it will be better if you don't have to pass &somePoint as an argument. In other words my goal is to achieve the same behavior by calling somePoint.Print(); instead of somePoint.Print(&somePoint); .
Anyways I am no expert in C and I was about to post this answer on those links:
#include <stdlib.h>
#include <string.h>
typedef struct Point
{
int x;
int y;
void (*Print)();
} Point;
void _print_point(Point* p)
{
printf("x=%d,y=%d\n", p->x, p->y);
}
void Point_Constructor(Point* p, int x, int y){
p->x = x;
p->y = y;
// create wrapper function
void inline_helper() { _print_point(p);}
p->Print = inline_helper;
}
int main(){
Point p1;
Point_Constructor(&p1,1,2);
p1.Print(); // I CAN CALL THE PRINT FUNCTION WITHOUT HAVING TO PASS AGAIN THE SAME POINT AS REFERENCE
return 0;
}
Why nobody suggested that? Is it safe if I run code like that?
Related
can you please explain in details this line of code inside struct:
There is a pointer to function but why would you reference it to struct?
void (*function)(struct Structure *);
what does this mean
(struct Structure *)?
(struct Structure *)
It means that the function have a struct Structure * argument. Actually it will make more sense with (struct Structure *variable of struct).
In this way, you can use a pointer to point a struct and should put the address of the struct variable which can be used in the function.
#include <stdio.h>
typedef struct circle{
int rad;
int area;
} Circle;
void ShowCircleInfo(Circle *info)
{
printf("rad value: %d\n", info->rad);
printf("area value: %d", info->area);
}
int main(void)
{
Circle circle_one;
circle_one.rad = 2;
circle_one.area = 3;
ShowCircleInfo(&circle_one);
return 0;
}
void (*function)(struct Structure *); declares function to be a pointer to a function that has a parameter of type struct Structure * and does not return a value.
For example
#include <stdio.h>
struct Structure {
int a;
void (*function)(struct Structure *);
};
void foo(struct Structure *a) {
if (a->function == NULL) a->function = foo;
a->a++;
printf("%d\n", a->a);
}
int main(void) {
struct Structure a = {42, foo};
struct Structure b = {0}; // don't call b.function just yet!!
a.function(&b); // foo(&b)
b.function(&a); // foo(&a)
}
See code running at https://ideone.com/7E74gb
In C, function pointer declarations have almost the same structure as function headers.
Only the function name will change to have some parantheses and a "*" in it, and the arguments won't have names, because only their types are important when using pointers (we don't access the values of the arguments, so we don't need their names).
They basically look like this:
<return_value> (*<function_name>)(<argument_list>)
So, for example, the function pointer for the function
void swap(int* a, int* b);
would be
void (*swap_ptr)(int*, int*);
Notice that the name of the pointer is in the place of the name of the function, and looks a bit odd compared to normal pointer declarations.
An excellent reading on this topic (you can skip the C++ stuff): https://www.cprogramming.com/tutorial/function-pointers.html
I want to create a constructor using C.
What is the cleanest way to achieve this?
My attempt:
#include <stdio.h>
struct line {
void (*add_line_ptr)(struct line*, int x, int y);
int x;
int y;
};
void add_line(struct line* lptr, int x, int y)
{
lptr->x = x;
lptr->y = y;
}
int main()
{
struct line line1 = {add_line, 0, 0};
line1.add_line_ptr(&line1, 10, 20);
printf("%d %d\n", line1.x, line1.y);
}
I think that using line1.add_line(&line1, is a bit redundant - since it's quite obvious that I want to do the operation on line1.
Is there a way to implement this without passing a pointer to the "object"(struct)? or some other way I didn't think of?
Using function pointers just for the sake of emulating C++-like syntax is just messy with no obvious benefits. You won't have RAII in C no matter what you do, so you need to call constructors/destructors explicitly. If you do so by typing obj.foo() or obj = foo() has absolutely nothing to do with OO, it's mere coding style.
The main problem here though, is that your code does not have proper OO design, since the struct is completely open and not using private encapsulation. For the same reason as class line { public: int x; int y; }; is not proper OO either - you don't get OO just because you smash some related variables into an aggregate type, regardless of language.
"Cleanest"/"prettiest" would mean full private encapsulation. In C, that can be achieved with opaque types. I prefer to implement them without hiding pointers behind typedef, so:
line.h
#include <stdio.h>
#include <stdlib.h>
typedef struct line line; // forward declaration of incomplete type
line* line_construct (int x, int y);
line.c
#include "line.h"
struct line { // actual definition of the struct, local to line.c
int x; // private variable
int y; // private variable
};
line* line_construct (int x, int y)
{
line* obj = malloc (sizeof *obj);
if(obj == NULL) { /* error handling here */ }
obj->x = x;
obj->y = y;
return obj;
}
caller.c
#include "line.h"
int main(void)
{
line* x = line_construct(10, 20);
}
Here line is 100% encapsulated and the contents of the struct cannot be accessed by the caller. Since I don't hide pointers behind typedef, the caller must always use line* pointers and can never declare an instance of the object directly.
If the constructor is only meant to zero-out the struct members, then it doesn't need to get passed any parameters but can do so internally.
And obviously you need to implement a corresponding destructor with free as well.
line* line_destruct(line* obj) { free(obj); return NULL; } or so.
I wouldn't put the initializer into your structure to begin with. Other functions, sure, but not the first one. Something like this:
#include <stdio.h>
struct line {
int x;
int y;
};
void add_line(struct line *lptr, int x, int y)
{
lptr->x = x;
lptr->y = y;
}
int main()
{
struct line line1 = {0, 0};
add_line(&line1, 10, 20);
printf("%d %d\n", line1.x, line1.y);
}
The reason is that you have to assign the initializer anyway after you allocate your structure, either implicitly or explicitly. In OOP languages you normally name the class you want once, and both the allocator and initializer will run. In C you have to run them separately. Whether you allocate an object on the stack or on the heap, you will have to explicitly name the function you want to call at least once anyway.
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;
}
For example, I have the C code below:
#include <stdio.h>
#include <stdlib.h>
struct a
{
void(*fun)(struct a *);
int x;
};
void fun(struct a *st)
{
++st->x;
}
struct a *new_a()
{
struct a *v = (struct a*)malloc(sizeof(struct a));
v->fun = fun;
return v;
};
int main()
{
struct a *v = new_a();
v->x = 5;
v->fun(v);
printf("%d\n", v->x);
}
This prints, of course, 6, however, is there a way of not making the function call dependent of using the same struct to call it: v->fun();, rather than v->fun(v);?
The short answer is no. You would need C++ for that.
No. In C there is no easy way to do this. C++ provides this feature, it's called methods. If you are going to implement your own C with classes, you'll run into a syntax nightmare, before giving up.
A good C-style approach to object-functions will be the convention for functions taking one (mostly the first) parameter as a "self" (which is the reference to the object that gets managed).
I have a struct defined as :
typedef struct pt {
int x;
int y;
}point;
I also have a stack push function declared as :
void push(point p);
Now whenever i wish to call this function, I can do the following :
point p = {x_value, y_value};
push(p);
I wanted to know if there is a less cumbersome workaround for this. Something which could enable me to do this in a single line. Maybe something like :
push((point){x_value, y_value});
Define a "constructor" function:
point make_point(int x, int y)
{
point result = {x, y};
return result;
}
Then
push(make_point(x, y));
The syntax you thought of works out of the box in C99:
typedef struct {
int x;
int y;
} point;
push((point){ 42, 1337 });
What's even better, the resulting literal is an lvalue, so you can take its address in case your push() function accepts a pointer:
void push(point *p);
// ...
push(&(point){ 42, 1337 });
Demo here.