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.
Related
There are some questions similar to this (namely, Define a struct with a member pointing to anothermember), but, given I'm complete noob at C, I cannot satisfy my doubt reading them, so I'm opening my own in the expectation of having some difference on it (if not, please point me to a proper question and close this as dupe).
What I'm trying to achive is self explanatory:
typedef struct {
int goals_as_visitor;
int goals_as_home;
int total_goals = goals_as_visitor + goals_as_home;
} team
I just want to store the total_goals struct member as permanently being the sum of the other two members. The above code doesn't compile. I don't know if I just haven't found how to do it just yet, or if this is not possible.
Any guidance?
No this is not possible. A C definition is roughly a definition of a storage space, no more. If you want to ensure that the field is always the sum of the first ones, then you need a discipline: each time you modify one of them, you'll have to modify the third. In this regard, OOP languages are better at this, C is too basic. Anyway you can try to use OOP style in C, something like:
typedef struct Team {
int goals_as_visitor;
int goals_as_home;
int total_goals;
} team;
void setGoalAsVisitor(struct Team *this,int value) {
this->goals_as_visitor = value;
this->total_goals = this->goals_as_visitor + this->goals_as_home;
}
...
setGoalAsVisitor(&team,666); // Roughly calling a method on team: aka team.setGoalAsVisitor(666) in Java style
...
and discipline yourself not to use the fields directly.
Note: you can hide many thing to enforce more the discipline, but alas C can let you make nasty things and violate the rules...
Here you are just defining a structures by telling the compiler what members it contains.
To use this structure first you have to declare the structure and then and then only will a memory be allocated for that structure.
Structure members cannot be initialised with declaration.
Definition would be like this:
typedef struct {
int goals_as_visitor;
int goals_as_home;
int total_goals;
} team
and declaration will be like:
team red;
team blue;
Now the structure has some memory allocated, and structure members can be accessed using dot [.] operator.
e.g. red.goals_as_visitor = 10;
Here is a sample code may be this can help you out
#include <stdio.h>
typedef struct {
int goals_as_visitor;
int goals_as_home;
int total_goals;
}team;
int main (void)
{
team red ;
red.goals_as_visitor=10;
red.goals_as_home = 5;
red.total_goals = red.goals_as_visitor + red.goals_as_home;
printf("%d %d %d\n", red.goals_as_visitor, red.goals_as_home, red.total_goals);
return 0;
}
You can refer below link for basics of structures [https://www.geeksforgeeks.org/structures-c/]
It is not possible in c.But the total_goals will always sum of goals_as_visitor and goals_as_home.So the better way is to use total_goals as a function pointer like this
#include<stdio.h>
/*structure and elements*/
struct team;
int tot_g(struct team *sthis);
typedef int (*tot_gol)(struct team *sthis);
struct team
{
int goals_as_visitor;
int goals_as_home;
const tot_gol total_goals;
}
const init={.goals_as_visitor=0,.goals_as_home=0,.total_goals=tot_g};
int tot_g(struct team *sthis)
{
return (sthis->goals_as_visitor+sthis->goals_as_home);
}
typedef struct team team;
/*structure and elements*/
int main()
{
team p=init;
p.goals_as_home=5;
p.goals_as_visitor=5;
printf("%d",p.total_goals(&p));
}
You must always initialize when a team object is defined with init.
Or
The simple way to do this is using a function like
#include<stdio.h>
typedef struct {
int goals_as_visitor;
int goals_as_home;
} team;
int total_goals(team var)
{
return (var.goals_as_home+var.goals_as_visitor);
}
int main()
{
team p;
p.goals_as_home=5;
p.goals_as_visitor=5;
printf("%d",total_goals(p));
}
You can use total_goals function parameter as const pointer also.
I have the following c code:
struct {
short s;
int n;
} variableName;
I want to write a function to capture this variable like so
void func(MyStruct* var){
//do stuff
}
func(&variableName);
I would like to do this without providing a definition for the struct. Is there a way to capture variableName?
No, you can't pass an "anonymous" struct into a function in C. You could of course define your function to accept the arguments individually:
void func(short s, int n) { ... }
Or you can define the MyStruct structure in a place that both the function and the calling code has visibility to. Note that the whole struct is passed by value (copy) when you do that, which may be the behavior you want here (or may not be).
You may be looking for something more like a "dictionary" or "associative array" or "hash" type that many other languages provide, with arbitrary key value pairs in it. Pure C does not have a facility for this; the compiler wants to know the layout of a structure in advance.
(I'm not sure if you might be asking about a slightly more esoteric idea, which is hiding the composition of a structure and passing around an "opaque handle" out of and into an API. There are ways to structure that in C, but please say so if that's what you're talking about.)
Completely overlooked "I would like to do this without providing a definition for the struct. Is there a way to capture variableName?" in the OP, unless it was edited after. The question makes less sense now, but heres how you could normally pass a struct to a function for future readers.
#include <stdio.h>
struct StructName{
short s;
int n;
};
void func(struct StructName struct_var){
printf("Param values are: %4X %4X\n", struct_var.s & 0xFFFF, struct_var.n & 0xFFFF);
}
int main(){
struct StructName struct_var;
struct_var.s = 0xDEAD;
struct_var.n = 0xBEEF;
func(struct_var);
}
//It looks like you are trying to use the definition as a variable. Here the definition is StructName and the variable is struct_var.
this sample code outputs:
Param values are: DEAD BEEF
If you use clang or gcc, you may be able to use typeof:
struct foo {
struct {
int i;
} anon;
} foo;
void do_something(typeof(foo.anon)* member) {
member->i = 1;
}
If there is no global instance of your type, you may be able to use typeof((struct foo){}.anon).
This comes with a lot of downsides. The most obvious ones are that:
it's not standard, and it ties you to clang/gcc
it's pretty darn ugly
it might not behave as you expect anyway
For instance, structurally-equivalent anonymous types do not have the same type, so in something like this:
struct foo {
struct {
int i;
} anon1;
struct {
int i;
} anon2;
} foo;
anon1 and anon2 both have a different type, meaning that typeof one of them cannot be used to refer to both.
In the long run, you will almost certainly find that it's worth naming the structures, especially if you use them as function arguments. For instance, if you want to make your variable available from a header, I think that you'll have to work pretty hard to keep it anonymous.
Although it's not particularly pretty and not compatible with C++, C puts the name of nested declarations in the global namespace, so this is portable and it's not a very big code change to front-load:
struct {
struct not_anon {
int i;
} anon;
} foo;
void do_something(struct not_anon* member) {
member->i = 1;
}
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.
I'm a bit new to structs and just wondering if these two structs are equivalent. I dont know if this is relevant, but im using these structs to build a stack.
Is this:
struct dataT
{
int m;
};
struct stack
{
int top;
struct dataT items[100];
} st;
equivalent to this?
struct stack
{
int top;
int items[100];
} st;
Arent these basically the same? The second method only uses one struct.
If im wrong, could you please tell me why it is not.
It will make a difference if you ever decide to change the dataT structure. If you know that it will always be only a wrapper for int, then it is a pretty useless structure. But if it may change, then the top one will probably be easier to maintain.
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.