代码按预期工作,直到第22-24行,我们在那里打印8,后面跟着地址。增加指针地址只会使地址增加一个字节,而它应该将地址移动4个字节。该问题不会出现在阵列中,或者如果线路22-24单独运行。
#include<iostream>
using namespace std;
void main()
{
int *p;
//int a[10] = { 0 };
//p = a;
int a = 100;
p=&a;
cout << "1. "<<p <<" "<<*p<< endl;
p++;
cout << "2. " << p << " " << *p << endl;
++p;
cout << "3. " << p << " " << *p << endl;
++*p;
cout << "4. " << p << " " << *p << endl;
++(*p);
cout << "5. " << p << " " << *p << endl;
++*(p);
cout << "6. " << p << " " << *p << endl;
*p++;
cout << "7. " << p << " " << *p << endl;
(*p)++; //This is the problem, increments the address by 1, even though its in int type
cout << "8. " << p << " " << *p << endl;
*(p)++;
cout << "9. " << p << " " << *p << endl;
*++p;
cout << "10. " << p << " " << *p << endl;
*(++p);
cout << "11. " << p << " " << *p << endl;
cin.get();
}
最初,您将p设置为指向堆栈上的一个整数变量。当你随后增加指针时,你指向的是堆栈上的一个内存区域,当函数被调用时,这个区域可能会改变(例如cout)。当函数返回时,它可能已经更改了递增指针p所指向的内存位置,这可能解释了您的问题。您应该声明一个足够大的数组,以容纳要遍历的指针地址范围。我注意到您注释掉了数组代码,它本来可以像您预期的那样工作。
您的代码是:
p = &a;
p++;
现在p
指向a
的末尾。这仍然可以,但在下一行:
cout << "2. " << p << " " << *p << endl;
当您写入*p
时,它试图读取超过a
末尾的内存,这会导致未定义的行为。
当发生未定义的行为时,C++语言的定义不再涵盖程序的功能。任何事情都有可能发生。
换句话说:当生成可执行文件时,编译器可以根据程序只做定义明确的事情的前提进行假设。
编译器可能会做出这样的假设来解释你的输出,如果你的程序正在确认,这种假设是合理的,但实际上是错误的,因为你的程序是无效的。
脑海中出现的一种解释是,您对p
进行了高级处理,直到它恰好指向存储p
本身的内存位置。编译器通过输出用于递增存储在p
所指向的位置处的int的指令来实现(*p)++
。在您的系统中,将此指令应用于实际存储p
的位置的结果是将p
的地址值增加一。