How make a Struct in C - c

I am currently trying to figure out how structs work in C.
I assume that this code is setting the values x and y for the respective position1, position2 to the assigned ones.
However, I keep getting the following error message:
error: expected '=', ',', ';', 'asm' or '__attribute__; before '.' token
Here is the code:
struct position {
int x;
int y;
} position1, position2;
position1.x = 60;
position1.y = 0;
position2.x = 60;
position2.y = 120;
Why is it throwing me that error?

You can initialize your global structs like this:
struct position {
int x;
int y;
} position1 = {60, 0}, position2 = {60, 120};
Or, with a little bit more clarity and designated initializers:
...
} position1 = {.x = 60, .y = 0},
position2 = {.x = 60, .y = 120};

Try:
#include <stdlib.h>
struct position_t {
int x;
int y;
};
int main()
{
struct position_t position1, position2;
position1.x = 60;
position1.y = 0;
position2.x = 60;
position2.y = 120;
return 0;
}
Another way is to use typedef to give the struct an alias:
#include <stdlib.h>
typedef struct position_t {
int x;
int y;
} position;
int main()
{
position position1, position2;
position1.x = 60;
position1.y = 0;
position2.x = 60;
position2.y = 120;
return 0;
}

It seems the problem is that you are trying to place these assignment statements outside a function. You may not do this. You may place only declarations outside a function.
So write the following way
struct position {
int x;
int y;
} position1 = { 60, 6 }, position2 = { .x = 60, .y = 120 };
Also inside a function you may use a compound literal to assign a value to an object of the structure.
Here is a demonstrative program
#include <stdio.h>
struct position {
int x;
int y;
} position1 = { 60, 6 }, position2 = { .x = 60, .y = 120 };
int main( void )
{
printf( "position1: { %d, %d }\n", position1.x, position1.y );
printf( "position2: { %d, %d }\n", position2.x, position2.y );
position1 = ( struct position ) { 10, 20 };
position2 = ( struct position ) { .x = 30, .y = 40 };
printf( "position1: { %d, %d }\n", position1.x, position1.y );
printf( "position2: { %d, %d }\n", position2.x, position2.y );
position1.x = 50;
position1.y = 60;
position2.x = 70;
position2.y = 80;
printf( "position1: { %d, %d }\n", position1.x, position1.y );
printf( "position2: { %d, %d }\n", position2.x, position2.y );
return 0;
}
Its output is
position1: { 60, 6 }
position2: { 60, 120 }
position1: { 10, 20 }
position2: { 30, 40 }
position1: { 50, 60 }
position2: { 70, 80 }

You just have to put all the code after the struct declaration inside the main() function and it does not throw any error. Like that:
#include <stdio.h>
struct position {
int x;
int y;
} position1, position2;
int main(void) {
position1.x = 60;
position1.y = 0;
position2.x = 60;
position2.y = 120;
printf("%d\n", position2.y); // this line is just for testing
}

Related

How do you pass a struct pointer through a function?

#define WIDTH_DATA 20
typedef struct
{
float inhalt;
unsigned int nr;
int status;
} Paket;
typedef struct
{
Paket Eingang[WIDTH_DATA];
int laenge;
float Ablage_A[WIDTH_DATA];
float Ablage_B[WIDTH_DATA];
} Data_t;
#include <stdio.h>
int pruefe_status(int i1)
{
if (i1==0)
{
return 0;
}
else
{
return 1;
}
}
int vergleiche(unsigned int i1, unsigned int i2)
{
if (i1<i2)
{
return 1;
}
else
{
return 0;
}
}
int verteile_Pakete(Data_t *dv){
int counterA=0,counterB=0;
for (int i=0; i<WIDTH_DATA; i++)
{
if (pruefe_status(dv->Eingang[i].status)==0)
{
if(vergleiche(dv->Eingang[i].nr,5000))
{
dv->Ablage_A[counterA] = dv->Eingang[i].inhalt;
counterA++;
}
else{
dv->Ablage_B[counterB] = dv->Eingang[i].inhalt;
counterB++;
}
}
}
return counterB + counterA;
}
int main(void)
{
// Beispiel für testdv1:
Data_t testdv1 = {{{12.5, 6067, 1}, {45.7, 3002, 0}, {56.0, 3456, 1}}, 3, {0}, {0}};
Data_t testdv2 = {{{12.5, 6067, 0}, {45.7, 3002, 1}, {56.0, 3456, 1}}, 3, {0}, {0}};
Data_t testdv3 = {{{12.5, 6067, 0}, {45.7, 7002, 0}, {56.0, 6456, 0}, {13.5, 6067, 0}, {1.7, 7772, 0}, {156.0, 5656, 0}}, 6, {0}, {0}};
int Anzahl_pakete1=0;
int Anzahl_pakete2=0;
int Anzahl_pakete3=0;
Anzahl_pakete1 = verteile_Pakete(&testdv1);
Anzahl_pakete2 = verteile_Pakete(&testdv2);
Anzahl_pakete3 = verteile_Pakete(&testdv3);
printf("test 1:\nAnzahl bearbeitenden Pakete:%f\n",Anzahl_pakete1);
for (int i=0;i<10;i++)
{
printf("AblageA %d: %f\nAblageB %d: %f\n",i,testdv1.Ablage_A[i],i,testdv1.Ablage_B[i]);
}
printf("test 2:\nAnzahl bearbeitenden Pakete:%f\n",Anzahl_pakete2);
for (int i=0;i<10;i++)
{
printf("AblageA %d: %f\nAblageB %d: %f\n",i,testdv2.Ablage_A[i],i,testdv2.Ablage_B[i]);
}
printf("test 3:\nAnzahl bearbeitenden Pakete:%f\n",Anzahl_pakete3);
for (int i=0;i<10;i++)
{
printf("AblageA %d: %f\nAblageB %d: %f\n",i,testdv3.Ablage_A[i],i,testdv3.Ablage_B[i]);
}
return(0);
}
Why is the data in testdv1 or 2 or 3 not going in the function verteile_Pakete?.
I tried to pass the address of these test variables to the function as a pointer but the values get lost and don't get through when I try to debug. So everything comes out as 0.
How can I solve this?
When you look at the compiler output (https://godbolt.org/z/jM43PY916) it warns you that you try to output the integer count as float.
Replace %f with %d in your format strings for integers and it works.

What is a smart way to recognize what struct contains the value you're working on?

EDIT: Full code has now been posted so u can compile.
So we're a few first semester software students kind of stuck on a problem regarding structs in c. Stack overflow has helped me so many times already, so figured I'd actually try asking this time, as i couldn't seem to find what im looking for.
Our logic (see code below):
Main calls empty_trash
empty_trash (in its parameter) calls compare_trash
Compare trash parses through 4 areas (structs)
Compare trash checks if the average of our data is over a margin, if so
checks if that average is higher than firstly our empty struct,
which presumably has 0 average, and then if a higher is found that
one. This leaves us with the index of the struct with the highest
average
Compare trash returns this struct to empty trash, and an int
pointer of the index to main.
empty trash then goes through the subareas and checks their average of data and resets the ones over margin2
we return the reset area to main
in main we have an array of our structs 1-4. We assign the area returned from empty trash to arrayofstructs[index pointed back]
In our minds the logic makes sense, but it seems it's not working as our program crashes at the line in main. We think it's because we don't assign the struct correctly in main, but not 100% sure.
We're kinda baffled as both of these functions work fine on their own when we tested them seperately, but together they do not.
Any help would be much appreciated <3
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define MARGIN 70
#define MARGIN2 30
#define SIZE 5
struct subarea
{
int co2_cost, time;
double average, sensorData[SIZE];
};
struct area
{
struct subarea sub_area1, sub_area2, sub_area3, sub_area4;
double average;
};
struct area simmulated_days(struct area area, int lower_random, int upper_random);
struct area average_trash(struct area area);
struct area sensor_data_start(struct area area1);
struct area compare_trash_to_empty(struct area area1, struct area area2, struct area area3, struct area area4, int *);
struct area empty_trash(struct area chosen_area, int *co2_counter_p, int *time_counter_p);
int main(void)
{
int co2_counter, time_counter;
int day_counter = 0;
int *co2_counter_p = &co2_counter;
int *time_counter_p = &time_counter;
int area_number;
srand(time(NULL));
struct subarea subarea1_1 = {50, 50, 0, {}};
struct subarea subarea1_2 = {50, 50, 0, {}};
struct subarea subarea1_3 = {50, 50, 0, {}};
struct subarea subarea1_4 = {50, 50, 0, {}};
struct area area1 = {subarea1_1, subarea1_2, subarea1_3, subarea1_4, 0};
struct subarea subarea2_1 = {50, 50, 0, {}};
struct subarea subarea2_2 = {50, 50, 0, {}};
struct subarea subarea2_3 = {50, 50, 0, {}};
struct subarea subarea2_4 = {50, 50, 0, {}};
struct area area2 = {subarea2_1, subarea2_2, subarea2_3, subarea2_4, 0};
struct subarea subarea3_1 = {50, 50, 0, {}};
struct subarea subarea3_2 = {50, 50, 0, {}};
struct subarea subarea3_3 = {50, 50, 0, {}};
struct subarea subarea3_4 = {50, 50, 0, {}};
struct area area3 = {subarea3_1, subarea3_2, subarea3_3, subarea3_4, 0};
struct subarea subarea4_1 = {50, 50, 0, {}};
struct subarea subarea4_2 = {50, 50, 0, {}};
struct subarea subarea4_3 = {50, 50, 0, {}};
struct subarea subarea4_4 = {50, 50, 0, {}};
struct area area4 = {subarea4_1, subarea4_2, subarea4_3, subarea4_4, 0};
struct area useless_area = {};
struct area all_areas[5] = {useless_area, area1, area2, area3, area4};
struct area local_area = {};
area1 = sensor_data_start(area1);
area2 = sensor_data_start(area2);
area3 = sensor_data_start(area3);
area4 = sensor_data_start(area4);
int running = 1;
while (running)
{
area1 = simmulated_days(area1, 7, 10);
area2 = simmulated_days(area2, 4, 7);
area3 = simmulated_days(area3, 9, 12);
area4 = simmulated_days(area4, 6, 9);
for (int i = 0; i < SIZE; i++)
{
printf("%lf | %lf | %lf | %lf |\n", area1.sub_area1.sensorData[i], area2.sub_area1.sensorData[i], area3.sub_area1.sensorData[i], area4.sub_area1.sensorData[i]);
}
day_counter++;
printf("Day %d\n", day_counter);
area1 = average_trash(area1);
area2 = average_trash(area2);
area3 = average_trash(area3);
area4 = average_trash(area4);
printf("hihi\n");
all_areas[area_number] = empty_trash(compare_trash_to_empty(area1, area2, area3, area4, &area_number), co2_counter_p, time_counter_p);
printf("titi\n");
for (int i = 0; i < SIZE; i++)
{
printf("Local area %lf\t", local_area.sub_area1.sensorData[i]);
}
printf("\n");
if (day_counter == 2)
{
running = 0;
}
}
}
struct area simmulated_days(struct area area, int lower_random, int upper_random)
{
for (int i = 0; i < SIZE; i++)
{
area.sub_area1.sensorData[i] += ((rand() % (upper_random - lower_random + 1)) + lower_random);
area.sub_area2.sensorData[i] += ((rand() % (upper_random - lower_random + 1)) + lower_random);
area.sub_area3.sensorData[i] += ((rand() % (upper_random - lower_random + 1)) + lower_random);
area.sub_area4.sensorData[i] += ((rand() % (upper_random - lower_random + 1)) + lower_random);
}
return area;
}
//Average Trash Function
struct area average_trash(struct area area)
{
double sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0;
for (int i = 0; i < SIZE; i++)
{
sum1 += area.sub_area1.sensorData[i];
sum2 += area.sub_area2.sensorData[i];
sum3 += area.sub_area3.sensorData[i];
sum4 += area.sub_area4.sensorData[i];
}
area.sub_area1.average = sum1 / SIZE;
area.sub_area2.average = sum2 / SIZE;
area.sub_area3.average = sum3 / SIZE;
area.sub_area4.average = sum4 / SIZE;
area.average = (area.sub_area1.average + area.sub_area2.average + area.sub_area3.average + area.sub_area4.average) / 4;
return area;
}
struct area sensor_data_start(struct area area1)
{
double x = 75;
for (int i = 0; i < SIZE; i++)
{
area1.sub_area1.sensorData[i] = x;
area1.sub_area2.sensorData[i] = x;
area1.sub_area3.sensorData[i] = x;
area1.sub_area4.sensorData[i] = x;
}
return area1;
}
struct area compare_trash_to_empty(struct area area1, struct area area2, struct area area3, struct area area4, int *area_number_p)
{
struct area local_area = {};
int i, highBlock = 0;
struct area block[5] = {local_area, area1, area2, area3, area4};
for (i = 1; i <= 4; i++)
{
if (block[i].average >= MARGIN)
{
if (block[i].average > block[highBlock].average)
{
highBlock = i;
}
}
}
*area_number_p = highBlock;
return block[highBlock];
}
struct area empty_trash(struct area chosen_area, int *co2_counter_p, int *time_counter_p)
{
int co2_counter = 0;
int time_counter = 0;
if (chosen_area.sub_area1.average > MARGIN2)
{
co2_counter += chosen_area.sub_area1.co2_cost;
time_counter += chosen_area.sub_area1.time;
chosen_area.sub_area1.average = 0;
for (int i = 0; i < SIZE; i++)
{
chosen_area.sub_area1.sensorData[i] = 0;
printf("ET %lf\t", chosen_area.sub_area1.sensorData[i]);
}
printf("\n");
}
if (chosen_area.sub_area2.average > MARGIN2)
{
co2_counter += chosen_area.sub_area2.co2_cost;
time_counter += chosen_area.sub_area2.time;
chosen_area.sub_area2.average = 0;
for (int i = 0; i < SIZE; i++)
{
chosen_area.sub_area2.sensorData[i] = 0;
}
}
if (chosen_area.sub_area3.average > MARGIN2)
{
co2_counter += chosen_area.sub_area3.co2_cost;
time_counter += chosen_area.sub_area3.time;
chosen_area.sub_area3.average = 0;
for (int i = 0; i < SIZE; i++)
{
chosen_area.sub_area3.sensorData[i] = 0;
}
}
if (chosen_area.sub_area4.average > MARGIN2)
{
co2_counter += chosen_area.sub_area4.co2_cost;
time_counter += chosen_area.sub_area4.time;
chosen_area.sub_area4.average = 0;
for (int i = 0; i < SIZE; i++)
{
chosen_area.sub_area4.sensorData[i] = 0;
}
}
*co2_counter_p = co2_counter;
*time_counter_p = time_counter;
return chosen_area;
}
My original comment:
Side note: Whenever I see (e.g.) v1 v2 v3 v4 v5 I want to replace it with an array v[5]. So, in struct area, you want: struct subarea sub_area[5]; This will greatly simplify your code. You already do this in main –
Craig Estey
Your response:
#Craig Estey Ye don't have a huge experience with debuggers yet, usually just use printfs, but sounds very helpful so ill youtube a guide side note: very helpful we didn't foresee this at first but would simplify so much, ty4input –
Thybo
I've done better(?) I've done the preliminary restructuring of your code. I believe this will be helpful to others in addition to yourselves.
I'm sorry, but (and I'm saying this with kindness), the code needs a lot of restructuring. The sheer [needless] complexity could be masking numerous bugs.
Things to note:
Passing a struct by value is hazardous. It is legal, but it makes the code complicated. Passing by pointer is 99.44% of the time better. You can just modify the given struct "in-place" rather than having to return it [again, by value].
Learn about iterating through an array by using a pointer to the "current" element instead of an index. You'll see this in the FORALL loop below.
Don't "replicate" code. Notice what happens when using arrays. Instead of (e.g) four copies of the code, we have one
Instead of 4 areas (e.g. area1, area2, area3, area4), if we had 10,000 areas. Would you replicate the code 10,000 times as was done in (e.g.) empty_trash?
I added typedef for your two struct to simplify things a bit.
I've added a few advanced techniques, such as the use of the FORALL macro to traverse arrays.
I've used preprocessor conditionals to denote old code vs new:
#if 0
// old code
#else
// new code
#endif
I've done some/most of the editing. I've compiled it. I could have made a zillion mistakes. But, it should give you the idea:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define MARGIN 70
#define MARGIN2 30
#define SIZE 5
#define NAREA 4
typedef struct subarea {
int co2_cost, time;
double average, sensorData[SIZE];
} subarea_t;
typedef struct area {
#if 0
struct subarea sub_area1, sub_area2, sub_area3, sub_area4;
#else
subarea_t sub_area[NAREA];
#endif
double average;
} area_t;
#define COUNTOF(_arr) \
(sizeof(_arr) / sizeof(_arr[0]))
#define FORALL(_ptr,_arr) \
__typeof__(_arr[0]) *_ptr = &_arr[0]; _ptr < &_arr[COUNTOF(_arr)]; ++_ptr
void
simulated_days(area_t *area, int lower_random, int upper_random)
{
for (FORALL(sub,area->sub_area)) {
for (FORALL(data,sub->sensorData)) {
*data += ((rand() % (upper_random - lower_random + 1)) +
lower_random);
}
}
}
//Average Trash Function
void
average_trash(area_t *area)
{
double sum[NAREA] = { 0 };
int i;
#if 0
for (int i = 0; i < SIZE; i++) {
sub[i] = a
sum1 += area.sub_area1.sensorData[i];
sum2 += area.sub_area2.sensorData[i];
sum3 += area.sub_area3.sensorData[i];
sum4 += area.sub_area4.sensorData[i];
}
#else
for (FORALL(sub,area->sub_area), ++i) {
i = 0;
for (FORALL(data,sub->sensorData), ++i)
sum[i] += *data;
}
#endif
#if 0
area.sub_area1.average = sum1 / SIZE;
area.sub_area2.average = sum2 / SIZE;
area.sub_area3.average = sum3 / SIZE;
area.sub_area4.average = sum4 / SIZE;
#else
i = 0;
for (FORALL(sub,area->sub_area), ++i)
sub->average = sum[i] / SIZE;
#endif
#if 0
area.average = (area.sub_area1.average +
area.sub_area2.average +
area.sub_area3.average +
area.sub_area4.average) / 4;
#else
area->average = 0;
for (FORALL(sub,area->sub_area))
area->average += sub->average;
area->average /= NAREA;
#endif
}
#if 0
area_t
sensor_data_start(area_t area1)
{
double x = 75;
for (int i = 0; i < SIZE; i++) {
area1.sub_area1.sensorData[i] = x;
area1.sub_area2.sensorData[i] = x;
area1.sub_area3.sensorData[i] = x;
area1.sub_area4.sensorData[i] = x;
}
return area1;
}
#else
void
sensor_data_start(area_t *area)
{
double x = 75;
for (FORALL(sub,area->sub_area)) {
for (FORALL(data,sub->sensorData))
*data = x;
}
}
#endif
#if 0
area_t
compare_trash_to_empty(area_t area1, area_t area2, area_t area3, area_t area4, int *area_number_p)
{
area_t local_area = { };
int i,
highBlock = 0;
area_t block[5] = { local_area, area1, area2, area3, area4 };
for (i = 1; i <= 4; i++) {
if (block[i].average >= MARGIN) {
if (block[i].average > block[highBlock].average) {
highBlock = i;
}
}
}
*area_number_p = highBlock;
return block[highBlock];
}
#else
area_t *
compare_trash_to_empty(const area_t *blocks, area_t *all_areas)
{
area_t local_area = { };
int i, highBlock = 0;
#if 0
area_t block[5] = { local_area, area1, area2, area3, area4 };
#else
const area_t *block;
#endif
for (i = 1; i < NAREA; ++i) {
block = &blocks[i];
if (block->average >= MARGIN) {
if (block->average > blocks[highBlock].average)
highBlock = i;
}
}
all_areas[highBlock] = blocks[highBlock];
return &all_areas[highBlock];
}
#endif
#if 0
area_t
empty_trash(area_t chosen_area, int *co2_counter_p, int *time_counter_p)
{
int co2_counter = 0;
int time_counter = 0;
if (chosen_area.sub_area1.average > MARGIN2) {
co2_counter += chosen_area.sub_area1.co2_cost;
time_counter += chosen_area.sub_area1.time;
chosen_area.sub_area1.average = 0;
for (int i = 0; i < SIZE; i++) {
chosen_area.sub_area1.sensorData[i] = 0;
printf("ET %lf\t", chosen_area.sub_area1.sensorData[i]);
}
printf("\n");
}
if (chosen_area.sub_area2.average > MARGIN2) {
co2_counter += chosen_area.sub_area2.co2_cost;
time_counter += chosen_area.sub_area2.time;
chosen_area.sub_area2.average = 0;
for (int i = 0; i < SIZE; i++) {
chosen_area.sub_area2.sensorData[i] = 0;
}
}
if (chosen_area.sub_area3.average > MARGIN2) {
co2_counter += chosen_area.sub_area3.co2_cost;
time_counter += chosen_area.sub_area3.time;
chosen_area.sub_area3.average = 0;
for (int i = 0; i < SIZE; i++) {
chosen_area.sub_area3.sensorData[i] = 0;
}
}
if (chosen_area.sub_area4.average > MARGIN2) {
co2_counter += chosen_area.sub_area4.co2_cost;
time_counter += chosen_area.sub_area4.time;
chosen_area.sub_area4.average = 0;
for (int i = 0; i < SIZE; i++) {
chosen_area.sub_area4.sensorData[i] = 0;
}
}
*co2_counter_p = co2_counter;
*time_counter_p = time_counter;
return chosen_area;
}
#else
void
empty_trash(area_t *chosen_area, int *co2_counter_p, int *time_counter_p)
{
int co2_counter = 0;
int time_counter = 0;
for (FORALL(sub,chosen_area->sub_area)) {
if (sub->average > MARGIN2) {
co2_counter += sub->co2_cost;
time_counter += sub->time;
for (FORALL(data,sub->sensorData))
*data = 0;
}
}
*co2_counter_p = co2_counter;
*time_counter_p = time_counter;
}
#endif
int
main(void)
{
int co2_counter, time_counter;
int day_counter = 0;
int *co2_counter_p = &co2_counter;
int *time_counter_p = &time_counter;
int area_number;
srand(time(NULL));
#if 0
subarea_t subarea1_1 = { 50, 50, 0, {} };
subarea_t subarea1_2 = { 50, 50, 0, {} };
subarea_t subarea1_3 = { 50, 50, 0, {} };
subarea_t subarea1_4 = { 50, 50, 0, {} };
area_t area1 = { subarea1_1, subarea1_2, subarea1_3, subarea1_4, 0 };
subarea_t subarea2_1 = { 50, 50, 0, {} };
subarea_t subarea2_2 = { 50, 50, 0, {} };
subarea_t subarea2_3 = { 50, 50, 0, {} };
subarea_t subarea2_4 = { 50, 50, 0, {} };
area_t area2 = { subarea2_1, subarea2_2, subarea2_3, subarea2_4, 0 };
subarea_t subarea3_1 = { 50, 50, 0, {} };
subarea_t subarea3_2 = { 50, 50, 0, {} };
subarea_t subarea3_3 = { 50, 50, 0, {} };
subarea_t subarea3_4 = { 50, 50, 0, {} };
area_t area3 = { subarea3_1, subarea3_2, subarea3_3, subarea3_4, 0 };
subarea_t subarea4_1 = { 50, 50, 0, {} };
subarea_t subarea4_2 = { 50, 50, 0, {} };
subarea_t subarea4_3 = { 50, 50, 0, {} };
subarea_t subarea4_4 = { 50, 50, 0, {} };
area_t area4 = { subarea4_1, subarea4_2, subarea4_3, subarea4_4, 0 };
#else
area_t areamain[NAREA];
for (FORALL(area,areamain)) {
for (FORALL(sub,area->sub_area)) {
sub->co2_cost = 50;
sub->time = 50;
sub->average = 50;
for (FORALL(data,sub->sensorData))
*data = 0.0;
}
}
#endif
#if 0
area_t useless_area = { };
area_t all_areas[5] = { useless_area, area1, area2, area3, area4 };
#else
area_t *all_areas = areamain;
#endif
area_t local_area = { };
#if 0
area1 = sensor_data_start(area1);
area2 = sensor_data_start(area2);
area3 = sensor_data_start(area3);
area4 = sensor_data_start(area4);
#else
for (FORALL(area,areamain))
sensor_data_start(area);
#endif
int running = 1;
while (running) {
simulated_days(&areamain[0], 7, 10);
simulated_days(&areamain[1], 4, 7);
simulated_days(&areamain[2], 9, 12);
simulated_days(&areamain[3], 6, 9);
#if 0
for (int i = 0; i < SIZE; i++) {
printf("%lf | %lf | %lf | %lf |\n",
area1.sub_area1.sensorData[i],
area2.sub_area1.sensorData[i],
area3.sub_area1.sensorData[i],
area4.sub_area1.sensorData[i]);
}
#else
for (int i = 0; i < SIZE; i++) {
for (FORALL(area,areamain))
printf("%lf |",area->sub_area[i]);
printf("\n");
}
#endif
day_counter++;
printf("Day %d\n", day_counter);
#if 0
area1 = average_trash(area1);
area2 = average_trash(area2);
area3 = average_trash(area3);
area4 = average_trash(area4);
#else
for (FORALL(area,areamain))
average_trash(area);
#endif
printf("hihi\n");
#if 0
all_areas[area_number] =
empty_trash(compare_trash_to_empty(area1, area2, area3, area4,
&area_number), co2_counter_p, time_counter_p);
#else
area_t *area_out = compare_trash_to_empty(areamain,all_areas);
empty_trash(area_out, co2_counter_p, time_counter_p);
#endif
printf("titi\n");
#if 0
for (int i = 0; i < SIZE; i++) {
printf("Local area %lf\t", local_area.sub_area1.sensorData[i]);
}
printf("\n");
#else
do {
subarea_t *sub = area_out->sub_area;
printf("Local area ");
for (FORALL(data,sub->sensorData))
printf("%f\t", *data);
printf("\n");
} while (0);
#endif
if (day_counter == 2) {
running = 0;
}
}
}

Why IsKeyDown always returns true?

I was working in a University C project (first sem), in which our group wanted to make a simple pong game, we decided to use raylib, as it seemed easy. But here is the problem, in the following code:
void UpdatePad(Pad* pad)
{
int height = GetScreenHeight();
if (IsKeyDown(pad->Scheme.DownButton)) {
printf("Down = %d\n", pad->Scheme.DownButton);
pad->Position.y += GetFrameTime() * pad->Speed;
if ( pad->Position.y + pad->Size.y/2 > height ) {
pad->Position.y = height - pad->Size.y /2;
}
}
if (IsKeyDown(pad->Scheme.UpButton)) {
printf("Up = %d\n", pad->Scheme.UpButton);
pad->Position.y -= GetFrameTime() * pad -> Speed;
if (pad->Position.y - pad->Size.y/2 < 0 ) {
pad->Position.y = pad->Size.y /2;
}
}
}
The function IsKeyDown of raylib always returns true, whatever I do. Even if I replace pad->Scheme.DownButton to KEY_UP or something, it always returns true and executes the code block, Is there any solution for this?
Full script is:
#include <raylib.h>
#include <stdio.h>
#include "pad.h"
#include "main.h"
void DrawPad(Pad* pad);
void UpdatePad(Pad* pad);
void Update();
void DrawUpdate();
void Loop();
int main()
{
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "Table Tennis");
SetTargetFPS(12);
Loop();
return 0;
}
void Loop()
{
while (!WindowShouldClose()) {
DrawUpdate();
}
}
void UpdatePad(Pad* pad)
{
int height = GetScreenHeight();
if (IsKeyDown(pad->Scheme.DownButton)) {
printf("Down = %d\n", pad->Scheme.DownButton);
pad->Position.y += GetFrameTime() * pad->Speed;
if ( pad->Position.y + pad->Size.y/2 > height ) {
pad->Position.y = height - pad->Size.y /2;
}
}
if (IsKeyDown(pad->Scheme.UpButton)) {
printf("Up = %d\n", pad->Scheme.UpButton);
pad->Position.y -= GetFrameTime() * pad -> Speed;
if (pad->Position.y - pad->Size.y/2 < 0 ) {
pad->Position.y = pad->Size.y /2;
}
}
}
void DrawPad(Pad* pad)
{
DrawRectangle(pad->Position.x, pad->Position.y - (pad->Size.y /2), pad->Size.x, pad->Size.y, WHITE);
}
void DrawUpdate()
{
const char* scoreLeft = TextFormat("%d", 10);
int scoreSizeLeft = MeasureText(scoreLeft, 20);
InputScheme Input = { .DownButton = KEY_S, .UpButton = KEY_W };
Vector2 paddySize = { .x = 5, .y = 50 };
Vector2 paddyPos = { .x = GetScreenWidth() - paddySize.x , .y = GetScreenHeight() - paddySize.y };
Pad pad = { .Size = paddySize, .Speed = 50, .Scheme = Input , .Position = paddyPos };
Vector2 from = {.x = (GetScreenWidth() / (float) 2), .y = 5};
Vector2 to = { .x = (GetScreenWidth() / (float) 2), .y = ( GetScreenHeight() - (float) 5 ) };
UpdatePad(&pad);
BeginDrawing();
ClearBackground(BLACK);
DrawLineEx(from, to, 2, LIGHTGRAY);
DrawText(scoreLeft, (GetScreenWidth()/2) - 10 -scoreSizeLeft, 10, 20, LIGHTGRAY);
DrawPad(&pad);
EndDrawing();
}
The pad is:-
#include <raylib.h>
typedef struct {
int UpButton;
int DownButton;
} InputScheme;
typedef struct {
InputScheme Scheme;
int Score;
float Speed;
Vector2 Position;
Vector2 Size;
} Pad;

Copy array's data with memmove function

I wrote my implementation of vector ( dynamicly growing array) for integer type. And I was faced with a problem when using memmove and memcpy functions for data reallocation goals. Memmmove and memcpy functions work as not expected. So i replaced it with for and now it works properly. But what is the why memove works this way ?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct vector {
int v_size;
int v_length;
int* v_data;
} vector;
typedef vector *vect;
vect
new_vector(int size) {
vect tmp = (vector*)malloc(sizeof(vector));
tmp->v_size = size;
tmp->v_length = 0;
tmp->v_data = (int*)malloc(sizeof(int) * size);
return tmp;
}
void
add_velem(vect tmp, int elem) {
if(tmp->v_length != tmp->v_size) {
tmp->v_data[tmp->v_length] = elem;
tmp->v_length += 1;
} else {
tmp->v_size = tmp->v_size * 2;
tmp->v_length += 1;
int *new_vector = (int*)malloc(sizeof(int) * tmp->v_size);
memmove(new_vector, tmp->v_data, tmp->v_length); // GOT INPUT LIKE THIS:
// 500, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
// ALOT OF ZERO
/*
for(int i = 0; i < tmp->v_length; i++) {
new_vector[i] = tmp->v_data[i];
}*/ // BUT GOT RIGHT INPUT WHEN USING FOR. WHAT IS THE REASON?
free(tmp->v_data);
tmp->v_data = new_vector;
tmp->v_data[tmp->v_length - 1] = elem;
}
return;
}
int
get_vlength(vect tmp) {
return tmp->v_length;
}
int
get_vsize(vect tmp) {
return tmp->v_size;
}
int
get_velem(vect tmp, int elem) {
if(tmp->v_data == NULL) {
fprintf(stderr, "Index out of range!\n");
}else if(elem >= tmp->v_length) {
fprintf(stderr, "Index is out of range!\n");
return -1;
}
return tmp->v_data[elem];
}
void
delete_vector(vect tmp) {
free(tmp->v_data);
tmp->v_data = NULL;
free(tmp);
tmp = NULL;
}
int
main(void) {
vect example = new_vector(10);
printf("lenth of vector is %d\n", get_vlength(example));
add_velem(example, 500);
printf("element %d is pushed into vector\n", 500);
printf("size of vector is %d and\nlength of vector is %d\n", get_vsize(example), get_vlength(example));
int velem = get_velem(example, 0);
printf("elem 0 of vector is %d\n", velem);
for(int i = 1; i < 30; i++) {
add_velem(example, i);
}
printf("length of vector is %d now\n", get_vlength(example));
for(int i = 0; i < get_vlength(example); i++) {
printf("%d, ", get_velem(example, i));
}
delete_vector(example);
return 0;
}

Pointer problem using header file with struct/array, resulting in multiple defenitions error (C)

I have a program (knapsack, optimized for returning the highest value solution with the least weight) for which I want to use external files for the typedef and struct data.
But I can't get it working, somewhere I am messing up with the pointers. I get an 'multiple definition' error or when I change it, I get an 'xxx not declared' error...
/tmp/ccMy5Yw0.o:(.data+0x0): multiple definition of `item1'
Any help on pointing out my thinking mistake in greatly appreciated.
(I compiled online # https://www.onlinegdb.com/)
It did work when I had everything in one file, but after splitting it in different files I can't get it working...
main.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "defs.h"
#include "data.c"
item_t *items[ITEMS_SIZE] = { &item1, &item2, &item3, &item4, &item5, &item6, &item7, &item8, &item9, &item10 };
int *knapsack (item_t * items, int n, int w)
{
int h, h_i, h_j, i, j, a, b, *mm, **m, *s;
mm = calloc ((n + 1) * (w + 1), sizeof (int));
m = malloc ((n + 1) * sizeof (int *));
m[0] = mm;
h = m[0][0];
h_i = 0;
h_j = 0;
for (i = 1; i <= n; i++)
{
m[i] = &mm[i * (w + 1)];
for (j = 0; j <= w; j++)
{
if (items[i - 1].weight > j)
{
m[i][j] = m[i - 1][j];
}
else
{
a = m[i - 1][j];
b = m[i - 1][j - items[i - 1].weight] + items[i - 1].value;
m[i][j] = a > b ? a : b;
if (m[i][j] > h)
{
h = m[i][j];
h_i = i;
h_j = j;
}
}
printf ("%d\t%d\t%d\n", h, h_i, h_j);
}
}
s = calloc (n, sizeof (int));
for (i = h_i, j = h_j; i > 0; i--)
{
if (m[i][j] > m[i - 1][j])
{
s[i - 1] = 1;
j -= items[i - 1].weight;
}
}
free (mm);
free (m);
return s;
}
int main ()
{
int i, n, tw = 0, tv = 0, *s;
for (i = 0; i < 10; i++)
{
if (items[i]->SwitchOn)
{
items[i]->value = items[i]->value;
}
else
{
items[i]->value = 0;
}
}
n = sizeof (items) / sizeof (item_t);
s = knapsack (items, n, 690);
for (i = 0; i < n; i++)
{
if (s[i])
{
printf ("%-22s %5d %5d\n", items[i]->name, items[i]->weight,
items[i]->value);
tw += items[i]->weight;
tv += items[i]->value;
}
}
printf ("%-22s %5d %5d\n", "totals:", tw, tv);
return 0;
}
defs.h
#ifndef SYSTEMDEFS_H_INCLUDED
#define SYSTEMDEFS_H_INCLUDED
#define ITEMS_SIZE 10
typedef struct Item
{
char name[40];
int weight;
int value;
bool SwitchOn;
} item_t;
extern item_t item1;
extern item_t item2;
extern item_t item3;
extern item_t item4;
extern item_t item5;
extern item_t item6;
extern item_t item7;
extern item_t item8;
extern item_t item9;
extern item_t item10;
#endif
data.c
#include <stdbool.h>
#include "defs.h"
item_t item1 =
{
.name = "part1",
.weight = 25,
.value = 8,
.SwitchOn = false,
};
item_t item2 =
{
.name = "part2",
.weight = 40,
.value = 2,
.SwitchOn = true,
};
item_t item3 =
{
.name = "part3",
.weight = 60,
.value = 7,
.SwitchOn = false,
};
item_t item4 =
{
.name = "part4",
.weight = 100,
.value = 6,
.SwitchOn = false,
};
item_t item5 =
{
.name = "part5",
.weight = 150,
.value = 2,
.SwitchOn = true,
};
item_t item6 =
{
.name = "part6",
.weight = 380,
.value = 10,
.SwitchOn = true,
};
item_t item7 =
{
.name = "part7",
.weight = 850,
.value = 2,
.SwitchOn = false,
};
item_t item8 =
{
.name = "part8",
.weight = 75,
.value = 15,
.SwitchOn = true,
};
item_t item9 =
{
.name = "part9",
.weight = 800,
.value = 1,
.SwitchOn = false,
};
item_t item10 =
{
.name = "part10",
.weight = 75,
.value = 8,
.SwitchOn = true,
};
As you included data.c in main.c
#include "defs.h"
#include "data.c"
then now the code in data.c is duplicated in two translation units: one with main.c and other with data.c.
Remove this line
#include "data.c"
from main.c.
Also pay attention to thatf you declared an array of the type item_t *[ITEM_SIZE]
item_t *items[ITEMS_SIZE] = { /*...*/ };
So if you will pass it as an argument expression to a function it is implicitly converted to the pointer to its first element of the type item_t **. But you are passing the array to the function knapsack
s = knapsack (items, n, 690);
the first parameter of which has the type item_t *.
int *knapsack (item_t * items, int n, int w)
So the compiler should issue a message that the pointer types are noyt compatible. That is whether the function is declared and defined incorrectly or you are calling it supplying incorrect arguments.

Resources