我正在自学C ++,并在指针上编写这个程序:
编写一个程序,将以下数字存储在名为miles的数组中:15,22,16,18,27,23和20.让您的程序将存储在里程中的数据复制到另一个名为dist的数组中,然后显示dist数组中的值。复制和显示数组元素时,程序应使用指针表示法。
所以我解决了问题,我的代码如下。在我的while循环中,我有声明:while(ptr1 < miles + SIZE)
。如果将此语句更改为while(ptr1 < ptr1 + SIZE)
并运行它,则会出现分段错误。为什么?即使里程是一个数组,我明白这实际上是一个指针。如果您执行cout << ptr1;
和cout << miles;
,则输出将相同。有人可以解释一下吗?谢谢。
#include<iostream>
#include<iomanip>
using namespace std;
void prob4()
{
int miles[] = {15, 22, 16, 18, 27, 23, 20};
const int SIZE = sizeof(miles)/sizeof(miles[0]);
int dist[SIZE] = {0};
int *ptr1 = miles;
int *ptr2 = dist;
while(ptr1 < miles + SIZE)
{
*ptr2 = *ptr1;
ptr2++;
ptr1++;
}
for(int i=0; i < SIZE; i++)
cout << setw(4) << dist[i];
cout << endl;
return;
}
int main()
{
prob4();
return 9;
}
答案 0 :(得分:4)
你在这里问几个问题。
条件ptr1 < ptr1 + SIZE
总是计算结果为true,因此循环永远不会结束,指针越过数组的末尾,你取消引用无效指针,这会导致未定义的行为(即任何可能会发生),而你幸运你得到的只是一个分段错误。
数组变量miles
实际上是指向数组中第一个元素的指针 - 首先与ptr1
完全相同。这就是C ++处理数组的方式。
答案 1 :(得分:3)
数组不是指针。
指针指向事物。数组包含的东西。
循环的安全方法是按项目计数,而不是按指针位置计数。
一个问题是结束指针值可能不在范围内或不存在。
分析 - “ptr1&lt; miles + size”
不要将指针与数组进行比较,这很危险
试试这个:“ptr1&lt;&amp; miles [size]”
分析 - “ptr1&lt; ptr1 + SIZE”
这是一个移动目标,因为ptr1
总是在变化。
答案 2 :(得分:1)
您知道,您接受的答案表明许多错误。
“循环的安全方法是按项目计数,而不是按指针位置计算。”
实际上,如果您处理要求您不要编写慢速代码的项目(游戏),那么按计数循环对新手程序员来说确实更容易:T *begin = X;
T *end = X + size;
T *copyTo = Y;
for (T *i=begin; i!=end; ++i, ++copyTo)
*copyTo = *i;
更快,也更优雅..编译器会优化开始和结束变量以及copyTo,(最终变量最终将成为寄存器,以及copyTo)
这可能是你的书所要求的。
“指针指向事物。数组包含事物。”
在C / C ++中,这只是一个奇怪的事情。数组是指针,指针是数组。
int x[32];
x[5] equates to *(x + 5) where x really is "int *"
x is a pointer to an area of the stack in this case.
这就是为什么你可以将指针转换为诸如char * x []之类的函数声明。
“一个问题是结尾指针值可能不在范围内或不存在。”
这也是一个奇怪的事情。
如果你编写一个超出范围的循环,那么它会超出范围,无论你是处理解引用指针(* p)还是做指针算术(x [5])
在把堆栈溢出的话当作真理之前,先阅读你的书。
答案 3 :(得分:0)
在你的第一次迭代中,而循环ptr1确实等于英里。
但是ptr1在第二次迭代中是什么相等?
...
while(...)在每次迭代时进行评估 (一些优化者可能会做一些聪明的事情来简化评估,如果他们能够确定它是可能的话)