我对指针有点困惑,并通过引用传递。
这是我的代码。
int y = 60;
int *x = &y;
int foo(int &something){
something = 6;
return 0;
}
foo(y);
这是我的问题,如果foo获取指针的地址,我不应该把foo(x)代替foo(y)吗?
不是y的x地址?如果是这样,为什么我不能把foo(x)?
答案 0 :(得分:2)
函数foo
不取"指针的地址" (不确定你的意思是什么......实际上你可以说foo(int **something)
取指针的地址。)
你拥有它的函数需要一个int引用。不要因为在这两种情况下使用&
符号而感到困惑。它的相似但不同,所需的语法也相应不同。
答案 1 :(得分:1)
如果你通过指针传递,那么你可以使用foo(x)。但是,引用传递并不等同于指针传递 - 尽管语法可能会错误地使您认为它们是兼容的。您的函数正在传递某些内容作为参考。如果某些东西是一个int,那么应该提供一个int变量 - 某些东西与指向int的指针不兼容。
您可以找到有关这些机制的更完整说明here。
答案 2 :(得分:1)
查看以下C ++代码
void foo(int *x){
*x = 1;
}
void bar(int &x){
x = 1;
}
int main(){
int y = 2;
foo(&y);
bar(y);
}
这是由g ++和命令行参数-S
生成的汇编代码 .file "main.c"
.text
.globl __Z3fooPi
.def __Z3fooPi; .scl 2; .type 32; .endef
__Z3fooPi:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl $1, (%eax)
popl %ebp
ret
.globl __Z3barRi
.def __Z3barRi; .scl 2; .type 32; .endef
__Z3barRi:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl $1, (%eax)
popl %ebp
ret
.def ___main; .scl 2; .type 32; .endef
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
call ___main
movl $2, 28(%esp)
leal 28(%esp), %eax
movl %eax, (%esp)
call __Z3fooPi
leal 28(%esp), %eax
movl %eax, (%esp)
call __Z3barRi
movl $0, %eax
leave
ret
实际上,通过引用传递的概念有其自己的哲学,已经反复提到过,但正如您在实现阶段(重要的阶段)中所看到的那样,它们是相同的(为两个指针生成了相同的汇编代码)和参考,你可以看到)。我看到人们在使用'按引用传递'时遇到了问题,因为它没有像人们预期的那样实现;所以也许它会更好,因为它们在实现中是相同的并且它们引起混淆,你使用指针,它的根源在较低的层次。希望它有所帮助: - )
答案 3 :(得分:0)
foo正在引用整数 - 而不是指针。引用非常类似于指针,因为在幕后传递的是传递给函数的整数的地址。在您的调用中,传递y变量的地址(在堆栈上)。
由于指针也是地址,因此它们是相似的。使用指针,访问变量的方式会有所不同 - 指针需要更明确。
下面的代码与您的代码相同,但使用不同的语法。
int foo_pointer(int *pointerToSomething)
{
*pointerToSomething = 6; // The '*' de-references the pointer, so you are assigning what goes at the address referred to
return 0;
}
foo_pointer(&y); //to pass the address of you explicitly
通常,指针用于指动态(堆)分配的结构或对象 - 不适用于您的示例等情况。