识别哪个结构包含您正在处理的值的聪明方法是什么?
What is a smart way to recognize what struct contains the value you're working on?
编辑:完整代码现已发布,您可以编译。
所以我们是一些第一学期的软件专业学生,他们在某种程度上陷入了与 c 中的结构有关的问题。 Stack overflow 已经帮了我很多次了,所以我想这次我真的会试着问一下,因为我似乎找不到我要找的东西。
我们的逻辑(见下面的代码):
- 主要来电empty_trash
- empty_trash(在其参数中)调用 compare_trash
- 通过 4 个区域(结构)比较垃圾解析
- 比较垃圾检查我们的数据平均值是否超过一定范围,如果是的话
首先检查该平均值是否高于我们的空结构,
大概有 0 个平均值,然后如果发现更高
一。这给我们留下了最高的结构的索引
平均
- 比较垃圾return这个结构清空垃圾,和一个整数
指向 main 的索引指针。
- 然后清空垃圾遍历子区域并检查它们的平均数据并重置超过 margin2 的数据
- 我们return重置主区
- 在 main 中,我们有一个结构 1-4 的数组。我们将 returned 从空垃圾中分配给 arrayofstructs[index pointed back]
在我们看来,逻辑是有道理的,但它似乎不起作用,因为我们的程序在 main 的那一行崩溃了。我们认为这是因为我们没有在 main 中正确分配结构,但不是 100% 确定。
我们有点困惑,因为当我们单独测试这两个功能时,它们各自都能正常工作,但在一起时却不行。
如有任何帮助,我们将不胜感激<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;
}
我的原评论:
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
您的回复:
@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
我做得更好了(?)我已经对你的代码进行了初步的重构。相信这不仅对自己有帮助,对其他人也有帮助。
对不起,但是(我是带着好心说的),代码需要很多重构。纯粹的 [不必要的] 复杂性可能掩盖了许多错误。
注意事项:
- 通过 值 传递
struct
是 危险的 。它是合法的,但它使代码变得复杂。通过指针传递是 99.44% 的时间更好。您可以“就地”修改给定的结构,而不必 return 它 [再次按值]。
- 了解如何使用指向“当前”元素的 指针 而不是 索引 来遍历数组。您将在下面的
FORALL
循环中看到它。
- 不要“复制”代码。注意使用数组时会发生什么。我们有一个
而不是(例如)四个代码副本
- 而不是 4 个区域(例如
area1
、area2
、area3
、area4
),if 我们有 10,000领域。您是否会像在(例如)empty_trash
? 中那样将代码复制 10,000 次?
- 我为你的两个
struct
添加了 typedef
以简化事情。
- 我添加了一些高级技术,例如使用
FORALL
宏来遍历数组。
我使用预处理器条件来表示旧代码与新代码:
#if 0
// old code
#else
// new code
#endif
我已经完成了 some/most 的编辑。我已经编译了。我本可以犯无数错误。但是,它应该给你这样的想法:
#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;
}
}
}
编辑:完整代码现已发布,您可以编译。
所以我们是一些第一学期的软件专业学生,他们在某种程度上陷入了与 c 中的结构有关的问题。 Stack overflow 已经帮了我很多次了,所以我想这次我真的会试着问一下,因为我似乎找不到我要找的东西。
我们的逻辑(见下面的代码):
- 主要来电empty_trash
- empty_trash(在其参数中)调用 compare_trash
- 通过 4 个区域(结构)比较垃圾解析
- 比较垃圾检查我们的数据平均值是否超过一定范围,如果是的话 首先检查该平均值是否高于我们的空结构, 大概有 0 个平均值,然后如果发现更高 一。这给我们留下了最高的结构的索引 平均
- 比较垃圾return这个结构清空垃圾,和一个整数 指向 main 的索引指针。
- 然后清空垃圾遍历子区域并检查它们的平均数据并重置超过 margin2 的数据
- 我们return重置主区
- 在 main 中,我们有一个结构 1-4 的数组。我们将 returned 从空垃圾中分配给 arrayofstructs[index pointed back]
在我们看来,逻辑是有道理的,但它似乎不起作用,因为我们的程序在 main 的那一行崩溃了。我们认为这是因为我们没有在 main 中正确分配结构,但不是 100% 确定。
我们有点困惑,因为当我们单独测试这两个功能时,它们各自都能正常工作,但在一起时却不行。
如有任何帮助,我们将不胜感激<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;
}
我的原评论:
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
您的回复:
@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
我做得更好了(?)我已经对你的代码进行了初步的重构。相信这不仅对自己有帮助,对其他人也有帮助。
对不起,但是(我是带着好心说的),代码需要很多重构。纯粹的 [不必要的] 复杂性可能掩盖了许多错误。
注意事项:
- 通过 值 传递
struct
是 危险的 。它是合法的,但它使代码变得复杂。通过指针传递是 99.44% 的时间更好。您可以“就地”修改给定的结构,而不必 return 它 [再次按值]。 - 了解如何使用指向“当前”元素的 指针 而不是 索引 来遍历数组。您将在下面的
FORALL
循环中看到它。 - 不要“复制”代码。注意使用数组时会发生什么。我们有一个 而不是(例如)四个代码副本
- 而不是 4 个区域(例如
area1
、area2
、area3
、area4
),if 我们有 10,000领域。您是否会像在(例如)empty_trash
? 中那样将代码复制 10,000 次?
- 我为你的两个
struct
添加了typedef
以简化事情。 - 我添加了一些高级技术,例如使用
FORALL
宏来遍历数组。
我使用预处理器条件来表示旧代码与新代码:
#if 0
// old code
#else
// new code
#endif
我已经完成了 some/most 的编辑。我已经编译了。我本可以犯无数错误。但是,它应该给你这样的想法:
#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;
}
}
}