指针前pressions:** PTR ++,* ++ * PTR,并++ **使用PTR [英] Pointer expressions: **ptr++, *++*ptr and ++**ptr use
问题描述
我想在C指针文学我的手。在插图中的一个,我遇到了以下code。
I am trying my hands on a C pointer literature. In one of the illustrations, I encountered the following code.
# include <stdio.h>
int main()
{
static int a[]={0,1,2,3,4};
static int *p[]={a, a+1, a+2, a+3, a+4};
int **ptr;
ptr =p;
**ptr++;
printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);
*++*ptr;
printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);
++**ptr;
printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);
return 0;
}
我收到的输出。
1 1 1
1 2 2
1 2 3
我在证明这一输出面临的一个问题。我做了很多箱子上副本的问题很容易掌握。我能够证明输出 111
,我的麻烦开始的发言, * ++ * PTR
。
I am facing a problem in justifying this output. I made lot of boxes on a copy for easy grasp of the problem. I am able to justify the output 1 1 1
, my trouble starts with the statement, *++*ptr
.
一直以来,一元运算符从右到左执行。因此, * PTR
将首先解决,然后在 PTR
的值将递增。
此增量后,我不知道会发生什么,书上说,不知怎的, P
也增加指向这个数组中的下一个元素。输出 1 2 2
只能通过增量 P
来实现。
Since, a unary operators are executed from right to left. So, *ptr
would be tackled first, then the value at ptr
would be incremented.
After this increment, I am not sure what happens, the book says that somehow p
is also incremented to point to the next element in this array. The output 1 2 2
can only be achieved through the increment of p
.
我不知道,这种问题完全适合于计算器。结果
我尽我所能,至少浪费了10页与绘制在他们的箱子。
I am not sure that this kind of question fits exactly on stackoverflow.
I tried my best, wasted at least 10 pages with boxes drawn over them.
任何澄清将AP preciated。
Any clarification would be appreciated.
推荐答案
记住数组名可以很容易地衰变为指针,第一个元素在最前pressions(读一些的其中数组名不衰变成一个指针,第一个元素异常?巧妙地@ ħ回答 2 CO 3 )。结果
为了更好地理解,认为我的图:
Remember array name can easily decays into pointer to first element in most expressions (read some exceptions where array name not decaying into a pointer to first element? ably answered by @H2CO3).
For better understanding, consider my diagrams:
首先,假设 A
存储在内存中,如下所示。
First, suppose a
stored in memory as follows.
a
+----+----+----+----+---+
| 0 | 1 | 2 | 3 | 4 |
+----+----+----+----+---+
▲ ▲ ▲ ▲ ▲
| | | | |
a a+1 a+2 a+3 a+3
宣言静态INT * P [] = {A,A + 1,+ 2,+ 3,+ 4};
创建指针的新数组为整数,具有以下值:
Declaration static int *p[] = {a, a+1, a+2, a+3, a+4};
creates a new array of pointers to integer, with following values:
p[0] == a
p[1] == a + 1
p[2] == a + 2
p[3] == a + 3
p[4] == a + 4
现在, P
也可以承担存储在内存中类似如下:
Now, p
can also be assume to be stored in memory something like below:
p
+----+----+----+----+-----+
| a |a +1| a+2| a+3| a+4 |
+----+----+----+----+-----+
▲ ▲ ▲ ▲ ▲
| | | | |
p p+1 p+2 p+3 p+4
任务后 PTR = P;
事情会是这样的:
p a
+----+----+----+----+-----+ +----+----+----+----+---+
| a |a +1| a+2| a+3| a+4 | | 0 | 1 | 2 | 3 | 4 |
+----+----+----+----+-----+ +----+----+----+----+---+
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
| | | | | | | | | |
p p+1 p+2 p+3 p+4 a a+1 a+2 a+3 a+3
ptr
Notice: ptr points to first location in pointer array p[]
防爆pression:** PTR ++;
现在我们考虑前pression ** PTR ++;
之前,首先printf语句。
Expression: **ptr++;
Now we consider expression **ptr++;
before first printf statement.
-
PTR
是等于P
这是指针数组第一个元素的地址。
因此,PTR
指向第一个元素P [0]
在阵列(或者我们可以说,PTR
==&安培; p [0]
)
ptr
is equals top
that is address of first element in array of pointers. Hence,ptr
point to first elementp[0]
in array (or we can sayptr
==&p[0]
).
* PTR
办法 P [0]
因为 P [0]
是 A
,所以 * PTR
是 A
(所以 * PTR
== A
)
*ptr
means p[0]
and because p[0]
is a
, so *ptr
is a
( so *ptr
== a
).
而因为 * PTR
是 A
,那么 ** PTR
是 *一个
== *(A + 0)
== A [0]
是 0
。
And because *ptr
is a
, then **ptr
is *a
== *(a + 0)
== a[0]
that is 0
.
请注意在EX pression ** PTR ++;
,我们不会将其值赋给变量的任何LHS结果
因此,的效果** PTR ++;
简直就是为 PTR ++相同;
== PTR = PTR + 1
= p + 1
结果
在这前pression后这样 PTR
指向 P [1]
(或者我们可以说 PTR
== &安培; p [1]
)。
Note in expression **ptr++;
, we do not assign its value to any lhs variable.
So effect of **ptr++;
is simply same as ptr++;
== ptr = ptr + 1
= p + 1
In this way after this expression ptr
pointing to p[1]
(or we can say ptr
== &p[1]
).
打印1:
在第一个printf事情变得:
Before first printf things become:
p a
+----+----+----+----+-----+ +----+----+----+----+---+
| a | a+1| a+2| a+3| a+4 | | 0 | 1 | 2 | 3 | 4 |
+----+----+----+----+-----+ +----+----+----+----+---+
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
| | | | | | | | | |
p p+1 p+2 p+3 p+4 a a+1 a+2 a+3 a+3
ptr
Notice: ptr is equals to p + 1 that means it points to p[1]
现在我们可以理解的首页的printf:
Now we can understand First printf:
-
PTR - P
输出1
,因为:结果PTR = P + 1
,所以PTR - P
==P + 1 - P
==1
ptr - p
output1
because:
ptr = p + 1
, soptr - p
==p + 1 - p
==1
* PTR - 一个
输出 1
,因为:结果 PTR = P + 1
,所以 * PTR
== *(P + 1)
== p [1]
== A + 1
结果
这意味着: * PTR - 一个
= A + 1 - 一个
== 1
*ptr - a
output 1
because:
ptr = p + 1
, so *ptr
== *(p + 1)
== p[1]
== a + 1
This means: *ptr - a
= a + 1 - a
== 1
** PTR
输出 1
,因为:结果
* PTR
== A + 1
从点-2结果
因此, ** PTR
== *(A + 1)
== A [1]
== 1
**ptr
output 1
because:
*ptr
== a + 1
from point-2
So **ptr
== *(a + 1)
== a[1]
== 1
第一个printf后,我们有一个前pression * ++ * PTR;
。
Expression: *++*ptr;
After first printf we have an expression *++*ptr;
.
正如我们从上面的点2的知道* PTR
== P [1]
。
因此, ++ * PTR
(即 + P [1]
)将递增 p [1]
到 A + 2
As we know from above point-2 that *ptr
== p[1]
.
So, ++*ptr
(that is ++p[1]
) will increments p[1]
to a + 2
再次明白了,前pression * ++ * PTR;
我们不将其值赋给任意LHS变量,这样的效果 * ++ * PTR;
就是 ++ * PTR;
Again understand, in expression *++*ptr;
we don't assign its value to any lhs variable so effect of *++*ptr;
is just ++*ptr;
.
现在,在第二个printf事情变成了:
Now, before second printf things become:
p a
+----+----+----+----+-----+ +----+----+----+----+---+
| a |a+2 | a+2| a+3| a+4 | | 0 | 1 | 2 | 3 | 4 |
+----+----+----+----+-----+ +----+----+----+----+---+
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
| | | | | | | | | |
p p+1 p+2 p+3 p+4 a a+1 a+2 a+3 a+3
ptr
Notice: p[1] became a + 2
打印2:
现在我们可以理解的二的printf:
Now we can understand Second printf:
-
PTR - P
输出1
,因为:结果PTR = P + 1
,所以PTR - P
==P + 1 - P
==1
ptr - p
output1
because:
ptr = p + 1
, soptr - p
==p + 1 - p
==1
* PTR - 一个
输出 2
,因为:结果 PTR = P + 1
所以 * PTR
== *(P + 1)
== p [1]
== A + 2
结果
这意味着: * PTR - 一个
== A + 2 - 一个
== 2
*ptr - a
output 2
because:
ptr = p + 1
so *ptr
== *(p + 1)
== p[1]
== a + 2
This means: *ptr - a
== a + 2 - a
== 2
** PTR
输出 2
,因为:结果
* PTR
== A + 2
从点-2结果
因此, ** PTR
== *(A + 2)
== A [2]
== 2
**ptr
output 2
because:
*ptr
== a + 2
from point-2
So **ptr
== *(a + 2)
== a[2]
== 2
现在前pression ++ ** PTR;
前第三的printf。
Expression: ++**ptr;
Now expression ++**ptr;
before third printf.
当我们从上述观点-3 ** PTR
== 知道[2]
。
因此, ++ ** PTR
== ++中的[2]
将增量 A [ 2]
到 3
As we know from above point-3 that **ptr
== a[2]
.
So ++**ptr
== ++a[2]
will increments a[2]
to 3
所以在第三printf的事情变成了:
So before third printf things become:
p a
+----+----+----+----+-----+ +----+----+----+----+---+
| a | a+2| a+2| a+3| a+4 | | 0 | 1 | 3 | 3 | 4 |
+----+----+----+----+-----+ +----+----+----+----+---+
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
| | | | | | | | | |
p p+1 p+2 p+3 p+4 a a+1 a+2 a+3 a+3
ptr
Notice: a[2] = 3
打印3:
现在我们可以理解的第三的printf:
Now we can understand Third printf:
-
PTR - P
输出1
,因为:结果PTR = P + 1
所以PTR - P
==P + 1 - P
==1
ptr - p
output1
because:
ptr = p + 1
soptr - p
==p + 1 - p
==1
* PTR - 一个
输出 2
,因为:结果 PTR = P + 1
所以 * PTR
== *(P + 1)
== p [1]
== A + 2
结果
这意味着: * PTR - 一个
= A + 2 - 一个
== 2
*ptr - a
output 2
because:
ptr = p + 1
so *ptr
== *(p + 1)
== p[1]
== a + 2
This means: *ptr - a
= a + 2 - a
== 2
** PTR
输出 3
,因为:结果 * PTR
== A + 2
从点-2结果
因此, ** PTR
== *(A + 2)
== A [2]
== 3
**ptr
outputs 3
because:
*ptr
== a + 2
from point-2
So **ptr
== *(a + 2)
== a[2]
== 3
修改注意:两个指针的差异有键入 ptrdiff_t的
,为此,正确的转换操作符 TD%
,而不是%d个
。
Edit Note: The difference of two pointers has type ptrdiff_t
, and for that, the correct conversion specifier is %td
, not %d
.
另外一点:结果
<子>我要补充,我相信这将是新的学习者
假设我们有以下两行多一个4 个的printf在你面前code 返回0;
Suppose we have following two lines with one more 4th printf in you code before return 0;
**++ptr; // additional
printf("%d %d %d\n", ptr-p, *ptr-a, **ptr); // fourth printf
一个可以检查这个工作code @ codepade ,这条线输出 2 2 3
。
由于 PTR
是等于 P + 1
,之后增量 ++
操作 PTR
变成 p + 2
(或者我们可以说 PTR
== &安培; p [2]
)结果。
这双尊重术后 **
==> **(P + 2)
== * p [2]
== *(A + 2)
== A [2]
== 3
。结果
现在,又因为我们没有在此声明的任何分配操作,因此前pression的效果 ** ++ PTR;
就是 ++ PTR;
。
Because ptr
is equals to p + 1
, after increment ++
operation ptr
becomes p + 2
(or we can say ptr
== &p[2]
).
After that double deference operation **
==> **(p + 2)
== *p[2]
== *(a + 2)
== a[2]
== 3
.
Now, again because we don't have any assignment operation in this statement so effect of expression **++ptr;
is just ++ptr;
.
所以经过前pression事情 ** ++ PTR;
如下成为图:
So thing after expression **++ptr;
becomes as below in figure:
p a
+----+----+----+----+-----+ +----+----+----+----+---+
| a | a+2| a+2| a+3| a+4 | | 0 | 1 | 3 | 3 | 4 |
+----+----+----+----+-----+ +----+----+----+----+---+
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
| | | | | | | | | |
p p+1 p+2 p+3 p+4 a a+1 a+2 a+3 a+3
ptr
Notice: ptr is equals to p + 2 that means it points to p[2]
打印4:
考虑第四的printf我在问题补充:
Considering Forth printf I added in question:
-
PTR - P
输出2
,因为:结果PTR = P + 2
所以PTR - P
==P + 2 - P
==2
ptr - p
output2
because:
ptr = p + 2
soptr - p
==p + 2 - p
==2
* PTR - 一个
输出 2
,因为:结果 PTR = P + 2
所以 * PTR
== *(P + 2)
== p [2]
== A + 2
结果
这意味着: * PTR - 一个
= A + 2 - 一个
== 2
*ptr - a
output 2
because:
ptr = p + 2
so *ptr
== *(p + 2)
== p[2]
== a + 2
This means: *ptr - a
= a + 2 - a
== 2
** PTR
输出 3
,因为:结果 * PTR
== A + 2
从上面点-2结果
因此, ** PTR
== *(A + 2)
== A [2]
== 3
**ptr
outputs 3
because:
*ptr
== a + 2
from above point-2
So **ptr
== *(a + 2)
== a[2]
== 3
这篇关于指针前pressions:** PTR ++,* ++ * PTR,并++ **使用PTR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!