对dtostrf功能感到困惑

时间:2018-01-09 14:31:28

标签: c arduino char double avr

我目前正在开发一个个人AVR项目,并编写了一个功能,用于使用UART将双重传输到我的串行LCD屏幕。为此,我将一个double转换为一个char数组,然后通过char串行传输它。

令我困惑的是char缓冲区数组的长度必须是多少。数组的长度似乎与double的大小不对应。有趣的是,我可以将数组的长度设置为0,它仍然可以工作,如下所示:

    void USART_Transmit_Double(double doubleNumber) {

    char aNumberAsString[0];
    dtostrf(doubleNumber, 3, 0, aNumberAsString);

    USART_Transmit_String(aNumberAsString);
}

这里我在主循环中打印1234号,它在我的液晶显示屏上显示就好了。如果我将精度更改为1,那么整个事情就会变得混乱。

我在我的Arduino上测试了相同的功能并且不断得到完全不同的结果,每个字符似乎对应于数组的每个元素,所以如果我想打印1234.2,我必须将缓冲区长度设置为6

那么这里发生了什么?

1 个答案:

答案 0 :(得分:2)

您正在遇到 undefined behavior 。特别是,在此链接中,短语:未定义行为的示例是数组边界之外的内存访问,... 可能适用于您描述的方案。如果您尝试访问(但不拥有)的内存不会违反另一个变量的内存空间,则可能会工作一千次。第一次,你的程序会崩溃。

以下陈述虽然合法,但会产生无用的变量,这可能是您看到奇怪结果的原因:

char aNumberAsString[0];

发表评论
您可能会混淆创建包含单个值的缓冲区所需的索引值,以及创建变量后访问该值所需的索引值。即

char aNumberAsString[1] = 'A'; //creates an array of 1 char ([1])

将创建一个可以包含单个char值的变量。

char value = aNumberAsString[0]; // accesses the only value in array ([0])

实施例
请参阅如何使用dtostrf函数 here 的示例 请注意此示例使用的变量的大小:

static float f_val = 123.6794;
static char outstr[15];

支持以下电话:

 dtostrf(f_val,7, 3, outstr);

产生以下输出:

123.679