我看到你得到的答案回答了这个问题,但没有给出解释,从它的外观来看,你可以使用一个很好的解释,所以这就是正在发生的事情:
C中的类型
您需要了解不同的类型(int
, char
, float
, double
)在内存中占用不同的大小。在 C 中,achar
总是被认为占用一个字节,并且在 -127 到 128 的范围内。(unsigned char
从 0 到 255。) int
s 占用 4 个字节,它们的范围是从 -2M 到 2M - 1 . float
分别double
占用 4 和 8 个字节,范围很大,但精度有限。(有关更多信息,只需搜索“c type range”,您会发现很多信息,包括 Stack Overflow 上的这些链接,这些链接也为您提供了很好的解释:Definition of a range of a data type , Guarantateed minimum size/range C 数据类型)。
此外,您知道足够的 ascii 以知道将 48 添加到一个数字以获得 char 版本,但请确保您附近有一个 ascii 表。方便的是,您可以在http://www.asciitable.com找到一个。
您还必须了解编译器将尽最大努力从一个转换为另一个,但在某些情况下,例如将 afloat
转换为 an int
,如果您不明确执行此操作,您的编译器至少应该发出警告。
字符串在 C 中不作为类型存在。相反,您打印到数组中。其他答案告诉你如何做到这一点。他们的代码正在做的是将您想要的值打印到字符数组中,这就是您所需要的。
你的代码在做什么
现在,让我们看看您当前的代码在做什么:
首先,一个快速的侧边栏:当你做一个for
循环时,最好把增量放在循环本身,所以:
for(count=1.5;count<=2.5;count=count+0.5)
{
for(i=0;i<=15;i=i+5)
会更规范。
现在,您的第一行是sendBuffer[0]=count+48;
. 这是发生的事情:
- 您正在计数,从 1.5 开始,再加上 48,所以第一个数字是 49.5。
- 编译器会自动将 a 更改
float
为 an int
,尽管它应该给你一个警告。它通过截断值来实现,将 49.5 更改为 45。
- 然后它会更改
(int)49
为(char)49
相同的值,但占用一个字节而不是 4。Ascii 49 是“1”,所以这恰好是您想要的数字。
- 编译器对浮点的其余部分不做任何事情。它从不为此值设置 sendBuffer[1] 或 [2]。
接下来的 3 行将字符串的第二个、第三个和第四个字符硬编码为abc
. 即使您的第一行已将完整的浮点值设置为sendBuffer
,这也会覆盖它。
您的最后一行将 i 取为 0、5、10 和 15,并将其添加到 48。这就像第一步一样,没有截断 from float
。因此,它首先查找 ascii 48,即“0”,然后查找 ascii 53,即“5”。当i
为 10 时,它现在采用 int 58 并将其转换为字符(再次将其从 4 个字节更改为 1 个字节)。打印 ascii 58 得到 ':',打印 ascii 63 得到 '?'。这就是你的输出结果如何。
可能的解决方案
最后,对您给出的解决方案说几句话:
由于您所做的只是输出结果,因此您不需要sendBuffer
也不snprintf
. 只需使用
printf("%.1fabc%d\n", count, i);
就足够了。
不过,想想 printf 系列函数的作用是有启发性的。虽然效率较低,但让我们用几个snprintf
s 来看看它在做什么:
int index = 0;
index = snprintf(&sendbuf[index], sizeof(sendbuf) - index, "%.1f", count);
index += snprintf(&sendbuf[index], sizeof(sendbuf) - index, "abc");
index += snprintf(&sendbuf[index], sizeof(sendbuf) - index, "%d", i);
sendbuf[index++] = '\n';
sendbuf[index] = '\0';
当你传递多个参数时,它的作用是*printf
:跟踪你写了多少,并用它来告诉你在哪里写下一部分。
如果你不知道,a += b
语法是a = a + b
. a++
意思是“给我 a 的值,然后增加它”。
所以我的代码的第二行会将浮点值打印到 sendbuf 中,从 0 位置开始。 *printf
总是返回打印的字符数,所以在这个例子中,它总是打印 3 个字符,我设置index
为 3。
下一行将字符串 abc 写入 sendbuf,从位置 3 开始,之后的行将值打印i
到位置 6。最后,我为新行添加 \n,最后一行是空终止符。我不放index++
是因为我不再关心索引,所以不需要费心增加它。我把\0
(和你上面一样)而不是 0,只是因为\0
提醒程序员我们正在处理一个 char 数组,而不是一个整数数组。
同样,所有这些行都不是必需的,但由于某些问题似乎是理解什么printf
,我认为这会有所帮助。