C 关于dtostf函数的困惑

C 关于dtostf函数的困惑,c,arduino,char,double,avr,C,Arduino,Char,Double,Avr,我目前正在从事一个个人AVR项目,并编写了一个函数,用于使用UART将双精度数据传输到我的串行LCD屏幕。为此,我将一个double转换成一个char数组,然后逐字符串行传输它 让我困惑的是字符缓冲区数组的长度。数组的长度似乎与double的大小不一致。有趣的是,我可以将数组的长度设置为0,它仍然可以工作,如下所示: void USART_Transmit_Double(double doubleNumber) { char aNumberAsString[0]; dt

我目前正在从事一个个人AVR项目,并编写了一个函数,用于使用UART将双精度数据传输到我的串行LCD屏幕。为此,我将一个double转换成一个char数组,然后逐字符串行传输它

让我困惑的是字符缓冲区数组的长度。数组的长度似乎与double的大小不一致。有趣的是,我可以将数组的长度设置为0,它仍然可以工作,如下所示:

    void USART_Transmit_Double(double doubleNumber) {

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

    USART_Transmit_String(aNumberAsString);
}
在这里,我在主循环中打印1234号,它在我的LCD上显示得很好。但是,如果我将精度更改为1,整个过程就会失控

我在Arduino上测试了相同的函数,结果完全不同,每个字符似乎对应于数组的每个元素,因此如果我想打印1234.2,我必须将缓冲区长度设置为6

这是怎么回事?

你遇到了什么。特别是,在这个链接中,短语:未定义行为的示例是数组边界之外的内存访问,。。。可能适用于您描述的场景。如果您试图访问(但不拥有)的内存没有违反另一个变量的内存空间,那么它可能会工作一千次。第一次这样做时,您的程序将崩溃

以下语句虽然合法,但创建了一个无用的变量,这可能是您看到奇怪结果的原因:

char aNumberAsString[0];
回应您的评论:
您可能会混淆创建包含单个值的缓冲区所需的索引值与创建变量后访问该值所需的索引值。i、 e

char aNumberAsString[1] = 'A'; //creates an array of 1 char ([1])
将创建一个可以包含单个字符值的变量

char value = aNumberAsString[0]; // accesses the only value in array ([0])
示例:
请参见如何使用
dtostrf
功能的示例。
注意本例使用的变量的大小:

static float f_val = 123.6794;
static char outstr[15];
要支持以下呼叫:

 dtostrf(f_val,7, 3, outstr);
将生成以下输出:

123.679
你遇到了麻烦。特别是,在这个链接中,短语:未定义行为的示例是数组边界之外的内存访问,。。。可能适用于您描述的场景。如果您试图访问(但不拥有)的内存没有违反另一个变量的内存空间,那么它可能会工作一千次。第一次这样做时,您的程序将崩溃

以下语句虽然合法,但创建了一个无用的变量,这可能是您看到奇怪结果的原因:

char aNumberAsString[0];
回应您的评论:
您可能会混淆创建包含单个值的缓冲区所需的索引值与创建变量后访问该值所需的索引值。i、 e

char aNumberAsString[1] = 'A'; //creates an array of 1 char ([1])
将创建一个可以包含单个字符值的变量

char value = aNumberAsString[0]; // accesses the only value in array ([0])
示例:
请参见如何使用
dtostrf
功能的示例。
注意本例使用的变量的大小:

static float f_val = 123.6794;
static char outstr[15];
要支持以下呼叫:

 dtostrf(f_val,7, 3, outstr);
将生成以下输出:

123.679

你能把显示的代码段直接放到帖子里吗?在其他内容的上下文中更容易看到。关于…打印1234.2,我必须将缓冲区长度设置为6。:包含字符串
1234.2
所需的缓冲区需要有容纳7个字符的空间。
C字符串
是一个以空字符结尾的字符数组。@Ryker我没有使用字符串,我在一个字符数组中迭代,并通过串行传输字符。更奇怪的是,它在缓冲区长度为0的情况下运行良好。欢迎来到未定义的世界behavior@ryyker“需要包含字符串1234.2的缓冲区需要有容纳7个字符的空间”,没错。。但现在我更困惑了,因为我用整数和itoa函数尝试了相同的过程,它是一对一的映射,例如,要显示255,我需要缓冲区长度为1。你能把显示的代码段直接放到帖子中吗?在其他内容的上下文中更容易看到。关于…打印1234.2,我必须将缓冲区长度设置为6。:包含字符串
1234.2
所需的缓冲区需要有容纳7个字符的空间。
C字符串
是一个以空字符结尾的字符数组。@Ryker我没有使用字符串,我在一个字符数组中迭代,并通过串行传输字符。更奇怪的是,它在缓冲区长度为0的情况下运行良好。欢迎来到未定义的世界behavior@ryyker“需要包含字符串1234.2的缓冲区需要有容纳7个字符的空间”,没错。。但现在我更困惑了,因为我尝试了使用整数和itoa函数的相同过程,它是一对一映射,例如,要显示255,我需要缓冲区长度为1。解决注释的第二部分-否,我声明了一个长度为0的新字符数组。@Hypomania-是的,这就是问题所在。长度==0的数组无效。创建一个简单的char变量,或者创建一个char数组,其中至少有1个值的空间。这是有意义的,但无论如何都没有区别。在我的自定义板上,字符数和缓冲区长度之间没有直接关系(在Arduino上可以正常工作)。@Hypomania-你没有得到它。如果使用零长度数组传递单个
char
值,则调用的是未定义的行为。它可能会进行数百次迭代,然后突然间,没有明显的原因,您的程序将崩溃。现在它在什么系统上工作并不重要。听听凯文的评论,然后重新阅读我的帖子。两者都提供了很好的建议,即使现在没有意义。@Hypomania-你至少同意
char-anumberastring[0]虽然是一个法律声明,但没有用?请回答您评论的第二部分-不,我声明了一个长度为的新字符数组