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

时间:2017-04-03 19:18:26

标签: 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[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;
}

你能告诉我为什么我会收到编译时错误。 我还需要知道如何为{2}数组malloc空间,因为当函数退出返回垃圾值时,C的当前实现将超出范围。

2 个答案:

答案 0 :(得分:0)

您的代码无法编译的原因有两个: 你得到函数的错误超出范围,因为函数strassen没有编译,并且它没有编译,因为你返回一个在函数内声明的数组。

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

Heres是一种不使用动态内存的解决方案(虽然我觉得这样做会更容易)

new NpgsqlConnection

请注意,您传递C作为函数的引用,因此您在函数内所做的更改也会影响函数外部

答案 1 :(得分:0)

正如许多评论中所提到的,您的解决方案是典型的 C风格,它可能会产生许多问题(特别是当您是初学者时)。 C ++为C可能变得复杂的许多情况提供了强大的内存保存和易于使用的解决方法。

不要误会我的意思:C语言很棒,但是当你决定使用C ++时,请使用它!

对于您的案例std::array是完美的,因为您使用明确定义的数组。它的工作方式如下:使用std::array<type,size>定义其内容的大小和类型。

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

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

正如您对C样式数组所做的那样,二维arrrays被实现为数组数组std::array<std::array<T,size>,size>>

对于AB初始化中看起来奇怪的大括号,请参阅Why can't simple initialize (with braces) 2D std::array? [duplicate]的最佳答案。

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

之类的内容进行编译