简体   繁体   English

C ++指针动态数组和函数

[英]C++ pointers dynamic arrays and functions

This is from a beginning C++ class, no grade involved since I'm simply following along trying to remember stuff after too many years. 这是从一个C ++课开始,没有涉及等级,因为我只是跟着试图记住太多年后的东西。 The class has reached the point where we're using pointers and dynamic arrays. 该类已达到我们使用指针和动态数组的程度。 I'm trying to pass the array (or the pointer) to different functions having to do with various calculations on a list of integers. 我试图将数组(或指针)传递给不同的函数,这些函数与整数列表上的各种计算有关。 Some of the functions are working and others aren't. 有些功能正在发挥作用,而其他功能则没有。 But I'm passing them all the same way and I'm calling them all the same way as well. 但是我以同样的方式传递它们,我也以同样的方式调用它们。 Since some of the functions are returning garbage values, it feels like I'm not actually pointing where I think I am AND the functions that are working are only working by accident. 由于某些函数正在返回垃圾值,感觉我实际上并没有指向我认为我在哪里而且正在运行的函数只是偶然起作用。

Before someone helpfully suggests that I should be using vectors and not arrays, the point of the exercise is to use dynamically allocated arrays. 在有人建议我应该使用向量而不是数组之前,练习的重点是使用动态分配的数组。

Here's my code so far. 到目前为止,这是我的代码。 It's the findavg() and findmedian() that are returning garbage. 这是返回垃圾的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;
}
int length = 0;
int *an_array;

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

You're allocating zero bytes for an_array , because length is 0 . 你为an_array分配零字节,因为length0 That is one problem I can see. 这是我能看到的一个问题。

You should allocate memory for an_array in getarray function, after reading the length of array: 在读取数组的长度后,你应该在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
}

Alternatively,you can write a struct as: 或者,您可以将结构编写为:

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

And then use this everywhere. 然后到处使用它。 It is better because you tied the size and data together, and instead of using two independent objects, you can use just one object of type array , as described below. 它更好,因为您将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!
}

And then call this as: 然后将其称为:

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

Also, if you're going to use this, then other functions signature would become: 此外,如果您打算使用此功能,那么其​​他功能签名将变为:

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

Now you need to modify these functions as well, but fortunately, there will not be major change : wherever you're using a and l , use arr.data and arr.size respectively instead. 现在你需要修改这些函数,但幸运的是,不会有重大改变:无论你在哪里使用al ,分别使用arr.dataarr.size And you're done! 而且你已经完成了!

With all these improvements, your main() would become this: 通过所有这些改进,您的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;
}

This looks better. 这看起来更好。

You are not allocating any memory for the array. 您没有为阵列分配任何内存。 Undefined behaviour ensues. 随之而来的是未定义的行为。

Change your getarray function to do the allocate and return the newly created and populated array: 更改你的getarray函数来进行分配并返回新创建和填充的数组:

int* getarray(int &length)

or even 甚至

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

for a more symmetrical interface. 用于更对称的界面。

If you want a non-terminating loop use 如果你想要一个非终止循环使用

while(true)

There is no need to bring input into your while loop. 无需在while循环中输入输入。

There's no point passing the length by reference in any of the other routines since you are not modifying it. 由于您没有修改它,因此在任何其他例程中通过引用传递长度是没有意义的。 In fact you are asking for trouble passing by reference since a coding error may inadvertently change the value. 事实上,您要求通过引用传递麻烦,因为编码错误可能会无意中更改该值。 You should declare it with const to make the compiler catch any silly mistakes you might make. 您应该使用const声明它,以使编译器捕获您可能犯的任何愚蠢错误。

I most heartily agree with Nawaz's suggestion to tie together the pointer and length variables. 我非常衷心地同意纳瓦兹关于将指针和长度变量联系在一起的建议。

In your average calculation I personally would declare total to be a float and thus avoid the awkward looking casts. 在你的平均计算中,我个人会声明总数是一个浮点数,从而避免看起来很笨拙的演员表。

Your implementation of median is plain wrong, but that seems to be a side issue. 你的中位数实现是完全错误的,但这似乎是一个侧面问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM