在范围内定义的函数,但编译器抱怨它超出范围
Function defined in scope but the compiler complains that it is out of scope
我试图为两个 2x2 矩阵实现 strassens 算法,以便制作递归矩阵乘法算法,但是该实现无法编译,给我这样的错误:
"strassen was not declared in this scope"
and
"unqualified-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;
}
你能告诉我为什么会出现编译时错误吗?
我还需要知道如何 malloc
space 用于二维数组,因为我当前的 C
实现将在函数退出返回垃圾值后立即超出范围。
您的代码无法编译的原因有以下几个:
你得到函数超出范围的错误,因为函数 strassen 没有编译,它没有编译,因为你正在 returning 一个在函数内部声明的数组。
一个好的经验法则是永远不要 return 数组,也不要将它们作为参数传递,而是使用引用,这样可以节省内存和时间。
这是一个不使用动态内存的解决方案(虽然我认为那样做会更容易)
#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 是一种很棒的语言,但是当您决定使用 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 样式数组所做的那样,二维数组被实现为数组的数组,因此 std::array<std::array<T,size>,size>>
。
对于 A
和 B
初始化中奇怪的大括号数量,请参阅 Why can't simple initialize (with braces) 2D std::array? [duplicate] 的最佳答案。
请注意,我在 main()
中初始化数组的方式需要 -std=c++11
编译器标志。用 gcc -std=c++11 -o strassen strassen.c
之类的东西编译
我试图为两个 2x2 矩阵实现 strassens 算法,以便制作递归矩阵乘法算法,但是该实现无法编译,给我这样的错误:
"strassen was not declared in this scope" and "unqualified-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;
}
你能告诉我为什么会出现编译时错误吗?
我还需要知道如何 malloc
space 用于二维数组,因为我当前的 C
实现将在函数退出返回垃圾值后立即超出范围。
您的代码无法编译的原因有以下几个: 你得到函数超出范围的错误,因为函数 strassen 没有编译,它没有编译,因为你正在 returning 一个在函数内部声明的数组。
一个好的经验法则是永远不要 return 数组,也不要将它们作为参数传递,而是使用引用,这样可以节省内存和时间。
这是一个不使用动态内存的解决方案(虽然我认为那样做会更容易)
#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 是一种很棒的语言,但是当您决定使用 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 样式数组所做的那样,二维数组被实现为数组的数组,因此 std::array<std::array<T,size>,size>>
。
对于 A
和 B
初始化中奇怪的大括号数量,请参阅 Why can't simple initialize (with braces) 2D std::array? [duplicate] 的最佳答案。
请注意,我在 main()
中初始化数组的方式需要 -std=c++11
编译器标志。用 gcc -std=c++11 -o strassen strassen.c