这个C代码错了吗?
我知道指针包含变量的地址,例如:
int c = 5; int *p; p = &c; printf("%d",*p); // Outputs 5.
但是如果我想向一个函数发送一个地址呢:
void function (int *p) { p++; } int c; function (&c);
调用函数时, &c
的值分配给int *p
。 我想确切的说明是: *p = &c;
,但我不明白这意味着什么。
我更喜欢写int* p = &c;
也就是说,指向int类型的指针被赋予c的地址。
正如您所注意到的,指针符号可能会令人困惑,因为这两者是等价的:
int *p = &c;
和
int *p; p = &c;
希望这可以帮助!
编辑:混淆是因为*
既用作解除引用运算符,又用于声明指针。 所以当p
包含c
的地址时, *p
取消引用指针并返回c
的值。 但是当你说int *p = &c;
, *
表示“p是指向int的指针”,但没有进行任何解除引用。
*p = &c;
手段:
获取内存中c
的地址,该地址在编译时链接时确定( 感谢Mikeage ),例如,0x1234作为示例。 指向int类型的指针,即*p
被分配给0x1234,这听起来不对我,我认为你应该这样做, p = &c
然后*p
将具有c
的地址指向的值。 因此*p
将具有指定c
的值(称为解除引用 – 通过在指针变量之前放置*
然后您可以获取该值)。
在您的函数中,您尝试增加p指向的值。
void函数(int * p) { * P ++; } //它会像这样被调用 int c = 5; function(C); //现在c会有6个!
关键是你想要通过引用传递,这是参数&c
作用。 如果你省略了像这样的传递:
void函数(int p) { 的p ++; } //并像这样称呼它 int c = 5; 函数(C); // c仍然是5
现在c
仍然是5,但在函数本身c
是6,但没有复制传回,因为它在函数本身的本地堆栈中递增。
我不能真正弄清楚你的问题,但这个function
对我来说就像是虫子,你的意思是,或许,
++(*p)
否则它就是无操作。
如果你希望函数在用&c
调用时增加&c
,那么写下:
void function(int *p) { ++(*p); }
function(int *p)
表示p
是函数参数。 因此无论调用者给出什么值,都会将其分配给p
(而不是*p
)。
p
的类型是int *
。 也就是说, p
是指向int的指针。
如果p
是指向int的指针,则*p
是它指向的int。
c
是一个int。 因此&c
是指向int的指针,它指向的int是c
。 因此,如果p
是&c
,则*p
是c
。
使用我的函数版本,这段代码:
int c = 5; function(&c);
与此代码相同:
int c = 5; // same as before int *p; // parameter of the function p = &c; // assign the caller's value to the parameter ++(*p); // body of the function, increments *p, which is the same as c.
与此代码相同:
int c = 5; ++c;
你确定p++;
你的意思是你的function? 这是递增p
指向的位置,它不会增加当前位置的值。 如果你想增加值(即使c
变为6),那么你想要的是(*p)++;
。
其他人回答了你的问题。 我将补充一点,读取指针声明的有用方法就是这样。 假设我有以下声明:
int i;
这真的很容易。 在这里, i
是一个int
。 现在,让我说我有这个:
int *pi;
在这里,你可以说pi
是指向int
的指针(这是正确的)。 另一种看待它的方法是*pi
是一个 int
,即当你的代码中有*pi
时, *pi
将是int
类型。 理解了这一点后,我认为很容易看出++pi
或pi++
不会增加int
,因为pi
是错误的类型。 你想要(*pi)++
。 括号是必需的,因为在C中,operator ++
优先级高于一元运算符*
。 由于您不使用增量的任何副作用,您也可以这样做: ++*p
。
当然,和所有指针一样, pi
必须指出一些有用的东西才能使上述有意义。