我最近开始阅读“头第一C”一书。我想在写好的、习惯的、现代的C方面跟上速度。我也读过现代C书的前几章,但我发现Head首先是对语言的更好的介绍。
下面的代码是第一个更大的,arduino任务。这是一个非常直接的任务,LED应该用来指示植物的土壤湿度。我已经超越了基本的任务,使用3色LED,其中引脚11应该是高的绿色,12高的红色和两个高的橙色。
这给创建一个抽象这些细节的好的、一致的api带来了一些挑战。我想在解决方案中使用指针和指针算术,只是为了了解它们。我可能可以使用数组重写,并避免使用0最后的元素,尽管我仍然需要处理指针衰减。
任何指点:-)什么可以改变,把它变成一个好的,惯用的,现代的解决方案?不管指针使用与否。
int const RED[] = { 12, 0 };
int const GREEN[] = { 11, 0 };
int const ORANGE[] = { 11, 12, 0 };
int const DEFAULT_DURATION = 1000;
int const DEFAULT_COUNT = 1;
void blink(int color[]);
void blink(int color[], int duration, int count);
void blinkSequence(int* color[]);
void blinkSequence(int* color[], int duration, int count);
void on(int color[]);
void off(int color[]);
void setup() {
// initialize LED Pins as output
Serial.begin(9600);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
digitalWrite(13, LOW);
}
void loop() {
int m = analogRead(0);
int interval = 2000;
Serial.print("Moisture is: ");
Serial.println(m);
if (m <= 580) {
//Really Dry!: 580-
int* seq[] = { RED, ORANGE, 0 };
blinkSequence(seq, 150, 2);
interval = 0;
} else if (m <= 700) {
//Needs water: 700 - 581
blink(RED, 500);
interval = 500;
} else if (m <= 740) {
//Could be wetter: 740 - 701
blink(ORANGE, 4000);
interval = 50;
} else if (m <= 870) {
//Happy range: 870 - 741
blink(GREEN, 5000);
interval = 50;
} else {
//Overwatered: 870+
int* seq[] = { GREEN, ORANGE, 0 };
blinkSequence(seq, 200, 5);
interval = 3000;
}
delay(interval);
}
void blinkSequence(int* colors[], int duration, int count) {
for (int i = count; i > 0; i--) {
int** inner = colors;
for(;*inner;inner++) {
blink(*inner, duration);
}
}
}
void blink(int color[], int duration) {
on(color);
delay(duration);
off(color);
}
void blinkSequence(int* colors[]) {
for(;*colors;colors++) {
blink(*colors);
}
}
void blink(int color[]) {
on(color);
delay(DEFAULT_DURATION);
off(color);
}
void on(int color[]) {
for(;*color;color++) {
digitalWrite(*color, HIGH);
//Serial.print("HIGH:");
//Serial.println(*color);
}
}
void off(int color[]) {
for(;*color;color++) {
digitalWrite(*color, LOW);
//Serial.print("LOW:");
//Serial.println(*color);
}
}发布于 2019-07-18 17:37:38
您编写了几个没有空格的for循环。请不要这样做,因为它使代码更难阅读。
而不是
for(;*colors;colors++) {
blink(*colors);
}你可能更喜欢
while (*colors) {
blink(*colors++);
}将loop()移动到文件底部将为您节省一些前向声明。
添加一个Serial.print()标志可能会使您的debug语句受益,因此不需要对它们进行注释。
像计数和持续时间这样的事情不会变成负数。我看不到delay()和digitalWrite()的签名,但你的一些ints可能想成为uint。
发布于 2019-07-18 19:14:54
首先,这可能是C++而不是C,C编程语言不支持函数重载(例如眨眼)。
在编程中,幻数是代码中的一个数值常量,它不确定是什么。神奇的数字使代码更难理解、调试和维护。当魔术数字被用作数组的基础时,这意味着代码可能需要在多个地方进行编辑,而不仅仅是在一个位置。
示例:
int *colors[10];
for (c = 0; c < 10; c++)
{
do_something_with_color(colors[c]);
}如果定义了符号常量,这将更容易修改和维护。
int const MAX_COLORS = 10;
int *colors[MAX_COLORS];
for (c = 0; c < MAX_COLORS; c++)
{
do_something_with_color(colors[c]);
}程序中有大量的数字常量,很少情况下是使用int const SYMBOLIC_NAME = value定义的。如果以这种方式定义所有数字常量,可能会更好。这些数值常量的一些例子是700、581、500、2000、4000等。
是500毫秒、2000毫秒和4000毫秒?
评论
评论
//Really Dry!: 580-
//Needs water: 700 - 581
//Could be wetter: 740 - 701在这种情况下并不是很有意义。如果您想要创建一个块注释来描述LED的用途,然后将常量的符号名建立在这个块注释上,这可能会更有帮助。
https://codereview.stackexchange.com/questions/224393
复制相似问题