gpt4 book ai didi

c - 为什么 getline 的第一个参数是指向指针 "char**"而不是 "char*"的指针?

转载 作者:太空狗 更新时间:2023-10-29 16:23:43 27 4
gpt4 key购买 nike

我使用 getline 函数从 STDIN 中读取一行。

getline的原型(prototype)是:

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

我将其用作测试程序,它来自 http://www.crasseux.com/books/ctutorial/getline.html#getline

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int atgc, char *argv[])
{
int bytes_read = 1;
int nbytes = 10;
char *my_string;

my_string = (char *)malloc(nbytes+1);

puts("Please enter a line of text");

bytes_read = getline(&my_string, &nbytes, stdin);

if (bytes_read == -1)
{
puts ("ERROR!");
}
else
{
puts ("You typed:");
puts (my_string);
}

return 0;
}

这很好用。

我的疑问是?

  1. 为什么使用 char **lineptr 而不是 char *lineptr 作为函数 getline 的参数?

    <
  2. 为什么我用下面的代码会出错:

    char **my_string;
    bytes_read = getline(my_string, &nbytes, stdin);
  3. 我对 *& 感到困惑。

部分警告:

testGetline.c: In function ‘main’: 
testGetline.c:34: warning: pointer targets in passing argument 2 of
‘getline’ differ in signedness
/usr/include/stdio.h:671:
note: expected ‘size_t * __restrict__’ but argument is of type ‘int *’
testGetline.c:40: warning: passing argument 1 of ‘putchar’ makes integer
from pointer without a cast
/usr/include/stdio.h:582: note: expected ‘int’ but argument is of
type ‘char *’

我使用 GCC 版本 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5)。

最佳答案

Why use char **lineptr instead of char *lineptr as a parameter of function getline?

想象一下 getline 的原型(prototype)看起来像这样:

ssize_t
getline(char *line, size_t n, FILE *stream);

你这样调用它:

char *buffer = NULL;
size_t len = 0;
ssize_t read = getline(buffer, len, stdin);

在调用getline之前,buffer为空:

+------+
|buffer+-------> NULL
+------+

getline 被调用时,line 获取 buffer 的副本,因为函数参数在 C 中是按值传递的。 getline 内部,我们无法再访问 buffer:

+------+
|buffer+-------> NULL
+------+ ^
|
+------+ |
| line +----------+
+------+

getline 使用 malloc 分配一些内存并将 line 指向 block 的开头:

+------+
|buffer+-------> NULL
+------+

+------+ +---+---+---+---+---+
| line +------->+ | | | | |
+------+ +---+---+---+---+---+

getline 返回后,我们无法再访问 line:

+------+
|buffer+-------> NULL
+------+

我们又回到了起点。我们不能将 buffer 重新指向 getline 中新分配的内存,因为我们只有 buffer 的副本。


getline的原型(prototype)实际上是:

ssize_t
getline(char **lineptr, size_t *n, FILE *stream);

你这样调用它:

char *buffer = NULL;
size_t len = 0;
ssize_t read = getline(&buffer, &len, stdin);

&buffer 返回指向 buffer 的指针,所以我们有:

+-------+        +------+
|&buffer+------> +buffer+-------> NULL
+-------+ +---+--+

getline 被调用时,lineptr 得到 &buffer 的副本,因为 C 是按值调用的。 lineptr 指向与&buffer 相同的地方:

+-------+        +------+
|&buffer+------->+buffer+-------> NULL
+-------+ +---+--+
^
+-------+ |
|lineptr+------------+
+-------+

getline 使用 malloc 分配一些内存并指向 lineptr 的指针(即 lineptr 指向的东西) 在 block 的开头:

+-------+        +------+        +---+---+---+---+---+
|&buffer+------->+buffer+------->+ | | | | |
+-------+ +---+--+ +---+---+---+---+---+
^
+-------+ |
|lineptr+------------+
+-------+

getline 返回后,我们无法再访问 lineptr,但我们仍然可以通过 buffer 访问新分配的内存:

+-------+        +------+        +---+---+---+---+---+
|&buffer+------->+buffer+------->+ | | | | |
+-------+ +---+--+ +---+---+---+---+---+

关于c - 为什么 getline 的第一个参数是指向指针 "char**"而不是 "char*"的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5744393/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com