How I can initialize an element in a struct? I have this struct:
typedef struct { int mat[x][x]; int res; } graphe;
graphe g;
I was expecting this to work:
g.mat = {{0, 1}, {1, 0}, {1, 1}, {0, 1}};
but it does not.
The main problem is that arrays are not assignable, and by the time you want to set g.mat, it has already been default initialized. What you are attempting is to assign values to the members of an existing instance. A lesser problem is some missing braces.
Instead of default-initializing g and then attempting to assign values to its members, you can initialize the graphe object with the desired values for the members:
graphe g = {{{0, 1}, {1, 0}, {1, 1}, {0, 1}}};
This will also implicitly initialize g.res to 0, but you can also initialize it to a specific value:
graphe g = {{{0, 1}, {1, 0}, {1, 1}, {0, 1}}, 42};
Here's an example using designated initializers. This might be easier to read than the previous examples, and you can change the order of the fields:
graphe g = { .mat = {{0, 1}, {1, 0}, {1, 1}, {0, 1}}, .res = 42};
You can initialize your g at the point of definition, as shown in #juanchopanza's answer.
However, you can also assign a new value to g later (if the need arises) by using a similar syntax in combination with the compound literal feature of C language
g = (graphe) { { { 0, 1 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }, 42 };
Note that the assignment operator will only work for the entire struct object. If you want to assign a new value only to the g.mat array, not touching any other fields of g, then the assignment operator won't work for that purpose since arrays in C are not assignable. However, you can still use memcpy in combination with a compound literal to copy new values into g.mat
memcpy(g.mat, (int [x][x]) { { 0, 1 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }, sizeof g.mat);
This is actually what you tried to do in your question.
Related
I'm new to c, and currently making chess program.
There's the code.
#include <stdio.h>
int spider[8][2] = {{0, 1}, {1, 1}, {1, 0}, {1, -1},
{0, -1}, {-1, -1}, {1, 0}, {-1, 1}};
int jump[8][2] = {{1, 2}, {2, 1}, {2, -1}, {1, -2},
{-2, -1}, {-1, -2}, {-1, 2}, {-2, 1}};
typedef struct
{
int color;
int type;
char symbol;
int unit[8][2];
} piece;
void add_piece(piece piece, int color, int type, char symbol, int unit[8][2])
{
piece.color = color;
piece.type = type;
piece.symbol = symbol;
for(int i = 0; i < 8; i++)
{
for(int j = 0; j < 2; j++)
{
piece.unit[i][j] = unit[i][j];
}
}
}
int main(void)
{
piece wk;
add_piece(wk, 0, 0, 'K', spider);
printf("%d", wk.color);
return 0;
}
expected output : 0
console output : 8388608
I found that 8GB = 8388608KB.
What's the meaning of that output?
Is there any problem of initializing property of structure or elsewhere?
Can you see some not good habits in this code?
Remember that in C all arguments are passed by value.
That means the value of the argument in the call is copied into the functions argument value.
So in the call
add_piece(wk, 0, 0, 'K', spider);
the value (current uninitialized contents) of the structure object wk will be copied into the argument variable piece inside the add_piece function.
When you modify the local argument variable, for example through an assignment like
piece.color = color;
you only modify the local copy. The original value used in the call will not be modified.
You can solve this in two ways:
Return the structure, and assign to a variable when doing the call; Or
Emulate pass by reference by using pointers.
Option number 2 is the most common it seems, so I will show it here.
First you need to modify the function to take a pointer to the structure object:
void add_piece(piece *piece, int color, int type, char symbol, int unit[8][2])
{
...
}
Then you need to use the "pointer to structure" syntax using the "arrow" to access structure members:
piece->color = color;
piece->type = type;
// And so on for all access to piece members...
Finally, when you call the function you need to pass a pointer to the wk variable, using the "pointer to" or "address of" operator &:
add_piece(&wk, 0, 0, 'K', spider);
I described the pass by reference emulation because it's so common and because you need to learn to recognize it. For your specific case I would rather recommend that you define a new structure object in the function and return it:
piece add_piece(int color, int type, char symbol, int unit[8][2])
{
piece piece;
piece.color = color;
piece.type = type;
// And so on, much like your current function...
// Return the structure
return piece;
}
Now you can use it as such:
piece wk = add_piece(0, 0, 'K', spider);
Note that sometimes it's not possible, or desirable, to return structures like this, and you still need to emulate pass by reference. So you need to learn both ways.
Lastly a note about the output you get: Uninitialized local (non-static) variables really are uninitialized. They will have indeterminate (read: garbage) values.
Since in your current code doesn't really initialize the original wk structure object, all its members will have such indeterminate values.
Depending on type and use, using such indeterminate values could lead to undefined behavior.
struct mystruct s[10] = {{0}};
This appears to initialize an array of structs to 0. How does the nested braces syntax work?
Any fields not specified are initialized to zero. So here you have an array of structs. You're initializing the first element of the array with a structure initializer that initializes the first element of the structure to zero. The rest of the first structure and the rest of the array elements will all be zero too. It's a nice idiom.
As shown?
Basically, you should enclose each compound type - array, structure, etc - inside its own level of braces.
Consider:
struct mystruct
{
int i;
double d;
char s[10];
int a[5];
} s[10] =
{
{ 0, 0.0, "abc", { 1, 2, 3, 4, 5 } },
{ 1, 1.0, "def", { 2, 3 } }, // Partially initialized array
{ 2, 2.0, { 'x', 'y', 'z' }, { 0 } }, // Strings are a shorthand
[9] = { 9, 99, 0, { 9, 8, 7, 6, 5 } }, // C99 - initialize row 9
};
But you can also omit braces if you insist (bad, archaic practice):
struct mystruct t[3] =
{ // You cannot avoid using these outside braces
0, 0.00, "abc", 1, 2, 3, 4, 5, // Omitted braces
1, 1.11, "bcd", 2, 3, 4, 5, 4,
2, 2.34, // Omitted values
};
Any omitted initializers are treated as zeroes.
It is not the nested braces that initializes. The outer braces are indicating that an array is being initialized:
struct mystruct s[10] = { };
Since this is an array of structures, each structures can be initialized with further braces:
struct mystruct { int x, y, z};
struct mystruct s[10] = { {0, 1, 2}, // <-- initializes s[0].x, s[0].y, s[0].z
{1, 2, 3}, // <-- initializes s[1].x, s[1].y, s[1].z
{2, 3, 4} // <-- initializes s[2].x, s[2].y, s[2].z
};
Notice that only first three elements are initialized. According to C standard the rest 7 elements must be initialized to 0. This is what happens to your code too. As xscott mentioned in his reply, everything omitted in initializer list is initialized to 0.
It's useful to note that while the inner braces are optional, the compiler will check to ensure that opening braces only appear where they ought, and that no nested item has too many initializers. Further, one may leave out some fields of a structure and have the compiler automatically zero them, even if the structure is not at the end of the array. Note that implementations vary in their efficiency of handling this; some will divide the initialization record into small pieces, while others will simply insert lots of zeroes in the code. For example, if each struct looked like:
typedef struct {
char name[8];
char more_stuff[1016];
} THINGIE;
THINGIE my_array[] = {{"Fred"},{"George"},{"Mark"}};
some compilers would generate 3K worth of const data, while others would generate three relatively-small 'const-init' records.
I have been writing test cases using "testing" package of Golang. And I've come across a situation where I have to write array and function pointers into a table.
I tried following:
type myFunctionType func( []float64, []float64 ) float64
var testMatrix = []struct {
dataX []float64
dataY []float64
result float64
myFunction myFunctionType
} {
{ {2, 3}, {8, 7}, 1, doMagicOne},
{2, 3}, {8, 7}, 1, doMagicTwo},
}
But every time I end up getting following error or something else:
missing type in composite literal
Any input in the above? Thanks in advance.
The error you are reporting is caused by the lack of a declaration of type before the arrays in your array. The error:
missing type in composite literal
Is referring to this bit of your declaration:
{2, 3}
That needs to specify the type of the array:
[]float64{2, 3}
So you need:
var testMatrix = []struct {
dataX []float64
dataY []float64
result float64
myFunction myFunctionType
}{
{[]float64{2, 3}, []float64{8, 7}, 1, doMagicOne},
{[]float64{2, 3}, []float64{8, 7}, 1, doMagicTwo},
}
https://play.golang.org/p/AguxDJ11HS
I'm writing a program in C and declared the following structure:
typedef struct
{
int type[4][4];
int color;
} block;
So, I wrote the following function to initialize the variables:
void inicialize(block aux[1])
{
aux[0].type[4][4] = {
{0, 0, 0, 0},
{1, 2, 0, 2},
{3, 2, 0, 0},
{0, 0, 0, 0}
};
}
But when I compile the program, I got the following message:
C:\ncurses\tetris.c|11|error: expected expression before '{' token|
Please, I need to finalize this program. Can someone help me with this?
Thanks.
void inicialize(block aux[1]){
memcpy(aux[0].type,
(int [4][4]){
{0, 0, 0, 0},
{1, 2, 0, 2},
{3, 2, 0, 0},
{0, 0, 0, 0}
},
sizeof(aux[0].type));
}
So, I wrote the following function to initialize the variables:
No, you didn't. That's not initialization, that's an assignment, and you can't assign arrays. Either really initialize the variable, or fill the array elements one by one, or initialize an array and memcpy(), or whatever...
You are using initialization syntax in an assignment. And that's not allowed.
You could just assign the values you need to the variable. Or you could define a constant using the initialization syntax, and assign that constant to the variable.
The latter looks like this:
const int initialBlock[4][4] = { ... };
And then you can assign like this:
aux[0].type = initialBlock;
It's also a little odd that you pass an array of block of length one to your function. It would be more usual to pass the address of a single struct.
I have a problem, I was asked to declare an array of structures, with one structure inside like so:
typedef struct {
int a;
int b;
int c;
}blah;
int main()
{
blah arr[1] = {{0, 0, 0}};
//...
}
Is the above initialization correct?
Yes, it's totally correct.
Array of length 1 is not much different from those containing multiple elements: they all are aggregate types and their initialization should be enclosed in curly braces. If your array had 2 elements, the initialization would be like
blah arr[2] = { {0, 0, 0}, {0, 0, 0} };
Yes.
You don't need to specify the size if you're going to have an explicit initializer, let the compiler figure it out:
blah arr[] = { { 0, 0, 0 } };
I've also included spaces to make the nesting a bit clearer.