我正在做一个任务,我应该使用getline函数从终端读取用户的输入。下面是我的代码:
int main(int ac, char **av)
{
printf("Write something: \n");
char **buf = NULL;
size_t buf_size = 0;
ssize_t bytes_read = getline(buf, &buf_size, stdin);
if (bytes_read != -1)
write(STDOUT_FILENO, buf, buf_size);
else
printf("An error occured\n");
free(buf);
return (0);
}
从上面的代码中.我的程序显示了文本:发生了一个错误。做了一些代码重构,这是我得出的结果:
int main(int ac, char **av)
{
printf("Write something: \n");
char *buf = NULL;
size_t buf_size = 0;
ssize_t bytes_read = getline(&buf, &buf_size, stdin);
if (bytes_read != -1)
write(STDOUT_FILENO, buf, buf_size);
else
printf("An error occured\n");
free(buf);
return (0);
}
瞧!代码显示了输入的任何内容,正是我想要的。所以我修复了这个问题。但是我想知道的是第一个代码片段有什么问题?这样做是对的吗?:char **name = "John Doe";
或char **name = NULL;
我在一个在线编译器上做了一些快速测试。代码如下:
int main() {
// Write C code here
char **name = "John Doe";
printf("%p\n", name); //0x55f5f9890004
printf("%p\n", *name); //0x656f44206e686f4a
printf("%c\n", *name); //J
printf("%p", "John Doe"); //0x55f5f9890004
return 0;
}
我意识到双指针只是被当作一个字符指针。不确定我的发现是否正确。如果你能给予一个更好的解释上面的主要功能,这将是很酷。
4条答案
按热度按时间mwg9r5ms1#
当你想改变一个函数中的变量时,你需要通过引用传递它。否则,函数将处理一个原始对象的值的副本,作为参数表达式使用,并且改变值的副本不会影响原始对象的值。
在C语言中,通过引用传递意味着通过指向对象的指针间接传递对象。
因此,解除指针的引用,函数将直接访问原始对象,并可以更改它。
在此代码片段中
在调用函数
getline
之后,你希望指针buf
指向函数中读取的字符串,所以你需要像传递另一个变量buf_size
一样通过引用将它传递给函数,该变量的值也在函数中改变,函数的调用者需要知道变量的结果值。如果你肯写
则其自身内的函数将试图解引用导致未定义行为的空指针
buf
,因为它认为所谓的“双指针”指向函数需要改变的类型char *
的对象。为了更清楚地说明这一点,请考虑以下演示程序。
程序输出为
指针
s
传递给函数的是值。也就是说,函数处理的是指针值的副本。更改副本不会影响指针s
的原始值。现在考虑下一个程序
程序输出为
也就是说,当指针s通过引用传递给函数时,函数可以通过解引用传递给函数的指向原始指针
s
的指针来改变原始指针s
。则编译器应发出声明错误的消息。用作初始化器的字符串文字被隐式转换为指向其
char *
类型的第一个元素的指针。但初始化的变量具有char **
类型,并且这些指针类型之间没有隐式转换。此外,转换说明符
%s
需要char *
类型的参数,而不是char **
类型的参数。所以你必须写
或者,由于您不能更改字符串文字,因此最好将声明编写为
uurity8g2#
在
char *buf
的情况下,getline
将转到指针buf
的存储器位置并改变该地址。在
char **buf = NULL;
的情况下,getline
将去内存位置“null”,并试图改变该地址,这是毫无意义的。你本质上是对getline
撒谎,告诉它你在内存位置“null”为它存储了一个指针。至于
char **name = "John Doe";
,它违反了C的赋值规则,任何事情都可能发生,因为代码不是有效的C。包括“似乎一直工作得很好,直到几年后在实际生产代码中发生神秘的崩溃”。bwitn5fc3#
一个双指针必须引用一个有效的指针才能工作(因为该指针将存储对新分配的内存的引用。
2nc8po8w4#
在C语言中没有“双指针”,因此不能使用它们。
但是对于任何类型的T,你都可以创建一个“指向T的指针”类型。如果T也是一个指针类型,那就是这种情况。这是一个指向指针的指针。而不是一个“双指针”。如果你把char**看作一个“双指针”,你将永远感到困惑。