How can I use struct A to modify the data inside a struct B. Which has no name, just a type.
struct A {
struct B;
};
struct B {
int data;
};
Since this is for school, I can't change the code above. I can only use it. I tried something like this for my main but it doesn't work
int main (){
struct A myStruct;
myStruct.B.data = 3;
return 0;
}
Thanks in advance.
Edit: Sorry I was just trying to post this as fast as possible that's why I didn't post this with proper c syntax. Anyway, it's my fault for not being clear enough on my question.
I'm aware that my main doesn't work I just want to know if it's ever possible to access the data inside struct B without declaring a name for it inside struct A as I have above. This is the code I was given by a teacher, so I didn't want to modify the structs because I thought maybe she wants us to brainstorm a way to use it the way she wrote it.
The way iharob explains it works perfectly by declaring struct B before struct A, and actually giving a name to struct B.
Is it simply not possible to access that data inside struct B without giving it a name?
The code you posted is not even c code, it would not compile.
Your main mistake is that you don't need to use the struct name to access the member. This should be good
struct B
{
int data;
};
struct A
{
struct B member;
};
int main(void)
{
struct A instance;
instance.member.data = 3;
return 0;
}
I assume that you posted some sample code, don't do that. Post the actual code that has issues. The code you posted is completely invalid because some one of the definitions lack the type, you can't declare structs without using struct in c except if you typedef it. So please post the actual code the next time.
And don't build such complicated structs with struct members unless you really know what you are doing.
Related
To make my code as clear as possible, I am trying to do something like :
struct Test {
int a;
int b;
struct Test2 c;
};
struct Test2{
int d;
};
Of course this code is wrong because struct Test2 is used before being defined. I want to declare the struct forward. So I typed struct Test2; before struct Test but it didn't work. Is there a solution?
I know it is possible with functions, so maybe it should be the case for structures?
The reason that this is not possible is that when you place a concrete struct Test2 object inside struct Test, you need to know the size of Test2 to determine the size of Test. But you can't know the size without knowing the full definition first.
Forward declarations allow you to use a pointer to a type, since you can point to something without knowing the details until later. While it may not completely satisfy your needs, you could do something like the following with a forward declaration:
struct Test {
int a;
int b;
struct Test2 *c;
};
The reason that a function declaration works is that it tells you everything you need to know about how to interface with the function. You don't need the function itself for that.
It only works if struct Test holds a pointer of type struct Test2*.
If it holds an instance, struct Test2 must be defined before struct Test because the size of struct Test2 must be known.
I'm a beginner in C and I came across some codes in a header file that I'm not sure what style it uses and what it means.
typedef struct tActiveObject *testActiveObjectPtr;
typedef struct tActiveObject {
ActiveObject ao;
int state;
} testActiveObject, *testActiveObjectPtr;
Why do we need to create a pointer as an alias i.e. testActiveObject and *testActiveObjectPtr? And is this just some C style that I am not aware of?
Thanks.
If the both those typedefs occur in the same header file, then the code doesn't make any sense. In that case, the first typedef is completely superfluous and the whole code could get replaced with
typedef struct {
ActiveObject ao;
int state;
} testActiveObject, *testActiveObjectPtr;
Otherwise if the typedefs were in different files, the code might have been a failed attempt to create a pointer to an incomplete type, but it doesn't look like that's the case. The struct tag is superfluous, but also smells like a failed attempt to create a self-referencing struct.
Also, good programming practice dictates that you never hide a pointer behind a typedef.
So it would seem the whole code was created by a rather confused person who didn't quite know what they were doing. If possible, throw the code away and replace it with:
typedef struct {
ActiveObject ao;
int state;
} testActiveObject,
...
testActiveObject* ptr; // whenever you need a pointer to this type
I stumbled upon a very strange feature of C: you can declare a named structure inside another structure provided that declare a member variable of that type at the same time:
struct Robot_st {
int pos_x;
int pos_y;
struct BatteryStatus_st { /* <- named struct */
int capacity;
int load;
} battery;
};
The inner structure becomes then available outside the structure as any other type, rendering strange code like this perfectly valid:
struct Robot_st my_robot = {2, 3, {200, 50}};
struct BatteryStatus_st battery_snapshot; /* <- use of inner struct */
memcpy(
&battery_snapshot,
&my_robot.battery,
sizeof(struct BatteryStatus_st)
);
printf("robot position: %d,%d\n", my_robot.pos_x, my_robot.pos_y);
printf("battery load: %d%%\n", battery_snapshot.load);
Nesting unnamed structures feels right, because as you cannot access the type later, there is no confusion about the scope of the type. The above code is also not valid in C++, although the nested declaration is, because C++ understands it as a type in the namespace of the outer structure, so you need to access it using
struct Robot_st::BatteryStatus_st battery_snapshot;
which, despite feeling strange to declare both a type and a member at the same time, makes more sense.
So why is this construct valid in C? Is there any history/reason behind? Is there a use case for such a construct? (Mine was a mistake that led to failures, thus the question.)
Link to full working code.
Such constructs were allowed in C originally because structure names occupied a universe all their own which never had any sort of scoping rules applied to it [struct member names did too, by the way, which is why some of the structure types in older standard libraries have prefixes on their members]. Because some code exists which uses structure names in a fashion inconsistent with scoping, the standard could not be changed to prohibit such usage without breaking existing code. While there are times when it's worthwhile to break existing code (e.g. to rid C of the abomination called gets) this really isn't one of them.
In addition to the other two answers, here is a real usecase that calls for such a named inner struct:
struct LinkedList {
//data members stored once per list
struct LinkedListNode {
//data members for each entry of the list
struct LinkedListNode *next;
} *head, *tail;
};
Its hard to write a more concise definition for the structure of a linked list.
An unnamed inner struct won't do: The code that inserts something into the linked list will likely have to declare local variables with node pointers. And there is no point in declaring the node structure outside of the linked list structure.
Well, this is legal in C:
struct BatteryStatus_st {
int capacity;
int load;
};
struct Robot_st {
int pos_x;
int pos_y;
struct BatteryStatus_st battery;
};
and, as you pointed out, it is effectively identical to the code you posted (since C doesn't have the namespace/scoping rules introduced in C++).
If moving the "inner" type inside doesn't change anything, but may sometimes clarify intent, it would seem odd to prohibit it.
Let's say I have this structure:
struct OuterStruct
{
int a;
struct InnerStruct
{
int i;
int j;
} b;
} s;
Now I can access s.a, and I can even save it in a variable, to better handle it, pass it to functions, ...
int sa = s.a;
Well, now I want to do the same with s.b, and to do so I need InnerStruct to have a name!
???? sb = s.b; // here I have to use InnerStruct, otherwise sb would have no valid type!
The alternative would be to declare InnerStruct outside of OuterStruct, and then putting an instance of it inside as member of OuterStruct. But this would hide the fact that InnerStruct belongs to OuterStruct, making your intent less clear.
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.
This question already has answers here:
Understanding typedef with struct [duplicate]
(6 answers)
Closed 5 years ago.
I have few questions connected with struct and typedef, there is piece of code and I have marked some places where I'm not sure if the syntax is correct. I use Eclipse editor and it shows me when there is problem in compilation. I just don't understand why is sometimes keyword struct needed and sometimes not. I may have also some mistakes of using this keyword. So plese help me to understand it.
let's have struct
typedef struct player
{
char *name;
int gameId;
int points;
int socketfd; //socket descriptor of player
int state;
} player_struct;
lets have another struct
#define PLAYERSLEN 2
typedef struct game{
struct player_struct *players[PLAYERSLEN]; //PLACE1
//some code
} game_struct;
let's have function
player_struct *create_player() //PLACE2
{
player_struct *player; //PLACE3
//alokace pameti
player = (player_struct *) malloc(sizeof(player_struct)); //PLACE4
//PLACE5
player->gameId = -1;
player->points = 0;
player->state = 0;
return player;
}
let's have function? In fact what does this definition mean?
void *( player_struct *player) //PLACE6
{
//some code
}
Questions references:
PLACE1 - is this correct? why can't I use just player_struct *players[PLAYERSLEN]; ??
PLACE2 - it looks like there is not needed struct before player_struct , is it correct? why?
PLACE3 - it looks like there is struct also not needed, is it correct? why?
PLACE4 - it looks like there is struct also not needed, is it correct? why?
PLACE4 & PLACE5 I may should handle errors there, cause there is malloc so I should probably put all the line with PLACE4 to if and if the malloc fails I should put at PLACE 5 free(player). Am I right?
PLACE6 what could have mean this function or whatever it is? The code inside brackets which is not included here should delete the player .. I just don't understand the syntax of wrote function - what does it mean?
PLACE6 - again similar as previous why is not necessary put the keyword struct before player_struct at this line? is it correct?
Really thanks you for your time.
You're doing two things in the initial definition:
You're defining the structure with the type name struct player.
You're creating a typedef called player_struct, which is just an alias for struct player.
As such, either struct player or player_struct is correct (and more-or-less equivalent), but struct player_struct refers to a completely separate type, and is probably incorrect unless you're trying to confuse people.
Now, handling your six cases in order:
PLACE1: As noted above, this code is actually wrong as it stands.
PLACE2, PLACE3, PLACE4: All correct; see above for an explanation.
PLACE5: Yes, you should probably check that player != NULL here just to be sure.
PLACE6: Again, this is correct, and the reason why is above. I'm not sure what void *(...) is supposed to be, though -- if * is actually a function name then it's probably fine though.
It's because the labels are in two separate namespaces (yes, even in C). There's a special namespace for structs.
I like to declare the label in both namespaces, using this:
typedef struct mon_struct {
int a;
} mon_struct;
then you can use either/both struct mon_struct mon = ... or just mon_struct mon = ....
Update
If you want to use just one label, then you can use one of the following:
struct mon_struct { int a; };
// requires namespace resolution using struct tag:
void f(struct mon_struct p);
// -= OR =-
// slightly awkward declaration
typedef struct { int a; } mon_struct;
// but the type exists in the global namespace,
// so we don't need to use the struct tag:
void f(mon_struct p);
but this becomes messy if you are using the struct in both C and C++, particularly when the declaration or implementations move between C and C++ translations without proper guarding (extern "C" { ...stuff... }).
so you might opt to declare it in both namespaces to minimise breakage:
typedef struct mon_struct { int a; } mon_struct;
void f(struct mon_struct p); // << ok
void f2(mon_struct p); // << ok
No. player_struct is a typedef for struct player. You don't need the struct keyword in this case.
Correct. You created a type definition called player_struct which means struct player.
Same reason as 2.
Same reason as 2 & 3.
Yes, you should check to see if malloc() returns NULL. In addition, don't cast the return value from malloc(). Doing so can hide #include errors.
That's not a valid function definition. You don't need struct because of the typedef - same as above.
You may find this all makes more sense if you remove the words typedef, player_struct, and game_struct from your code entirely. Then once you get used to how that all works, you can reintroduce the typedefs and maybe cut down on some typing. As a quick example, you can break down your first definition into its components:
struct player
{
char *name;
int gameId;
int points;
int socketfd; //socket descriptor of player
int state;
};
typedef struct player player_struct;
Maybe that will help you make sense of it?
You don't need struct in PLACE1... as long the definition of player_struct is known, ie, declared before it, or from a .h before it.