Does somebody know how to do send name of structure parameter as argument? I have code like this:
typedef struct {
double x;
double y;
double dis;
} Point;
void bucketSort (Point * points, name /*name of parameter*/)
{
printf("%lf",points.name);
}
And, for example, call of function as i see it:
bucketSort(point1,"dis");
I think You can't send variable name as parameter But. You can check it like below
typedef struct {
double x;
double y;
double dis;
} Point;
void bucketSort (Point * points,char *name /*name of parameter*/)
{
if(name[0] == 'd' ) printf("%lf",points.dis);
else if(name[0] == 'x') printf("%lf",points.x);
else if(name[0] == 'y') printf("%lf",points.y);
}
You can define an enum and store all possible names. Then you can use this enum as the parameter to your function.
typedef enum {
ENUM_X = 0,
ENUM_Y = 1,
ENUM_DIS = 2
} STRCT_PARAM_NAME;
typedef struct {
double x;
double y;
double dis;
} Point;
void bucketSort (Point * points, STRCT_PARAM_NAME name) {
switch (name) {
case ENUM_X: printf("%lf\n", points->x); break;
case ENUM_Y: printf("%lf\n", points->y); break;
case ENUM_DIS: printf("%lf\n", points->dis); break;
default: printf("Invalid\n"); break;
}
}
Now, you can call bucketSort like this:
bucketSort(points_obj, ENUM_X);
Related
#define NUMBER_OF_CARDS 54
typedef enum type{
QUEEN;
JACK;
KING
} CardTypes;
typedef struct game{
CardTypes cards[NUMBER_OF_CARDS];
struct{
int hearts;
int spades;
int clubs;
int diamonds;
}
int players_cards;
}GameState;
I have something similar like this and I want to access any variable from enum when this function is called
void set_cards(GameState gamestate, int x, int y, CardTypes cardtypes){
gamestate.cards[x * y] = cardtypes;
}
void generate_game(GameState gamestate){
/*
some code
*/
if(variable == 0){
set_cards(gamestate, x, y, gamestate.cards[NUMBER_OF_CARDS].JACK;
//This is what I have tried but it doesn't work
I hope you understand what I mean, because I really don't know how to explain this any better.
set_cards(gamestate, x, y, gamestate.cards[NUMBER_OF_CARDS].JACK;
//this is what I have tried but it doesn't work
please ignore any inaccuracies in the code. what is important for me is how can i access any of the enum's variable in the function generate_game().
this right here: if(variable == 0){ set_cards(gamestate, x, y, gamestate.cards[NUMBER_OF_CARDS].JACK; //This is what I have tried but it doesn't work
Based upon what #Aconcagua wrote your code should be using pointers :
// gamestate is a structure , so it must be passed as pointer to enable modification to be seen by caller
void set_cards(GameState *gamestate, int x, int y, CardTypes cardtypes){
gamestate->cards[x * y] = cardtypes;
}
void generate_game(GameState *gamestate){ // here also pointer so caller know the changes
/*
some code
*/
if(variable == 0){
// next depends on what you intend to do :
// 1- set the current games rate card with value of last card
set_cards(gamestate, x, y, gamestate->cards[NUMBER_OF_CARDS-1]);
// 2- set the current gamestate to JACK
set_cards(gamestate, x, y, JACK);
Your types do not have too much sense. Card is defined by its colour and type.
typedef enum {
QUEEN,
JACK,
KING,
//you neeed some more
} CardTypes;
typedef enum {
HEART,
SPADE,
CLUB,
DIAMOND,
} CardColour;
typedef struct
{
CardTypes type;
CardColur colour;
}Card;
Card deck[54];
How to access:
void foo(Card *card)
{
Card card1;
card1.colour = HEART;
card1.type = JACK;
card -> colour = DIAMOND;
card -> type = KING;
card[34].colour = CLUB;
card[34].type = QUEEN;
}
I'm using tagged unions in a personal project. As an example, this is the type of code I use:
struct data_unit {
enum {
d_A, d_B, d_C
} dtype;
union {
char a;
int b;
double c;
} data;
};
void print_data(data_unit du) {
switch (du.dtype) {
case d_A: {
printf("%c", du.data.a);
break;
}
case d_B: {
printf("%d", du.data.b);
break;
}
case d_C: {
printf("%lf", du.data.c);
break;
}
default:
break;
}
return;
};
Is there more efficient way to implement print_data, one without manually checking each case of dtype? If C allowed lists of types, I would just iterate through it using the enum, but that isn't an available utility. I need a general way to do this, as I plan on adding a lot of data types to the union.
Is this possible to do? If not, what would a better strategy be for me in this context?
You could make use of the fact that a pointer to a struct-object may be treated as a pointer to its first member. Hence, when exchanging dtype and data, you could access all members in some generic way:
struct data_unit {
union {
char a;
int b;
double c;
} data;
enum {
d_A, d_B, d_C
} dtype;
};
typedef void (print_data_unit) (struct data_unit *du);
void print_data_unit_char(struct data_unit *du) {
printf("%c\n", *((char*)(du)));
}
void print_data_unit_double(struct data_unit *du) {
printf("%lf\n", *((double*)(du)));
}
void print_data_unit_int(struct data_unit *du) {
printf("%d\n", *((int*)(du)));
}
static print_data_unit* functions[3] = { print_data_unit_char, print_data_unit_int, print_data_unit_double };
void print_data(struct data_unit du) {
functions[du.dtype](&du);
}
int main() {
struct data_unit du;
du.dtype = 0;
du.data.a = 'c';
print_data(du);
du.dtype = 1;
du.data.b = 100;
print_data(du);
du.dtype = 2;
du.data.c = 200.55;
print_data(du);
}
I have a structure like this :
typedef struct s_struct
{
float x1;
float y1;
float x2;
float y2;
} t_struct;
this is used to draw some stroke on my screen but I have a little problem, I want to change my X value when the right arrow is pressed but it segfaults, I think it's because I don't send properly my structure address...
This is how I do :
void draw_all(t_struct *param)
{
draw_horizon(param);
draw_verti(param);
}
void draw_horizon(t_struct *param)
{
param->x1 = param->x1 + param->C_Y;
param->y1 = param->y1 + param->C_X;
param->x2 = param->x2 + param->C_Y;
param->y2 = param->y2 + param->C_X;
param->y2 = param->y2 + param->C_X;
stroke(param);
}
And the function who is called when I press my right arrow :
int event(int keycode, t_struct *param)
{
if (keycode == 53)
{
printf("exit succes.\n");
exit(1);
}
if (keycode == 124)
{
printf("====\n");
printf("PRE C_X = %f\n", param->C_X);
param->C_X = param->C_X + 1;
printf("POST C_X = %f\n", param->C_X);
draw_all(¶m);
}
return (0);
}
My function draw_verti is the same but for verticals stroke...
The segfault is because I have a copy of my structure and I do not succeed to send the address ...
Thank you !
In the event function the variable param is a pointer. When you do ¶m you get a pointer to the pointer, which is of type t_struct **. This is not what the draw_all function expected.
Your compiler should be complaining about it, if you had proper prototypes.
I must read and extract some values from string.
These values are coded like this:
k="11,3,1" v="140.3"
I have defined the codes and created struct with all field as well as a temp one where I store k and v. In fillFields proc I transfer values from temp struct to the right one (with the valid types).
It works but I have many fields and fillFields would need to have many if-conditions. Maybe someone could give me any hint how to write it smarter.
The simplified code now:
#define ASK "11,3,1"
#define BID "11,2,1"
#define CLOSE "3,1,1"
typedef struct tic {
float ask;
float bid;
float close;
}tic, *ticP;
typedef struct pElem {
char * k;
char * v;
}pElem, *pElemP;
void fillFields(ticP t, pElemP p)
{
if (strcmp( ASK, p->k)==0)
{
printf ("ASK %s\n", p->v);
t->ask = atof(p->v);
}
if (strcmp( BID, p->k)==0)
{
printf ("BID %s\n", p->v);
t->bid = atof(p->v);
}
if (strcmp( CLOSE, p->k)==0)
{
printf("CLOSE >>>%s<<<\n", p->v) ;
t->close = atof (p->v);
}
}
Rather than save the text value in pElem, save the converted values.
This creates an extra step in parsing k="11,3,1" v="140.3", to convert text to an enumerated type, but it's paid once. The fillFields() calls then run simpler. Assuming you have more ticP variables, it's a win.
typedef enum pElem_type {
pElem_None, pElem_ASK, pElem_BID, pElem_CLOSE, pElem_N
} pElem_type;
typedef struct pElem {
pElem_type type;
float value;
} pElem;
void fillFields(ticP t, const pElem *p) {
switch (p->type) {
case pElem_ASK:
printf("ASK %f\n", p->value);
t->ask = p->value;
break;
case pElem_BID:
printf("BID %f\n", p->value);
t->bid = p->value;
break;
case pElem_CLOSE:
printf("Close %f\n", p->value);
t->close = p->value;
break;
default:
printf("Error\n");
}
}
// Further simplifications possible
typedef struct tic {
float field[pElem_N];
}tic, *ticP;
static const char *FieldName[pElem_N] = {
"None", "ASK", "BID", "Close"
};
void fillFields(ticP t, const pElem *p) {
if (p->type < pElem_N) {
printf("%s %f\n", FieldName[p->type], p->value);
t->field[p->type] = p->value;
}
}
Based on the answer to the question Passing variable type as function parameter:
I could write something like this:
enum {
TYPEA,
TYPEB,
TYPEC,
TYPED
} TYPE;
void foo(TYPE t, void* x){
switch(t){
case TYPEA:
struct A* y = (struct A*)x;
//do something with a member named "next"
break;
case TYPEB:
struct B* y = (struct B*)x;
//do something with a member named "next"
...
}
}
Is there any way to avoid rewriting the "something with a member named next" multiple times?
We are assuming that "next" in A and B are not in the same relative memory position in each struct.
Assuming the items of the enum aren't given custom numbers, you can do a compact version of a switch-statement, by using function pointers.
enum {
TYPEA,
TYPEB,
TYPEC,
TYPED,
TYPE_N // number of enum items
} TYPE;
typedef void(*type_func_t)(void*);
static void TYPEA_specific (void* x)
{
struct A* y = x;
// specific stuff related to TYPEA here
do_something_with_next(y->next);
}
static void TYPEB_specific (void* x)
{
struct B* y = x;
// specific stuff related to TYPEB here
do_something_with_next(y->next);
}
static const type_func_t TYPE_HANDLER [TYPE_N] =
{
TYPEA_specific,
TYPEB_specific
...
};
inline void foo (TYPE t, void* x)
{
TYPE_HANDLER[t](x);
}
This solution uses a macro:
#include <stdio.h>
#define POLYCAST_AB(etype, target, member) \
*((etype) == TYPEA ? &((struct A *)(target))->member : \
(etype) == TYPEB ? &((struct B *)(target))->member : 0)
enum TYPE {
TYPEA,
TYPEB
};
struct A {
int next;
} a = {42};
struct B {
int i;
int next;
} b = {43, 44};
static void foo(enum TYPE t, void *x) {
POLYCAST_AB(t, x, next) += 100; // <-- most other answers can't do this
printf("next=%d\n", POLYCAST_AB(t, x, next));
}
int main(void) {
foo(TYPEA, &a);
foo(TYPEB, &b);
return 0;
}
If you don't need an lvalue, you can omit the extra * and & in the macro definition (and also omit the assumption that the next all have the same type).
C doesn't have dynamic look-up of structure members, of course.
The solution that will save the most keystrokes is probably to use a macro.
Also, there's no point in casting the pointer when converting from void *.
In each case, you can take the address of next with &y.next and then either pass it to a function or transfer control to code that uses the pointer to do something with next. This presumes that next has the same type in each struct, although it may be in different locations.
Here are three examples:
// Example 0: Functional call.
switch(t)
{
case TYPEA:
MyFunction(&(struct A *)x->next);
break;
case TYPEB:
MyFunction(&(struct B *)x->next);
break;
}
// Example 1: Code after the switch.
TypeOfNext *next;
switch(t)
{
case TYPEA:
next = &(struct A *)x->next;
break;
case TYPEB:
next = &(struct B *)x->next;
break;
}
… code that uses next…
// Example 2: Code in the switch, with goto.
switch(t)
{
TypeOfNext *next;
case TYPEA:
next = &(struct A *)x->next;
goto common;
case TYPEB:
next = &(struct B *)x->next;
common:
… code that uses next…
break;
}