I've tried a lot of simple examples of this and haven't gotten any to work.
My goal is to have a function which declares a struct internally, sets the values of the struct, and then returns the struct.
struct getData(void){
typedef struct{
int count1;
int count2;
} MyStruct;
MyStruct myData;
myData.count1 = 5;
myData.count2 = 6;
return myData;
};
int main(void) {
struct myData = getData()
printf("count1: %i", myData.count1);
printf("count2: %i", myData.count2);
}
Every example I've found does something similar to this, but for some reason it's not finding my struct called MyStruct. Exact error is:
error: expected identifier or ‘(’ before ‘void’
struct getData(void){
^~~~
The error I keep getting makes me think it doesn't like the struct inside the function.
Your problem seems to be a confusion regarding the usage of the struct keyword. You don't do struct myData to declare a variable named myData that is of struct type, because there isn't really a struct type. What you do is struct myData <SOMETHING> to define <SOMETHING> as being a new data type named struct myData. You can then say struct myData dat;, thereby declaring that dat is a variable of type struct myData.
You're also demonstrating the same confusion at the top, where you have struct getData(void)... you're attempting to declare getData as a function returning a struct, but you'd really have to do something like struct myData getData(void) to declare a function returning type struct myData.
I think the more standard way to write what you're after is this, using an independent definition of the struct, and then using a pointer for the function call. As written your code seems to have some scope issues (declaring a struct typedef inside a function, hmmm...) [Incorrect->] plus I don't believe structs can be passed around that way in C, I'm pretty sure you have to use pointers. [Edit oops this is incorrect! See comments]
#include<stdio.h>
typedef struct {
int count1;
int count2;
} MyStruct;
void getData (MyStruct* myDataPtr) {
myDataPtr->count1 = 5; //note pointer access notation ->
myDataPtr->count2 = 6;
};
int main(void) {
MyStruct myData;
MyStruct* sPtr = &myData; //create pointer to struct, assign to myDaya
getData(sPtr); //pass pointer to function
printf("count1: %i \n", myData.count1);
printf("count2: %i \n", myData.count2);
}
Outputs:
count1: 5
count2: 6
Related
My problem is that car_name_str could not be resolved. Why is it not callable and I want to keep the code structure?
I want to keep the structure as struct with union and enum (different datatypes).
Template: How can mixed data types (int, float, char, etc) be stored in an array?
//car_union.h
typedef struct {
enum { number_of_seats_int, car_cost_float, car_name_str } type;
union {
int number_of_seats;
float car_cost;
char* car_name;
} value;
}Car_data_ex[30][3];
extern Car_data_ex *Car_data[30][3];
//fill_car.c
#include "car_union.h"
Car_data_ex *Car_data[30][3];
Car_data[0][0]->type = car_name_str; //-> because pointer but doesnt work
Car_data[0][0]->value->car_name= "land rover";
Car_data[0][1]->type = car_cost_float; //doesnt work
Car_data[0][1]->value->car_cost= 45000;
Just remove the [30][3] from the type def, like this
#include <stdio.h>
//car_union.h
typedef struct {
enum { number_of_seats_int, car_cost_float, car_name_str } type;
union {
int number_of_seats;
float car_cost;
char* car_name;
} value;
}Car_data_ex;
extern Car_data_ex *Car_data[30][3];
int main() {
Car_data_ex *Car_data[30][3];
Car_data[0][0]->type = car_name_str; //-> because pointer but doesnt work
Car_data[0][0]->value.car_name= "land rover";
Car_data[0][1]->type = car_cost_float; //doesnt work
Car_data[0][1]->value.car_cost= 45000;
}
Regardless of what's in your struct, when you do
typedef struct Car_dataStructTag{
//...
}Car_data_ex[30][3];
(I've tagged the struct so it can be referred to by struct Car_dataStructTag),
then Car_data_ex is a type alias resolving to struct Car_dataStructTag [30][3]
which means
extern Car_data_ex *Car_data[30][3];
is fully equivalent to
extern struct Car_dataStructTag (*Car_data[30][3])[30][3];
which means Car_data[x][y] is a pointer to a two-dimensional array of struct Car_dataStructTag,
which is definitely not something you can apply -> to.
Try:
typedef struct Car_dataStructTag{
//...
}Car_data_ex[30][3];
extern Car_data_ex *Car_data[30][3];
extern struct Car_dataStructTag (*Car_data[30][3])[30][3];
in a compiler -- it gets accepted, confirming the declaration equivalence.
Running into situations such as this one is why it's generally considered ill-advisable to typedef arrays or pointers.
You have over complexified everything.
A typedef is just to give an alias to a (complex) type. Here the type is a struct containing an enum and an union. So it should be:
typedef struct {
enum { number_of_seats_int, car_cost_float, car_name_str } type;
union {
int number_of_seats;
float car_cost;
char* car_name;
} value;
}Car_data_ex;
Next, using an array of pointers can make sense, but provided each pointer in the array does point to a true object. Here you only want a plain (2D) array:
Car_data_ex Car_data[30][3];
Once this has been done, you can write with no error or warning:
Car_data[0][0].type = car_name_str;
Car_data[0][0].value.car_name= "land rover";
Car_data[0][1].type = car_cost_float;
Car_data[0][1].value.car_cost= 45000;
And you should avoid extern Car_data_ex Car_data[30][3];. It declares a global array, that will have to be defined in one single compilation unit (.c file). Here again, it can make sense, but IMHO it is a rather advanced feature that can be hard to correctly use. And nothing in the shown code lets think that is is required...
I'm trying to create a structure which contains multiple function pointers, however when I try to create an instance of the structure I get a error "variable "stCmdTable" was declared with a never-completed type".
I have a header file in which I have the following code:
typedef int (*pStCmd) (void);
struct stCmdStruc {
pStCmd id;
pStCmd measure;
pStCmd setRelay;
};
typedef struct stCmdStruct stCmdStruct;
stCmdStruct stCmdTable;
I want to create stCmdTable and assign functions to all the function pointers in the stCmdTable, but when it doesn't like my declaration of stCmdTable.
I've also tried doing something like this, where I try to initialise all the function pointers to functions straight of the bat with my structure defintion, but it really doesn't like this telling me expected a ";" at the end of each line in the struct.
typedef int (*pStCmd) (void);
struct stCmdStruc {
pStCmd id = sendId2;
pStCmd measure = sendMeasurement2;
pStCmd setRelay = setRelay2;
};
typedef struct stCmdStruct stCmdStruct;
stCmdStruct stCmdTable;
Can anyone please shed some light on what I'm doing wrong?
Try this . . .
typedef int (*pStCmd_Type) (void);
typedef struct _stCmdStruct {
pStCmd_Type id;
pStCmd_Type measure;
pStCmd_Type setRelay;
} stCmdStruct_Type;
stCmdStruct_Type stCmdTable[your_table_size];
stCmdTable[0].id = sendId2;
stCmdTable[0].measure = sendMeasurement2;
stCmdTable[0].setRelay = setRelay2;
struct one
{
int member;
};
struct two
{
int member;
} structure;
If I want to call the above structures in the main() function then in the first case do I need to name the struct one to any random name of my choice and then and then call its member like this:
int main() {
struct one random_name;
random_name.member = 1;
}
and in the second case I have already named the structure so it's just that I can directly call the member with the name structure like this:
int main() {
structure.member = 1;
}
Is the version below valid or do I have to put typedef in front of the struct?
struct {
int member;
} structure;
Using int as the type of the structure members throughout, then:
struct one
{
int member;
};
This is a perfectly fine definition of the type struct one. It defines no variables of type struct one; it is simply a type that can be used later in the translation unit.
struct two
{
int member;
} structure;
This is a perfectly fine definition of the type struct two and is also the definition of a variable structure of type struct two.
If I want to call the above structures in the main() function then in the first case do I need to name the struct one to any random name of my choice and then and then call its member like this:
int main(void)
{
struct one random_name;
random_name.member = 1;
}
If you want to use a variable of type struct one, you will have to define it, and the way you've done so is fine. You don't 'call' members of structures. You use them.
and in the second case I have already named the structure so it's just that I can directly call the member with the name structure like this:
int main(void)
{
structure.member = 1;
}
This is also valid because you defined the variable structure at the same time as you defined the type struct two.
Is the below version valid or do I have to put typedef in front of the struct:
struct
{
int member;
} structure;
This is also legitimate code. It defines an anonymous structure type and defines a single variable of that type. It is the only variable of that type that can exist, but occasionally it is useful to use this.
Note that if the last structure was followed by:
struct
{
int member;
} form;
the types of the variables form and structure are different; you cannot legitimately assign one to the other, for example, or pass either of them to another function, etc.
More typically, you either give the structure type a tag (struct three) or use a typedef (typedef struct { int member; } four;) or both (typedef struct five { int member; } five;, where it is legitimate to use the same name for the tag and the type name as I showed, though there is also an extensive tradition of using different names for the type and the tag).
So with typedef struct { int member; } structure;, in main() creating one or more variables of type structure is possible, like this?
structure first_var;
structure second_var;
This is entirely legitimate. You could instead write:
structure first_var, second_var;
though many people prefer one variable per declaration.
Whereas if we don't use typedef and just do struct { int member; }structure; then I have just got one variable with name structure and can use that only in main(), such as structure.member = 1; and can't create more.
More or less. You can write:
struct { int member; } var1, var2, … varN;
and now you have multiple variables all of the same type. However, although you can write:
struct { int member; } var1;
struct { int member; } var2;
the two variables var1 and var2 are not officially of the same type. There are complicated bits of wording in the standard in section 6.2.7 Compatible types and composite types which might let you off the hook, but GCC 4.9.1 set fussy says:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -c tagless.c
tagless.c: In function ‘main’:
tagless.c:13:10: error: incompatible types when assigning to type ‘struct <anonymous>’ from type ‘struct <anonymous>’
var1 = var2;
^
$
tagless.c
struct
{
int member;
} var1;
struct
{
int member;
} var2;
int main(void)
{
var1.member = 1;
var2.member = 2;
var1 = var2;
return 0;
}
two more doubts:::::::
Whereas if we don't use typedef and just do struct{int member;}structure;
then i just got one variable with name structure and can use that only in
main structure.member=1; and can't create more –
Ans : You can always create more than just one variable once you have declared the structure, so its not that if you dont use typedef you can have only one variable for your structure. For eg:
struct structure
{
int number;
};
int main()
{
structure var1, var2, var3; //...any number of variables can be declared here.
var1.number = 30;
var2.number = 45;
var3.number = 90;
printf("\nvar1 = %d, var2 = %d, var3 = %d\n", var1.number, var2.number, var3.number);
return 0;
}
For a better understanding of typedef,
Consider this example :
1.
struct structure
{
int number;
};
typedef struct structure structure;
2.
typedef struct structure
{
int number;
}structure;
---------------------
Both of the above declarations are equivalent.
typedef is used to define a new name for a variable or a keyword.
Suppose in case if your structure declaration is something like this :
struct this_is_my_structure
{
int number;
};
then every time you declare an instance of this structure you will have to use this long name in front of your instance, like:
int main()
{
struct this_is_my_structure var1; // you dont want to write such long types for variables
var1.number = 23;
return 0;
};
You will find typedef helpful here :
typedef struct this_is_my_structure structure;
Now every time you want to declare an instance of type "this_is_my_structure" all you have to do is the following :
int main()
{
structure var1;
var1.number = 23;
return 0;
}
What I want to accomplish: I want to use a typedef'd function pointer inside of a typedef'd struct where the function pointer takes a struct pointer as an argument (i.e. something like an 'object method' which takes a self-reference to the 'object').
I have this C code (simplified, hopefully not oversimplified):
typedef struct MYSTRUCT myStruct;
typedef void (*getSomething)(myStruct*);
typedef struct MYSTRUCT {
getSomething get_something;
};
void get_property() {
myStruct *structure = NULL;
}
So what I think I'm doing is: forward declare the struct, use that declaration in the function pointer typedef, then declare the actual struct using the typedef'd function pointer.
This code compiles with the intel compiler on linux (and seems to do the intended thing) but the Visual compiler throws an error:
error C2275: 'myStruct' : illegal use of this type as an expression
see declaration of myStruct
Is there a way to make the VC accept my intended construct?
typedef struct MYSTRUCT {
getSomething get_something;
};
should be
struct MYSTRUCT {
getSomething get_something;
};
struct MYSTRUCT; // Forward declare the struct
typedef struct MYSTRUCT myStruct; // define the typedef;
typedef void (*getSomething)(myStruct*); // use the typedef;
struct MYSTRUCT { // define the struct
getSomething get_something;
};
void get_property() { // use the typedef again.
myStruct *structure = NULL;
}
// Warning: I didn't actually compile that, and I'm going from memory.
Sorry. I just realized this was not a problem of my forward declaration but rather because what I really did in my actual code was this:
void get_property() {
some = assignment_statement;
myStruct *structure = NULL;
}
I.e. I accidentally put my variable declaration + definition below the first code statement. So indeed, I had oversimplified my code fragment. Sorry for this.
I've got a function that takes as an argument a pointer to an array of structs:
void foo (int *StructArrayAddress)
Within the function, I then build a new struct that looks like this
struct
{
int a;
int b;
char c[10];
}myStruct;
What I would then like to do is copy that struct to my array of structs based on the pointer to that array that I received as an argument. Not having any luck with the syntax, or I'm missing something. Can anyone advise?
Thanks!
EDIT: I'm not sure I explained myself correctly, as I don't think the solution posted here is what I want to do. To clarify: there is some array of structs outside my function here. I receive the address of the correct struct element in an array of structs as an argument to my function. Assume the caller already took care of passing me the correct address; I don't have to index it up at all.
I then locally build a struct from some other data. I now want to copy this struct that I built locally to the struct at the location in the array that I received as an argument.
void foo (int *StructArrayAddress)
{
struct
{
int a;
int b;
char c[10];
}myStruct;
a = 5;
b = 10;
c = {1,2,3,4,5,6,7,8,9,10};
//Copy local struct myStruct to location StructArrayAddress here
StructArrayAddress = myStruct; //Something like this but I have the syntax wrong
}
I hope that makes more sense.
EDIT2: I may have just realized something that you guys have been trying to convey to me that I was missing: is a reference to my local struct needed in the argument somehow so that the format of the structure as I pass it back is known?
Your function definition should be like
void foo (myStruct *StructArrayAddress, int index)
{
myStruct x;
x.a = 1;
x.b = 2;
strncpy(x.c, "Test", 9);
/* Now copy this struct to the array of structs at index specified by second argument */
memcpy((StructArrayAddress + index), &x, sizeof(myStruct));
}