我正在用Arduino编程,我的程序包含了很多while循环。当Arduino接收到一个字符时,它必须进行一些计算,并且在接收到一个字符时从它所处的循环中中断。我将给出一个简单的例子(假设i和j被设为0):
while (i < 256)
{
// some calculations #1
i++;
if (Serial.available() > 0)
{
setStringOne = "string one"
setStringTwo = "string two"
setStringThree = "string three"
setStringFour = "string four"
break;
}
}
while (j < 256)
{
// some calculations #2
j++;
if (Serial.available() > 0)
{
setStringOne = "string one"
setStringTwo = "string two"
setStringThree = "string three"
setStringFour = "string four"
break;
}
}您可以看到,在这两种情况下,我在if语句中都使用了相同的代码。我希望它能写出这样的东西。
while (i < 256)
{
// some calculations #1
i++;
if (Serial.available() > 0)
checkAndBreak();
}
while (j < 256)
{
// some calculations #2
j++;
if (Serial.available() > 0)
checkAndBreak();
}
void checkAndBreak()
{
if (Serial.available() > 0)
{
setStringOne = "string one"
setStringTwo = "string two"
setStringThree = "string three"
setStringFour = "string four"
break;
}
}用外部方法中断循环。
它给了我一个错误--“非循环或开关中的中断语句”,这是预期的,因为它不知道该从哪个循环中断,但我只是想知道是否有可能沿着这些路线来做一些事情。
提前感谢!
发布于 2016-07-02 14:22:27
你不能那样打破,所以不可能。只需平衡一下每种方法所做的事情:
while (i < 256)
{
if (Serial.available() > 0)
{
setThoseStrings();
break;
}
i++;
}另一个选择
while (i < 256)
{
if (checkSerialAndSetStrings())
{
break;
}
i++;
}这看起来更短,但是如果您需要在其他情况下设置字符串(例如,在计时器超时时设置字符串),您将浪费时间从checkSerialAndSetStrings中删除串行检查并更新代码。我会和第一位一起去。
发布于 2016-07-02 16:17:24
您可以在return中使用类似的技巧,尽管对于一些老派程序员来说,这一点可能不那么明显。假设Serial.avaiable()返回无符号整数,您不想在计算之前检查它,而且在更新字符串时实际上需要更新的i,j计数器作为后置效果,我会这样做:
// Obviously this function somehow has
// access to the strings being modified
// And possibly to some other state affected by calculations #1 and #2
// I'm leaving it similar to how you've written it
// for the sake of clarity
bool checkAndBreak()
{
if (!Serial.available())
return false;
setStringOne = "string one";
setStringTwo = "string two";
setStringThree = "string three";
setStringFour = "string four";
return true;
}
size_t i = 0, j = 0;
do {
// calculations #1
} while (++i, !checkAndBreak() && i < 256);
do {
// calculations #2
} while (++j, !checkAndBreak() && j < 256);请注意,i,j最终产生的值与示例中的值相同。另一个有趣的方法是:
// define `i,j` outside of the loops if you need their final values
// !i and !j checks are to make sure checkAndBreak()
// won't execute before the loop body
for (size_t i = 0; (!i || !checkAndBreak()) && i < 256; ++i)
// calculations #1
for (size_t j = 0; (!j || !checkAndBreak()) && j < 256; ++j)
// calculations #2您还可以将计算提取到函数中:
void calc1(size_t i) { ... }
void calc2(size_t j) { ... }
for (size_t i = 0; i < 256 && (calc1(i++), !checkAndBreak()); );
for (size_t j = 0; j < 256 && (calc2(j++), !checkAndBreak()); );这样,您首先得到< 256检查,然后用旧的i/j值执行calc1/calc2,然后i/j值增加,然后执行检查。如果检查返回true,则整个for循环将终止。
请注意,这些做法不符合接吻原则,因此,请您调整代码、预条件和后置效果,只需编写。
for (size_t i = 0; i < 256; ++i)
{
// do the calculations #1
// now check the side effects of those calculations
if (serialCheckedAndStateChanged())
break;
}
// The same for #2发布于 2016-07-02 19:28:23
这是一个很好的例子,说明您不应该在方法/过程中使用“中断”、“继续”或多个返回语句。您无法提取减少冗余的方法。我的建议是在没有中断语句的情况下重新制定代码以工作。
我试着采取以下办法:
do {
// some calculations #1
i++;
} while (i < 256 && Serial.available() == 0)
if (Serial.available() > 0)
{
setStringOne = "string one"
setStringTwo = "string two"
setStringThree = "string three"
setStringFour = "string four"
}
do {
// some calculations #2
j++;
} while (j < 256 && Serial.available() == 0)
if (Serial.available() > 0)
{
setStringOne = "string one"
setStringTwo = "string two"
setStringThree = "string three"
setStringFour = "string four"
}现在您可以改进代码:
提取方法并将模板模式应用到计算代码中(尽可能在Arduino中)以减少冗余。
提取方法示例:
void determineString()
{
if (Serial.available() > 0)
{
setStringOne = "string one"
setStringTwo = "string two"
setStringThree = "string three"
setStringFour = "string four"
}
}https://stackoverflow.com/questions/38161060
复制相似问题