我知道指针包含变量的地址,例如:
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;
,但我不明白这意味着什么。
答案 0 :(得分:4)
我更喜欢写int* p = &c;
,也就是说,指向int类型的指针被赋予c的地址。
正如您所注意到的,指针符号可能会令人困惑,因为这两者是等价的:
int *p = &c;
和
int *p;
p = &c;
希望这有帮助!
编辑:混淆是因为*
既用作解除引用运算符,又用于声明指针。因此,当p
包含c
的地址时,*p
会取消引用指针并返回c
的值。但是当你说int *p = &c;
时,*
说“p是一个指向int的指针”,但是没有做任何解除引用。
答案 1 :(得分:4)
*p = &c;
表示:
获取内存中c
的地址,该地址由编译时链接时确定( 感谢Mikeage ),例如,以0x1234为例。指向int类型的指针,即*p
被分配给0x1234,这听起来不对我,我认为你应该这样做,p = &c
然后*p
会有价值通过c
的地址指向。因此,*p
将具有c
被赋予的值(称为解除引用 - 通过在指针变量之前放置*
然后您可以获得价值)。
在你的函数中,你试图增加p。
指向的值void function (int *p) { *p++; } // It would be called like this int c = 5; function(&c); // Now c would have 6!
关键是你要通过引用传递,这是参数&c
的作用。
如果你省略了这样的传递:
void function (int p) { p++; } // And call it like this int c = 5; function(c); // c is still 5
现在c
仍然是5,但在函数本身c
内是6,但没有副本传回,因为它在函数本身的本地堆栈中递增。
答案 2 :(得分:3)
如果您希望函数在使用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;
答案 3 :(得分:3)
我无法弄清楚你的问题,但是function
看起来像我的错误,你的意思是,或许,
++(*p)
否则这是一个无操作。
答案 4 :(得分:2)
您确定p++;
是您在函数中的意思吗?这会增加p
指向的位置,但不会增加当前位置的值。如果您想要增加该值(即将c
变为6),那么您想要的是(*p)++;
。
答案 5 :(得分:1)
其他人回答了你的问题。我将补充一点,读取指针声明的有用方法就是这样。假设我有以下声明:
int i;
这很容易。在此,i
是int
。现在,让我说我有这个:
int *pi;
在这里,您可以说pi
是指向int
的指针(这是正确的)。查看它的另一种方法是*pi
是 int
,即当您的代码中有*pi
时,*pi
将int
属于++pi
类型。理解了这一点后,我认为很容易看出pi++
或int
不会增加pi
,因为(*pi)++
是错误的类型。你想要++
。需要括号,因为在C中,运算符*
的优先级高于一元运算符++*p
。由于您不使用增量的任何副作用,您也可以这样做:pi
。
当然,正如所有指针一样,{{1}}必须指出有用的内容才有意义。