【问题标题】:C++ pointers dynamic arrays and functionsC++ 指针动态数组和函数
【发布时间】:2011-11-30 07:43:59
【问题描述】:

这是从一门 C++ 课程开始,不涉及年级,因为我只是在多年后继续努力记住东西。该类已经到了我们使用指针和动态数组的地步。我试图将数组(或指针)传递给与整数列表上的各种计算有关的不同函数。一些功能正在工作,而另一些则没有。但是我以同样的方式传递它们,我也以同样的方式称呼它们。由于一些函数返回垃圾值,感觉就像我实际上并没有指出我认为我在哪里并且正在工作的函数只是偶然地工作。

在有人有用地建议我应该使用向量而不是数组之前,练习的重点是使用动态分配的数组。

到目前为止,这是我的代码。返回垃圾的是findavg()findmedian()

#include <iostream>
#include <iomanip>

using namespace std;

void getarray(int *a, int &l)
{
    int input = 0;

    //-1 is not important here, just to make the while loop run
    while(input != '-1') 
    {
        cout << "Enter length of the list of numbers: ";

        if(!(cin >> input))
        {
            cout << "Please enter numeric characters only." << "\n";    
            //show error if they don't enter a number
            cin.clear();                                                
            //get rid of invalid characters
            cin.ignore(10000,'\n');
        }

        else if(input <= 0)
        {
            cout << "Please enter a number greater than 0." << "\n";    
            //show error if they enter a non-positive number
            cin.clear();                                                
            //get rid of invalid characters
            cin.ignore(10000,'\n');
        }
        else
        {
            l = input;  //input is a positive number
            break; //got good input, break out of while loop
        }

    }


    int i;
    int x; 

    cout << "Enter " << l << " integers on one line seperated by spaces.\n";


    for( i = 0; i < l  &&  cin >> x; ++i)
    {
        a[i] = x;
    }

}

void printarray(int *a, int &l)
{
    int i;

    cout << "The array of integers is:\n";
    for( i = 0; i < l; ++i)
        cout << setw(4) << a[i];
    cout << "\n";

}

int findmin(int *a, int &l)
{
    int min = 0;
    min = a[0]; 

    for(int i = 1; i<l; i++)
    {
        if(a[i] < min)
            min = a[i];
    }
    return min; 
}

int findmax(int *a, int &l)
{
    int max = 0;
    max = a[0];

    for(int i = 1; i<l; i++)
    {
        if(a[i] > max)
            max = a[i];
    }
    return max; 
}

float findavg(int *a, int &l)
{
    int total = 0;
    total = a[0];

    for(int i = 1; i<l; i++)
    {
        total = total + a[i];
    }

    return static_cast<float>(total/static_cast<float>(l));

}

float findmedian(int *a, int &l)
{
    int max = 0;
    int min = 0;

    max = findmax(a, l);
    min = findmin(a, l);

    return static_cast<float>((max + min)/2.0);

}


int main()
{

    int length = 0;
    int *an_array;

    an_array = new int[length];

    getarray(an_array, length);

    printarray(an_array, length);

    cout << "Maximum value in list is: "<< findmax(an_array, length) << "\n";
    cout << "Minimum value in list is: "<< findmin(an_array, length) << "\n";
    printf("Average is: %10.5f", findavg(an_array, length));
    cout << "\n";
    printf("Median is: %10.5f", findmedian(an_array, length));
    cout << "\n";

    delete [] an_array;

    return 0;
}

【问题讨论】:

  • 你了解std::vector等吗?人。还是您的教授从动态数组开始?
  • 我不认为median 和你想的一样。
  • length 在为数组分配内存时总是为0!!你需要在getarray中分配内存
  • 已经用 std::vector 做了一个练习。对于这个练习,我们被明确告知不要使用向量。
  • @John:很好,至少你的 C++ 课程不是垃圾,因为很多都是从动态数组等开始的。人。在展示标准库之前。 :)

标签: c++ arrays function pointers


【解决方案1】:
int length = 0;
int *an_array;

an_array = new int[length]; //What is this ?

您正在为an_array 分配零字节,因为length0。这是我能看到的一个问题。

在读取数组长度后,你应该在getarray函数中为an_array分配内存:

void getarray(int * &a, int &l) //see the change here!
{
    //code which reads length is omitted for brevity

    a = new int[l]; //alllocate memory after reading length

    //now read array elements here
}

或者,您可以将结构编写为:

struct array
{
      int *data;
      size_t size;
};

然后到处使用它。更好的是,因为您将sizedata 绑定在一起,而不是使用两个独立的对象,您可以只使用一个array 类型的对象,如下所述。

array getarray() 
{
    array arr;

    //read length into arr.size

    arr.data= new int[arr.size]; //alllocate memory after reading length

    //now read array elements into arr.data

    return arr; //returning arr means you're returning both: data and size!
}

然后将其称为:

 array arr = getarray(); //no need to pass any argument!

另外,如果你要使用这个,那么其他函数签名会变成:

void printarray(array arr);
int findmax(array arr);
float findavg(array arr);
float findmedian(array arr);

现在您还需要修改这些函数,但幸运的是,不会有重大变化:无论您使用al,请分别使用arr.dataarr.size。你就完成了!

通过所有这些改进,您的main() 将变为:

int main()
{
    array arr = getarray();

    printarray(arr);

    cout << "Maximum value in list is: "<< findmax(arr) << "\n";
    cout << "Minimum value in list is: "<< findmin(arr) << "\n";

    printf("Average is: %10.5f\n", findavg(arr));
    printf("Median is: %10.5f\n", findmedian(arr));

    delete [] arr.data;
    return 0;
}

这看起来更好。

【讨论】:

  • 感谢您的提示 - 将您的积分与其他所有人的 cmets 结合起来应该可以帮助我。
  • @JohnMcDermon:现在,看看main() 的样子!
  • 我喜欢。当我实现正确的getmedian()sort() 函数时,我将不得不试一试,看看它是如何影响事物的。谢谢!
  • @JohnMcDermon:这些功能也没有重大变化。例如,无论您使用al,请分别使用arr.dataarr.size
  • @Nawaz:您认为分配和释放内存作为结构的 ctor 和 dtor 的一部分,以便忘记 main() 中的 delete [] 是个好主意吗?还是我在这方面遗漏了什么?
【解决方案2】:

您没有为数组分配任何内存。未定义的行为随之而来。

更改您的 getarray 函数以执行分配并返回新创建和填充的数组:

int* getarray(int &length)

甚至

void AllocateAndPopulateArray(int* &array, int &length)

为了更对称的界面。

如果你想要一个非终止循环使用

while(true)

无需将输入带入您的 while 循环。

在任何其他例程中通过引用传递长度是没有意义的,因为您没有修改它。事实上,您正在寻求通过引用传递的麻烦,因为编码错误可能会无意中更改值。你应该用 const 声明它,让编译器捕捉到你可能犯的任何愚蠢的错误。

我非常同意 Nawaz 将指针和长度变量绑定在一起的建议。

在你的平均计算中,我个人会声明 total 是一个浮点数,从而避免看起来尴尬的演员表。

您对中位数的实现是完全错误的,但这似乎是一个附带问题。

【讨论】:

  • 谢谢大卫,我明白你指出的一切。当然对 getmedian() 中的错误感到愚蠢——它太长了 :( 有一件事,当我不使用 static_cast 时,我只得到 getavg() 的整数结果。不知道为什么,如果编译器应该这样做将它提升为浮点数 - 也许它没有因为 l 是一个 int 并且我不能添加一个小数位来诱导浮点数学没有强制转换?
  • 那是我的错误。我急忙看错了。我假设总计是一个浮点数。这就是我会做的。不应该假设。
  • 啊,但你提出了一个很好的观点——我应该将总计声明为浮点数,然后我会避免演员表。我喜欢它:)
猜你喜欢
  • 2016-01-12
  • 2013-12-23
  • 1970-01-01
  • 2020-06-28
  • 2017-07-03
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 2015-03-29
相关资源
最近更新 更多