C++ 函数在作用域中定义,但编译器抱怨它超出了作用域

C++ 函数在作用域中定义,但编译器抱怨它超出了作用域,c++,scope,unqualified-name,C++,Scope,Unqualified Name,我尝试为两个2x2矩阵实现strassens算法,以便生成递归矩阵乘法算法,但该实现未编译,给我带来以下错误: strassen未在此范围内声明 和 不合格id 代码如下: #include <iostream> #include <cstdlib> using namespace std; int[][] strassen(int A[][2], int B[][2]) { int s1 = B[0][1] - B[1][1]; int s2 = A

我尝试为两个2x2矩阵实现strassens算法,以便生成递归矩阵乘法算法,但该实现未编译,给我带来以下错误:

strassen未在此范围内声明 和 不合格id

代码如下:

#include <iostream>
#include <cstdlib>

using namespace std;

int[][] strassen(int A[][2], int B[][2])
{
    int s1 = B[0][1] - B[1][1];
    int s2 = A[0][0] + A[0][1];
    int s3 = A[1][0] + A[1][1];
    int s4 = B[1][0] - B[0][0];
    int s5 = A[0][0] + A[1][1];
    int s6 = B[0][0] + B[1][1];
    int s7 = A[0][1] - A[1][1];
    int s8 = B[1][0] + B[1][1];
    int s9 = A[0][0] - A[1][0];
    int s10 = B[0][0] + B[0][1];

    int p1 = A[0][0] * s1;
    int p2 = s2 * B[1][1];
    int p3 = s3 * B[0][0];
    int p4 = A[1][1] * s4;
    int p5 = s5 * s6;
    int p6 = s7 * s8;
    int p7 = s9 * s10;

int C[2][2];

C[0][0] = p5 + p4 - p2 + p6;
C[0][1] = p1 + p2;
C[1][0] = p3 + p4;
C[1][1] = p5 + p1 - p3 - p7;

return C[][];
}

int main()
{
    int A[2][2] = {{1,3},{7,5}};
    int B[2][2] = {{6,8},{4,2}};
    int C[][2] = strassen(A,B);
    cout<<C[0][0]<<endl<<C[0][1]<<endl<<C[1][0]<<endl<<C[1][1]<<endl;
    return 0;
}
你能告诉我为什么会出现编译时错误吗。
我还需要知道如何为2D数组分配malloc空间,因为一旦函数退出并返回垃圾值,我当前的C实现就会超出范围。

代码无法编译的原因有两个: 由于函数strassen未编译,因此函数的错误超出范围;由于返回函数内部声明的数组,因此函数未编译

一个好的经验法则是永远不要返回数组,也不要将它们作为参数传递,而是使用引用,这样可以节省内存和时间

这是一个不使用动态内存的解决方案,尽管我认为这样做会更容易

#include <iostream>

using namespace std;

void strassen(int (&A)[2][2], int (&B)[2][2], int (&C)[2][2])
{
    int s1 = B[0][1] - B[1][1];
    int s2 = A[0][0] + A[0][1];
    int s3 = A[1][0] + A[1][1];
    int s4 = B[1][0] - B[0][0];
    int s5 = A[0][0] + A[1][1];
    int s6 = B[0][0] + B[1][1];
    int s7 = A[0][1] - A[1][1];
    int s8 = B[1][0] + B[1][1];
    int s9 = A[0][0] - A[1][0];
    int s10 = B[0][0] + B[0][1];

    int p1 = A[0][0] * s1;
    int p2 = s2 * B[1][1];
    int p3 = s3 * B[0][0];
    int p4 = A[1][1] * s4;
    int p5 = s5 * s6;
    int p6 = s7 * s8;
    int p7 = s9 * s10;

    C[0][0] = p5 + p4 - p2 + p6;
    C[0][1] = p1 + p2;
    C[1][0] = p3 + p4;
    C[1][1] = p5 + p1 - p3 - p7;

}

int main()
{
    int A[2][2] = {{1,3},{7,5}};
    int B[2][2] = {{6,8},{4,2}};
    int C[2][2];

    strassen(A,B,C);

    cout<<C[0][0]<<endl<<C[0][1]<<endl<<C[1][0]<<endl<<C[1][1]<<endl;

    return 0;
}

请注意,您将C作为函数的引用传递,因此您在函数内部对它所做的更改也将影响函数外部的C。正如许多注释中提到的,您的解决方案是典型的C风格,这可能会产生许多问题,特别是当您是初学者时。C++提供了强大的、内存节省和易于使用的解决方案,在很多情况下C可以变得复杂。p> 不要误会我的意思:C是一种很棒的语言,但是当你决定使用C++时,使用它!p> 对于您的情况,std::array是完美的,因为您使用的数组具有明确定义的大小。它的工作原理如下:使用std::array定义其内容的大小和类型

以下代码使用std::array实现您的尝试:

与使用C样式数组一样,二维数组被实现为数组的数组,因此std::array>

有关初始化A和B时大括号的奇怪数目,请参见的顶部答案


请注意,我在main中初始化数组的方式需要-std=c++11编译器标志。使用gcc-std=c++11-o strassen-strassen.c之类的工具进行编译

您应该始终逐字发布编译器/链接器错误。返回c[][];-你到底想通过这个达到什么目的?忘了malloc的事吧!不要在C++中使用它!问题是您创建了一个函数,该函数需要一个[][],它是一个取消引用的指针,但尝试在main中向它传递一个指针。我打赌你的编译器会告诉你像候选人斯特拉森。。。无法使用…由于strassen的定义中存在编译错误,因此它从未定义过。您需要按出现的顺序修复错误。当我们将整数传递给函数,但在声明中使用&时,这意味着什么。与您一样,传入的A、B、C都是参数,但当您定义了所使用的函数&A、B和C时,为什么它们会出现在括号中。该符号表示您不是在复制参数,而是在向它们发送引用,函数中的变量将引用与作为参数传递的变量完全相同的内存空间。在括号中,它们用于指定您发送的不是引用数组,而是对数组的引用。如果您发送的是引用,即地址,为什么在进行所有相应的数学运算时不取消对a、B、C的引用?因为引用不需要取消引用,指针可以取消引用。这是引用和指针之间的主要区别。引用是引用另一个变量的变量,而不是存储引用的变量。数组不应该通过引用传递吗。那么为什么你需要明确地写&A等等?
#include <iostream>
// #include <cstdlib> // use C libraries only when really needed
#include <array> 

using namespace std;

array<array<int,2>,2> strassen(array<array<int,2>,2> A, array<array<int,2>,2> B){
    int s1 = B[0][1] - B[1][1];
    int s2 = A[0][0] + A[0][1];
    int s3 = A[1][0] + A[1][1];
    int s4 = B[1][0] - B[0][0];
    int s5 = A[0][0] + A[1][1];
    int s6 = B[0][0] + B[1][1];
    int s7 = A[0][1] - A[1][1];
    int s8 = B[1][0] + B[1][1];
    int s9 = A[0][0] - A[1][0];
    int s10 = B[0][0] + B[0][1];

    int p1 = A[0][0] * s1;
    int p2 = s2 * B[1][1];
    int p3 = s3 * B[0][0];
    int p4 = A[1][1] * s4;
    int p5 = s5 * s6;
    int p6 = s7 * s8;
    int p7 = s9 * s10;

    array<array<int,2>,2> C;

    C[0][0] = p5 + p4 - p2 + p6;
    C[0][1] = p1 + p2;
    C[1][0] = p3 + p4;
    C[1][1] = p5 + p1 - p3 - p7;

    return C;
}

int main(){
    array<array<int,2>,2> A  {{{{1,3}},{{7,5}}}};
    array<array<int,2>,2> B  {{{{6,8}},{{4,2}}}};
    array<array<int,2>,2> C = strassen(A,B);
    cout<<C[0][0]<<endl<<C[0][1]<<endl<<C[1][0]<<endl<<C[1][1]<<endl;
}