C++ 指针表达式:*ptr++、*++ptr 和 ++*ptr
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18481740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pointer expressions: *ptr++, *++ptr and ++*ptr
提问by allocated
Recently I have come across this problem which I am unable to understand by myself.
最近我遇到了这个我自己无法理解的问题。
What do these three Expressions REALLYmean?
这三个表达式的真正含义是什么?
*ptr++
*++ptr
++*ptr
I have tried Ritchie. But unfortunately was unable to follow what he told about these 3 operations.
我试过里奇。但不幸的是,他无法理解他讲述的这 3 次手术。
I know they are all performed to increment the pointer/the value pointed to. I can also guess there may be a lot of things about precedence and order of evaluation. Like one increments the pointer first then fetches the content of that pointer, one simply fetches the content and then increments the pointer etc etc. As you can see, I don't have a clear understanding about their actualoperations, which i would like to clear as soon as possible. But I am truly lost when I get a chance to apply them in programs. For example:
我知道它们都是为了增加指针/指向的值而执行的。我也可以猜测可能有很多关于优先级和评估顺序的事情。就像先增加指针然后获取该指针的内容一样,一个简单地获取内容然后增加指针等等。正如你所看到的,我对他们的实际操作没有清晰的理解,我想尽快清除。但是当我有机会在程序中应用它们时,我真的迷失了。例如:
int main()
{
const char *p = "Hello";
while(*p++)
printf("%c",*p);
return 0;
}
gives me this output:
给我这个输出:
ello
But my expectation was that it would print Hello
.
One final request -- Please give me examples for how each expression works in a given code snippet. As most of the time only a mere paragraph of theory gets flown over my head.
但我的期望是它会打印Hello
. 最后一个请求——请举例说明每个表达式在给定代码片段中的工作方式。因为大多数时候只有一小段理论会飞过我的脑海。
回答by verbose
Here's a detailed explanation which I hope will be helpful. Let's begin with your program, as it's the simplest to explain.
这里有一个详细的解释,我希望会有所帮助。让我们从您的程序开始,因为它最容易解释。
int main()
{
const char *p = "Hello";
while(*p++)
printf("%c",*p);
return 0;
}
The first statement:
第一条声明:
const char* p = "Hello";
declares p
as a pointer to char
. When we say "pointer to a char
", what does that mean? It means that the value of p
is the address of a char
; p
tells us where in memory there is some space set aside to hold a char
.
声明p
为指向char
. 当我们说“指向 a 的指针char
”时,它是什么意思?这意味着 的值p
是 a 的地址char
;p
告诉我们在内存中的哪个地方留出了一些空间来保存char
.
The statement also initializes p
to point to the first character in the string literal "Hello"
. For the sake of this exercise, it's important to understand p
as pointing not to the entire string, but only to the first character, 'H'
. After all, p
is a pointer to one char
, not to the entire string. The value of p
is the address of the 'H'
in "Hello"
.
该语句还初始化p
为指向字符串文字中的第一个字符"Hello"
。就本练习而言,重要的是要理解p
为不指向整个字符串,而只指向第一个字符'H'
. 毕竟,p
是一个指向 one 的指针char
,而不是整个字符串。的值p
是'H'
in的地址"Hello"
。
Then you set up a loop:
然后你设置一个循环:
while (*p++)
What does the loop condition *p++
mean? Three things are at work here that make this puzzling (at least until familiarity sets in):
循环条件*p++
是什么意思?这里有三件事情在起作用,使这个令人费解(至少在熟悉之前):
- The precedence of the two operators, postfix
++
and indirection*
- The value of a postfix increment expression
- The side effect of a postfix increment expression
- 后缀
++
和间接两个运算符的优先级*
- 后缀增量表达式的值
- 后缀增量表达式的副作用
1. Precedence. A quick glance at the precedence table for operators will tell you that postfix increment has a higher precedence (16) than dereference / indirection (15). This means that the complex expression *p++
is going to be grouped as: *(p++)
. That is to say, the *
part will be applied to the value of the p++
part. So let's take the p++
part first.
1. 优先级。快速浏览运算符的优先级表会告诉您,后缀增量的优先级 (16) 比取消引用/间接 (15) 的优先级更高。这意味着复杂的表达式*p++
将被分组为:*(p++)
。也就是说,*
零件将应用于零件的值p++
。所以让我们p++
先来看看。
2. Postfix expression value. The value of p++
is the value of p
before the increment. If you have:
2.后缀表达式值。的值p++
是p
增量之前的值。如果你有:
int i = 7;
printf ("%d\n", i++);
printf ("%d\n", i);
the output will be:
输出将是:
7
8
because i++
evaluates to i
before the increment. Similarly p++
is going to evaluate to the current value of p
. As we know, the current value of p
is the address of 'H'
.
因为在增量之前i++
评估为i
。同样p++
将评估为 的当前值p
。众所周知, 的当前值p
是 的地址'H'
。
So now the p++
part of *p++
has been evaluated; it's the current value of p
. Then the *
part happens. *(current value of p)
means: access the value at the address held by p
. We know that the value at that address is 'H'
. So the expression *p++
evaluates to 'H'
.
所以现在已经评估了 的p++
部分*p++
;它是 的当前值p
。然后*
部分发生。*(current value of p)
表示:访问 持有的地址处的值p
。我们知道那个地址的值是'H'
。因此表达式的*p++
计算结果为'H'
。
Now hold on a minute, you're saying. If *p++
evaluates to 'H'
, why doesn't that 'H'
print in the above code? That's where side effectscome in.
现在等一下,你是说。如果*p++
计算为'H'
,为什么不在'H'
上面的代码中打印?这就是副作用的来源。
3. Postfix expression side effects. The postfix ++
has the valueof the current operand, but it has the side effectof incrementing that operand. Huh? Take a look at that int
code again:
3.后缀表达式的副作用。后缀++
具有当前操作数的值,但它具有增加该操作数的副作用。嗯?int
再看看那段代码:
int i = 7;
printf ("%d\n", i++);
printf ("%d\n", i);
As noted earlier, the output will be:
如前所述,输出将是:
7
8
When i++
is evaluated in the first printf()
, it evaluates to 7. But the C standard guarantees that at some point before the second printf()
begins executing, the side effectof the ++
operator will have taken place. That is to say, before the second printf()
happens, i
will have been incremented as a result of the ++
operator in the first printf()
. This, by the way, is one of the few guarantees the standard gives about the timing of side effects.
当i++
在第一评估printf()
中,评估为7.但C标准保证在某个点之前的第二printf()
处开始执行,在副作用的的++
操作员将已经发生。也就是说,在第二个printf()
发生之前,i
将由于第一个中的++
运算符而增加printf()
。顺便说一下,这是标准给出的关于副作用时间的少数保证之一。
In your code, then, when the expression *p++
is evaluated, it evaluates to 'H'
. But by the time you get to this:
然后,在您的代码中,当计算表达式时*p++
,它的计算结果为'H'
。但是当你达到这个目的时:
printf ("%c", *p)
that pesky side-effect has occurred. p
has been incremented. Whoa! It no longer points to 'H'
, but to one character past 'H'
: to the 'e'
, in other words. That explains your cockneyfied output:
那个讨厌的副作用已经发生了。p
已增加。哇!它不再指向'H'
,而是指向过去的一个字符'H'
:'e'
换句话说,指向。这解释了你笨拙的输出:
ello
Hence the chorus of helpful (and accurate) suggestions in the other answers: to print the Received Pronunciation "Hello"
and not its cockney counterpart, you need something like
因此,其他答案中有很多有用(且准确)的建议:要打印收到的发音"Hello"
而不是它的 cockney 对应物,您需要类似的东西
while (*p)
printf ("%c", *p++);
So much for that. What about the rest? You ask about the meanings of these:
这么多。剩下的呢?你询问这些的含义:
*ptr++
*++ptr
++*ptr
We just talked about the first, so let's look at the second: *++ptr
.
我们刚刚谈到了第一个,那么让我们来看看第二个:*++ptr
.
We saw in our earlier explanation that postfix increment p++
has a certain precedence, a value, and a side effect. The prefix increment ++p
has the same side effectas its postfix counterpart: it increments its operand by 1. However, it has a different precedenceand a different value.
我们在前面的解释中看到后缀增量p++
具有一定的优先级、值和副作用。前缀增量与其后缀对应项++p
具有相同的副作用:它将其操作数增加 1。但是,它具有不同的优先级和不同的值。
The prefix increment has lower precedence than the postfix; it has precedence 15. In other words, it has the same precedence as the dereference / indirection operator *
. In an expression like
前缀增量的优先级低于后缀;它的优先级为 15。换句话说,它与取消引用/间接操作符具有相同的优先级*
。像这样的表达
*++ptr
what matters is not precedence: the two operators are identical in precedence. So associativitykicks in. The prefix increment and the indirection operator have right-left associativity. Because of that associativity, the operand ptr
is going to be grouped with the rightmost operator ++
before the operator more to the left, *
. In other words, the expression is going to be grouped *(++ptr)
. So, as with *ptr++
but for a different reason, here too the *
part is going to be applied to the value of the ++ptr
part.
重要的不是优先级:两个运算符的优先级相同。所以结合性开始了。前缀增量和间接运算符具有左右结合性。由于这种结合性,操作数ptr
将与最右侧的运算符分组,++
然后再与更左侧的运算符*
. 换句话说,表达式将被分组*(++ptr)
。因此,与*ptr++
但出于不同原因一样,这里也将*
零件应用于++ptr
零件的价值。
So what is that value? The value of the prefix increment expression is the value of the operand after the increment. This makes it a very different beast from the postfix increment operator. Let's say you have:
那么这个值是多少呢?前缀增量表达式的值是增量后的操作数的值。这使它成为与后缀增量运算符非常不同的野兽。假设你有:
int i = 7;
printf ("%d\n", ++i);
printf ("%d\n", i);
The output will be:
输出将是:
8
8
... different from what we saw with the postfix operator. Similarly, if you have:
...与我们在后缀运算符中看到的不同。同样,如果您有:
const char* p = "Hello";
printf ("%c ", *p); // note space in format string
printf ("%c ", *++p); // value of ++p is p after the increment
printf ("%c ", *p++); // value of p++ is p before the increment
printf ("%c ", *p); // value of p has been incremented as a side effect of p++
the output will be:
输出将是:
H e e l // good dog
Do you see why?
你明白为什么吗?
Now we get to the third expression you asked about, ++*ptr
. That's the trickiest of the lot, actually. Both operators have the same precedence, and right-left associativity. This means the expression will be grouped ++(*ptr)
. The ++
part will be applied to the value of the *ptr
part.
现在我们得到你问的第三个表达式,++*ptr
。实际上,这是最棘手的。两个运算符具有相同的优先级和左右结合性。这意味着表达式将被分组++(*ptr)
。该++
部分将应用于该部分的值*ptr
。
So if we have:
所以如果我们有:
char q[] = "Hello";
char* p = q;
printf ("%c", ++*p);
the surprisingly egotistical output is going to be:
令人惊讶的自负输出将是:
I
What?! Okay, so the *p
part is going to evaluate to 'H'
. Then the ++
comes into play, at which point, it's going to be applied to the 'H'
, not to the pointer at all! What happens when you add 1 to 'H'
? You get 1 plus the ASCII value of 'H'
, 72; you get 73. Represent that as a char
, and you get the char
with the ASCII value of 73: 'I'
.
什么?!好的,所以该*p
部分将评估为'H'
。然后++
开始发挥作用,此时,它将应用于'H'
,而不是指针!将 1 添加到 会发生什么'H'
?你得到 1 加上 的 ASCII 值'H'
,72;你得到 73. 将它表示为 a char
,你得到char
ASCII 值为 73: 'I'
。
That takes care of the three expressions you asked about in your question. Here is another, mentioned in the first comment to your question:
这会处理您在问题中询问的三个表达式。这是您问题的第一条评论中提到的另一个:
(*ptr)++
That one is interesting too. If you have:
那一个也很有趣。如果你有:
char q[] = "Hello";
char* p = q;
printf ("%c", (*p)++);
printf ("%c\n", *p);
it will give you this enthusiastic output:
它会给你这个热情的输出:
HI
What's going on? Again, it's a matter of precedence, expression value, and side effects. Because of the parentheses, the *p
part is treated as a primary expression. Primary expressions trump everything else; they get evaluated first. And *p
, as you know, evaluates to 'H'
. The rest of the expression, the ++
part, is applied to that value. So, in this case, (*p)++
becomes 'H'++
.
这是怎么回事?同样,这是一个优先级、表达式值和副作用的问题。由于括号的原因,该*p
部分被视为主要表达式。主要表达胜过其他一切;他们首先得到评估。并且*p
,如您所知,计算结果为'H'
。表达式的其余++
部分,即部分,应用于该值。因此,在这种情况下,(*p)++
变为'H'++
。
What is the value of 'H'++
? If you said 'I'
, you've forgotten (already!) our discussion of value vs. side effect with postfix increment. Remember, 'H'++
evaluates to the current value of'H'
. So that first printf()
is going to print 'H'
. Then, as a side effect, that 'H'
is going to be incremented to 'I'
. The second printf()
prints that 'I'
. And you have your cheery greeting.
的价值是'H'++
什么?如果你说'I'
,你已经忘记(已经!)我们关于后缀增量的价值与副作用的讨论。请记住,'H'++
计算为 的当前值'H'
。所以首先printf()
要打印'H'
. 然后,作为副作用,它将'H'
增加到'I'
。第二个printf()
打印出来'I'
。还有你愉快的问候。
All right, but in those last two cases, why do I need
好的,但在最后两种情况下,为什么我需要
char q[] = "Hello";
char* p = q;
Why can't I just have something like
为什么我不能有类似的东西
/*const*/ char* p = "Hello";
printf ("%c", ++*p); // attempting to change string literal!
Because "Hello"
is a string literal. If you try ++*p
, you're trying to change the 'H'
in the string to 'I'
, making the whole string "Iello"
. In C, string literals are read-only; attempting to modify them invokes undefined behavior. "Iello"
is undefined in English as well, but that's just coincidence.
因为"Hello"
是字符串文字。如果您尝试++*p
,则您正在尝试'H'
将字符串中的更改为'I'
,从而使整个字符串"Iello"
. 在 C 中,字符串文字是只读的;尝试修改它们会调用未定义的行为。"Iello"
英语中也未定义,但这只是巧合。
Conversely, you can't have
相反,你不能有
char p[] = "Hello";
printf ("%c", *++p); // attempting to modify value of array identifier!
Why not? Because in this instance, p
is an array. An array is not a modifiable l-value; you can't change where p
points by pre- or post- increment or decrement, because the name of the array works as though it's a constant pointer. (That's not what it actually is; that's just a convenient way to look at it.)
为什么不?因为在这个例子中,p
是一个数组。数组不是可修改的左值;您不能通过p
前后递增或递减来更改指向的位置,因为数组的名称就像一个常量指针一样工作。(实际情况并非如此;这只是一种方便的查看方式。)
To sum up, here are the three things you asked about:
总结一下,这里是你问的三件事:
*ptr++ // effectively dereferences the pointer, then increments the pointer
*++ptr // effectively increments the pointer, then dereferences the pointer
++*ptr // effectively dereferences the pointer, then increments dereferenced value
And here's a fourth, every bit as much fun as the other three:
这是第四个,和其他三个一样有趣:
(*ptr)++ // effectively forces a dereference, then increments dereferenced value
The first and second will crash if ptr
is actually an array identifier. The third and fourth will crash if ptr
points to a string literal.
如果ptr
实际上是数组标识符,第一个和第二个将崩溃。如果ptr
指向字符串文字,第三个和第四个将崩溃。
There you have it. I hope it's all crystal now. You've been a great audience, and I'll be here all week.
你有它。我希望现在一切都是水晶。你一直是一个很棒的观众,我整个星期都会在这里。
回答by nickie
Suppose ptr
points to the i-th element of array arr
.
假设ptr
指向 array 的第 i 个元素arr
。
*ptr++
evaluates toarr[i]
and setsptr
to point to the (i+1)-th element ofarr
. It is equivalent to*(ptr++)
.*++ptr
setsptr
to point to the (i+1)-th element ofarr
and evaluates toarr[i+1]
. It is equivalent to*(++ptr)
.++*ptr
increasesarr[i]
by one and evaluates to its increased value; the pointerptr
is left untouched. It is equivalent to++(*ptr)
.
*ptr++
计算arr[i]
并设置ptr
为指向 的第 (i+1) 个元素arr
。它相当于*(ptr++)
。*++ptr
设置ptr
为指向的第 (i+1) 个元素arr
并计算为arr[i+1]
。它相当于*(++ptr)
。++*ptr
增加arr[i]
一并评估其增加的值;指针ptr
保持不变。它相当于++(*ptr)
。
There's also one more, but you'd need parentheses to write it:
还有一个,但你需要括号来写它:
(*ptr)++
increasesarr[i]
by one and evaluates to its value before being increased; the pointerptr
is again left untouched.
(*ptr)++
增加arr[i]
1 并评估其值,然后再增加;指针ptr
再次保持不变。
The rest you can figure out yourself; it was also answered by @Jaguar.
剩下的你自己想办法;@Jaguar 也回答了这个问题。
回答by Jainendra
*ptr++ : post increment a pointer ptr
*ptr++ : post increment a pointer ptr
*++ptr : Pre Increment a pointer ptr
*++ptr : Pre Increment a pointer ptr
++*ptr : preincrement the value at ptr location
++*ptr : preincrement the value at ptr location
Read hereabout pre increment and post increment operators
在此处阅读有关前增量和后增量运算符的信息
This will give Hello
as output
这将 Hello
作为输出
int main()
{
const char *p = "Hello";
while(*p)
printf("%c",*p++);//Increment the pointer here
return 0;
}
回答by nouney
The condition in your loop is bad:
循环中的条件不好:
while(*p++)
printf("%c",*p);
Is the same as
是相同的
while(*p)
{
p++;
printf("%c",*p);
}
And that's wrong, this should be:
这是错误的,这应该是:
while(*p)
{
printf("%c",*p);
p++;
}
*ptr++
is the same as *(ptr++)
, which is:
*ptr++
与 相同*(ptr++)
,即:
const char *ptr = "example";
char value;
value = *ptr;
++ptr;
printf("%c", value); // will print 'e'
*++ptr
is the same as *(++ptr)
, which is:
*++ptr
与 相同*(++ptr)
,即:
const char *ptr = "example";
char value;
++ptr;
value = *ptr;
printf("%c", value); // will print 'x'
++*ptr
is the same as ++(*ptr)
, which is:
++*ptr
与 相同++(*ptr)
,即:
const char *ptr = "example";
char value;
value = *ptr;
++value;
printf("%c", value); // will print 'f' ('e' + 1)
回答by Nobilis
You right about precedence, note that the *
has precedence over prefix increment, but not over postfix increment. Here's how these breakdown:
您对优先级是正确的,请注意*
优先级高于前缀增量,但不高于后缀增量。以下是这些细分的方式:
*ptr++
- going from left-to-right, dereference the pointer, and then increment the pointer value (not what it points to, due to the precedence of postfix over dereference)
*ptr++
- 从左到右,取消引用指针,然后增加指针值(不是它指向的值,因为后缀优先于取消引用)
*++ptr
- increment the pointer and then dereference it, this is because prefix and dereference have the same precedence and so they are evaluated in order right-to-left
*++ptr
- 增加指针然后取消引用它,这是因为前缀和取消引用具有相同的优先级,因此它们按从右到左的顺序进行评估
++*ptr
- similar to the above in terms of precedence, again going from right-to-left in order dereference the pointer and then increment what the pointer points to. Please note that in your case this one will lead to undefined behaviour because you're trying to modify a read-only variable (char* p = "Hello";
).
++*ptr
- 在优先级方面与上述类似,再次从右到左依次取消引用指针,然后增加指针指向的内容。请注意,在您的情况下,这将导致未定义的行为,因为您正在尝试修改只读变量 ( char* p = "Hello";
)。
回答by gman
I'm going to add my take because while the other answers are correct I think they're missing something.
我要添加我的看法,因为虽然其他答案是正确的,但我认为他们遗漏了一些东西。
v = *ptr++
means
方法
temp = ptr;
ptr = ptr + 1
v = *temp;
Where as
然而
v = *++ptr
means
方法
ptr = ptr + 1
v = *ptr
It's important to understand that post increment (and post decrement) mean
重要的是要了解后递增(和后递减)意味着
temp = ptr // Temp created here!!!
ptr = ptr + 1 // or - 1 if decrement)
v = *temp // Temp destroyed here!!!
Why does it matter? Well in C that's not so important. In C++ though ptr
might be a complex type like an iterator. For example
为什么这有关系?那么在 C 中,这不是那么重要。在 C++ 中,虽然ptr
可能是像迭代器这样的复杂类型。例如
for (std::set<int>::iterator it = someSet.begin(); it != someSet.end(); it++)
In this case, because it
is a complex type it++
maybe have side effects because of the temp
creation. Of course if you're lucky the compiler will try to throw away code that's not needed but if iterator's constructor or destructor do anything then it++
is going to show those effects when it creates temp
.
在这种情况下,因为it
是一个复杂类型,it++
可能会因为temp
创建而产生副作用。当然,如果幸运的话,编译器会尝试丢弃不需要的代码,但是如果迭代器的构造函数或析构函数执行任何操作,那么it++
它会在创建时显示这些效果temp
。
The short of what I'm trying to say is Write What You Mean. If you mean increment ptrthen write ++ptr
not ptr++
. If you mean temp = ptr, ptr += 1, temp
then write ptr++
我想说的短的是写你的意思。如果您的意思是increment ptr则写++ptr
not ptr++
。如果你的意思是temp = ptr, ptr += 1, temp
然后写ptr++
回答by David R Tribble
*ptr++ // 1
This is the same as:
这与:
tmp = *ptr;
ptr++;
So the value of the object pointed to by ptr
is retrieved, then ptr
is incremented.
所以指向的对象的值ptr
被检索,然后ptr
递增。
*++ptr // 2
This is the same as:
这与:
++ptr;
tmp = *ptr;
So the pointer ptr
is incremented, then the object pointed to by ptr
is read.
所以指针ptr
递增,然后ptr
读取指向的对象。
++*ptr // 3
This is the same as:
这与:
++(*ptr);
So the object pointed to by ptr
is incremented; ptr
itself is unchanged.
所以指向的对象自ptr
增;ptr
本身不变。
回答by Kiran Padwal
postfix and prefix has higher precedence than dereference so
后缀和前缀的优先级高于取消引用,因此
*ptr++ here post increment ptr and then pointing to new value of ptr
*ptr++ 在这里发布增量 ptr 然后指向 ptr 的新值
*++ptr here Pre Increment fist then pointing to new value of ptr
*++ptr 在这里预增量拳头然后指向 ptr 的新值
++*ptr here first get the value of ptr pointing to and increment that vlaue
++*ptr 这里首先获取指向的 ptr 的值并增加该 vlaue
回答by Achal
Pointer Expressions : *ptr++, *++ptr and ++*ptr :
指针表达式:*ptr++、*++ptr 和 ++*ptr:
Note: pointers must initialized and must have valid address. Because in RAM apart from our program(a.out) there are lot more program running simultaneously i.e if you are try to access some memory which was not reserved for you OS will through Segmentation fault.
注意:指针必须初始化并且必须具有有效地址。因为在 RAM 中,除了我们的程序 (a.out) 之外,还有更多的程序同时运行,即如果您尝试访问一些不是为您保留的内存,操作系统将通过分段错误。
Before explaining this lets consider simple example ?
在解释这个之前让我们考虑一个简单的例子?
#include<stdio.h>
int main()
{
int num = 300;
int *ptr;//uninitialized pointer.. must be initialized
ptr = #
printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
*ptr = *ptr + 1;//*ptr means value/data on the address.. so here value gets incremented
printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
/** observe here that "num" got changed but manually we didn't change, it got modified by pointer **/
ptr = ptr + 1;//ptr means address.. so here address got incremented
/** char pointer gets incremented by 1 bytes
Integer pointer gets incremented by 4 bytes
**/
printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}
analyze the output of above code, I hope you got the output of above code. One thing is clear from above code is that pointer name (ptr) means we are talking about addressand *ptrmeans we are talking abbout value/data.
分析上面代码的输出,希望你得到上面代码的输出。从上面的代码中可以清楚地看出,指针名称 ( ptr) 表示我们正在谈论地址,而*ptr意味着我们正在谈论值/数据。
CASE 1: *ptr++ , *++ptr, *(ptr++) and *(++ptr) :
情况 1: *ptr++ , *++ptr, *(ptr++) 和 *(++ptr) :
above mentioned all 4 syntax are similar, in all address gets incremented
but how address gets incremented that's different.
上面提到的所有 4 种语法都是相似的,address gets incremented
但除了地址如何递增之外,其他所有语法都是不同的。
Note: for solving any expression find out how many operators are there in expression, then find out prioritiesof operator. I multiple operators having same priority then check order of evolution or associativitythat may right(R) to left(L) ot left to right.
注意:求解任何表达式,先找出表达式中有多少个运算符,然后找出运算符的优先级。我有多个具有相同优先级的运算符,然后检查可能从右(R)到左(L)或从左到右的演化顺序或结合性。
*ptr++: Here 2 operators are there namely de-reference( *) and ++(increment). Both are having same priority then check the associativity which is R to L. So starts solving from Right to Left, whatever operators is coming first.
*ptr++:这里有 2 个运算符,即取消引用(*)和 ++(增量)。两者都具有相同的优先级,然后检查从 R 到 L 的结合性。所以从右到左开始求解,无论哪个运算符先出现。
*ptr++: first ++ came while solving from R to L, so address gets incremented but its post increment.
*ptr++:第一个 ++ 在从 R 求解到 L 时出现,因此地址增加但其后增加。
*++ptr: Same as first one here also address gets incremented but its pre increment.
*++ptr:与此处的第一个相同,地址也会增加,但它的预增加。
*(ptr++): Here there are 3 operators, among them grouping () having highest priority, So first ptr++ solved i.e address gets incremented but post.
*(ptr++): 这里有 3 个操作符,其中 grouping () 具有最高优先级,所以首先 ptr++ 解决了即地址增加但发布。
*(++ptr): Same as above case here also address gets incremented but pre increment.
*(++ptr):与上面的情况相同,这里的地址也增加但预增加。
CASE 2: ++*ptr, ++(*ptr), (*ptr)++ :
情况 2: ++*ptr, ++(*ptr), (*ptr)++ :
above mentioned all 4 syntax are similar, in all value/data gets incrementedbut how value gets changed that's different.
上面提到的所有 4 种语法都是相似的,在所有值/数据中都增加了但是值如何改变是不同的。
++*ptr: first * came while solving from R to L, so value gets changed but its pre increment.
++*ptr:第一个 * 是在从 R 求解到 L 时出现的,因此值会改变但它的预增量。
++(*ptr): Same as above case, value gets modified.
++(*ptr):与上述情况相同,值被修改。
(*ptr)++: Here there are 3 operators, among them grouping () having highest priority, Inside () *ptr is there , So first *ptr is solved i.e value gets incremented but post.
(*ptr)++:这里有 3 个运算符,其中 grouping () 具有最高优先级, Inside () *ptr 在那里,所以首先解决了 *ptr ,即值增加但发布。
Note: ++*ptr and *ptr = *ptr + 1 both are same, in both case value gets changed. ++*ptr : only 1 instruction (INC) is used, directly value gets changed in single shot. *ptr = *ptr + 1 : here first value gets incremented(INC) and then assigned(MOV).
注意:++*ptr 和 *ptr = *ptr + 1 都是相同的,在这两种情况下值都会改变。++*ptr : 仅使用 1 条指令 (INC),单次直接更改值。*ptr = *ptr + 1 :这里第一个值增加(INC)然后分配(MOV)。
To understand all above different syntax of increment on pointer lets consider simple code :
要理解上述所有不同的指针增量语法,让我们考虑简单的代码:
#include<stdio.h>
int main()
{
int num = 300;
int *ptr;
ptr = #
printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
*ptr++;//address changed(post increment), value remains un-changed
// *++ptr;//address changed(post increment), value remains un-changed
// *(ptr)++;//address changed(post increment), value remains un-changed
// *(++ptr);//address changed(post increment), value remains un-changed
// ++*ptr;//value changed(pre increment), address remains un-changed
// (*ptr)++;//value changed(pre increment), address remains un-changed
// ++(*ptr);//value changed(post increment), address remains un-changed
printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}
In above code, try to comment/un-comment comments and analyze outputs.
在上面的代码中,尝试注释/取消注释注释并分析输出。
Pointers as Constant: there are no of ways by which you can make pointers as constant, few I am mentioning here.
指针为常量:没有任何方法可以使指针为常量,我在这里提到的很少。
1)const int *p OR int const *p: Here value
is constant, address is not constanti.e where p is pointing ? Some address ? On that address what is the value ? Some value right ? That value is constant, you can't modify that value but where pointer is pointing ? Some address right ? It can point to other address also.
1) const int *p OR int const *p:这里value
是常量,地址不是常量,即 p 指向哪里?一些地址?在那个地址上有什么价值?有些价值吧?该值是常量,您不能修改该值,但指针指向哪里?一些地址对吗?它也可以指向其他地址。
To understand this lets consider below code :
要理解这一点,让我们考虑以下代码:
#include<stdio.h>
int main()
{
int num = 300;
const int *ptr;//constant value, address is modifible
ptr = #
printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
*ptr++;//
// *++ptr;//possible bcz you are trying to change address which is possible
// *(ptr)++;//possible
// *(++ptr);//possible
// ++*ptr;//not possible bcz you trying to change value which is not allowed
// (*ptr)++;//not possible
// ++(*ptr);//not possible
printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}
Try to analyze the output of above code
尝试分析上面代码的输出
2)int const *p: it's called '**constant pointe**r
' i.e address is constant but value is not constant
. Here you are not allowed to change the address but you can modify the value.
2) int const *p:它被称为 ' **constant pointe**r
' 即address is constant but value is not constant
。此处不允许更改地址,但可以修改值。
Note: constant pointer(above case) must initialize while declariung itself.
注意:常量指针(上述情况)必须在声明自身时初始化。
To understand this lets check simple code.
为了理解这一点,让我们检查简单的代码。
#include<stdio.h>
int main()
{
int x = 300;
int* const p;
p = &x;
printf("x = %d p =%p and *p = %d\n",num,p,*p);
}
In above code, if you observe that there is no ++*p or *p++ So you may thought this is simple case because we are not changing address or value but it will produce error. Why ? Reason I mention in comments.
在上面的代码中,如果你观察到没有 ++*p 或 *p++ 那么你可能认为这是一个简单的情况,因为我们没有改变地址或值,但它会产生错误。为什么 ?我在评论中提到的原因。
#include<stdio.h>
int main()
{
int x = 300;
/** constant pointer must initialize while decaring itself **/
int* const p;//constant pointer i.e its pointing to some address(here its pointing to garbage), it should point to same address(i.e garbage ad
dress only
p = &x;// but here what we are doing ? we are changing address. we are making p to point to address of x instead of garbage address.
printf("x = %d p =%p and *p = %d\n",num,p,*p);
}
So whats the Solution of this problem ?
那么这个问题的解决方案是什么?
int* const p = &x;
for more about this case lets consider below example.
有关此案例的更多信息,让我们考虑以下示例。
#include<stdio.h>
int main()
{
int num = 300;
int *const ptr = #//constant value, address is modifible
printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
*ptr++;//not possible
// *++ptr;//not possible bcz you are trying to change address which is not possible
// *(ptr)++;//not possible
// *(++ptr);//not possible
// ++*ptr;// possible bcz you trying to change value which is allowed
// (*ptr)++;// possible
// ++(*ptr);// possible
printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}
3)const int* const p: Here both address and value are constant.
3) const int* const p:这里的地址和值都是常量。
To understand this lets check below code
要理解这一点,让我们检查下面的代码
#include<stdio.h>
int main()
{
int num = 300;
const int* const ptr = #//constant value,constant address
printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
*ptr++;//not possible
++*ptr;//not possible
printf(" num = %d ptr = %p and data on ptr : %d \n",num,ptr,*ptr);
}
回答by iammosespaulr
const char *p = "Hello";
*p means "Hello"
^
|
p
*p++ means "Hello"
^
|
p
*++p means "Hello"
^
| (WHILE THE STATEMENT IS EXECUTED)
p
*++p means "Hello"
^
| (AFTER THE STATEMENT IS EXECUTED)
p
++*p
means that you are trying to increment the ASCII value of *p
which
++*p
意味着你正在试图增加的ASCII值,*p
这
is "Hello"
^
|
p
you cannot increment the value 'cause it's a constant so you would get an error
你不能增加值,因为它是一个常量,所以你会得到一个错误
as for your while loop the loop runs until *p++
reaches the end of the string where there is a '\0'
(NULL) character.
至于你的 while 循环,循环运行直到*p++
到达字符串的末尾,那里有一个'\0'
(NULL) 字符。
Now since *p++
skips the first character you would only get your output starting from the second character.
现在因为*p++
跳过第一个字符,你只能从第二个字符开始输出。
The following code will not output anything because while loop has '\0'
下面的代码不会输出任何东西,因为 while 循环有 '\0'
const char *p = "Hello";
while('const char *p = "Hello";
while(*++p)
printf("%c",*p);
')
printf("%c",*p);
The following code will give you the same output as the next code i.e ello .
以下代码将为您提供与下一个代码相同的输出,即 ello 。
const char *p = "Hello";
while(*p++)
printf("%c",*p);
...................................
…………………………………………………………………………………………………………………………………………………………………………………………
##代码##