我见过以下代码,取自libb64 project。 我试图理解switch块中while循环的目的是什么 -
switch (state_in->step)
{
while (1)
{
case step_a:
do {
if (codechar == code_in+length_in)
{
state_in->step = step_a;
state_in->plainchar = *plainchar;
return plainchar - plaintext_out;
}
fragment = (char)base64_decode_value(*codechar++);
} while (fragment < 0);
*plainchar = (fragment & 0x03f) << 2;
case step_b:
do {
if (codechar == code_in+length_in)
{
state_in->step = step_b;
state_in->plainchar = *plainchar;
return plainchar - plaintext_out;
}
fragment = (char)base64_decode_value(*codechar++);
} while (fragment < 0);
*plainchar++ |= (fragment & 0x030) >> 4;
*plainchar = (fragment & 0x00f) << 4;
case step_c:
do {
if (codechar == code_in+length_in)
{
state_in->step = step_c;
state_in->plainchar = *plainchar;
return plainchar - plaintext_out;
}
fragment = (char)base64_decode_value(*codechar++);
} while (fragment < 0);
*plainchar++ |= (fragment & 0x03c) >> 2;
*plainchar = (fragment & 0x003) << 6;
case step_d:
do {
if (codechar == code_in+length_in)
{
state_in->step = step_d;
state_in->plainchar = *plainchar;
return plainchar - plaintext_out;
}
fragment = (char)base64_decode_value(*codechar++);
} while (fragment < 0);
*plainchar++ |= (fragment & 0x03f);
}
}
什么可以给予时间?似乎无论如何,总是开关只会执行其中一种情况。我错过了什么吗?
感谢。
答案 0 :(得分:3)
答案 1 :(得分:3)
虽然这是Duff的设备,但这个版本不是关于实现循环展开优化,而是实现基于Base64编码流的迭代器。所以你可以这样做:
Base64Stream stream; // the base64 data
char c;
while ((c == stream->NextChar ()) != 0)
{
// do something with c
}
在给定的代码中,第一个切换用于跳回到先前return
退出的位置,然后while(1)允许迭代循环无限地继续。但是,此功能无法防止缓冲区溢出。
在C#中,有一个更简洁的解决方案,即yield
语句。
答案 2 :(得分:0)
如果是尝试实施Duff的设备,那么它可能是错位的。
请注意,对于Duff的设备,如维基百科中所述,循环是有限的,而在上面提供的代码中,它是一个无休止的循环。它完成的唯一可能性是满足(codechar == code_in + length_in)条件(尽管代码片段中的code_id和length_in是不可变的)。
我怀疑它甚至可以用作Duff的设备,即它会导致编译器进行适当的循环扩展。