这是什么"继续"确切地说?

时间:2017-05-12 21:21:12

标签: c

我有这部分代码,我不明白。我知道"继续"在if中,跳过该声明。但为什么?它应该打印出像#34; 073.45 * C&#34 ;. i=2代表数字,对吗? Temp_s[5-i}=result%10+0x30做了什么?有人可以解释一下这段代码。

void Convert_data_to_temp(unsigned long data)
{
    unsigned long result;
    unsigned char i=0;
    result=((33*1000*data)/4096)%100000;//rounding off to maximum 5 digits

    Temp_s[0]=0x30;
    Temp_s[3]='.';
    for(i=0;i<6;i++)
    {
        if(i==2){continue;}
        Temp_s[5-i]=(result%10)+0x30;
        result=result/10;
    }
    Temp_s[i]=32;
    Temp_s[i+1]=32;
    Temp_s[i+2]='*';
    Temp_s[i+3]=32;
    Temp_s[i+4]='C';
    Temp_s[i+5]=13;
    Temp_s[i+6]=10;
}

由于

4 个答案:

答案 0 :(得分:3)

这肯定是个烂摊子。这是这段代码的作用(假设范围内有一个Temp_s char数组,至少包含13个元素)。

void Convert_data_to_temp(unsigned long data)
{
    unsigned long result;
    unsigned char i=0;

    // Calculate... something.
    // Apparently the calculation is done in fixed-point decimal,
    // with 3 decimal places (hence `*1000`).
    // Also, the comment is wrong: that's not rounding off, the result will wrap.
    // In any case, we can be sure that 0 <= result < 100000.
    result=((33*1000*data)/4096)%100000;//rounding off to maximum 5 digits

    Temp_s[0]=0x30; // ASCII for '0'
    Temp_s[3]='.';

    // Now Temp_s looks like this (? represents an indeterminate value:
    //
    // 0 ? ? . ? ? ? ? ? ? ? ? ?

    // Now we're filling Temp_s backwards from the 5th index,
    // with the respective digits of `result`. The `continue` skips over
    // index 3 so we don't overwrite the '.' we just put there.
    for(i=0;i<6;i++)
    {
        if(i==2){continue;}
        Temp_s[5-i]=(result%10)+0x30; // Again, 0x30 is just ASCII '0'.
        result=result/10;
    }

    // Let's say that result was 12345. Now Temp_s looks like this:
    //
    // 1 2 3 . 4 5 ? ? ? ? ? ? ?

    // And now we fill the rest of Temp_s with these hard-coded values.
    // Note that we retrieve i at the value it was left by the for, i.e. 6.
    Temp_s[i]=32;   // 32 is an ASCII space
    Temp_s[i+1]=32;
    Temp_s[i+2]='*';
    Temp_s[i+3]=32;
    Temp_s[i+4]='C';
    Temp_s[i+5]=13; // ASCII Carriage return
    Temp_s[i+6]=10; // ASCII Line feed

    // In the end, Temp_s looks like this:
    //
    // 1 2 3 . 4 5 [space] [space] * [space] C \r \n
}

显然代码也被破坏了:result的计算提示固定点为3位小数,但表示最终只有两位小数,并覆盖了在{1}}分配的'0'一开始。

我建议你抛弃那些疯狂的代码并使用经过验证的标准库:

snprintf(
    Temp_s, sizeof Temp_s,
    "%.3lu.%.2lu  * C\r\n",
    result / 100, result % 100
);

答案 1 :(得分:1)

代码整体将5位十进制数字(例如54321)转换为"543.21 * C\r\n" - 除了它不能确保字符串为空终止。但是,如果目标数组Temp_s是一个全局变量并且足够大而且只能由此函数写入,那么最终可能已经存在空值,但确保它更简单,更安全。 / p>

可以删除作业Temp_s[0]=0x30;,并且可以更清楚地写出循环:

for (i = 0; i < 6; i++)
{
    if (i == 2)
        Temp_s[5-i] = '.';
    else
    {
        Temp_s[5-i] = (result % 10) + '0';
        result /= 10;
    }
}
strcpy(&Temp_s[6], "  * C\r\n");  // Adds null termination

坦率地说,它可以(也许应该)写成对sprintf()的调用(这也确保字符串为空终止):

int dp = result % 100;
int un = result / 100;
sprintf(Temp_s, "%.3d.%.2d  * C\r\n", un, dp);

您可以改为编写(注意resultunsigned long,因此更改了格式转换说明符):

sprintf(Temp_s, "%.3lu.%.2lu  * C\r\n", result / 100, result % 100);

最好能够使用snprintf(),但不清楚如何声明此全局变量,并且使用sizeof(Temp_s)可能不正确:

snprintf(Temp_s, sizeof(Temp_s), "%.3lu.%.2lu  * C\r\n", result / 100, result % 100);

答案 2 :(得分:0)

Temp_s[5-i]=(result%10)+0x30;

写入数组Temp_s的索引5-i 结果模10 + 48。

continue继续跳过循环中的语句并返回到i ++语句,然后返回循环的谓词。但只有我等于两个。

总而言之,这应该为您提供之前计算的结果作为字符串表示。

if i == 2保留您不会覆盖'.'

答案 3 :(得分:0)

这很奇怪。看起来你正在迭代for循环,但你没有执行i == 2的代码。继续语句会在你做任何事情之前将你发送到for循环的下一次迭代。

这种代码真的可以从一个好的评论中受益..