I am trying to define a structure in C for a square where each side can either have a given color (labeled by int) or not have any color at all.
I would like my struct to behave like a named tuple, i.e allow for referring to the north color by square.n = 0; or square.c[NORTH_DIRECTION] = 0; interchangeably.
Is the following a correct way to do it:
typedef struct {
union {
struct {
int n, e, s, w;
};
int c[4];
};
union {
struct {
bool n_is_null, e_is_null, s_is_null, w_is_null;
};
bool is_null[4];
};
} SquareColors;
Thank you very much!
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;
}
Im beggining with linked list in C, and I found some problems where (if I understood well) manipulate linked lists without knowing internal structre (fields)!
Is it possible to append/remove an item in a linked list without knowledge of it's internal structure(opaque) given a pointer to the linked list?
Edit (adding details).
So the problem is to create a set of functions to manipulate linked lists, given a handler on the linked list as a parameter which is declared in the follwoing way :
typedef struct list *handler;
so for example I created a function to create a linked list :
handler ListCreate()
{
handler list = (handler)malloc(sizeof(handler));
if(!list)
{
printf("can not allocate memory \n");
return NULL;
}
return list;
}
but when it comes to appending, Im just blocked and I thought it can't be done, but maybe I'm wrong.
So this is the prototype of the function :
int ListAppend(handler list, void *item)
I wanted to do something similar, but I had to figure it out myself. The idea is to make an opaque object interface, and then give access to attributes of the implementation file by casting using a switch statement. I'm doing it this way to follow the dependency inversion principle. All of the code is in a single file to show that it compiles, but the three comment lines //interface, //dependency, and //context can be broken into different files so you can try different implementations of the dependency file without having to change the interface file.
#include <stdlib.h>
#include <stdio.h>
//interface
typedef enum {
DEP1,
DEP2
} Type;
typedef struct Interface{
struct Interface* ptr;
void* data;
int (*getConcreteStuff)(struct Interface*, Type t);
} Interface;
//dependency
typedef struct {
int concreteStuff1;
} Dependency1;
typedef struct {
int concreteStuff2;
} Dependency2;
static int getConcreteStuff(Interface* interface, Type t) {
switch(t){
case DEP1:
return ((Dependency1*) interface->data)->concreteStuff1;
break;
case DEP2:
return ((Dependency2*) interface->data)->concreteStuff2;
break;
}
}
Interface Dependency1_new(Interface* ptr){
Dependency1* d = malloc(sizeof(*d));
d->concreteStuff1 = 1;
struct Interface x = {ptr, d, getConcreteStuff };
return x;
}
Interface Dependency2_new(Interface* ptr){
Dependency2* d = malloc(sizeof(*d));
d->concreteStuff2 = 2;
struct Interface y = {ptr, d, getConcreteStuff };
return y;
}
//context
typedef struct {
Interface i;
} Context;
void Context_doSomething(Context* ctx, Type t){
printf("%d\n", ctx->i.getConcreteStuff(&ctx->i, t));
}
int main(){
Context ctx1 = { Dependency1_new(NULL) };
Context_doSomething(&ctx1, DEP1);
Context ctx2 = { Dependency2_new(&ctx1.i) };
Context_doSomething(&ctx2, DEP2);
Context ctx3 = { *ctx2.i.ptr };
Context_doSomething(&ctx3, DEP1);
return 1;
}
I have a struct with variety of data types. I want to create a universal function
that can:
look through any struct and check if the item values are within
certain range for given types: (E.G. item 1 should be within 10~35,
item 3 should be either 0/1). Note that the struct's item types and
names are not passed to the function, just the struct(any struct)
Count how many items are in the struct given any structure
Example:
typedef struct _anyStruct_t
{
uint8_t item1;
uint16_t item2;
bool item3;
char item4;
}anyStruct_t
What you are asking for is effectively impossible in C.
First of all, struct types contain no metadata about their contents. At runtime, a struct object is just a sludge of bytes. There's no way to determine at runtime the number or types of members in a struct object.
Secondly, if you want to do this for any struct type, you will have to pass its address to the function as a void *, meaning you have no way of knowing whether it's a struct type at all.
You would basically have to create your own "class" type that a) stores metadata about its members and b) supports some form of inheritance such that you can pass a pointer to the base "class" type and use that to access the metadata and members.
IOW, you'd have to re-implement a good chunk of C++.
Edit
Actually, as Andrew mentions below, even C++ doesn't support reflection. You'd have to go even further.
As others have said, C doesn't support reflection and so there is no universal way to figure out what attributes exist in C data structure.
In the past I've seen folks write a meta-compiler which from some description language can be taught to generate C data structures and accessor methods.
Usually this is done if you're trying to write code that will iterate over and fill in data structures without needing to know all the details of the structures being processed - this can be useful in building messaging frameworks. But always feels cumbersome because some of your source code files are generated at build time (think lex and yacc).
Of course the other application for something like this is gdb. In that case the compiler, given '-g', generates the metadata about the data structures and embeds that in it the stabs (or gstabs, or some other) information in the object file. Your program could use /proc/self/ to find its object code on disk, open it and process through all of the stabs info. While clever, that would be very platform specific and probably pretty brittle.
look through any struct and check if the item values are within certain range for given types: (E.G. item 1 should be within 10~35, item 3 should be either 0/1). Note that the struct's item types and names are not passed to the function, just the struct(any struct)
This is not possible in C. If you only have a pointer to an unknown struct, there is no way to find out which fields the struct has.
As mentioned, one needs more information about what is in the struct. C, as opposed to C++, etc, wasn't designed around this abstraction. However, it's not impossible; nothing is stopping one from defining one's own virtual table.
#include <stdlib.h> /* EXIT rand */
#include <string.h> /* strcpy */
#include <stdio.h> /* sprintf, printf */
#include <assert.h> /* assert */
#include <stdint.h> /* (C99) uint8_t uint16_t */
#include <stdbool.h> /* (C99) bool */
union AllTypes {
bool boolean;
char letter;
uint8_t byte;
uint16_t word;
};
/* `is_valid` functions. */
static bool is_valid_boolean(const union AllTypes all) {
/* Not sure this will ever be false. */
return all.boolean == true || all.boolean == false;
}
static bool is_valid_letter(const union AllTypes all) {
return (all.letter >= 'a' && all.letter <= 'z')
|| (all.letter >= 'A' && all.letter <= 'Z');
}
static bool is_valid_byte(const union AllTypes all) {
return all.byte <= 35 && all.byte >= 10;
}
static bool is_valid_word(const union AllTypes all) {
return all.word < 1000;
}
/* `to_string` functions */
static void boolean_to_string(const union AllTypes all, char (*const a)[12]) {
strcpy(*a, all.boolean ? "true" : "false");
}
static void letter_to_string(const union AllTypes all, char (*const a)[12]) {
sprintf(*a, "'%c'", all.letter);
}
static void byte_to_string(const union AllTypes all, char (*const a)[12]) {
sprintf(*a, "b%u", all.byte);
}
static void word_to_string(const union AllTypes all, char (*const a)[12]) {
sprintf(*a, "w%u", all.word);
}
typedef void (*ToString)(const union AllTypes all, char (*const a)[12]);
/* The virtual-table. */
static const struct VTable {
ToString to_string;
bool (*is_valid)(const union AllTypes);
} vt_boolean = { &boolean_to_string, &is_valid_boolean },
vt_letter = { &letter_to_string, &is_valid_letter },
vt_byte = { &byte_to_string, &is_valid_byte },
vt_word = { &word_to_string, &is_valid_word };
/* The data has an extra `vt`; this would be implicit in C++. */
struct Data {
const struct VTable *vt;
union AllTypes all;
};
static void to_string(const struct Data *const data, char (*const a)[12]) {
data->vt->to_string(data->all, a);
}
static bool is_valid(const struct Data *const data) {
return data->vt->is_valid(data->all);
}
/* Testing. */
static void fill(struct Data *const data) {
assert(data);
switch(rand() / (RAND_MAX / 4 + 1)) {
case 0: data->vt = &vt_boolean;
data->all.boolean = rand() / (RAND_MAX / 2); break;
case 1: data->vt = &vt_letter;
data->all.letter = rand() / (RAND_MAX / 26 + 1) + 'a'; break;
case 2: data->vt = &vt_byte;
data->all.byte = rand() / (RAND_MAX / 25 + 1) + 10; break;
case 3: data->vt = &vt_word;
data->all.word = rand() / (RAND_MAX / 999 + 1); break;
}
}
int main(void) {
struct Data data[32], *d, *const d_end = data + sizeof data / sizeof *data;
char a[12];
/* Fill the data with random values. */
for(d = data; d < d_end; d++) {
fill(d);
if(!is_valid(d)) return fprintf(stderr, "Impossible!\n"), assert(0),
EXIT_FAILURE;
}
/* Print. */
fputs("{ ", stdout);
for(d = data; d < d_end; d++) {
if(d != data) fputs(", ", stdout);
to_string(d, &a);
fputs(a, stdout);
}
fputs(" }.\n", stdout);
return EXIT_SUCCESS;
}
Prints out on my machine,
{ false, w458, b15, true, b33, 'n', w34, true, b10, 'b', 'r', b33,
w526, true, 's', w761, 'b', b18, b28, w364, true, b28, b11, b32, 'l',
w477, false, 'e', 'x', w60, w504, b17 }.
BOOL MACIsTxReady(void)
{
return !ReadETHReg(ECON1).ECON1bits.TXRTS;
}
is this ReadETHReg(ECON1) a function and then what the thing that follows it is?
Excuse my bad English.
read it as this
xx = ReadETHReg(ECON1);
yy = xx.ECON1bits;
zz = !yy.TXRTS;
you need to explore the definition of ReadETHReg to find out what it returns (probably a struct)
or it might be a macro
Due to operator precedence,
return !ReadETHReg(ECON1).ECON1bits.TXRTS;
is equivalent to:
return !(ReadETHReg(ECON1).ECON1bits.TXRTS);
It would seem that ReadETHReg(ECON1) returns a struct that has a member ECON1bits, which in turn is a struct that has a member TXRTS.
This ReadETHReg(ECON1) is a function that returns a struct. This .ECON1bits.TXRTS is accessing a value inside another struct inside the first struct returned.
Like in this code:
#include <stdbool.h>
typedef bool BOOL;
int ECON1 = 42;
struct S {
struct {
bool TXRTS;
} ECON1bits;
};
struct S ReadETHReg(int val)
{
struct S ret;
ret.ECON1bits.TXRTS = val > 40 && val < 50;
return ret;
}
BOOL MACIsTxReady(void)
{
return !ReadETHReg(ECON1).ECON1bits.TXRTS;
}
I have this array:
static const Layout layouts[] = {
{ "[]=", tile },
{ "><>", NULL },
{ "[M]", monocle },
};
This function should cycle through the array:
int
cyclelayout(const Arg *arg) {
static unsigned short int layout = 0;
if (++layout >= sizeof(layouts)/sizeof(layouts[0])) {
layout = 0;
}
setlayout( &((Arg) {.v = &layouts[layout]}));
}
When it is called it should set next layout or return to 0 if it goes beyond array elements. but it goes over the array elements and the program crashes. I cant figure out whats wrong?
Arg and Layout:
typedef union {
int i;
unsigned int ui;
float f;
const void *v;
} Arg;
typedef struct {
const char *symbol;
void (*arrange)(Monitor *);
} Layout;
Complete program:
dwm-6.0
dwm-6.0-cyclelayout.patch
int // This says to return an int.
cyclelayout(const Arg *arg) {
static unsigned short int layout = 0;
if (++layout >= sizeof(layouts)/sizeof(layouts[0])) {
layout = 0;
}
setlayout( &((Arg) {.v = &layouts[layout]})); // This doesn't look like valid C to me?
return 4; // http://xkcd.com/221/
}
If your function should "cycle through an array", shouldn't it have a loop somewhere?
Loops come in the flavors:
for
do-while
while
I don't see any of those keywords in your function, so I conclude it doesn't "cycle" through anything.
My 2 cents:
you have an hidden if/else construct there, setLayout is part of the else clause, it's not a real error but you have something that is implicit and not readable to anyone, not explicit
you are using a pre-increment operator ++variable which returns a reference and not a copy of the object like the post-increment operator variable++ does, it's probably not the "quantity" that you want to use in a comparison
you are not returning any value considering that you have declared to return an int in the signature for your function
It will also help to know what is Arg and Layout as a type.