How to set a constant value inside an array of structures? - c

typedef struct all{
int x;
int ast[5];
}ALL;
ALL x[5];
int main(void){
ALL y[5];
// ...
}
How will I be able to set a constant value to ast[5] so that all array variables will have the same value of ast[]?

typedef struct all {
int x;
int ast[5];
} ALL;
ALL x[5];
ALL constast = {0, {1, 2, 3, 4, 5}};
int main(void) {
ALL y[5] = {[0] = constast, [1] = constast, [2] = constast,
[3] = constast, [4] = constast};
// ...
}

I'm assuming from the tags that the question is for C and not C++.
You could have a function that takes the size of the struct array and returns a pointer to the start of the array, like this:
typedef struct my_struct{
int i;
int var[5];
} my_struct;
my_struct* init_my_struct(int size){
my_struct *ptr = malloc(size * sizeof(struct));
for(my_struct *i = ptr; (i - ptr) < size; i++)
i->var = // whatever value you want to assign to it
// or copy a static value to the the array element
}
Now you can use it in your code in this way:
my_struct *my_struct_ptr = init_my_struct(5); // values inited as required
The drawbacks of this approach are that you are moving from declaring an array to using memory on the heap.
Also, you cannot keep someone from creating an array of a certain size and using it with values being assigned to it the way you would want.

Related

How to insert a structure instance inside a structure type array in c?

What do I want to do?
I want to make an array of struct types and insert struct instances into it.
{"struct Matrix matrix1", "struct Matrix matrix2"}
What have I done till now?
I have created a function create_struct() that takes the necessary parameters for the struct and return a struct pointer.
typedef struct
{
size_t rows, columns;
int *table;
} mat;
mat *create_struct(int x, int y)
{
mat *data = (mat *)malloc(sizeof(*data));
data->table = malloc(sizeof(int[(x * y)]));
data->columns = y;
data->rows = x;
return data;
}
Then I created a pointer-to-object in this case struct and tried inserting struct instances with help of a for loop and the create_struct() function. But doing so the program crashes.
int main()
{
size_t dimensions[2][2] = {{3, 3}, {3, 2}};
mat *matrix;
for (size_t i = 0; i < 2; i++)
{
matrix[i] = create_struct(dimensions[i][0], dimensions[i][1]);
}
return 0;
}
I think the main issue is with this line.
matrix[i] = create_struct(dimensions[i][0], dimensions[i][1]);
First of all, the above will result in to compile error a value of type "mat *" cannot be assigned to an entity of type "mat"
So to solve this I did something like this. Which I think is completely vague. I might be wrong.
matrix[i] = *create_struct(dimensions[i][0], dimensions[i][1]);
What do I expect from the answers
The following should be the main point of focus:
Is it possible to do something like I'm doing?
Is there a better way or procedure to insert struct instances into a struct types array?
Provide information if you feel that I lack any conceptual knowledge.
Of course. Just allocate the memory for pointers to mat rather than dereferencing uninitialized pointer matrix. Alternatively use an array of pointer to mat.
int main()
{
size_t dimensions[2][2] = {{3, 3}, {3, 2}};
mat** matrix = calloc(2, sizeof *matrix);
// OR
// mat* matrix[2];
for (size_t i = 0; i < 2; i++)
{
matrix[i] = create_struct(dimensions[i][0], dimensions[i][1]);
}
return 0;
}

Sorting multiple arrays in the struct based on the ascending order of one array in C

I am trying to sort the multiple arrays based on the ascending order of one array.
Here is the example:
int a[10] = {55140, 32294, 33321, 64321, 55312}
float b[10] = {11.11, 202.22, 3213.21, 144.32, 1.32}
const char* c[10] = {+, -, -, -, +}
unsigned char* d[10] = {22DS3K, 1FGJ29, 21FD43, 98DS03, 56DK23}
Now, after arranging the array 'a' in ascending order I want to sort the other arrays. The output should look like as follows:
a[10] = {32294, 33321, 55140, 55312, 64321}
b[10] = {202.22, 3213.21, 11.11, 1.32, 144.32}
c[10] = {-, -, +, +, -}
d[10] = {1FGJ29, 21FD43, 22DS3K, 56DK23, 98DS03}
Arranging the ascending order works fine. But, I am unable to sort the other arrays. I woould like to create a function to use it in my main function. Pleased to hear some suggestions.
I have seen the below post, but did not help me.
Sorting an array based on another in C
Here is the code that I have tried:
struct Data{
int a[10];
float b[10];
const char* c[10];
unsigned char* d[10];
} data;
int data_a[10];
float data_b[10];
const char* data_c[10];
unsigned char* d[10];
void ascending(int *t; int N){
int i,j,tmp;
for(i=0;j<N;j++){
for(j=i+1;j<N;j++){
if(t[i] > t[j]){
tmp=t[i];
t[i]=t[j];
t[j]=tmp;
}}}}
int main(){
int i;
for(i=0;i<5;i++){
data.a[i] = data_a[i];
data.b[i] = data_b[i];
data.c[i] = data_c[i];
data.d[i] = data_d[i];
}
ascending(data.a, 5);
for(i=0;i<5;i++){
printf("Data is %d,%.2f,%s,%hhn\n", data.a[i],data.b[i],data.c[i],data.d[i]};
}}
May I know if I am missing something or doing something completely wrong?
Keeping such a set of arrays in synch is a nightmare.
What you seem to want is an array of structs instead of 5 separate arrays.
If I get you right, this is what would fit your needs better:
(Also your initializers don't really match the data type of your arrays c and d.)
typedef struct data_s {
int a;
float b;
const char *c;
const char *d;
} data_t;
data_t data[10] =
{
[0] = {.a=55140, .b=11.11, .c="+", .d="22DS3K"},
[1] = {.a=32294, .b=202.22, .c="-", .d="1FGJ29"},
[2] = {.a=33321, .b=3213.21, .c="-", .d="21FD43"},
[3] = {.a=64321, .b=144.32, .c="-", .d="98DS03"},
[4] = {.a=55312, .b=1.32, .c="+", .d="56DK23"}
};
Then you can sort (just use qsort) for member a of your struct and as you will swap whole structs at once, the corresponding other members will be sorted accordingly:
int compare_a(const void *data1, const void*data2)
{
return ((data_t*)data2)->a - ((data_t*)data1)->a;
}
int compare_d(const void *data1, const void*data2)
{
return strcmp(((data_t*)data1)->d, ((data_t*)data2)->d);
}
int main(void)
{
...
// optional:
// Populate the missing fields with some default data
size_t num_elem = sizeof(data)/sizeof(data[0]);
for (size_t i = 5; i < num_elem; i++)
{
data[i].a = (int)i * 111;
data[i].b = i * 1.11;
data[i].c = "none";
data[i].d = "";
}
// Sort for field a
qsort(data, num_elem, sizeof (data[0]), compare_a);
// Variant: Size unknown, use dynamic memory allocation
size_t num_elem2 = 123;
data_t *data2 = malloc(num_elem2 * sizeof (*data2));
for (size_t i = 0; i < num_elem; i++)
{
data2[i].a = (int)i * 111;
data2[i].b = i*1.11;
data2[i].c = "none";
data2[i].d = "";
}
// Sort for field d
qsort(data, num_elem, sizeof (data[0]), compare_d);
}

C incomplete Type in structs

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.

C language error: request for member ‘value’ in something not a structure or union

I got really confused why I can not use while loop to access the entire value for reading all of struct...Thank you guys... I think about 3 hours but have no clue. I do not know why does the value is not realized by the program, since I already defined that this is a struct.
#include <stdio.h>
struct card{
int isRed;
int hasLetter;
union{
int charValue;
int intValue;
}value;
};
typedef struct card typeCard;
int deckValue(typeCard *deck[])
{
int i = 0;
int sum = 0;
while(deck[i] != NULL){
sum += deck[i].value.intValue;
i += 1;
}
return sum;
}
int main()
{
int sum;
typeCard card1 = {.isRed = 1,.hasLetter = 0,.value.intValue = 200};
typeCard card2 = {.isRed = 100,.hasLetter = 0,.value.intValue = 200};
typeCard deck[] = {card1,card2,NULL};
sum = deckValue(deck);
printf("%d",sum);
return 0;
}
The problem is that the parameter to your function:
int deckValue(typeCard *deck[])
Doesn't match how you're using it:
sum += deck[i].value.intValue;
The function definition says that desk is an array of pointers to typeCard. So when you do deck[i].value it thinks that you have an array of typeCard.
You instead want:
sum += deck[i]->value.intValue;
This will dereference the pointer for the array element.
Also in main, you're not passing an array of pointers to typeCard:
typeCard deck[] = {card1,card2,NULL};
sum = deckValue(deck);
You're passing an array of typeCard. Since you want an array of pointers so you can use a NULL pointer as a sentinel, you need to change the definition to an array of pointers, and initialize the array elements accordingly:
typeCard *deck[] = {&card1, &card2, NULL};

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;
}

Resources