【问题标题】:Is it possible to use a repetition structure in this code?是否可以在此代码中使用重复结构?
【发布时间】:2019-07-08 14:05:43
【问题描述】:

我想要优化这部分代码。它只是在重复自己,但我不知道如何使用我使用的定义在这里使用重复结构。

我定义了 GPIO_Ports 和 Pins。 这会一直持续到 SEL8。

if (out & (1 << 0)) {
    GPIO_SetBits(SEL0_GPIO_Port, SEL0_Pin);
} else {
    GPIO_ResetBits(SEL0_GPIO_Port, SEL0_Pin);
}

if (out & (1 << 1)) {
    GPIO_SetBits(SEL1_GPIO_Port, SEL1_Pin);
} else {
    GPIO_ResetBits(SEL1_GPIO_Port, SEL1_Pin);
}

if (out & (1 << 2)) {
    GPIO_SetBits(SEL2_GPIO_Port, SEL2_Pin);
} else {
    GPIO_ResetBits(SEL2_GPIO_Port, SEL2_Pin);
}

【问题讨论】:

  • SELx_GPIO_PortSELx_Pin 元素定义数组,然后遍历它们。
  • 你的意思是这样的: char SELx_GPIO_Port[9] = {SEL0_GPIO_Port, SEL1_GPIO_Port, SEL2_GPIO_Port, ...} 我不确定我是否做得正确。我需要使用''吗?这个数组是什么类型的?字符?
  • 与这些符号的类型相同...此时只有您知道。
  • 请告诉我们SEL0_GPIO_PortSEL0_Pin等是什么,以及GPIO_SetBitsGPIO_ResetBits的原型
  • @Eduardo 请向我们展示您在评论中提到的代码,否则很难判断它是否正确。数组should is probably be char`的类型,但要确定你需要在我之前的评论中回答我的问题。

标签: c for-loop repeat


【解决方案1】:

我们不知道所使用的变量类型。代码可能如下所示:

#include <assert.h>

// Indexas valid are from 0 to 8, some 9
#define IDX_MAX 9

typedef /* insert the type of SELx_GPIO_Port here */ gpio_port_type;

static gpio_port_type get_gpio_port_from_idx(size_t idx) {
  const gpio_port_type ports[] = {
    SEL0_GPIO_Port,
    SEL1_GPIO_Port,
    SEL2_GPIO_Port,
    SEL3_GPIO_Port,
    SEL4_GPIO_Port,
    SEL5_GPIO_Port,
    SEL6_GPIO_Port,
    SEL7_GPIO_Port,
    SEL8_GPIO_Port,
  };
  static_assert(IDX_MAX == sizeof(ports)/sizeof(*ports));
  assert(idx < sizeof(ports)/sizeof(*ports));
  return ports[idx];
}

typedef /* insert the type of SELx_Pin here */ pin_type ;

static pin_type get_sel_pin_from_idx(size_t idx) {
  const pin_type pins[] = {
    SEL0_Pin,
    SEL1_Pin,
    SEL2_Pin,
    SEL3_Pin,
    SEL4_Pin,
    SEL5_Pin,
    SEL6_Pin,
    SEL7_Pin,
    SEL8_Pin,
  };
  static_assert(IDX_MAX == sizeof(pins)/sizeof(*pins));
  assert(idx < sizeof(pins)/sizeof(*pins));
  return pins[idx];
}

void set_out(int out) {
   for (size_t i = 0; i < IDX_MAX; ++i) {
        (
           (out & (1 << i)) ? GPIO_SetBits : GPIO_ResetBits
        )(get_gpio_port_from_idx(i), get_gpio_pin_from_idx(i));
    }
}

前两个函数将一个从 0 到 8 范围内的静态索引分别映射到 SELx_GPIO_Port 和 SELx_Pin 变量。之后,set_out 函数检查输入变量 int out 中的每个位,并根据该位设置或取消设置调用 GPIO_SetBitsGPIO_ResetBits。我使用了三元运算符,如果函数有不同的原型,或者是宏,你可以:

void set_out(int out) {
   for (size_t i = 0; i < IDX_MAX; ++i) {
        if (out & (1 << i)) {
            GPIO_SetBits(get_gpio_port_from_idx(i), get_gpio_pin_from_idx(i));
        } else {
            GPIO_ResetBits(get_gpio_port_from_idx(i), get_gpio_pin_from_idx(i));
        }
    }
}

【讨论】:

  • 有什么理由去做你的建议? (添加两个表和一个循环)您可以编写该代码只是为了让编译器展开循环,因为它只有三到四次通过它。我并不是想避免给你答案应得的荣誉,但有时,最好说不,这是不可能的,或可取的,而不是试图与之抗争。即使在 PIC 应该在头文件中标识 30000 个标志的情况下,编写那段代码也是没有意义的。而且我不会对您的回答投反对票,这似乎是正确的。
猜你喜欢
  • 2023-02-25
  • 1970-01-01
  • 2018-01-17
  • 2013-09-17
  • 1970-01-01
  • 2021-06-09
  • 1970-01-01
  • 2011-03-29
  • 1970-01-01
相关资源
最近更新 更多