struct using a pointer, ... in something not a struct or union - c

I defined a structure called coordonnees declared as a pointer, I want to append values to the pointer a_visiter but it's not working. How can I fix that?
Here is the struct code:
typedef struct couple
{
int ligne;
int colonne;
}*coordonnees;
int main()
{
coordonnees a_visiter;
a_visiter=(coordonnees)malloc(DIMENSION*4*sizeof(struct couple));
int p=0;
etc ...
}
void voisin_egaux(char matrice[][DIMENSION+1],int x, int y,coordonnees **a_visiter,int *p)
{
if (matrice[x][y]==matrice[x+1][y]){
(a_visiter+(*p))->ligne=x+1;
(a_visiter+(*p))->colonne=y;
++(*p);
}
I get as an error: request for member ligne in something not a structure or union.

This parameter declaration
coordonnees **a_visiter
is equivalent to
struct couple ***a_visiter
Thus the expression
(a_visiter+(*p))
has the above pointer type that does not point to an object of the structure type.
To make this code semantically valid
(a_visiter+(*p))->ligne=x+1;
(a_visiter+(*p))->colonne=y;
the parameter should be declared like
coordonnees a_visiter
Otherwise you need to write
( **a_visiter+(*p))->ligne=x+1;
( **a_visiter+(*p))->colonne=y;

Related

Struct with pointer to function

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

Using a function from a function array stored in a struct in C

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:)

Getting the value inside a pointer pointed by another pointer?

I have a queue that stores thread structures
struct x
{
int n;
char *c;
void *f;
};
The function below returns a structure defined as the following:
struct s {
void *data;
};
When I call *new = allocate(&x_ptr), how can I access the members of x?
I tried the following but it does not work:
printf("%d\n", new ->data->n)
I get this error: request for member ‘n’ in something not a structure or union
data has type of void *, you need to cast it to the correct pointer type (assuming it is referencing a valid object of that type).
printf("%d\n", node->data->threadid);
---->
printf("%d\n", ((threaddesc *)(node->data))->threadid);

Nested struct in C issue

I have a struct declaration in C that looks something like this:
static struct {
int a;
int b;
} myStruct[10];
I want to declare a struct member variable inside myStruct, so I try to add this:
static struct {
int c;
int d;
struct myStruct[10] s;
} myNestedStruct[100];
I'm getting a bunch of errors i.e. syntax error before or at: [ and
syntax requires ";" after last struct/union member. What would the better way to implement the nested structs be?
EDIT: My code now looks like this:
static struct {
int a;
int b;
} myStruct[10];
static struct {
int c;
int d;
struct myStruct s[10];
} myNestedStruct[100];
However I'm getting an error: incomplete struct/union/enum myStruct: s
You need to declare myStruct first before using it as a struct type.
struct myStruct {
int a;
int b;
};
static struct {
int c;
int d;
struct myStruct s[10];
} myNestedStruct[100];
This creates a variable called myNestedStruct which is an array of 100 structs, each containing two ints and an array of 10 mystructs.
When you write code like
struct { ... } Foo;, it's not declaring a type named Foo but a variable. Its type is an anonymous struct corresponding to what you put in the curly braces. If you want to declare a type, write struct Foo { ... };.
That's where your error is coming from -- myStruct is not a type name, so when you write struct myStruct in the definition of myNestedStruct the compiler thinks you're about to define a struct by that name. But then it encounters an [ which shouldn't be the next token in a struct declaration ever so it tells you can't make sense of the code.

Why typedef for a function pointer is different from a regular typedef?

typedef regularly works like: typedef <type> <type_alias>. But typedefs for function pointers seems to have different structure: typedef int (*fn)(char *, char *); - there is no type alias, just a single function signature.
Here is the example code:
#include <stdio.h>
typedef void (*callback)(int);
void range(int start, int stop, callback cb) {
int i;
for (i = start; i < stop; i++) {
(*cb)(i);
}
}
void printer(int i) {
printf("%d\n", i);
}
main(int argc, int *argv[])
{
if (argc < 3) {
printf("Provide 2 arguments - start and stop!");
}
range(atoi(argv[1]), atoi(argv[2]), printer);
}
So - why typedefs for function pointers are different?
The syntax for using typedef to define a function pointer type follows the same syntax as you would use for defining function pointers.
int (*fn)(char *, char *);
Defines fn to be a pointer to a function ...
typedef int (*fn)(char *, char *);
Defines fn to be a type that is a pointer to a function ...
It works the same. You just have to look at it in a slightly different way. typedef defines your own type name by putting it in exactly the place where the identifier of your variable would go without the typedef. So
uint8_t foo;
becomes
typedef uint8_t footype;
footype foo;
edit: so "R Sahu" was a bit faster and see his example for the same principle applied to function pointers.
C declaration syntax is much more complicated than type identifier, with examples like
T (*ap)[N]; // ap is a pointer to an N-element array
T *(*f())(); // f is a function returning a pointer to
// a function returning a pointer to T
Syntactically, typedef is treated as a storage class specifier like static or extern. So you can add typedef to each of the above, giving
typedef T (*ap)[N]; // ap is an alias for type "pointer to N-element array
typedef T *(*f())(); // f is an alias for type "function returning
// pointer to function returning pointer to T"

Resources