He folks,
i got a problem and a question.
Hopefully u can help and explain me.
first of all i have 2 stucts:
typedef struct {
double x;
double y;
} A;
typedef struct {
unsigned int count;
A(*stack)[];
}B;
this struct B i declare in main() and passing a Pointer of B to a function this will initializ
main(){
B x;
function rr(&x);
}
void rr(B* test) {
test->stack= malloc((4) * sizeof(A)); //4Elements
for (unsigned int i = 0; i < 4; i++) {
(test->stack+ i)->x= 89;
}
}
on this line
(test->stack+ i)->x= 89;
compiler says incomplete Type
i know why it is incomplete cause in struct B their is no dimension.
but array should initialize in function rr
Maybe u understand what i mean and how to solve my problem.
function rr i am not allowed to change.
Greetings
EDIT 1
Thank you for all answers
mabey i schould clearify my problem
typedef struct {
unsigned int count;
A(*stack)[]; // here i want a pointer to an array of A's
}B;
//over main it is declared
void rr(B*);
main(){
B x;
function rr(&x);
}
// this func is not allowed to change
void rr(B* test) {
test->stack= malloc((4) * sizeof(A)); //4Elements
for (unsigned int i = 0; i < 4; i++) {
(test->stack+ i)->x= 89; // error cause incomplete type but i
//have to use this line
}
}
Hope now it is easier to i understand what i want
This declaration:
A(*stack)[];
Says that stack is a pointer to an array of A of unknown size. That is an incomplete type which means it can't be used directly.
It seems like what you actually want is not a pointer to an array, but a pointer to the first member of a dynamic array of A. So declare the member as a pointer:
A *stack;
In the expression:
(test->stack+ i)->x= 89;
before accessing an array via a pointer to an array you must dereference it.
Try:
(*test->stack)[i].x= 89;
You do not know how to use flexible array members.
Simply:
typedef struct {
double x;
double y;
} A;
typedef struct {
size_t count;
A stack[];
}B;
B *createStack(size_t size)
{
B *s = malloc(sizeof(*s) + size * sizeof( s -> stack[0]));
return s;
}
void rr(B* test) {
for (unsigned int i = 0; i < 4; i++) {
(test->stack+ i)->x= 89;
}
}
int main(void)
{
B *stack = createStack(4);
rr(stack);
free(stack);
}
You need only one allocation to mallloc/realloc or free the structure. The array will decay into pointer for your assignment in rr function.
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;
I have a larger piece of code (I didn't write it) that makes use of complex numbers defined through a structure. I need to edit it and simply multiply a complex number by a real but cant seem to get it right. I keep getting the following error message.
error: invalid operands to binary * (have ‘cplx’ and ‘double’)
I know this could be done using the complex.h library but that would mean a lot of rewriting so is there a simpler way? The code below reproduces my problem.
#include <stdio.h>
#include <math.h>
typedef struct cplxS {
double re;
double im;
} cplx;
int main()
{
double a = 1.3;
cplx b = {1, 2};
c = a * b;
}
You will first have to initialize a node using malloc
#include <stdlib.c>
int main(){
double a = 1.3;
//initialize struct
struct cplxS* b = malloc(sizeof(struct cplxS));
//set values for b
b->re = 1;
b->im = 2;
//preform your multiplication
double c = a*(b->re); //value c with re
double d = a*(b->im); //value d with im
//free node memory
free(b);
b = NULL;
}
If you want to update the struct by multiplying c to its values, it would follow
#include <stdlib.c>
int main(){
double a = 1.3;
//initialize struct
struct cplxS* b = malloc(sizeof(struct cplxS));
//set values for b
b->re = 1;
b->im = 2;
//preform your multiplication
b->re = a*(b->re); //update b with a*re
b->im = a*(b->im); //value b with a*im
//free node memory
free(b);
b = NULL;
}
Hope this helps!
You need to either cast the double as a complex number, and use the complex multiplication function (which presumably exists, or could/should be written by overloading * operator)
int main()
{
double a = 1.3;
cplx a_c = {1.3, 0}
cplx b = {1, 2};
c = a_c * b;
}
or actually perform the multiplication, either by building a definition for multiplication of reals and complex numbers (not shown), or just doing it yourself.
int main()
{
double a = 1.3;
cplx b = {1, 2};
cplx c = {b.re*a, b.im*a};
}
Is it valid C code to have flexible array members inside nested structs? So is my sample code below guarenteed to work as expected with a sane compiler?
#include <stdio.h>
#include <stdlib.h>
struct d {
char c;
int ns[];
};
struct c {
struct d d;
};
struct b {
struct c c;
};
struct a {
int n;
struct b b;
};
int main() {
const int n = 10;
struct a *pa = malloc(sizeof(*pa) + n * sizeof(pa->b.c.d.ns[0]));
pa->n = n;
pa->b.c.d.c = 1;
for (int i = 0; i < n; ++i) {
pa->b.c.d.ns[i] = i;
}
for (int i = 0; i < n; ++i) {
printf("%d\n", pa->b.c.d.ns[i] + pa->b.c.d.c);
}
free(pa);
}
It's not valid per the standard. I'm not sure how reliable it is in practice.
C11 (ISO/IEC 9899:2011), §6.7.2.1.3 says the following (emphasis mine):
A structure or union shall not contain a member with incomplete or function type (hence, a structure shall not contain an instance of itself, but may contain a pointer to an instance of itself), except that the last member of a structure with more than one named member may have incomplete array type; such a structure (and any union containing, possibly recursively, a member that is such a structure) shall not be a member of a structure or an element of an array.
Later on, §6.7.2.1.18 clarifies that the above is referring to flexible array members (FAMs):
As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member.
From some quick experimentation, GCC and Clang both add the trailing padding required to align the FAM properly even when the struct is nested, and only warn about structures with FAMs being members of other structures or arrays if -Wpedantic is passed, so take that as a sign that it'll probably work if you will :). It feels a bit hackish though.
Note that it probably wouldn't make sense to have the FAM anywhere but at the end. If you do
struct e {
struct d d;
int n;
} e;
, then e.d.ns[0] and e.n are likely to overlap in memory.
Try something like this;
struct d {
char c;
int ns[];
};
struct a {
int n;
int d_fam[];
};
int main() {
const int n = 10;
struct a *pa = malloc(offsetof (struct a, d_fam) + offsetof (stuct d, ns) + n * sizeof(int));
struct d *pd = pa + (uintptr_t) offsetof (struct a, d_fam);
pa->n = n;
pd->c = 1;
for (int i = 0; i < n; ++i) {
pd->ns[i] = i;
}
for (int i = 0; i < n; ++i) {
printf ("%d\n", pd->ns[i] + pd->c);
}
free(pa);
}
I'm trying to make an array of structs where each struct represents a celestial body.
I don't have that much experience with structs, which is why I decided to try to use them instead of a whole bunch of arrays. However, I keep on running into numerous different errors. I've tried to implement the techniques that I've seen on various threads and on StackOverflow (such as Array of structs in C and C - initialize array of structs), however not all of them were applicable.
Further information for those who have read this far: I don't need any of this to be dynamic, I know/define the size of everything beforehand. I also need this to be a global array as I'm accessing this in several different methods which have defined arguments (i.e. GLUT methods).
This is how I'm defining the struct in my header:
struct body
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
};
I have a list of other global variables that I'm defining before I define the interior of the struct, and one of those is the array of this struct (basically, if I'm being too unclear in my fogged speak, the line below is above the stuff above):
struct body bodies[n];
Just so you know, n is something that I've legitimately defined (i.e. #define n 1).
I use this array in several different methods, but the easiest and least space consuming one is a simplified form of my main. Here I initialize all of the variables in each of the structs, just to set the variables for certain before I modify them in some way:
int a, b;
for(a = 0; a < n; a++)
{
for(b = 0; b < 3; b++)
{
bodies[a].p[b] = 0;
bodies[a].v[b] = 0;
bodies[a].a[b] = 0;
}
bodies[a].mass = 0;
bodies[a].radius = 1.0;
}
The current error that I'm facing is nbody.c:32:13: error: array type has incomplete element type where line 32 is where I'm making the array of the structs.
One last clarification, by header I mean the space above int main(void) but in the same *.c file.
#include<stdio.h>
#define n 3
struct body
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
};
struct body bodies[n];
int main()
{
int a, b;
for(a = 0; a < n; a++)
{
for(b = 0; b < 3; b++)
{
bodies[a].p[b] = 0;
bodies[a].v[b] = 0;
bodies[a].a[b] = 0;
}
bodies[a].mass = 0;
bodies[a].radius = 1.0;
}
return 0;
}
this works fine. your question was not very clear by the way, so match the layout of your source code with the above.
Another way of initializing an array of structs is to initialize the array members explicitly. This approach is useful and simple if there aren't too many struct and array members.
Use the typedef specifier to avoid re-using the struct statement everytime you declare a struct variable:
typedef struct
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
}Body;
Then declare your array of structs. Initialization of each element goes along with the declaration:
Body bodies[n] = {{{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0},
{{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0},
{{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0}};
To repeat, this is a rather simple and straightforward solution if you don't have too many array elements and large struct members and if you, as you stated, are not interested in a more dynamic approach. This approach can also be useful if the struct members are initialized with named enum-variables (and not just numbers like the example above) whereby it gives the code-reader a better overview of the purpose and function of a structure and its members in certain applications.
So to put it all together by using malloc():
int main(int argc, char** argv) {
typedef struct{
char* firstName;
char* lastName;
int day;
int month;
int year;
}STUDENT;
int numStudents=3;
int x;
STUDENT* students = malloc(numStudents * sizeof *students);
for (x = 0; x < numStudents; x++){
students[x].firstName=(char*)malloc(sizeof(char*));
scanf("%s",students[x].firstName);
students[x].lastName=(char*)malloc(sizeof(char*));
scanf("%s",students[x].lastName);
scanf("%d",&students[x].day);
scanf("%d",&students[x].month);
scanf("%d",&students[x].year);
}
for (x = 0; x < numStudents; x++)
printf("first name: %s, surname: %s, day: %d, month: %d, year: %d\n",students[x].firstName,students[x].lastName,students[x].day,students[x].month,students[x].year);
return (EXIT_SUCCESS);
}
I think you could write it that way too. I am also a student so I understand your struggle. A bit late response but ok .
#include<stdio.h>
#define n 3
struct {
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
}bodies[n];
move
struct body bodies[n];
to after
struct body
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double mass;
};
Rest all looks fine.
Solution using pointers:
#include<stdio.h>
#include<stdlib.h>
#define n 3
struct body
{
double p[3];//position
double v[3];//velocity
double a[3];//acceleration
double radius;
double *mass;
};
int main()
{
struct body *bodies = (struct body*)malloc(n*sizeof(struct body));
int a, b;
for(a = 0; a < n; a++)
{
for(b = 0; b < 3; b++)
{
bodies[a].p[b] = 0;
bodies[a].v[b] = 0;
bodies[a].a[b] = 0;
}
bodies[a].mass = 0;
bodies[a].radius = 1.0;
}
return 0;
}
That error means that the compiler is not able to find the definition of the type of your struct before the declaration of the array of structs, since you're saying you have the definition of the struct in a header file and the error is in nbody.c then you should check if you're including correctly the header file.
Check your #include's and make sure the definition of the struct is done before declaring any variable of that type.
You can do it in a same manner as you create the array of numbers but wrap the element's values in braces like this ->
struct Wrestler studs[count] = {
{"John", "Cena"},
{"The", "Undertaker"},
{"The", "Big Show"},
{"The", "Rock"},
{"Triple", "H"},
{"Scott", "Hall"},
{"Roman", "Reings"},
{"Dean", "Ambrose"}};
Here is full code
#include <stdio.h>
struct Wrestler
{
char firstName[20];
char secondName[20];
};
void pIntro(struct Wrestler *s)
{
printf("Hi, I am %s %s.\n", s->firstName, s->secondName);
};
int main(int argc, char const *argv[])
{
#define count 8
struct Wrestler studs[count] = {
{"John", "Cena"},
{"The", "Undertaker"},
{"The", "Big Show"},
{"The", "Rock"},
{"Triple", "H"},
{"Scott", "Hall"},
{"Roman", "Reings"},
{"Dean", "Ambrose"}};
for (int i = 0; i < count; i++)
{
pIntro(&(studs[i]));
}
return 0;
}