我知道,指针包含的变量的地址,例如:这个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;
,但我不明白这是什么意思。
我知道,指针包含的变量的地址,例如:这个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++;
是您的意思吗?这会增加p
指向的位置,但不会递增当前位置的值。如果你想增加价值(即使c
变成6),那么你想要的是(*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;
非常感谢很多人,这正是我所要求的 – hamza 2009-12-15 17:30:19
我无法真正弄清楚你的问题,但function
看起来像我的错误,你的意思是我s,或许,
++(*p)
否则它是一个没有操作。
严格地说,该函数中的'p ++'调用未定义的行为(因为递增p会创建一个指向无效位置的指针)。实际上,在所有普通的C编译器中,它什么都不做。 – 2009-12-13 14:40:10
不,没有未定义的行为,因为递增的p永远不会使它脱离函数并立即被丢弃。 – 2009-12-13 14:47:43
但是即使计算这样一个指针也是未定义的行为,不是吗? – 2009-12-13 15:31:52
*p = &c;
指:
获取其在
编译时决定
链接时(感谢Mikeage)e.g,0x1234的作为例子的c
在存储器中的地址。类型为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,但没有副本传递回了,因为它是在本地栈内增加内函数本身。
迂腐,它只在编译时部分确定;取决于所得到的对象的操作系统和/或共享文库[我知道这不是一个短语],它可能是可重定位的。但你仍然得到一个+1为使用提问者的正确水平的细节(我当然没有......) – Mikeage 2009-12-13 13:35:17
@Mikeage:谢谢:)那么,在编译时发生在连接权之前? ;)你就在那里......也许这个词应该是'在链接时',而不是编译时......感谢指出它! :) – t0mm13b 2009-12-13 13:43:50
实际上,在加载时间;有些情况下,它可以在运行时重新定位 – Mikeage 2009-12-15 09:29:19
其他人已回答你的问题。我将补充一点,阅读指针声明的有用方法是这样的。假设我有以下声明:
int i;
这真的很容易。这里,i
是int
。现在,让我们说我有这样的:
int *pi;
在这里,你可以说pi
是一个指向int
(这是正确的)。另一种看待它的方式是*pi
是int
,即当你的代码中有*pi
时,*pi
将是int
类型。在了解之后,我认为很容易看出++pi
或pi++
不会增加int
,因为pi
是错误的类型。你想要(*pi)++
。括号是必需的,因为在C中,运算符++
比一元运算符*
具有更高的优先级。既然你不使用任何增量的副作用,你也可以这样做:++*p
。
当然,就像所有的指针一样,pi
必须指出一些对上述有用的东西是有意义的。
不,它不会“增加p指向的位置”,它只是增加p。 – 2009-12-13 13:07:07
对不起,我的部分表达不好。由于'p'是一个指针,所以递增它会调用指针算术,这会将指针有效指向的内存地址移动一个点(改变*位置*,而不是*位置处的值* - 这就是我的意思通过递增位置,而不是递增位置处的值)。 – Amber 2009-12-13 13:10:37