I have three objects, which (at the moment) I am representing as structs:
a Dataset
a DatasetWindow
a MovingWindow
and a variable windowSize
There may be multiple Dataset's and each should have it's own DatasetWindow.
Ok, fair enough, to me that sounds like I make a DatasetWindow struct and put it as a member of a Dataset struct
There would be just one MovingWindow, but it should know about all the Dataset's.
Ok, so far it seems pretty simple. I create another struct for MovingWindow and it has a pointer to Dataset. (an array of datasets).
So so far, I have something like this:
typedef struct {
int *buffer;
int someOtherMember;
} DatasetWindow;
typedef struct {
int someMember;
DatasetWindow *window; //Pointer to a DatasetWindow obj.
} Dataset;
typedef struct {
int offset;
int someMember;
Dataset *datasets; //Array of Dataset
} MovingWindow;
The part I am having trouble with is this:
MovingWindow should know windowSize, as should each DatasetWindow.
But Dataset should preferably not need to know what windowSize is.
I don't know how to arrange my structures to support this?
You can modify the definitions of structs MovingWindow and DatasetWindow to incorporate a member (pointer or a interger variable) holding the value of your windowSize.
Related
After juggling and trying to learn how to get this done I thought it's time to ask the experts.
I have more than one structures and would like to "manipulate" the data in them using only one node.
What is the best way to do this?
code example:
typedef struct printQuality{ int dpi; } quality ;
typedef struct paperSize{ char* dim; } sizes ; //this would be A3 , A4 this is why i picked char
typedef struct printColour{ char* color; } colors;
typedef struct printStyle{ char* side; } sides;
typedef struct printOrientation { char* orientation; } orientations;
typedef union printOptions{
quality dpi;
sizes size;
colors color;
sides side;
orientations orientation;
} options;
struct optNode{
options* inf;
optNode* next;
optNode* prev;
};
From your comments, I believe your issue has to do with the behavior of Unions in C vs structs. In C/C++, Unions are structures which can only instantiate one of their values at a given time. With your printOptions union, you have 5 variables. At any given time, only one of those variables (the last one you set) is guaranteed to hold a value. Here is a good article on how Unions work: https://www.programiz.com/c-programming/c-unions. Structs in C/C++ do not have this behavior. Whichever values you set remain set until the instance of the struct goes out of scope or is deleted. I think that if you make printOptions a struct, you will be able to access all of your other structs from your options pointer in your optNodes.
I've done some searching around, but nothing I've found has answered my question specifically regarding structs:
In my program I have two structures: one contains data, the other contains an array of the first structure (used to make returning struct arrays easier).
I do not know the size of the aforementioned structure array until running a few lines of code. From what I've found there isn't a way to define the size of an array (or any type) after it has already been declared, although I would like to know if this holds true for structs.
If not, is there way to define the size of a previously declared array within a struct without using malloc? Using malloc with struct arrays seems a bit complicated and I haven't been able to wrap my head around it.
typedef struct
{
char **data;
} struct1;
typedef struct
{
struct1 data[];
} struct2;
int main(int argc, char **argv)
{
//Pretend there is code here that finds the size I need
size = 5;
struct2 Info;
Info.data = new struct1[size]; //Clearly this won't work, but does C offer anything comparable?
return 0;
}
I have an abstract data type in C, LIST OF THINGS, ist node has a void* pointer, what i'm trying to do is create a function to compare an specific field of different structures in order to sort my list of things.
typedef struct node{
char *name;
void *thing;
struct node *next;
}Node;
This is the node i'm working with, i've already created a list of integers, list of structures and te compare function for both, but i can't figure out how to do a compare function to diferent structures. for example:
given these types:
typedef struct main{
float weight;
char*model;
float maxspeed;
}Main;
typedef struct airplane{
float weight;
float maxspeed;
}Airplane;
typedef struct car{
char*model;
float maxspeed;
}Car;
And this is the function, so you have an idea of what i'm trying to do, it doesn't work, Main has fields that doesn't exist in either one or the other structure.
int comparefunction(void*a,void*b){
Main a1, a2;
a1=*(Main*)a;
a2=*(Main*)b;
return a1.weight-a2.weight;
}
This function(doesn't work) is passed as a paremeter to the function that links the nodes in order to use the comparefunction.
//insert prototype:
//insert(Node*listp,Node*newp,int(*func_comp)(void*,void*));
list=insert(list,newItem(&car1),comparefunction);
list=insert(list,newItem(&airplane1),comparefunction);
list=insert(list,newItem(&airplane2),comparefunction);
How can i do to compare a single field of two or more different structures? assuming that i know what each structure contains
If you're trying to compare somewhat similar things, you can look into unions.
struct attributes{
float weight;
// other common things?
};
struct thing {
enum { Car, Main, Airplane } type;
struct attributes attrs;
union {
struct Car car;
struct Main main;
struct Airplane airplane;
} other_thing;
};
You'd change your list to store the thing struct, which is a structure that encapsulates all your possible types. The common elements of each type are extracted to the attributes struct. Your compare function would then operate on the attributes struct of the thing struct. The union is used here to only create enough space within struct thing for the largest of the union elements, so that you're not wasting space storing all three structs and only using one.
Well, your car struct doesn't have a weight field, so I'm not exactly sure what you're trying to accomplish here. If you had your car struct look like
typedef struct car {
float weight;
char* model;
float maxspeed;
} Car;
I think your function would work. Note, it is important that the member that you want to compare is at the same offset into each struct including the Main struct.
EDIT
This does work.
Another edit based on comments
You can't compare two completely unrelated things. This is not a technical deficiency with C. It just does not logically make any sense to compare for example an Airplane and an int.
So I am still pretty new to C programming. I have learned Python though, so I am familliar to some of the codes.
For instance when I create a function in python, I am able to make it general and usable for different classes.
I want to do something similar here. I have two structs which look practically the same. I want to use the same function for both structs, but ofcourse I cant send in the struct name as an argument into the function. What do I do instead?
For now dont worry about what the function does. Its the principle of being able to use two structs in the same function that counts for me. If this is a totally wrong perspective, then I am sorry but this was my first thought when coming upon this problem.
typedef struct{
int number;
struct node *next;
}struct_1;
struct node *head;
typedef struct{
int number;
struct node *next;
}struct_2;
void main()
{
int number1 = 10;
int number2 = 20;
function(number1);
function(number2);
}
void function(int x, struct) // Here is where I want to be able to use 2 different structs for the same function
{
struct *curr, *head;
curr=(node1*)malloc(sizeof(node1));
printf("%d", curr->number);
}
You could have two instances of one structure.
The function can accept either instance and process it as needed.
typedef struct{
int number;
struct node *next;
}mystruct;
void function(int x, mystruct *eachstruct);//prototype
int main()
{
int number1 = 10;
int number2 = 20;
//declare two instances of mystruct
mystruct list_1 = { 0, NULL};
mystruct list_2 = { 0, NULL};
// call the function with one or the other instance of mystruct
function(number1, &list_1);
function(number2, &list_2);
}
void function(int x, mystruct *eachstruct)
{
//do stuff in function
eachstruct->number = x;
if ( eachstruct->next == NULL)
{
//do more stuff
}
}
C does not use duck typing as Python does so you cannot pass one structure that looks like other, completely unrelated structure as if it was this other structure.
Unfortunately C cannot do what you want.
Your options are:
Refactor the code to use the same struct type for all items.
Pass the fields of interest in the structs directly to the functions
Write code to marshal the similar structs to a common struct.
Play fast and loose with the type system and arrange shared elements the same way in the two different structs and cast your pointers.
If you just want a linked list check out how code re-use is achieved in the linux kernel
Answer: No, you cannot do it directly. Welcome to static typing.
There is a way to achieve something similar by using our beloved void * and some castings but, believe me, it is not what you want to do. If you really want to do it ask directly for it. You have been warned.
As the question states I am looking to create a struct in C whose total size I do not know at compile time.
For example, I would like to create a struct that contains a count value and an array with count elements. I know this could be implemented as:
typedef struct myStruct{
int count;
int *myArray;
} myStruct;
However, I want this struct to take up one solid block of memory so I could use memcpy() on it at a later point in time. Like this:
typedef struct myStruct{
int count;
int myArray[count];
} myStruct;
It sounds like you're looking for flexible array members:
typedef struct myStruct
{
int count;
int myArray[];
} myStruct;
Then, when you allocate it later:
myStruct *x = malloc(sizeof(myStruct) + n * sizeof(int));
x->count = n;
Yes, you can. If you use C99, there's flexible array members. Otherwise, you can do what Microsoft does. Take your original structure definition and map it to an existing block of memory. Reassign the pointer to point just after the structure definition.
Also, the MS approach would allow multiple members with variable size; you just need to properly update each pointer.
(Note: The "MS approach" is just something encountered often in Windows APIs; I don't know if there's an actual term for the practice.)