I have a tree structure. The nodes would have a leaf node type and internal node type, so I defined these structures, so the internal node would be able to point to either internal nodes or leaf nodes. However, I am having trouble in accessing the child pointers, how can I do that, after all does my code make sense at all?
typedef struct leaf_node_t {
int type;
int key;
int *data_ptr[2]; //This will point to real data.
} leaf_node_t;
typedef struct internal_node_t {
int type;
int key;
typedef union{
struct internal_node_t* iptrs[2];
leaf_node_t* lptrs[2];
} node_ptr;
} internal_node_t;
The typedef of node_ptr does not actually add a field to its enclosing struct. The following adds the fields first, and then follows up with the typedef. The other change I made was having the union represent a single pointer, leaving it to the struct that uses it to decide how many pointers it wants.
typedef struct internal_node_t{
int type;
int key;
union node_ptr_t {
struct internal_node_t* iptr;
leaf_node_t* lptr;
} node_ptr[2];
}internal_node_t;
typedef union node_ptr_t node_ptr_t;
Try this:
typedef struct leaf_node_t{
int key;
int *data_ptr[2];//this will point to real data
} leaf_node_t;
struct internal_node_t;
typedef union{
struct internal_node_t* iptrs[2];
leaf_node_t* lptrs[2];
} node_ptr;
typedef struct internal_node_t{
int key;
node_ptr node;
} internal_node_t;
int main()
{
internal_node_t inode;
leaf_node_t* leaf_node = inode.node.lptrs[0];
return 0;
}
Alternately, if you don't actually need to use the union typedef anywhere else:
typedef struct leaf_node_t{
int key;
int *data_ptr[2];//this will point to real data
}leaf_node_t;
typedef struct internal_node_t{
int key;
union{
struct internal_node_t* iptrs[2];
leaf_node_t* lptrs[2];
}node_ptr;
}internal_node_t;
int main()
{
internal_node_t inode;
leaf_node_t* leaf_node = inode.node_ptr.lptrs[0];
return 0;
}
You should add a flag in the internal_node to know what is the node_ptr, if it's an internal_node_t or a leaf_node_t. Probably a int isInternal[2]; (after the key and before the typedef). if it's 0 the it's internal, if it's 1 then it's leaf_node_t. C language doesn't have a typeof or a GetType to know what type of memory is pointed by a pointer (and C++ has it only if you are compiling with the RTTI "option" activated)
Related
I'm working on this project for college and they gave me a sample code to use while declaring a structure, the other one is how I declared it with the information on PowerPoints and other study material.
This is the code they gave me:
typedef struct sala local, *plocal;
struct sala {
int id;
int capacidade;
int liga[3];
};
This is the code for another structure i did:
typedef struct pessoa {
char id[15];
int idade;
char estado;
int dias;
} pessoa;
Can anyone explain the difference to me ?
In my code editor "local" and "*local" appear in blue. (I use Netbeans).
This typedef declaration
typedef struct sala local, *local;
struct sala {
int id;
int capacidade;
int liga[3];
};
is invalid because the name local is declared twice with different meanings: the first one as an alias for the type struct sala and the second one as an alias for the type struct sala *.
This is the difference between the first and the second typedef declarations.:)
As for the placement of typedef declaration then it may be placed either before a corresponding structure definition. together with structure definition or after structure definition.
For example
typedef struct A A;
struct A
{
int x;
};
or
typedef struct A
{
int x;
} A;
or
struct A
{
int x;
};
typedef struct A A;
An essence difference between these declarations is that if you want to refer to the defined structure inside its definition then in the second and third cases you have to use the type name struct A because the typedef name A was not yet declared.
For example
typedef struct Node Node;
struct Node
{
int x;
Node *next;
};
but for example
typedef struct Node
{
int x;
struct Node *next;
} Node;
I've written this code with all correct understandings i have. please check my problems.
#include<stdio.h>
#include<stdlib.h>
// Define a structure for the dequeue elements
This structure is all good, with data, next, previous pointers.
typedef struct RanElmt_ {
void *data;
struct DeqElmt_ *prev;
struct DeqElmt_ *next;
void (*destroy)(void *data);
//Your Code here
} RanElmt;
THis is ok too, acording to what i think is correct.
typedef struct RandQ_{
int size;
struct RanElmt *head;
struct RanElmt *tail;
}RandQ;
RandQ * RandomizedQueue(void (*destroy)(void *data)){
RandQ *relmt = (RandQ*)malloc(sizeof(RandQ));
} // construct an empty randomized queue
int isREmpty(RandQ *rQ){
if ( rQ->size == 0)
return 1;
return 0;
} // is the queue empty?
int rsize(RandQ *rQ){
return rQ->size;
}
// return the number of items on the queue
ACtually this is only one function,(enqueue) I'm going to get the idea and code other functions(dequeue, sample etc..)
int enqueue(RandQ *rQ, const void *data){
RanElmt *relmt = (RanElmt*)malloc(sizeof(RanElmt));
relmt->data = (void*)data;
if (rQ->head == NULL){
relmt = rQ->head;
relmt = rQ->tail;
relmt->prev = NULL;
relmt->next = NULL;
}
else{
rQ->head = relmt;
}
(rQ->head)->prev = relmt;
relmt->prev = rQ->head;
rQ->head = relmt;
} // add the item
main(){
Deque(free);
printf(" okk \n");
}
THis program is giving these errors:
Errors i'm getting
In C struct tags and type names live in different name spaces. That is struct RanElmt and RanElmt are two different types, in addition struct RanElmt is not completely defined.
Your RandQ should be defined something like
typedef struct RandQ_{
int size;
struct RanElmt_ *head; // or RanElmt* head;
struct RanElmt_ *tail; // or RanElmt* tail;
}RandQ;
in addition your RanElmt is probably not what you want, maybe you meant:
typedef struct RanElmt_ {
void *data;
struct RanElmt_ *prev; // pointer to a struct of the same type
struct RanElmt_ *next; // pointer to a struct of the same type
void (*destroy)(void *data);
// You cannot put code here in C (or even a function definition AFAIK).
} RanElmt;
You have confused the struct tag and the typedeffed alias for the queue elements in the definition of the queue:
typedef struct RandQ_{
int size;
struct RanElmt *head;
struct RanElmt *tail;
} RandQ;
Here, the head and tail are of the type struct RanElmt. This struct doesn't exist in your program. You have a struct RanElmt_ (with trailing underscore) that you can also call ´RanElmtwithout thestructkeyword, because you have combined the struct definition with atypedef`.
The compiler still generates the code, because pointers to unknown structs are okay, unless you try to get at their data. Obviously the compiler can't access the struct fields if it doesn't know them.
There's no need for the underscore. The names of structs are in a separate namespace, so you can have both a struct called RandQ and a type (in global namespace) called RanQ. I recommend to use the same name for struct tag and aliassed type.
You can also get rid of the need to use the struct keyword inside the struct defnition if you separate the typedef from the struct definition:
typedef struct RanElmt RanElmt; // use just RanElmt from now on
struct RanElmt {
void *data;
RanElmt *prev;
RanElmt *next;
} RanElmt;
Your code has several other problems, but I think he program is in an early state, so I don't address them here.
The function doesnt work. The rest of the code is okay. It finds the maximum in the lists (its also the last element of the list) and then doesn't quit the iteration, instead of that, the program crashes. I got a hint, that suggests, that I have problems wit the us of "()". Maxhelye means the max_pos
typedef short int shorti;
typedef struct szelveny{
int szsorszam;
int lsorszam;
int het;
shorti talalat;
int tnyeremeny;
}szelveny; //szelveny-->ticket, szsorszam-->ticketnumer, //lsorszam-->lotterynumber,het-->week, tnyeremeny-->prize
typedef struct szelveny_element{
szelveny szelveny;
struct szelveny_element *next;
}szelveny_element,*szelveny_pointer;
typedef struct lottozo{
int lsorszam;
shorti het;
int sszelveny;
int nyeremeny;
} lottozo; //lottozo-->lottery
typedef struct lottozo_element{
lottozo lottozo;
struct lottozo_element *next;
} lottozo_element,*lottozo_pointer;
typedef struct het{
shorti het;
lottozo_pointer lhead;
szelveny_pointer szhead;
} het;
typedef struct het_element{
het het;
struct het_element *next;
}het_element,*het_pointer;
szelveny_pointer szelvenyek=0;
lottozo_pointer lottozok=0;
het_pointer hetek=0;
int maxnyeremenyhelye2(int ahet) //maxprizeposition, ahet-->week got as parameter
{
int max=0,maxhelye=-1;
het_pointer hp;
for(hp=hetek;hp!=0;hp=hp->next)
if(hp->het.het==ahet)
{
lottozo_pointer lp;
for(lp=hp->het.lhead;lp!=0;lp=lp->next)
{
if(lp->lottozo.nyeremeny>=max)
{
max=lp->lottozo.nyeremeny;
maxhelye=lp->lottozo.lsorszam;
}
}
return maxhelye;
}
}
Your function int maxnyeremenyhelye2(int ahet) does not always return a value - didn't your compiler warn you about this? The line
return maxhelye;
should be moved down below the following brace.
I have 2 different stuctures but i need to contain them in the same generic list.
The structures are :
typedef struct Val1{
int num1;
int num2;
int num3;
}Val1;
typedef struct Val2{
char name[50];
char surname[50];
int ID;
}Val2;
And the list is:
typedef stuct list {
void *value;
struct node *next;
}list;
typedef struct L_head{
node *head;
int num_members;
}L_head;
I need to use the same list implementation but the list needs to handle both of the
strucrure types.I cant figure out how to initialize the list and put some elements in the list .Any advice will be helpfull.
The canonical solution for C would add a common initial field having distinct values to both structures.
typedef struct Val1 {
int discriminator;
int num1;
int num2;
int num3;
} Val1;
typedef struct Val2 {
int discriminator;
char name[50];
char surname[50];
int ID;
} Val2;
If neccessary, you can define a new struct instead.
That has the advantage of preserving the previous layout and alignment guarantees:
struct packed {
int discriminator;
union {struct Val1;struct Val2};
};
Anyway, you could integrate it directly into the node:
typedef stuct node {
struct node *next;
int discriminator; /* You might want to reserve 0 for no content */
union {struct Val1;struct Val2};
} node;
The technical term of the solution is "discriminated union".
You can have a two element array of void pointers - One pointing to struct of type 1 and another to type 2. This should help to get the right structures with the right casting.
If you are able to distinguish between the type of each of the nodes, you could resort to C unions, like in:
typedef struct Val1{
int num1;
int num2;
int num3;
} Val1;
typedef struct Val2{
char name[50];
char surname[50];
int ID;
} Val2;
union {
Val1 val1;
Val2 val2;
} Val;
For adding the list items, you need to cast them to (void*).
In order to determine the type again upon access, you could add another field(enum) to the list, which stores it's type.
I bet this is some training or homework. If C++ is possible:
start using std::list or boost::list implementation.
Looked through many other SO posts related to this, but none were able to help me. So, I have the following structs defined:
typedef struct
{
int created;
double data;
int timeLeft;
int destination;
}dataPacket;
typedef struct
{
dataPacket *array;
int currIndex;
int firstIndex;
int nextTick;
int maxLength;
int length;
int stime;
int total;
}packetBuffer;
typedef struct{
int mac;
struct wire *lconnection;
struct wire *rconnection;
int numRecieved;
struct packetBuffer *buffer;
int i;
int backoff;
}node;
typedef struct{
float length;
float speed;
int busy;
struct dataPacket *currPacket;
struct node *lnode;
struct node *rnode;
}wire;
And then I'm trying to use the following function:
int sendPacket(node *n, int tick)
{
if(n->buffer->length > 0)
{
if(n->backoff <= 0)
{
if (n->lconnection->busy != 0 || n->lconnection->busy != 0)
{
n->i++;
n->backoff = (512/W * genrand()*(pow(2,n->i)-1))/TICK_LENGTH;
}
else
{
n->lconnection->busy = 1;
n->rconnection->busy = 1;
n->lconnection->currPacket = n->buffer[n->buffer->currIndex];
n->rconnection->currPacket = n->buffer[n->buffer->currIndex];
}
}
else
{
n->backoff--;
}
}
}
I'm getting the error described in the title everytime I try to access a member of buffer, lconnection, or rconnection.
struct packetBuffer *buffer;
You've defined a type packetBuffer (a typedef for an otherwise anonymous struct).
You haven't defined struct packetBuffer.
In the absence of an existing type struct packetBuffer, the compiler treats it as an incomplete type, assuming that you'll complete it later. The declaration
struct packetBuffer *buffer;
is perfectly legal, but you can't dereference buffer unless the type struct packetBuffer is visible.
Just drop the struct keyword.
(My personal preference is to drop the typedef and consistently refer to struct types as struct whatever, but that's a matter of style and taste.)
The following:
typedef struct {
int x;
char *y;
...
} my_struct;
creates an identifier for an anonymous structure. In order, for a structure to refer to an instance of itself, it must not be "anonymous":
typedef struct my_struct {
int x;
char *y;
struct my_struct *link
....
} my_struct_t;
This means that my_struct_t is now the type struct my_struct and not just an anonymous struct. Also, note that struct my_struct can be used within its own structure definition. That is not possible with anonymous structs.
As a final complication, the my_struct in struct my_struct is in a differenct "namespace" than the my_struct_t. This is sometimes used to to simplify (or confuse) things in code like this:
typedef struct my_struct {
int x;
char *y;
struct my_struct *link
....
} my_struct;
Now I can use my_struct anywhere in my code instead of struct my_struct.
Finally, you could separate the typedef from the structure definition to achieve the same effect:
struct my_struct {
int x;
char *y;
struct my_struct *link;
....
};
typedef struct my_struct my_struct;
As noted in David R.Hanson's C Interfaces and Implementations, "This definition is legal because structure, union, and enumeration tags occupy a same name space that is separate from the space for variables, functions, and type names."