1

我正在自学 C++,并在指针上编写这个程序:

编写一个程序,将以下数字存储在名为 miles 的数组中:15、22、16、18、27、23 和 20。让您的程序将存储在 miles 中的数据复制到另一个名为 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;
}
4

4 回答 4

4

你在这里问了几个问题。

条件ptr1 < ptr1 + SIZE 总是计算为真,所以循环永远不会结束,指针经过数组的末端,你取消引用无效的指针,这会导致未定义的行为(即任何事情都可能发生),你很幸运,你得到的只是一个分段过错。

数组变量miles实际上是指向数组中第一个元素的指针——一开始与 , 完全相同ptr1。这就是 C++ 处理数组的方式。

于 2013-11-12T01:50:43.260 回答
3

数组不是指针。

指针指向事物。数组包含事物。

循环的一种安全方法是按项目计数,而不是按指针位置。

一个问题是结束指针值可能不在范围内或不存在。

分析 - “ptr1 < 英里 + 大小”
不要比较指向数组的指针,这很危险。
试试这个:“ptr1 < &miles[size]”

分析 - “ptr1 < ptr1 + SIZE”
这是一个移动的目标,因为ptr1它总是在变化。

于 2013-11-12T01:51:19.817 回答
1

正如您所知,您接受的答案暗示了许多错误的事情。


“循环的一种安全方法是按项目计数,而不是按指针位置。”

虽然确实,对于新手程序员来说,按计数循环确实更容易,如果您从事的项目(游戏)要求您不要编写慢代码:

T *begin = X;
T *end = X + size; 
T *copyTo = Y;

for (T *i=begin; i!=end; ++i, ++copyTo)
  *copyTo = *i;

更快更优雅.. 编译器将优化 begin 和 end 以及 copyTo 的变量,(end 变量很可能最终成为寄存器,以及 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]),它都会超出范围


在你把堆栈溢出这个词当作真理之前,请阅读你的书。

于 2013-11-12T03:14:22.223 回答
0

在您的第一次迭代中,while 循环 ptr1 确实等于英里。

但是 ptr1 在第二次迭代中等于什么?

...

每次迭代都会评估 while (...) (如果他们可以确定可能的话,一些优化器可能会做一些聪明的事情来简化评估)

于 2013-11-12T01:51:03.427 回答