我是 C 的新手,并试图理解为什么以下内容适用于固定大小的字符数组而不适用于指针:
float number = 1245.12;
// allocate a character array for the buffer
char number_as_string[50];
sprintf(number_as_string, "%f", number);
但是分配一个指针(我认为它会指向内存中的一个位置,并允许迭代到下一个内存点等)是行不通的:
float number = 1245.12;
// allocate a pointer
char * number_as_string;
sprintf(number_as_string, "%f", number);
最佳答案
我将分两部分回答您的问题。
你写的
float number = 1245.12;
char number_as_string[50];
sprintf(number_as_string, "%f", number);
这很好并且可以工作,尽管像这样的固定大小缓冲区的一个问题当然是它们很容易溢出,有时会带来灾难性的后果。所以一个首选的替代方案是
snprintf(number_as_string, sizeof(number_as_string), "%f", number);
snprintf
是 sprintf
的变体,可让您指定缓冲区的大小。这样一来,snprintf
就可以注意不要向缓冲区写入超过其容量的字符。
现在让我们看看如何在第二个示例中使用 snprintf
:
char *number_as_string;
snprintf(number_as_string, ???, "%f", number);
但是我们使用什么尺寸呢?第二个 number_as_string
指向的缓冲区有多大?我们不知道,这有助于我们意识到我们还没有为第二个 number_as_string
分配一个缓冲区来指向它。
你想要做的是使用 malloc
为 number_as_string
分配一些内存以指向:
number_as_string = malloc(50);
现在,假设 malloc
成功,您知道将什么数字作为缓冲区大小传递给 snprintf
:
snprintf(number_as_string, 50, "%f", number);
实际上,当然,我们有一个变量保存分配的缓冲区大小,而不是在多个地方重复数字“50”。所以这是更现实的例子,包括确保 malloc
没有失败的测试:
int buffer_size = 50;
char *number_as_string = malloc(buffer_size);
if(number_as_string == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
snprintf(number_as_string, buffer_size, "%f", number);
只要确保你不这样做:
snprintf(number_as_string, sizeof(number_as_string), "%f", number);
当 number_as_string
是指针时。在这种情况下,您将获得指针的大小(目前通常为 4 或 8 个字节),而不是您想要的指向缓冲区的大小。
我喜欢用一些方框箭头图来理解内存分配和指针。这是 char number_as_string[50]
:
+--+--+--+--+--+--+--+--+--+--+--+--+--+ +--+--+
number_as_string: | | | | | | | | | | | | | |...| | |
+--+--+--+--+--+--+--+--+--+--+--+--+--+ +--+--+
这是 char *number_as_string
后跟一个成功的 number_as_string = malloc(50)
:
+-------+
number_as_string: | * |
+---|---+
|
v
+--+--+--+--+--+--+--+--+--+--+--+--+--+ +--+--+
| | | | | | | | | | | | | |...| | |
+--+--+--+--+--+--+--+--+--+--+--+--+--+ +--+--+
但这里的 char *number_as_string
本身就是:
+-------+
number_as_string: | *--------> ???
+-------+
箭头——指针——指向“无处”。
关于c - 分配固定字符数组与指针以转换为字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57762353/