2

我正在尝试将用户定义的数组(此处定义为 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;
}
4

2 回答 2

3

您必须在 main 函数中声明该数组,以便其他函数也可以访问它。在除 main 之外的函数内声明的数组在堆栈上具有本地范围,并且在函数体执行后立即销毁。

话虽如此,您有两个同名实体,一个矩阵数组和一个函数。这不会编译器使它们的名称独一无二。像这样在 main 中声明你的矩阵数组。

int matrix[10][10] ;

现在像这样将它传递给您的输入函数matrix1

matrix1(matrix, nS) ;

你的矩阵函数会是这样的。

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

det您也可以以类似的方式将其传递给函数。最好设置行号和列号,const以便稍后在程序中轻松更改它们。

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

您可以在此处的类似答案中了解有关传递列号的原因以及如何将二维数组传递给函数的更多信息。

二维数组作为函数的参数

于 2012-11-29T14:20:28.417 回答
1

在 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);
}

这是非模板方式的示例:

#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);
}

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

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

#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 :)
}

因此,对于动态数组,您始终必须知道长度。但是,有时当程序员不想携带数组的长度时,他们可以引入一个用于确定数组结尾的约定(以避免访问无效的内存/元素)。例如,程序员可能会说,无论数组有多长,最后一个元素将始终为 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";
}

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

#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);
}

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

#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;
}

希望能帮助到你。祝你好运!

于 2012-11-29T14:58:41.080 回答