运算符是运算符的&
“地址”。so&a
表示address of a
,而不仅仅是 a 的值。
这告诉你的是 a 的地址是1002
(或者正如 dreamlax 所指出的,由于 printf 的使用方式很奇怪,很可能不是真正的地址),即使值是10
. 请注意,这两个值之间没有严格的相关性,您可以很容易地拥有a=121765
和&a=494260
。
知道变量的地址允许您操纵变量“引用”或“指向”的特定值/对象。如果您希望函数操作该特定值/对象而不是操作副本,则应传递变量的地址。
取以下代码(不一定是完整代码):
int main(void)
{
int a = 10;
doIt(a);
printf("after doIt: %d", a);
doItByReference(&a);
printf("after doItByReference: %d", a);
}
void doIt(int val)
{
val = 13;
}
void doItByReference(int *val)
{
*val = 15;
}
调用doIt
传递由 保存的值a
,并且不同地址的新整数变量将该值复制到其中。该函数可以自由地对此复制副本进行任何更改,并且不会在原始a
变量中看到任何修改。
但是,调用doItByReference
会传递 的地址a
。对给定地址的值所做的任何更改都将反映为对 的更改a
。
如果您想对给定对象进行更改并将这些更改反映在原始副本中,这本身就很有用。但是,即使您不想修改原始副本中的值,这在性能方面也很有用,因为您避免了复制任何值。对于一个可能是 4 个字节(确切值不重要)的简单 int,这无关紧要。
但是,假设您有一个数千或数百万字节的结构:
struct LargeStruct
{
int buffer[134217728];
};
void doIt(LargeStruct buffer)
{
// ... do something
}
void doItByReference(LargeStruct *buffer)
{
// ... do something
}
这一次,每次调用doIt
都必须复制LargeStruct
数百万字节的整个对象,而对 doItByReference 的调用只使用现有对象,不需要复制。