如何将数组传递到函数中?

时间:2022-10-23 21:43:20

I'm trying to pass a user-defined array (defined here as matrix1) into a function (det) with the aim of calculating the determinant. Any help would be appreciated, I'm sure there's an easy way to do this, but my various attempts using pointers/vectors have been futile!

我试图将一个用户定义的数组(在这里定义为matrix1)传递给一个函数(det),目的是计算行列式。任何帮助都将是感激的,我肯定有一个简单的方法来做,但我的各种尝试使用指针/向量是徒劳的!

#include <iostream>
#include <math.h>
#include <vector>

using namespace std;

int c, d;

int matrix1(int nS)
{
    cout << "Enter the elements of first matrix: ";
    int matrix1[10][10];
    for (c = 0 ; c < nS ; c++ )
    for (d = 0 ; d < nS ; d++ )
        cin >> matrix1[c][d];

for (c = 0 ; c < nS ; c++ )
    {   
        for (d = 0 ; d < nS ; d++ )
            cout << matrix1[c][d] << "\t";
            cout << endl;
    }
}

int det(int nS, int matrix)
{
    int det;
    int iii;
    for (iii = 0; iii < nS; iii++)
    {
        double a;
        double b;
        int c;
        for (c = 0; c<nS; c++)
        {
//          cout << (iii+c)%nS << endl;
//          cout << (nS-1) - (iii+c)%nS << endl;
        int z = (iii+c)%nS;
        cout << c << ", " << z << endl;
            a *= matrix[c][z];
            b *= matrix[c][(nS-1) - (iii+c)%nS];
        }

    det+= a-b;
    }
    cout << det << endl;
}

int main()
{
    cout << "Enter the number of rows and columns of matrix: ";
    int nS;
    cin >> nS;

    matrix1(nS);

    det(nS, matrix1);

    return 0;
}

2 个解决方案

#1


3  

You have to declare the array inside your main function for other functions to access it as well. An array declared inside a function other than main has a local scope on the stack and it gets destroyed as soon the function body gets executed.

您必须在主函数中声明数组以供其他函数访问。在除main之外的函数中声明的数组在堆栈上有一个局部作用域,一旦函数体被执行就会被销毁。

That being said, you have two entities with the same name, a matrix array and a function. This wont compiler so make their names unique. Declare your matrix array in main like this.

也就是说,有两个同名的实体,一个矩阵数组和一个函数。这个不会编译,所以它们的名称是唯一的。像这样声明你的矩阵数组。

int matrix[10][10] ;

Now pass it to your input function matrix1 like this.

现在像这样把它传递给输入函数矩阵。

matrix1(matrix, nS) ;

And your matrix function would be like this.

矩阵函数是这样的。

int matrix1(int matrix[][10], int nS)
{
  //code runs here
}

You can pass it to the det function as well in a similar fashion. And it is better if you make the row and column numbers as const so that you can change them later in your program easily.

你也可以用类似的方式把它传递给det函数。如果您将行和列编号作为const,这样您可以在您的程序中轻松地更改它们。

const int ROWS = 10 ;
const int COLS = 10 ;

You can learn more on why the column number is passed and how a 2D array gets passed to a function in a similar answer here.

您可以了解更多关于为什么传递列号以及如何以类似的答案将2D数组传递给函数的信息。

2D-array as argument to function

2 - d -array作为函数的参数。

#2


1  

There are generally two ways of passing arrays in C++. One that does use a template and is C++-specific and another one that does not use templates and can be used in both C and C++ programs. Here is an example of the template version:

在c++中,通常有两种传递数组的方法。一个是使用模板的,是特定于c++的,另一个是不使用模板的,可以在C和c++程序中使用。以下是模板版本的一个示例:

#include <cstddef>   // for std::size_t
#include <iostream>  // for std::cout
#include <algorithm> // for std::copy
#include <iterator>  // for std::ostream_iterator

template <std::size_t length>
static void accept_array(const int (&array)[length])
{
    std::cout << "Got array of " << length << " elements:\t";
    std::copy(array, array+length, std::ostream_iterator<int>(std::cout, ", "));
    std::cout << " and that's all.\n";
}

int main()
{
    int arr[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
    accept_array(arr);
}

And here is an example of a non-template way:

这里有一个非模板的例子:

#include <cstddef>   // for std::size_t
#include <iostream>  // for std::cout
#include <algorithm> // for std::copy
#include <iterator>  // for std::ostream_iterator

static void accept_array(const int *array, std::size_t length)
{
    std::cout << "Got array of " << length << " elements:\t";
    std::copy(array, array+length, std::ostream_iterator<int>(std::cout, ", "));
    std::cout << " and that's all.\n";
}

int main()
{
    int arr[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
    accept_array(arr, 10);
}

Please note that in both cases, an array itself is decayed to a pointer. In other words, it is being passed to accept_array() function as const int *array in both cases. The only difference is that in a template version, compiler helps you to automatically determine the size of array.

请注意,在这两种情况下,数组本身都衰减为指针。换句话说,它被作为const int *数组传递给accept_array()函数。唯一的区别是,在模板版本中,编译器可以帮助您自动确定数组的大小。

Note, however, that compiler does not always know about the length of array (array subscripts). For example, the code might be more complicated and involve a dynamic allocation, in which case the only thing that compiler knows is that it is a pointer to one or more elements, but it doesn't know how many elements are there (if any :-)). Here is an example where it would not be convenient to use a template version (even though an insistent programmer still could use it through potentially unsafe type casting):

但是请注意,编译器并不总是知道数组的长度(数组下标)。例如,代码可能更复杂,涉及动态分配,在这种情况下,编译器只知道它是指向一个或多个元素的指针,但它不知道有多少元素(如果有的话:-)。这里有一个例子,使用模板版本并不方便(即使坚持的程序员仍然可以通过潜在不安全的类型转换使用模板版本):

#include <cstddef>   // for std::size_t
#include <iostream>  // for std::cout
#include <algorithm> // for std::copy
#include <iterator>  // for std::ostream_iterator

static void accept_array(const int *array, std::size_t length)
{
    std::cout << "Got array of " << length << " elements:\t";
    std::copy(array, array+length, std::ostream_iterator<int>(std::cout, ", "));
    std::cout << " and that's all.\n";
}

int main()
{
    int *a1 = new int[5];
    for (int i = 0; i < 5; ++i)
        a1[i] = i+1;
    accept_array(a1, 5); // In here, we know we have just allocated 5 elements.
                         // But compiler doesn't really know it. So calling a
                         // template version just like that won't work. We must
                         // know how the length of the array...
    delete [] a1; // Never forget to free what you have allocated :)
}

So for dynamic arrays you always must know the length. However, sometimes when programmers do not want to carry array's length around, they can introduce a convention that is used to determine the end of array (to avoid accessing invalid memory/elements). For example, a programmer may say that no matter how long the array is, the last element will always be 0. And the code is built with that in mind (which is a bit dangerous and requires extra care and may not allow for storing certain values in array — say you cannot have 0 value in array without other code thinking it is an end of array indicator rather than a normal value). Most often this approach is used for arrays of pointers and programmers agree that a nil pointer is an indicator of the end. But strings are a very good example of that approach where \0 is an end of string indicator. For example:

对于动态数组,你必须知道长度。然而,有时当程序员不希望携带数组的长度时,他们可以引入一个约定来确定数组的末尾(以避免访问无效的内存/元素)。例如,程序员可能会说,无论数组有多长,最后一个元素总是0。和代码构建的(这是有点危险,需要格外小心,不得允许某些值存储在数组——说你不能有0值在数组没有其他代码的思考是一个数组年底指标而不是正常价值)。大多数情况下,这种方法用于指针数组,程序员同意nil指针是结束的指示器。但是字符串是这种方法的一个很好的例子,\0是字符串指示符的结束。例如:

#include <iostream>

static unsigned int my_strlen(const char *value)
{
    // How long is our string? We don't really know unless we
    // go through its characters and count them until we see '\0'.
    // WARNING: Please do not use this function in your code as it is
    //          extremely inefficient and serves an example purpose:
    unsigned int result = 0;
    while (value[result] != '\0')
        ++result;
    return result;
}

int main()
{
    const char str[] = "Hello, world!";
    std::cout << "The length of '" << str << "' is " << my_strlen(str)
              << " bytes.\nThe size of the array where the data is stored is "
              << sizeof(str)/sizeof(str[0]) << " bytes.\n";
}

Also, a template version might be very useful in certain cases. For example, you can use compile-time assertions to make sure that array length is sufficient or the array is not too large. You can also mix two approaches together. Here is a complete example for your reference:

此外,模板版本在某些情况下可能非常有用。例如,您可以使用编译时断言来确保数组长度足够或者数组不太大。你还可以混合两种方法。这里有一个完整的例子供你参考:

#include <cstddef>
#include <iostream>
#include <algorithm>
#include <iterator>

static void accept_array(const int *array, std::size_t length)
{
    std::cout << "Got array of " << length << " elements:\t";
    std::copy(array, array+length, std::ostream_iterator<int>(std::cout, ", "));
    std::cout << " and that's all.\n";
}

template <std::size_t length>
static void accept_array(const int (&array)[length])
{
    // Generally, we can just call a non-template version.
    // However, in this case "length" is a compile-time expression
    // and we can benefit from that. For example, by not letting users
    // compile if array length is more than 10 elements:
    static_assert(length <= 10, "Array is way too large"); // Beware: C++11 feature.
    accept_array(array, length);
}

int main()
{
    int *a1 = new int[5];
    for (int i = 0; i < 5; ++i)
        a1[i] = i+1;

    accept_array(a1, 5);
    delete [] a1;

    int a2[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
    accept_array(a2);
    accept_array(a2, sizeof(a2)/sizeof(a2[0]));

    // The below code would fail to compile:
    // int a3[11] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
    // accept_array(a3);
}

Oh, and I almost forgot to show you an example with matrices. It works exactly the same. For the same to keep it short, I won't do a template version since your program does not know the length of a matrix in compile-time and works with a run-time user's input instead. Here is how I would write your code:

哦,我差点忘了给你们看一个矩阵的例子。它的工作原理完全一样。同样,为了保持简短,我不会做模板版本,因为您的程序不知道编译时矩阵的长度,而是使用运行时用户的输入。我是这样写你的代码的:

#include <cstdlib>
#include <iostream>
#include <cmath>

static void grab_matrix(int **matrix, int nS)
{
    std::cout << "Enter the elements of first matrix ("
              << nS << " by " << nS << "): " << std::flush;

    for (int c = 0; c < nS; ++c)
        for (int d = 0 ; d < nS; ++d)
            std::cin >> matrix[c][d];

    std::cout << "Thank you! You have entered the following:\n";

    for (int c = 0; c < nS; ++c) {
        for (int d = 0 ; d < nS ; d++ )
            std::cout << matrix[c][d] << "\t";
        std::cout << '\n';
    }

    std::cout << std::flush;
}

static void det(int **matrix, int nS)
{
    std::cout << "Calculations:\n" << std::flush;
    double d = 0;
    for (int i = 0; i < nS; ++i) {
        double a = 0;
        double b = 0;
        for (int c = 0; c < nS; ++c) {
            int z = (i + c) % nS;
            a *= matrix[c][z];
            b *= matrix[c][(nS - 1) - (i + c) % nS];
            std::cout << c << ", " << z << '\n';
        }
        d += a - b;
    }
    std::cout << d << std::endl;
}

int main()
{
    std::cout << "Enter the number of rows and columns of matrix: "
              << std::flush;

    int nS = 0;
    std::cin >> nS;

    if (nS <= 0) {
        std::cerr << "Sorry, that's not a good number. Try again later!\n";
        return EXIT_FAILURE;
    }

    int **matrix = new int*[nS];
    for (int i = 0; i < nS; ++i)
        matrix[i] = new int[nS];

    grab_matrix(matrix, nS);
    det(matrix, nS);

    for (int i = 0; i < nS; ++i)
        delete [] matrix[i];
    delete [] matrix;
}

Hope it helps. Good Luck!

希望它可以帮助。好运!

#1


3  

You have to declare the array inside your main function for other functions to access it as well. An array declared inside a function other than main has a local scope on the stack and it gets destroyed as soon the function body gets executed.

您必须在主函数中声明数组以供其他函数访问。在除main之外的函数中声明的数组在堆栈上有一个局部作用域,一旦函数体被执行就会被销毁。

That being said, you have two entities with the same name, a matrix array and a function. This wont compiler so make their names unique. Declare your matrix array in main like this.

也就是说,有两个同名的实体,一个矩阵数组和一个函数。这个不会编译,所以它们的名称是唯一的。像这样声明你的矩阵数组。

int matrix[10][10] ;

Now pass it to your input function matrix1 like this.

现在像这样把它传递给输入函数矩阵。

matrix1(matrix, nS) ;

And your matrix function would be like this.

矩阵函数是这样的。

int matrix1(int matrix[][10], int nS)
{
  //code runs here
}

You can pass it to the det function as well in a similar fashion. And it is better if you make the row and column numbers as const so that you can change them later in your program easily.

你也可以用类似的方式把它传递给det函数。如果您将行和列编号作为const,这样您可以在您的程序中轻松地更改它们。

const int ROWS = 10 ;
const int COLS = 10 ;

You can learn more on why the column number is passed and how a 2D array gets passed to a function in a similar answer here.

您可以了解更多关于为什么传递列号以及如何以类似的答案将2D数组传递给函数的信息。

2D-array as argument to function

2 - d -array作为函数的参数。

#2


1  

There are generally two ways of passing arrays in C++. One that does use a template and is C++-specific and another one that does not use templates and can be used in both C and C++ programs. Here is an example of the template version:

在c++中,通常有两种传递数组的方法。一个是使用模板的,是特定于c++的,另一个是不使用模板的,可以在C和c++程序中使用。以下是模板版本的一个示例:

#include <cstddef>   // for std::size_t
#include <iostream>  // for std::cout
#include <algorithm> // for std::copy
#include <iterator>  // for std::ostream_iterator

template <std::size_t length>
static void accept_array(const int (&array)[length])
{
    std::cout << "Got array of " << length << " elements:\t";
    std::copy(array, array+length, std::ostream_iterator<int>(std::cout, ", "));
    std::cout << " and that's all.\n";
}

int main()
{
    int arr[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
    accept_array(arr);
}

And here is an example of a non-template way:

这里有一个非模板的例子:

#include <cstddef>   // for std::size_t
#include <iostream>  // for std::cout
#include <algorithm> // for std::copy
#include <iterator>  // for std::ostream_iterator

static void accept_array(const int *array, std::size_t length)
{
    std::cout << "Got array of " << length << " elements:\t";
    std::copy(array, array+length, std::ostream_iterator<int>(std::cout, ", "));
    std::cout << " and that's all.\n";
}

int main()
{
    int arr[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
    accept_array(arr, 10);
}

Please note that in both cases, an array itself is decayed to a pointer. In other words, it is being passed to accept_array() function as const int *array in both cases. The only difference is that in a template version, compiler helps you to automatically determine the size of array.

请注意,在这两种情况下,数组本身都衰减为指针。换句话说,它被作为const int *数组传递给accept_array()函数。唯一的区别是,在模板版本中,编译器可以帮助您自动确定数组的大小。

Note, however, that compiler does not always know about the length of array (array subscripts). For example, the code might be more complicated and involve a dynamic allocation, in which case the only thing that compiler knows is that it is a pointer to one or more elements, but it doesn't know how many elements are there (if any :-)). Here is an example where it would not be convenient to use a template version (even though an insistent programmer still could use it through potentially unsafe type casting):

但是请注意,编译器并不总是知道数组的长度(数组下标)。例如,代码可能更复杂,涉及动态分配,在这种情况下,编译器只知道它是指向一个或多个元素的指针,但它不知道有多少元素(如果有的话:-)。这里有一个例子,使用模板版本并不方便(即使坚持的程序员仍然可以通过潜在不安全的类型转换使用模板版本):

#include <cstddef>   // for std::size_t
#include <iostream>  // for std::cout
#include <algorithm> // for std::copy
#include <iterator>  // for std::ostream_iterator

static void accept_array(const int *array, std::size_t length)
{
    std::cout << "Got array of " << length << " elements:\t";
    std::copy(array, array+length, std::ostream_iterator<int>(std::cout, ", "));
    std::cout << " and that's all.\n";
}

int main()
{
    int *a1 = new int[5];
    for (int i = 0; i < 5; ++i)
        a1[i] = i+1;
    accept_array(a1, 5); // In here, we know we have just allocated 5 elements.
                         // But compiler doesn't really know it. So calling a
                         // template version just like that won't work. We must
                         // know how the length of the array...
    delete [] a1; // Never forget to free what you have allocated :)
}

So for dynamic arrays you always must know the length. However, sometimes when programmers do not want to carry array's length around, they can introduce a convention that is used to determine the end of array (to avoid accessing invalid memory/elements). For example, a programmer may say that no matter how long the array is, the last element will always be 0. And the code is built with that in mind (which is a bit dangerous and requires extra care and may not allow for storing certain values in array — say you cannot have 0 value in array without other code thinking it is an end of array indicator rather than a normal value). Most often this approach is used for arrays of pointers and programmers agree that a nil pointer is an indicator of the end. But strings are a very good example of that approach where \0 is an end of string indicator. For example:

对于动态数组,你必须知道长度。然而,有时当程序员不希望携带数组的长度时,他们可以引入一个约定来确定数组的末尾(以避免访问无效的内存/元素)。例如,程序员可能会说,无论数组有多长,最后一个元素总是0。和代码构建的(这是有点危险,需要格外小心,不得允许某些值存储在数组——说你不能有0值在数组没有其他代码的思考是一个数组年底指标而不是正常价值)。大多数情况下,这种方法用于指针数组,程序员同意nil指针是结束的指示器。但是字符串是这种方法的一个很好的例子,\0是字符串指示符的结束。例如:

#include <iostream>

static unsigned int my_strlen(const char *value)
{
    // How long is our string? We don't really know unless we
    // go through its characters and count them until we see '\0'.
    // WARNING: Please do not use this function in your code as it is
    //          extremely inefficient and serves an example purpose:
    unsigned int result = 0;
    while (value[result] != '\0')
        ++result;
    return result;
}

int main()
{
    const char str[] = "Hello, world!";
    std::cout << "The length of '" << str << "' is " << my_strlen(str)
              << " bytes.\nThe size of the array where the data is stored is "
              << sizeof(str)/sizeof(str[0]) << " bytes.\n";
}

Also, a template version might be very useful in certain cases. For example, you can use compile-time assertions to make sure that array length is sufficient or the array is not too large. You can also mix two approaches together. Here is a complete example for your reference:

此外,模板版本在某些情况下可能非常有用。例如,您可以使用编译时断言来确保数组长度足够或者数组不太大。你还可以混合两种方法。这里有一个完整的例子供你参考:

#include <cstddef>
#include <iostream>
#include <algorithm>
#include <iterator>

static void accept_array(const int *array, std::size_t length)
{
    std::cout << "Got array of " << length << " elements:\t";
    std::copy(array, array+length, std::ostream_iterator<int>(std::cout, ", "));
    std::cout << " and that's all.\n";
}

template <std::size_t length>
static void accept_array(const int (&array)[length])
{
    // Generally, we can just call a non-template version.
    // However, in this case "length" is a compile-time expression
    // and we can benefit from that. For example, by not letting users
    // compile if array length is more than 10 elements:
    static_assert(length <= 10, "Array is way too large"); // Beware: C++11 feature.
    accept_array(array, length);
}

int main()
{
    int *a1 = new int[5];
    for (int i = 0; i < 5; ++i)
        a1[i] = i+1;

    accept_array(a1, 5);
    delete [] a1;

    int a2[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
    accept_array(a2);
    accept_array(a2, sizeof(a2)/sizeof(a2[0]));

    // The below code would fail to compile:
    // int a3[11] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
    // accept_array(a3);
}

Oh, and I almost forgot to show you an example with matrices. It works exactly the same. For the same to keep it short, I won't do a template version since your program does not know the length of a matrix in compile-time and works with a run-time user's input instead. Here is how I would write your code:

哦,我差点忘了给你们看一个矩阵的例子。它的工作原理完全一样。同样,为了保持简短,我不会做模板版本,因为您的程序不知道编译时矩阵的长度,而是使用运行时用户的输入。我是这样写你的代码的:

#include <cstdlib>
#include <iostream>
#include <cmath>

static void grab_matrix(int **matrix, int nS)
{
    std::cout << "Enter the elements of first matrix ("
              << nS << " by " << nS << "): " << std::flush;

    for (int c = 0; c < nS; ++c)
        for (int d = 0 ; d < nS; ++d)
            std::cin >> matrix[c][d];

    std::cout << "Thank you! You have entered the following:\n";

    for (int c = 0; c < nS; ++c) {
        for (int d = 0 ; d < nS ; d++ )
            std::cout << matrix[c][d] << "\t";
        std::cout << '\n';
    }

    std::cout << std::flush;
}

static void det(int **matrix, int nS)
{
    std::cout << "Calculations:\n" << std::flush;
    double d = 0;
    for (int i = 0; i < nS; ++i) {
        double a = 0;
        double b = 0;
        for (int c = 0; c < nS; ++c) {
            int z = (i + c) % nS;
            a *= matrix[c][z];
            b *= matrix[c][(nS - 1) - (i + c) % nS];
            std::cout << c << ", " << z << '\n';
        }
        d += a - b;
    }
    std::cout << d << std::endl;
}

int main()
{
    std::cout << "Enter the number of rows and columns of matrix: "
              << std::flush;

    int nS = 0;
    std::cin >> nS;

    if (nS <= 0) {
        std::cerr << "Sorry, that's not a good number. Try again later!\n";
        return EXIT_FAILURE;
    }

    int **matrix = new int*[nS];
    for (int i = 0; i < nS; ++i)
        matrix[i] = new int[nS];

    grab_matrix(matrix, nS);
    det(matrix, nS);

    for (int i = 0; i < nS; ++i)
        delete [] matrix[i];
    delete [] matrix;
}

Hope it helps. Good Luck!

希望它可以帮助。好运!