C++ 指针自增与指针取引用自增运算优先级探究
C++中关于:单语句cout指针地址与指向的值的同时自增时,程序内部运算顺序探究
- cout输出指针自增(*p++)运算示例1
- 第一次原因分析
- 第一次源代码分析(错误,存在局限性)
- 第一次理论推导:
- 第一次实验验证:
- 第一次结论(错误,存在一定的局限性):
- cout输出指针自增(*p++)运算示例2
- 摘自他人结论
- 测试用例1:
- 测试用例2:(验证从从右往左计算 从左往右输出)
- 测试用例3:(后自增运算与输出语句执行 顺序)
- 测试用例4:
- 无心再测了,自闭...
- cin中的<<其实是一个重载了的operator <<,其实就是一个成员函数,c++标准规定在函数调用中,必须保证参数被求植,具体怎么求值,就要看编译器的实现了。各个编译器的实现不一样,各个编译器就会有不同的结果。
看不懂标题?没关系直接拿下面示例1代码试一下就会发现问题了,也就懂这个标题含义了
cout输出指针自增(*p++)运算示例1
(示例来源)
#include <iostream>
using namespace std;
int main()
{char s[] = "012345678", *p = s;cout << "s:" << s << endl;cout<< "*p++ = " << *p++ << endl<< "*(p++) = " << *(p++) << endl<< "(*p)++ = " << (*p)++ << endl<< "*++p = " << *++p << endl<< "*(++p) = " << *(++p) << endl<< "++*p = " << ++*p << endl<< "++(*p) = " << ++(*p) << endl;cout << "-------------------" << endl;char s1[] = "012345678";p = s1;cout << endl << "s1:" << s1 << endl;//cout << "*p = " << *p << endl;cout << "*p++ = " << *p++ << endl;//cout << "*p = " << *p << endl;cout << "*(p++) = " << *(p++) << endl;//cout << "*p = " << *p << endl;cout << "(*p)++ = " << (*p)++ << endl;//cout << "*p = " << *p << endl;cout << "*++p = " << *++p << endl;//cout << "*p = " << *p << endl;cout << "*(++p) = " << *(++p) << endl;//cout << "*p = " << *p << endl;cout << "++*p = " << ++*p << endl;//cout << "*p = " << *p << endl;cout << "++(*p) = " << ++(*p) << endl;cout << "-------------------" << endl;system("pause");return 0;
}
测试结果

第一次原因分析
经过前后两端代码及输出结果对比发现结果大相径庭
可以将后面一段用来对比的代码已经没有多大意义了,可以直接注释掉,添加cout<输出字符数组的值用于对比
结果为:213345678;

发现字符数组主要在前面部分发生改变
第一次源代码分析(错误,存在局限性)
其中包含
地址++ 2个
值 ++ 1个
++地址 2个
++值 2个
可简明地用下表表示:
| ++i | 类别 | i++ |
|---|---|---|
| 2个 | 地址 | 2个 |
| 2个 | 值 | 1个 |
则对比前后的s数组的值:
012345678
213345678
容易发现:++值发生在s[0],值++发生在s[2]。所以推测语句执行顺序是
++值>>++地址>>执行所在语句>>值++>>地址++
对比示例实验结果验证
++值 ++址 值++均为理论推导
址++为实验需要验证
通过在这句输出语句后再输出*pi
第一次理论推导:
++值
012345678//指针指向s[0]
112345678//指针指向s[0]
212345678//指针指向s[0]
++址
212345678//指针指向s[1]
212345678//指针指向s[2]
输出语句:
p++=//注意:这里++是在这条语句执行完后++,而不是输出了p++后执行++ 后面以此类推
…
值++
213345678//指针指向s[2]
址++
213345678//指针指向s[3]
213345678//指针指向s[4]
第一次实验验证:
cout<< *p<
结果:

与理论推导结果相符
第一次结论(错误,存在一定的局限性):
++值>>++地址>>执行所在语句>>值++>>地址++
cout输出指针自增(*p++)运算示例2
在私下用一段代码测试第一次得到的结论时,发现错误。
代码如下
char s[] = "012345678", *p = s;cout << *p <<endl<<*p++<< endl<<endl;//10//地址前自增cout << *++p <<endl<<*p<< endl<<endl;//11cout << *++p <<endl<<*++p<< endl<<endl;//33cout << *p <<endl<<*++p<< endl<<endl;//44
矛盾:
1.前面理论推导部分的假设为:这里++是在这条语句执行完后++,而不是输出了*p++后执行++
结论一预期输出为 0 0 实际输出 1 0
2.为了在输出中产生1这个数字并且不放弃之前得出的结论,提出新假设:p++与*++p同等地位,即p++与*++p都会在执行该语句时先自增。
产生新矛盾:在这样的假设下应该为0 1,而不是1 0
摘自他人结论
百思不得其解,百度,得到以下结果:点我查看原文
计算顺序:自右至左
输出顺序:自左至右
什么意思呢,其实意思就是说
cout里面的所有的计算都会从右向左执行,然后把结果放回原位,再直接从左往右输出、
根据该结论进行以下测试:
测试用例1:
char s[] = "012345678", *p = s;//地址前自增cout << *++p <<endl<<*p<< endl;cout << *++p <<endl<<*++p<< endl;cout << *p <<endl<<*++p<< endl;
预期:11 33 44
结果:

正确
测试用例2:(验证从从右往左计算 从左往右输出)
测试代码
int i = 0;cout << i << i++;//1 0
预期结果: 00
实验结果: 10

原因分析:
对于后自增运算与输出语句执行顺序不了解,于是进行下面一个测试;
测试用例3:(后自增运算与输出语句执行 顺序)
测试代码
int i = 0;cout << i++ << i << endl;cout << i << i++ << endl;cout << ++i << i++ << endl;cout << i++ << ++i << endl;
根据之前最开始时第一次的实验结论加上本次实验的测试用例2得到的数据猜想:语句会先执行i++,再执行输出语句,每执行完一小句(<<之间为一小句)就会紧接着执行后自增,而非像第一次实验的假设那样执行完cout再后自增;
预期结果:
00
21
42
55

结果分析
之所以第一句与预期不同而输出01
提出假设一:后自增从右到左,左到右输出与后自增。
但在进行该假设验证过程中,发现了一个更合理的假设
假设二:输出时< 其实在这次测试第一次预期时cout << i++ << i << endl;就忽略了这一点,即输出时从右向左运算时i由于不是运算,即并不会把后一个i的值计算出来即并不会把i当成1存回去而是直接进行下一个i++的计算得到第一个i=0再输出下一个i=1
测试用例4:
还没来得及测就被吓傻了


赶紧百度+谷歌
搜到以下结果:点我查看原网址

无心再测了,自闭…
cin中的<<其实是一个重载了的operator <<,其实就是一个成员函数,c++标准规定在函数调用中,必须保证参数被求植,具体怎么求值,就要看编译器的实现了。各个编译器的实现不一样,各个编译器就会有不同的结果。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
