I'm trying to create structs with default values. I don't know how to accomplish this because every code that I see, is about initialising, and I would it for the natural way like...
struct stuff {
int stuff_a = 1;
int stuff_b = 2...
...and so on...
};
and looking about, I found this (C++) code:
struct a{ a() : i(0), j(0) {}; INT i; INT j;}
I never saw anything like this for C. Please, help me to understand it; I think that it is very nice!
UPDATE: Wait, I'm asking about C!!!! Why changed my question? If that is not possible in C just say... I don't know C++, I didn't know that was about C++...
If you want to set a struct object in one go and you have a C99 compiler, try this:
struct stuff {
int stuff_a;
int stuff_b;
// and so on...
};
struct stuff foo;
/* ... code ... */
foo = (struct stuff){.stuff_b = 42, .stuff_a = -1000};
Otherwise, with a C89 compiler, you have to set each member one by one:
foo.stuff_b = 42;
foo.stuff_a = -1000;
Running example # ideone : http://ideone.com/1QqCB
The original line
struct a{ a() : i(0), j(0) {} INT i; INT j;}
is a syntax error in C.
As you have probably learned from the other answers, in C you can't declare a structure and initialize it's members at the same time. These are different tasks and must be done separately.
There are a few options for initializing member variables of a struct. I'll show a couple of ways below. Right now, let's assume the following struct is defined in the beginning of the file:
struct stuff {
int stuff_a;
int stuff_b;
};
Then on your main() code, imagine that you want to declare a new variable of this type:
struct stuff custom_var;
This is the moment where you must initialize the structure. Seriously, I mean you really really must! Even if you don't want to assign specific values to them, you must at least initialize them to zero. This is mandatory because the OS doesn't guarantee that it will give you a clean memory space to run your application on. Therefore, always initialize your variables to some value (usually 0), including the other default types, such as char, int, float, double, etc...
One way to initialize our struct to zero is through memset():
memset(&custom_var, 0, sizeof(struct stuff));
Another is accessing each member individually:
custom_var.stuff_a = 0;
custom_var.stuff_b = 0;
A third option, which might confuse beginners is when they see the initialization of struct members being done at the moment of the declaration:
struct stuff custom_var = { 1, 2 };
The code above is equivalent to:
struct stuff custom_var;
custom_var.stuff_a = 1;
custom_var.stuff_b = 2;
... create structs with default values ...
That is impossible in C. A type cannot have default values. Objects of any type cannot have a default value other than 0, though they can be initialized to whatever is wanted.
The definition of a struct is a definition of a type, not of an object.
What you asking is about the same thing as a way to have ints default to, say, 42.
/* WRONG CODE -- THIS DOES NOT WORK */
typedef int int42 = 42;
int42 a;
printf("%d\n", a); /* print 42 */
Or, adapting to your example
/* WRONG CODE -- THIS DOES NOT WORK */
struct stuff {
int42 stuff_a;
int65536 stuff_b;
}
struct stuff a;
printf("%d\n", a.stuff_b); /* print 65536 */
Update: This answer assumes we 're talking about C++ because the code posted in the answer is not legal C.
struct a {
a() : i(0), j(0) {} // constructor with initialization list
int i;
int j;
}
The line marked with the comment is simply the constructor for instances of struct a (reminder: structs are just like classes, except that the default member visibility is public instead of private).
The part after the : is called an initialization list: it allows you to initialize the members of the struct with values (either constants or passed as constructor parameters). Initialization of members in this list happens before the body of the constructor is entered. It is preferable to initialize members of classes and structs this way, if at all possible.
See also C++: Constructor versus initializer list in struct/class.
in C (pre C99) the following also works:
#include <stdio.h>
typedef struct
{
int a;
int b;
int c;
} HELLO;
int main()
{
HELLO a = {1,2,3};
printf("here: %d %d %d\n",a.a,a.b,a.c);
exit(1);
}
See codepad
I'm not sure quite sure what your problem is. The standard way of initialising structures in c is like this:
struct a_struct my_struct = {1, 2};
Or the more recent and safer:
struct a_struct my_struct = {.i1 = 1, .i2 = 2};
If there is more than one instance of a structure, or it needs to be re-initialised, it is useful to define a constant structure with default values then assign that.
typedef struct a_struct {
int i1;
int i2;
} sa;
static const sa default_sa = {.i1 = 1, .i2 = 2};
static sa sa1 = default_sa;
static sa sa2 = default_sa;
// obviously you can do it dynamically as well
void use_temp_sa(void)
{
sa temp_sa = default_sa;
temp_sa.i2 = 3;
do_something_with(&temp_sa);
}
// And re-initialise
void reset_sa(sa *my_sa)
{
*my_sa = default_sa;
}
Type initializer is not possible in C.
A value must be stored in the memory.
A type does not occupy memory, what occupies memory is a variable of that type.
struct stuff; is a type; it does not occupy memory
struct stuff aStuff; is a variable of that type; aStuff occupies memory
Because a type does not occupy memory, it is not possible to save values into a type.
If there is syntactic sugar to support store/initialize values into a type then there must be additional code that is inserted to assign values to every instant variables of that type (e.g: in constructor in C++). This will result in a less efficient C if this feature is available.
How often do you need to retain this default values? I think it is unlikely. You can create a function to initialize variable with the default values or just initialize every fields with the values you want. So type initializer is not fundamental thing. C is about simplicity.
Can't initialize values within a structure definition.
I'd suggest:
typedef struct {
int stuff_a;
int stuff_b;
} stuff ;
int stuffInit(int a, int b, stuff *this){
this->stuff_a = a;
this->stuff_b = b;
return 0; /*or an error code, or sometimes '*this', per taste.*/
}
int main(void){
stuff myStuff;
stuffInit(1, 2, &myStuff);
/* dynamic is more commonly seen */
stuff *dynamicStuff;
dynamicStuff = malloc(sizeof(stuff)); /* 'new' stuff */
stuffInit(0, 0, dynamicStuff);
free(dynamicStuff); /* 'delete' stuff */
return 0;
}
Before the days of Object Oriented Programming (C++), we were taught "Abstract Data Types".
The discipline said 'never access your data structures directly, always create a function for it' But this was only enforced by the programmer, instructor, or senior developer, not the language.
Eventually, the structure definition(s) and corresponding functions end up in their own file & header, linked in later, further encapsulating the design.
But those days are gone and replaced with 'Class' and 'Constructor' OOP terminology.
"It's all the same, only the names have changed" - Bon Jovi.
Related
I was recently reading about ways to create something that resembles c++ objects, but in C, and I came across some pretty good examples. However, there was this single piece of code that had me thinking for hours, since it was the first time I saw this kind of syntax, and I didn't find anything like it on Google...
The block itself is this one:
struct stack {
struct stack_type * my_type;
// Put the stuff that you put after private: here
};
struct stack_type {
void (* construct)(struct stack * this); // This takes uninitialized memory
struct stack * (* operator_new)(); // This allocates a new struct, passes it to construct, and then returns it
void (*push)(struct stack * this, thing * t); // Pushing t onto this stack
thing * (*pop)(struct stack * this); // Pops the top thing off the stack and returns it
int this_is_here_as_an_example_only;
}Stack = {
.construct = stack_construct,
.operator_new = stack_operator_new,
.push = stack_push,
.pop = stack_pop
};
Assuming all the functions being set to the pointers are defined somewhere else, my doubts are the following:
1) Why does the point ( '.' ) mean, or whats its purpose when initializing the function pointers? (example: .construct = stack_construct )
2) why is there an equal sign after 'Stack' at the end of the struct definition, and why is there something other than a ';' ( in this case the word 'Stack' ), given the fact that there is no typedef at the beginning?
I assume it has something to do with initialization (like a constructor, I don't know), but it is the first time I see a struct = {...,...,...} in the definition. I've seen that when you initialize a struct like in the following example:
typedef struct s{
int a;
char b;
}struc;
void main(){
struc my_struct={12,'z'};
}
But this is not in the main declaration of the struct, and still, there are no '=' within the {}, unlike the first example, where it showed something like...
struc my_struct={ a = 12,
b = 'z'};
3) This is a minor doubt, meaning, I'm much more interested in the first two. Anyway, here it goes...
At the beginning of the first code, it says something like '// Put the stuff that you put after private: here'. Why is that? how would that make them private?
That is all, I would appreciate anything, this had me thinking for hours! Thanks in advance, have a great day!
1) Don't worry about the members being functions, it's just this:
What does dot (.) mean in a struct initializer?
2) In
struct S {int i;}
s = {0};
the first line names a type that can be used to declare and initilize a variable.
It is really equivalent with something like
double d = 1;
where you replace double with struct S {int i;}, replace s with d, and replace 1 with the initializer for a struct, {0}. Now combine this with the dot syntax.
It just has the side effect of also defining struct S.
Update:
Regarding 3), I do not think that with private they refer to an implementation of access control, but rather refer to the fact that in C++, you would usually list the data members in the private section of the class, so I understand this as instructions to add the data members after the type identifying element.
Let's say we have two struct types as follows:
struct A {
int a;
}
struct B {
int b;
int c;
}
Would it be possible to initialize a flexible-length array to contain instances of both A and B using designated initializers, e.g:
<sometype> my_array[] = {
((struct A){ .a = 10, }),
((struct B){ .b = 1, .c = 5, }),
};
And since I need to know the type of elements in the array, a way to put some char before the structs would be nice too. :)
I know this looks terribly broken, but I am trying to pack some bytecode-like data structures together and this looks like an elegant way to define them (well, with the help of some macros at least).
Edit: To clarify a few points:
Dynamic allocation is not an option
Neither are unions - I want the elements to occupy exactly the space needed by their type
"Variable length array" in the question could have been misleading - the exact denomination would be "flexible length array", according to http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html. The example code is ideally how I'd like it to look like.
So what I'd basically like is to be able to pack some arbitrary, structured data into a memory area that is allocated in the .data segment of the binary. I do not need random access to elements, just to pack the data from structs - the use of a flexible length array in my example is because this construct seems to be the closest from what I want to achieve. But the declaration could be anything else that does the job (except assembler, I need to retain C portability).
The best way for this would be to use unions. You could define all your types within a union, including this union and the char you wanna you for defining what is the actual type into a struct.
struct TypesAB {
char type;
union {
struct {
int a;
} A;
struct {
int b;
int c;
} B;
};
};
enum {
TypeA,
TypeB
};
With this struct, you can define your array, and then set the elements.
struct TypesAB array[10];
array[0].type = TypeA;
array[0].A.a = 10;
array[1].type = TypeB;
array[1].B.b = 1;
array[1].B.c = 5;
Note that the memory layout will make you loose some space if your A and B types are not the same length. Indeed, with the above definition, struct TypesAB will be defined with a sizeof large enough to hold the larger of the A or B, plus the char. If you use it as a A, then the memory space that would have been used for the c member is lost. The same memory space is used for the a member of A and the b member of B.
I'm really new to C programming and I'm still trying to understand the concept of using pointers and using typedef structs.
I have this code snippet below that I need to use in a program:
typedef struct
{
char* firstName;
char* lastName;
int id;
float mark;
}* pStudentRecord;
I'm not exactly sure what this does - to me it seems similar as using interfaces in Objective-C, but I don't think that's the case.
And then I have this line
pStudentRecord* g_ppRecords;
I basically need to add several pStudentRecord to g_ppRecords based on a number. I understand how to create and allocate memory for an object of type pStudentRecord, but I'm not sure how to actually add multiple objects to g_ppRecords.
defines a pointer to the struct described within the curly bracers, here is a simpler example
typedef struct {
int x;
int y;
}Point,* pPoint;
int main(void) {
Point point = {4,5};
pPoint point_ptr = &point;
printf("%d - %d\n",point.x,point_ptr->x);
pPoint second_point_ptr = malloc(sizeof(Point));
second_point_ptr->x = 5;
free(second_point_ptr);
}
The first declares an unnamed struct, and a type pStudentRecord that is a pointer to it. The second declares g_ppRecords to be a pointer to a pStudentRecord. In other words, a pointer to a pointer to a struct.
It's probably easier to think of the second as an "array of pointers". As such, g_ppRecords[0] may point to a pStudentRecord and g_ppRecords[1] to another one. (Which, in turn, point to a record struct.)
In order to add to it, you will need to know how it stores the pointers, that is, how one might tell how many pointers are stored in it. There either is a size somewhere, which for size N, means at least N * sizeof(pStudentRecord*) of memory is allocated, and g_ppRecords[0] through g_ppRecords[N-1] hold the N items. Or, it's NULL terminated, which for size N, means at least (N+1) * sizeof(pStudentRecord*) of memory is allocated and g_ppRecords[0] through g_ppRecords[N-1] hold the N items, and g_ppRecords[N] holds NULL, marking the end of the string.
After this, it should be straightforward to create or add to a g_ppRecords.
A struct is a compound data type, meaning that it's a variable which contains other variables. You're familiar with Objective C, so you might think of it as being a tiny bit like a 'data only' class; that is, a class with no methods. It's a way to store related information together that you can pass around as a single unit.
Typedef is a way for you to name your own data types as synonyms for the built-in types in C. It makes code more readable and allows the compiler to catch more errors (you're effectively teaching the compiler more about your program's intent.) The classic example is
typedef int BOOL;
(There's no built-in BOOL type in older ANSI C.)
This means you can now do things like:
BOOL state = 1;
and declare functions that take BOOL parameters, then have the compiler make sure you're passing BOOLs even though they're really just ints:
void flipSwitch(BOOL isOn); /* function declaration */
...
int value = 0;
BOOL boolValue = 1;
flipSwitch(value); /* Compiler will error here */
flipSwitch(boolValue); /* But this is OK */
So your typedef above is creating a synonym for a student record struct, so you can pass around student records without having to call them struct StudentRecord every time. It makes for cleaner and more readable code. Except that there's more to it here, in your example. What I've just described is:
typedef struct {
char * firstName;
char * lastName;
int id;
float mark;
} StudentRecord;
You can now do things like:
StudentRecord aStudent = { "Angus\n", "Young\n", 1, 4.0 };
or
void writeToParents(StudentRecord student) {
...
}
But you've got a * after the typedef. That's because you want to typedef a data type which holds a pointer to a StudentRecord, not typedef the StudentRecord itself. Eh? Read on...
You need this pointer to StudentRecord because if you want to pass StudentRecords around and be able to modify their member variables, you need to pass around pointers to them, not the variables themselves. typedefs are great for this because, again, the compiler can catch subtle errors. Above we made writeToParents which just reads the contents of the StudentRecord. Say we want to change their grade; we can't set up a function with a simple StudentRecord parameter because we can't change the members directly. So, we need a pointer:
void changeGrade(StudentRecord *student, float newGrade) {
student->mark = newGrade;
}
Easy to see that you might miss the *, so instead, typedef a pointer type for StudentRecord and the compiler will help:
typedef struct { /* as above */ } *PStudentRecord;
Now:
void changeGrade(PStudentRecord student, float newGrade) {
student->mark = newGrade;
}
It's more common to declare both at the same time:
typedef struct {
/* Members */
} StudentRecord, *PStudentRecord;
This gives you both the plain struct typedef and a pointer typedef too.
What's a pointer, then? A variable which holds the address in memory of another variable. Sounds simple; it is, on the face of it, but it gets very subtle and involved very quickly. Try this tutorial
This defines the name of a pointer to the structure but not a name for the structure itself.
Try changing to:
typedef struct
{
char* firstName;
char* lastName;
int id;
float mark;
} StudentRecord;
StudentRecord foo;
StudentRecord *pfoo = &foo;
Given this simple C code:
struct {
struct a {
int foo;
};
struct b {
char *bar;
};
} s;
I am wondering whether there is a way to access a variable in one of the nested structures in a more compact way than s.a.foo = 5, for instance.
First, notice that your example is not standard C89 (but it is acceptable by some compilers when you ask for some language extensions. With GCC you'll need to extend the accepted C dialect with the -fms-extensions flag to the compiler). You are using unnamed fields. A more standard way of coding would be:
struct a {
int foo;
};
struct b {
char* bar;
};
struct {
struct a aa;
struct b bb;
} s;
Back to your question, no, there is no other way. However, you might use preprocessor macros, whcih could help. For instance, assuming the above declarations, you could
#define afoo aa.foo
#define bbar bb.bar
and then you can code s.afoo instead of s.aa.foo
You might also define macros like
#define AFOO(X) (X).aa.foo
and then code AFOO(s)
Using such preprocessor macros does have some annoyance: with my example, you cannot declare anymore a variable (or formal argument, or field, or function) named afoo
But I am not sure you should bother. My personal advice & habit is to give longer and often unique names to fields (and also to name struct a_st my struct-ures). Take advantage of the auto-completion abilities of your editor. Don't forget that your code is more often read than written, so use meaningful names in it.
There is not. You have to specify the path the the memory address you wish to reference.
You can't cast structs directly, but you can cast pointers to structs. So if you have this stuct:
typedef struct {
struct {
int foo;
} a;
struct {
char bar;
} b;
} s;
You can create a struct like this:
typedef struct {
int foo;
char bar;
} sa;
Now when you create the struct, stash a pointer to it:
s myS;
myS.a.foo = 123;
myS.b.bar = 10;
sa *mySA = (sa *)&myS;
Then you can do this:
printf("I'm really a s.a.bar %d", (*mySA).bar);
Which will print out the appropriate value.
So now you can do:
(*mySA).bar = 22;
printf("%d", myS.b.bar);
You aren't really saving that much typing though.
Why can't we initialize members inside a structure ?
example:
struct s {
int i = 10;
};
If you want to initialize non-static members in struct declaration:
In C++ (not C), structs are almost synonymous to classes and can have members initialized in the constructor.
struct s {
int i;
s(): i(10)
{
}
};
If you want to initialize an instance:
In C or C++:
struct s {
int i;
};
...
struct s s_instance = { 10 };
C99 also has a feature called designated initializers:
struct s {
int i;
};
...
struct s s_instance = {
.i = 10,
};
There is also a GNU C extension which is very similar to C99 designated initializers, but it's better to use something more portable:
struct s s_instance = {
i: 10,
};
The direct answer is because the structure definition declares a type and not a variable that can be initialized. Your example is:
struct s { int i=10; };
This does not declare any variable - it defines a type. To declare a variable, you would add a name between the } and the ;, and then you would initialize it afterwards:
struct s { int i; } t = { 10 };
As Checkers noted, in C99, you can also use designated initializers (which is a wonderful improvement -- one day, C will catch up with the other features that Fortran 66 had for data initialization, primarily repeating initializers a specifiable number of times). With this simple structure, there is no benefit. If you have a structure with, say, 20 members and only needed to initialize one of them (say because you have a flag that indicates that the rest of the structure is, or is not, initialized), it is more useful:
struct s { int i; } t = { .i = 10 };
This notation can also be used to initialize unions, to choose which element of the union is initialized.
Note that in C++ 11, the following declaration is now allowed:
struct s {
int i = 10;
};
This is an old question, but it ranks high in Google and might as well be clarified.
Edit2: This answer was written in 2008 and relates to C++98. The rules for member initialization have changed in subsequent versions of the language.
Edit: The question was originally tagged c++ but the poster said it's regarding c so I re-tagged the question, I'm leaving the answer though...
In C++ a struct is just a class which defaults for public rather than private for members and inheritance.
C++ only allows static const integral members to be initialized inline, other members must be initialized in the constructor, or if the struct is a POD in an initialization list (when declaring the variable).
struct bad {
static int answer = 42; // Error! not const
const char* question = "what is life?"; // Error! not const or integral
};
struct good {
static const int answer = 42; // OK
const char* question;
good()
: question("what is life?") // initialization list
{ }
};
struct pod { // plain old data
int answer;
const char* question;
};
pod p = { 42, "what is life?" };
We can't initialize because when we declared any structure than actually what we do, just inform compiler about their presence i.e no memory allocated for that and if we initialize member with no memory for that. Normally what happens when we initialize any variable that depends on the place where we declared variable compiler allocate memory for that variable.
int a = 10;
if it's auto than in stack memory going to allocate
if it's global than in data sections memory going to allocate
So what memory is required to hold that data but in case of structure no memory is there so not possible to initialize it.
As you said it's just a member not a variable. When you declare a variable the compiler will also provide memory space for those variables where you can put values. In the case a of a struct member the compiler is not giving memory space for it, so you cannot assign values to struct members unless you create a variable of that struct type.