将“指向指针的指针”和“指针的地址”传递给函数的区别
Difference between passing “pointer to pointer” and “address of pointer” to a function
我有一个接受 char **
的函数;它在内部使用它来维护连续调用之间的上下文。
定义char **x
并传递x
与定义char *x
并传递&x
有什么区别?
对于上下文: 在阅读源代码之前,我尝试自己实现 strtok
手册页中的示例。我遇到了段错误。然后在尝试之后我查看了源代码。
问题是我定义了 char **x
并将 x
作为 **saveptr
参数传递,但是将定义更改为 char *x
并将传递给 &x
解决了问题。
到底是什么问题?
当你定义例如
char **x;
然后你简单地定义一个指针。它是指向另一个指针的指针并不重要,重要的是它只是一个指针。因此,根据上面显示的定义,它没有被初始化。它没有指向任何特别的地方。取消引用它,就像您最有可能在函数中所做的那样,会导致 未定义的行为。
另一方面,定义如
char *x;
并使用 &x
获取指向它的指针,&x
返回的指针指向某个有效的地方,指向变量 x
。取消引用 &x
将允许函数访问和修改 x
本身。
以这种方式使用 address-of 运算符是一种模拟 按引用传递 的方法,C 没有。
因为在C中所有的函数参数都是通过值传递的,如果你定义char **x
并传递x
,它不会被修改功能。如果定义char *x
,传&x
,就可以修改(改变它的指向地址)。
第一个版本 char **x;
并传递 x
,创建并使用指向 char 的指针的未初始化指针。
第二个版本,使用 char * x;
并传递 &x
,创建一个指向 char 的未初始化指针,但传递一个值,该值是指向 char 的指针的有效地址,并且是一个定义值(即像一个初始化的指向指向 char 的未初始化指针的指针)。
基本上在第一个版本中,您要求在内存中的 "random" 位置写入(几乎肯定会出现段错误);其次,您要求写入现有的指针变量。
我有一个接受 char **
的函数;它在内部使用它来维护连续调用之间的上下文。
定义char **x
并传递x
与定义char *x
并传递&x
有什么区别?
对于上下文: 在阅读源代码之前,我尝试自己实现 strtok
手册页中的示例。我遇到了段错误。然后在尝试之后我查看了源代码。
问题是我定义了 char **x
并将 x
作为 **saveptr
参数传递,但是将定义更改为 char *x
并将传递给 &x
解决了问题。
到底是什么问题?
当你定义例如
char **x;
然后你简单地定义一个指针。它是指向另一个指针的指针并不重要,重要的是它只是一个指针。因此,根据上面显示的定义,它没有被初始化。它没有指向任何特别的地方。取消引用它,就像您最有可能在函数中所做的那样,会导致 未定义的行为。
另一方面,定义如
char *x;
并使用 &x
获取指向它的指针,&x
返回的指针指向某个有效的地方,指向变量 x
。取消引用 &x
将允许函数访问和修改 x
本身。
以这种方式使用 address-of 运算符是一种模拟 按引用传递 的方法,C 没有。
因为在C中所有的函数参数都是通过值传递的,如果你定义char **x
并传递x
,它不会被修改功能。如果定义char *x
,传&x
,就可以修改(改变它的指向地址)。
第一个版本 char **x;
并传递 x
,创建并使用指向 char 的指针的未初始化指针。
第二个版本,使用 char * x;
并传递 &x
,创建一个指向 char 的未初始化指针,但传递一个值,该值是指向 char 的指针的有效地址,并且是一个定义值(即像一个初始化的指向指向 char 的未初始化指针的指针)。
基本上在第一个版本中,您要求在内存中的 "random" 位置写入(几乎肯定会出现段错误);其次,您要求写入现有的指针变量。