cannot set values for variables in global structures? - c

struct ball{
int a;int b;
};
struct ball x;
x.a = 10; x.b = 20;
int main() {
x.a = 25; x.b = 50;
printf("%d %d\n",x.a,x.b);
}
Why won't this code work.Im trying to set struct ball x; as a global variable and then set the value of a and b.
This is the terminal error:
x.c:54:1: error: unknown type name 'x'
x.a = 10; x.b = 20;
^
x.c:54:2: error: expected identifier or '('
x.a = 10; x.b = 20;
^

The assignment
x.a = 10;
is an example of an expression statement. Expression statements (a statement which evaluates an expression, with an observable effect) are only permitted within functions.
It is possible to initialise a struct when defining a variable. For example;
struct ball x = {10, 20};
defines x (to be of type struct ball) and initialises its members (in order). Variable definitions that do initialisation like this are not restricted to only being used in a function body.
For standard C (1999 standard and later) it is also possible to use designated initialisers.
struct ball x = {.a = 10, .b = 20};

struct ball{
int a;int b;
};
struct ball x;
x.a = 10; x.b = 20; <-- Invalid to have assignment instruction outside of function body
int main()
{
...
return 0;
}
You intended to initialize the global variable. Yes, that is permitted and can be done as follows:
struct ball{
int a;int b;
};
struct ball x = {10, 20}; <-- struct global variable initialization

This works
struct ball{
int a;int b;
};
struct ball x;
//x.a = 10; x.b = 20;
int main() {
x.a = 25; x.b = 50;
printf("%d %d\n",x.a,x.b);
}

For global variable you are able to done the declaration part (struct ball x) and initialization part(int a = 0) only in outside of all functions.
Inside the functions only you are able to assign or modify the values for the global variables. So, only you are getting this error.

Related

C struct compound initialization without setting everything to zero

Is there any syntax similar to doing something like this
typedef struct foo
{
int X;
int Y;
int Z;
} foo;
int main()
{
// Initialize everything
foo Variable = (foo){
.X = 10;
.Y = 15;
.Z = 20;
};
// Assign the X and Y variables, but keep Z the same
Variable = (foo){
.X = 15;
.Y = 20;
// .Z stays the same
};
}
Would be nice to have this type of QOL syntax instead of having to type
int main()
{
foo Variable = {bla bla};
// Keep having to type Variable. to access struct members
Variable.X = 10;
Variable.Y = 15;
}
This gets really annoying with structs in structs i.e.
Struct1->Struct2.Struct3.Element.X = 10;
Struct1->Struct2.Struct3.Element.Y = 15;
No, C does not support this style of initialization or assignment.
If you want to access only a part of a structure, you need to express this explicitely.
EDIT:
You can get away with:
Variable = (foo){
.X = 15;
.Y = 20;
.Z = Variable.Z;
};
At least an optimizing compiler will just generate the operations for the changing elements. But it is more source than single assignments.
You can use the preprocessor to save your fingers (or copy/paste)...
struct {
int f1;
int f2;
struct {
int b1;
int b2;
int b3;
} bar;
} foo = {
1, 2, { 42, 43, 44 },
};
printf( "%d %d %d\n", foo.bar.b1, foo.bar.b2, foo.bar.b3 );
#define S foo.bar
S.b1 = 7;
S.b2 = 8;
printf( "%d %d %d\n", S.b1, S.b2, S.b3 );
#undef S

C how to allocate struct to struct?

The following code gives me a Compile error "incompatible types at assignment"
File 1:
struct x{
int a;
int b;
int c;
};
File 2:
static struct x d;
void copyStructVal(){
d-> a = 1;
d-> b = 2;
d-> c = 3;
}
x getStruct(){
copyStructVal();
return d;
}
File 3:
static struct x e;
void copy(){
e = getStruct();
}
I've searched for this and can't find the answer. Can I do it with a Pointer? (I'm a amateur in C)
In C, you need to write struct behind the name of a structure, unless you typedef it. In other words:
x getStruct(){
Must be:
struct x getStruct(){
Since you wrote it in the rest of the code, I guess it is a typo.
On top of that, you have to fix these 3 lines, since d is not a pointer:
d-> a = 1;
d-> b = 2;
d-> c = 3;
They should be:
d.a = 1;
d.b = 2;
d.c = 3;

Why Can't We Initialize A Structure Multiple Times in C?

Why is this illegal in C? What is wrong with reinitializing p to a different posn? The same effect can be achieved by changing the field values individually so I don't understand why it can't be done in one step with p = {1, 2}.
struct posn {
int x;
int y;
};
int main() {
struct posn p = {3, 4};
p = {1, 2}; //Causes error
// must do p.x = 1; p.y = 2;
return 0;
}
That's the way the language is specified.
To stay somewhat consistent with C's general design, in order to allow p = {1, 2}, {1, 2} would have to be an expression. But of what type? It could be int[2], or struct { int a; short s; }, or a lot of other things.
With C99, a compound literal can be used, which explicitly mentions the type (and thereby solves the problem of how to determine the type), a parenthesized type-name followed by an initializer in {} brackets:
p = (struct posn){1, 2};
You may use a compound literal. For example
#include <stdio.h>
struct posn
{
int x;
int y;
};
int main(void)
{
struct posn p = { 3, 4 };
p = ( struct posn ){ 1, 2 };
printf( "p.x = %d, p.y = %d\n", p.x, p.y );
return 0;
}
The program output is
p.x = 1, p.y = 2
This works because structures opposite to arrays have copy assignment operator.
However you can enclose an array in structure and use the same trick to reassign arrays.
Here is an example
#include <stdio.h>
struct posn
{
int a[2];
};
int main(void)
{
struct posn p = { { 3, 4 } };
p = ( struct posn ){ { 1, 2 } };
printf( "p.a[0] = %d, p.a[1] = %d\n", p.a[0], p.a[1] );
return 0;
}
Thus it looks like std::array in C++.:)
That is not entirely true, you can't use the initializer list but you certainly can initialize or more precisely change the members of your struct whenever you want, try this
p.x = 1;
p.y = 2;
initializer lists can only be part of a declaration.

Adding (or doing any other math) every member of two same structs with less code

So, basically, I want to addify every member of first struct, with every member of second struct, and the structs are of same type. Like this:
struct Foo
{
int bar1;
int bar2;
int bar3;
int bar4;
int bar5;
}
Foo AddFoos(Foo foo1, Foo foo2)
{
Foo foo3;
foo3.bar1 = foo1.bar1 + foo2.bar1;
foo3.bar2 = foo1.bar2 + foo2.bar2;
foo3.bar3 = foo1.bar3 + foo2.bar3;
foo3.bar4 = foo1.bar4 + foo2.bar4;
foo3.bar5 = foo1.bar5 + foo2.bar5;
return foo3;
}
However, when structs keep getting bigger, this way is weird. Is there any way to do it with less lines of code? And preferably without advanced pointer magic?
Use an array instead and a for loop to add the numbers:
struct Foo
{
int bars[100];
};
for (i=0;i<100;i++)
{
foo3.bars[i]=foo1.bars[i]+foo2.bars[i];
}
You can malloc if the array size is unknown at compile time and change the struct to this and then malloc for all three Foo variables.
struct Foo
{
int *bars;
};
You want the comfort of named fields (bar1 .. barN) and something like an array you can loop over to automate the operations. First we define the struct (a dense representation of the fields in memory):
struct VectorFields {
int a;
int b;
int c;
};
Then we need to get to know the number of the fields used in that struct:
#define VECTOR_FIELDS_LEN (sizeof(struct VectorFields) / sizeof(int))
(In C++ you could use some template magic foo, here we just use the preprocessor as a simpler variant). Next, we combine the struct VectorFields with an array of int so both match in size, also known as union:
union Vector {
struct VectorFields fields;
int raw[VECTOR_FIELD_LEN];
};
(Note: VECTOR_FIELD_LEN must be a known constant value to the compiler, hence the preprocessor thingy before.) You are now able to access the data either by it's name (.fields.a) or by an index (.raw[0]). So, let's write the function which adds the Vector together:
void vector_add(union Vector* result, union Vector* a, union Vector* b) {
int i;
for (i = 0; i < TUPLE_LEN; i++) {
result->raw[i] = a->raw[i] + b->raw[i];
}
}
You might use it like this then:
#include <stdio.h>
int main() {
union Vector a = { .fields = { 1, 2, 3 } };
union Vector b = { .fields = { 4, 5, 6 } };
union Vector sum;
vector_add(&sum, &a, &b);
printf("%d %d %d\n", sum.fields.a, sum.fields.b, sum.fields.c);
return 0;
}
Depending on what you call "advanced pointer magic", you can use the following moderately magical code:
Foo AddFoos(Foo foo1, Foo foo2)
{
Foo foo3;
int *pointer1 = &foo1.bar1; // first field here
int *pointer2 = &foo2.bar1; // first field here
int *pointer3 = &foo3.bar1; // first field here
while (pointer3 <= &foo3.bar5) // last field here
{
*pointer3++ = *pointer1++ + *pointer2++;
}
return foo3;
}
When you change the definition of Foo, just update the names of the first and last field.
This will only work when all fields are of the same type.
If you have only ints you can use an array
struct Foo {
int bar[5];
};
Foo AddFoos(Foo f1, Foo f2)
{
Foo f3;
int i;
for (i = 0; i < 5; ++i)
f3.bar[i] = f1.bar[i] + f2.bar[i];
return f3;
}

Basic struct question C

for example:
typedef struct {
int num;
int den;
} rational_number;
rational_number a;
What is the difference between using
a.num or a.den
and
a->num or a->den
Thx in advance.
-> is for accessing the members of a pointer to a struct, whereas . is for accessing members of the struct itself. a->num is really just shorthand for (*a).num. Example:
typedef struct {
int num;
int den;
} rational_number;
rational_number a;
r.num = 1;
rational_number *a_ptr = &a;
a_ptr->num = 2; /* a.num is now 2 */
you use a.num, when it is normal variable, and a->num when it is pointer
For ex.
rational_number a;
a.num; // is correct
a->num; // is wrong
rational_number *b;
b.num;// wrong
b->num; //is correct
The difference is that in the first case you access the structure via a stack variable:
rational_number a;
a.num = 1;
a.den = 1;
in the second case via a heap pointer:
rational_number* a = new rational_number();
a->num = 1;
a->den = 1;
If a were declared as a pointer to your structure, a->num would return the value of num.
rational_number *a;
a->num = 5;
int new_a;
new_a = a->num;
You have a is declared as a structure, so you should use a.num to return the value of num.
rational_number a;
a.num = 5;
int new_a;
new_a = a.num;
Both set the value of new_a to 5.
Also, you can get the address of a if it is a structure and use it like a pointer.
rational_number a;
(&a)->num = 5;
int new_a;
new_a = a.num;

Resources