I have been trying something in structures in C.
struct val{
unsigned int a : 1 ;
}store[100] ;
Now I want to initialize all the array members value to 1. That is, I want all the array members to have their variable a assigned to 1. I can use a loop for that but how can I do this during the declaration?
struct val
{
unsigned int a=1 : 1 ;
}store[100];
How can i achieve this? The above syntax is coming out to be wrong in code::blocks.
struct val
{
unsigned int a : 1;
}store[100];
I initially thought that what you were doing was a bitfield initialization. Further research though suggested I am wrong, and that you are trying to use gcc's designated initializers. What you want to do, is not possible that way. I found another way in your code that you can do it, though:
typedef struct {
unsigned int a;
} val;
then, where you want to initialize the array, you will do something like that:
val values[100] = {[0].a = 1};
This works by exploiting this behavior of gcc:
If the same field is initialized multiple times, it has the value from the last initialization. If any such overridden initialization has side-effect, it is unspecified whether the side-effect happens or not. Currently, GCC discards them and issues a warning.
My Test Program follows:
#include <stdio.h>
struct val {
unsigned int a;
};
int
main (void)
{
struct val value[100] = {[0].a = 1};
printf ("A random val's value is %d\n", value[40].a);
return 0;
}
Compiles and works cleanly on my GCC 4.9.1.
It's not possible.
You can use a loop, or, if by any chance you want to initialize all struct's data members to a specific value, you can also use memset:
struct val {
unsigned int a : 1 ;
} store[N];
memset(store, value, N * sizeof(struct val));
Before declaring a struct variable you can't initialize its member. Initialization can be done as
struct val{
unsigned int a : 1;
}store[100] = {[0].a = 1} ; // Designated initializer
but it will initialize a member of other elements of store to 0. To initialize member a of all elements of store you need a loop.
Related
#include <stdio.h>
struct virus
{
char signature[25];
int size;
}v[2];
int main(void) {
static v[0] = {"Yankee",1813};
static v[1] = {"Doodle",2813};
int i;
for(i=0;i<=1;i++)
{
printf("%s %d\n",v[i].signature,v[i].size);
}
return 0;
}
I am getting the compiler error in this C code.
Error: Declaration syntax in function main()
I am guessing that there is some error in v[2], as it is associated with extern class whereas, v[0] and v[1] are associated with static class.
But, I am not sure that is this the only reason or some other ?
Edit : I have edited the code by removing the wrong syntax.
There is no error in declaration of v[2], the problem is later.
You've written
static struct v[0] = {"Yankee",1813};
which attempts to define a 0-sized array, which is not allowed by default C standard.
That said, the syntax is also horribly wrong. You don't have a proper type there, remember, struct itself is not a type, it's a keyword. struct <something> is actually a type.
Then, from the logical point of view, you probably don't want a new variable altogether. In case you want to use the array elements from the v, just use the variable name, that's all. Something like
#include <stdio.h>
struct virus
{
char signature[25];
int size;
}v[2] = { {"Yankee",1813}, {"Doodle",2813}}; //get it initialized, job done
int main(void) {
int i;
for(i=0;i<=1;i++)
{
printf("%s %d\n",v[i].signature,v[i].size);
}
return 0;
}
will do the job in much better way, IMHO.
EDIT:
In case, you're interested in assigning individual elements (not initialization), well, you cannot use a brace-enclosed initializer for that purpose, it's not meant to be RHS operand for an assignment. You need to use a compound literal for that purpose, something like
v[0] = (struct virus){"Yankee",1813};
v[1] = (struct virus){"Doodle",2813};
will also do the job.
Don't mix up struct definitions with variable declarations, that's sloppy practice.
Instead, use a typedef:
typedef struct
{
char signature[25];
int size;
} virus_t;
Then you can declare variables of this type as you please:
static virus_t v[2] =
{
{"Yankee",1813},
{"Doodle",2813}
};
Or with designated initializers:
static virus_t v[2] =
{
[0] = {"Yankee",1813},
[1] = {"Doodle",2813}
};
When I declare structure given below, it is throwing compilation error.
typedef struct{
const char x; //it is throwing compilation error
const char y;
}A;
void main()
{
A *a1;
a1 = (A*)malloc(2);
}
How can I make structure's field (characters x and y) as constant?
That should be fine, but of course you can't assign to them, only use initialization.
So it doesn't make a lot of sense to allocate an instance on the heap.
This works:
#include <stdio.h>
int main(void) {
typedef struct {
const int x, y;
} A;
A my_a = { 12, 13 };
printf("x=%d\ny=%d\n", my_a.x, my_a.y);
return 0;
}
It prints:
x=12
y=13
Also, please don't cast the return value of malloc() in C.
First, you should use malloc to allocate the size of the struct, not a magic number 2. Also, don't cast malloc return value, it is automatically promoted to the compatible pointer type.
a1 = malloc(sizeof(A));
Second, there isn't really not much use to make struct member const.
A *a1;
a1 = malloc(sizeof(A));
a1's members are not initialized to any state here, yet the compiler forbidden any assignments to them, since it is defined as const, so a1->x = 'a'; won't compile.
A a2;
a2->x = 'a'; // won't compile too
The only valid use case is:
A a3 = {'a', 'b'};
You can't.
With POO in C you can disable the modification of those fields, if you:
define getters: char A_get_x(A *p); and char A_get_y(A *p);
define the struct in the .c to hide its implementation
only write typedef struct A A; in the .h file, to allow to use that type.
define a constructor : A *A_new(); which returns A with the values desired on x and y.
By doing this, you can only modify the values in the constructor, and after the object is created the values wont change (if you dont force the values with pointers etc..)
Is it safe to return a struct with array data member in C?
Something like
struct my_str {
int v[5];
};
struct my_str ret_stupid() {
struct my_str rval;
/*do something..*/
return rval;
}
I don't know why... I'm a bit puzzled. (I've tried and it does work). Is there some standard explaining how this operation actually is performed? I mean the mechanism of struct return and assignment too could be useful to understand better.
Is it safe to return a struct with array data member in C?
Yes.
struct are copied bit-wise. Bit-wise copying a struct that has an array as a member makes sure that the copy of struct has a copy of the array too.
Structures are a lot like arrays.
They can contain variables of any kind.
Their addresses will be sorted stacked as long as you leave no gaps or invoke the preprocessor directive #pragma pack
"Is it safe", depends of the code hiding there..
/do something../
But in general - yes. This is just a function of type struct my_str and has to return struct my_str
What the structure contains - doesn't matter. Still safe to use.
You can return a structure from a function without any problems. It's a well-defined part of the language. You can pass structures to functions as well - a structure is exactly the same as any built-in type for purposes of parameter passing, return values, and assignment.
Here's an example
#include <stdio.h>
int func(int x)
{
int r = x;
return r;
}
int main(void)
{
int x = 12;
int y = func(x);
printf("%d\n", y);
return 0;
}
If it weren't for the array member, the return would be an "rvalue", a value that is just a copy of the value that you have inside the return expression. If you have
struct toto {
double a;
};
struct toto g(void) {
struct toto retval = { 0.0 };
...
return retval;
}
int main(void) {
printf("%g\n", g().a);
}
The argument of the printf call sees a copy of the variable retval that is used inside the function. g().a calls the function and uses the .a field of the return value.
This return value is and
entity that is not an object but only lives because of its "value", called rvalue in the C jargon. It only can be found on the RHS of an assignment, thus the "r" in "rvalue".
The case that you are giving is actually specially treated, because a "value" is not sufficient for all use cases of the array. So this generates a so-called "object with temporary lifetime". This is needed because if you'd do ret_stupid().v[2] the [] operator wants to have a pointer, and a pointer can only point to an object, not a value.
These objects only "live" inside the expression that contains the function call, and even though they are not const qualified you are not allowed to modify them.
So all in all, this is a corner case of C, and you shouldn't abuse it.
Here is part of my code. I would like to initialize only the arraylist[0] as arraylist[0].x = 0 and arraylist[0].y = 0. I do not need to initialize the rest of the struct array. How can I do it? Thank you.
#include <stdio.h>
struct example {
int x;
int y;
};
struct example arraylist[40];
int main(int argc, char *argv[]){
printf("%d\n %d\n", arraylist[0].x, arraylist[0].y);
return 0;
}
You can initialise any particular element of the struct array.
For example:
struct example arraylist[40] = { [0]={0,0}}; //sets 0th element of struct
struct example arraylist[40] = { [5]={0,0}}; //sets 6th element of struct
This is called Designated Initializers which used to be a GNU extension before C99 adapted it and is also supported in standard C since C99.
Since you are talking about a variable in file scope, here, you don't have to do anything, since such variables are always initialized by 0 if you don't provide an explicit initializer.
In C, once you initialize part of a struct / array, you initialize the rest of it with 0.
You should have no problem with that, as you should not access uninitialized variables in first place, and their value is not defined.
In C all static and extern variables are initialized to 0 unless explicitly initialized otherwise.
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.