我正在研究一个函数,我想将参数作为指针传递并在函数内部分配其值。我通过使用指向指针的指针和单独使用指针来解决。如果在从参数分配指针的值时指针可以完全相同地作用,何时需要使用指向该指针的指针呢?
在下面查看我的示例代码。
var giveCoins = true;
function giveCoinsFunction(ID){...}
function ranWhenMessageIsSent(m){
giveCoins = true;
if(m.content.toLowerCase() === `!coins`){
giveCoins = false;
coins.run(bot,m,m.content.toLowerCase().split(" ");
}
if(giveCoins) giveCoinsFunction(m.author.id);
}
在Why use double pointer? or Why use pointers to pointers?中接受的答案并没有反过来说明为什么在C中需要使用双指针。
答案 0 :(得分:4)
这是各种各样的问题。您的程序没有不指示baz()
可以正常运行。看来只是因为其他问题。
y
中的变量bar()
是本地变量。它及其存储仅在执行bar()
期间有效。 bar()
完成后,y
不再有效,存储也不再有效。但是,您已经使num
指向该存储。这将导致不确定的行为。只是偶然,该存储没有被重用或覆盖,在您打印其值时仍保持为2。
baz()
不会影响num
指向的内容。该函数中的f
是一个参数,因此对于baz()
是局部的。对f
的分配仅影响该本地。
那么,为什么在调用*num
之后打印baz()
会产生“ 3”?因为num
仍然指向y
的调用中的bar()
的存储,而对baz()
的调用用3覆盖了该存储。这再次是偶然的,不可能依靠。
您确实确实需要使用指向num
的指针来影响bar()
。但是从本地范围返回后,切勿使用指向本地的指针。
答案 1 :(得分:1)
在'c'中有双,三,...指针的多种用法。推算您的示例,可以使用双指针将值分配给作为参数传递给函数的指针。
因此,如果您使用bar
函数,则其中会有部分用法:
void bar(int **f) {
...
(*f) = temp;
}
int main () {
int *ptr;
bar(&ptr);
}
在上面的示例中,函数bar
将为指针ptr分配一个值,该值以后可在主指针中使用。
但是,您的问题是,在您的示例中,您为其分配了一个仅在函数内部有效的指针。当函数返回时,将为ptr
分配一个值,因为它存在于函数内部,但是它将指向一个无效值。该程序的行为将在这一点上尚未定义。
此行为可用于返回指向动态分配的内存或静态变量的指针,即
void bar(int **f) {
int *tmp = (int*)malloc(sizeof(int));
*tmp = 10;
*f = tmp;
}
在此示例中,将为tmp分配一个动态分配的内存的指针,该指针将一直持续到使用了free
为止。您可以将tmp
的值分配给*f
,然后在main
中使用它。还有静态或全局变量的用法,这些变量在函数返回后仍然存在。
答案 2 :(得分:0)
在StackOverflow中搜索后,我发现当您想更改函数中指向的指针时,需要使用指向指针的指针作为函数参数。
我找到了以下链接Edit where a pointer points within a function和Changing address contained by pointer using function
C没有通过引用的传递,因此它的工作方式如下:
指针只是一个普通变量,将其他地址作为其值。如果将初始化的指针传递给函数,则该函数会接收到一个指针副本,其中包含原始地址作为其值。您可以通过取消对指针的引用并为其分配新值来更改指针所保存的内存地址上的值。指向该内存地址的任何其他指针也指向新值。这适用于指针所指向的值,但是您不能更改指针本身的地址(请记住,它只是原始指针的副本,其原始地址与函数的本地地址完全不同,对指针的任何更改指针本身的地址将在函数返回时丢失)
要在函数内更改指针本身(例如realloc
等时),必须将指针的地址作为参数传递。例如。 foo (&the_pointer)
函数参数必须是 pointer-to-pointer (例如,双指针)。它遵循相同的语义,但是现在您要按值传递指针的地址。然后,您可以通过将新的指针地址分配给函数中已取消引用的指针来自由更改指针的地址。然后,更改将在调用函数中可见。