[英]C Pointer to Pointer and Pass by Reference
我正在尝试学习 C,我对指针的指针有点挂断。 我想我理解你为什么需要它们,但不能完全理解正在发生的事情。
例如,下面的代码似乎不像我期望的那样工作:
#include <stdio.h>
int newp(char **p) {
char d = 'b';
*p = &d;
/*printf("**p = %c\n", **p);*/
return 1;
}
int main() {
char c = 'a';
char *p = &c;
int result;
result = newp(&p);
printf("result = %d\n", result);
printf("*p = %c\n", *p);
printf("c = %c\n", c);
return 0;
}
我得到的结果是这样的:
result = 1
*p =
c = a
*p 打印为空。 相反,我希望*p = b
。
但是,如果我取消注释第 6 行( newp
函数中的printf
),那么我会得到:
**p = b
result = 1
*p = b
c = a
我错过了什么?
您正在处理未定义的行为。 变量d
是本地的(驻留在堆栈上)并且在封闭的 function ( newp
) 返回后不可用。
当在newp
之外取消引用p
时,堆栈&d
上的地址可能会被其他一些局部变量覆盖,或者它可能包含垃圾。
您将局部变量 ( d
) 的地址存储在*p
中,然后在变量超出 scope 时取消引用它。 未定义的行为
您可能“缺少”关键字static
,如:
int newp(char **p) {
static char d = 'b'; /* <--- HERE */
*p = &d;
/*printf("**p = %c\n", **p);*/
return 1;
}
这个static
关键字使编译器将局部变量定位在“静态存储”中,该局部变量在调用newp()
之后的时间段内继续存在(即保持其值)。 但是,此 memory 只有一个副本 - 包含 function ( newp
) 的每个后续调用都重新使用相同的 memory 位置并可能覆盖当时的值。
如果没有static
关键字来限定您的局部变量声明,则存储将是“自动”的,这意味着在包含 function 已返回后,它将自动从当前使用中解除。 newp
返回后,以前用于局部变量的 memory 可以用于任何目的。
#include <stdio.h>
// Here *pointer means that the parameter that this function
// will expect will be a pointer.
void changeViaPointer(int *pointer);
// Pointer of a pointer.
void changeViaPointerInBetween(int **pointer);
int main(){
int number;
number = 20;
// Here *pointer means that the variable that is declared will be a pointer.
int *pointer;
// Actually asigning value to the pointer variable.
pointer = &number;
// Pointer of a pointer.
int **pointerInBetween;
// Assigning value to the pointer of a pointer.
// Assigning the memory location where this pointer points to.
// So this is a pointer in between.
pointerInBetween = &pointer;
printf("The number before changing is %d\n", number);
// Pass the pointer variable.
changeViaPointer(pointer);
printf("The number after pointer changing is %d\n", number);
// Pass the pointer of a pointer variable.
changeViaPointerInBetween(pointerInBetween);
printf("The number after pointer in between changing is %d\n", number);
return 0;
}
void changeViaPointer(int *pointer){
// Okay, at this point we have received a variable called pointer,
// which points to some value. In order to access this value
// we need to use *pointer.
// BUT THIS IS DIFFERENT FROM THE *pointer IN THE FUNCTION DECLARATION!!!
*pointer = *pointer + 20;
}
void changeViaPointerInBetween(int **pointer){
// **pointer explanation:
// Only pointer is the memory location
// *pointer is the value of that memory location, which in this specific case is also a memory location
// **pointer is the value of what the other pointer points to.
**pointer = **pointer + 20;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.