2017-04-03 27 views
0

我試圖實現兩個2×2矩陣的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; 
} 

你能告訴我爲什麼我得到編譯時錯誤。 我還需要知道如何爲一個二維數組創建空間,因爲當我的當前實現C將在函數退出返回垃圾值時立即超出範圍。

+2

你應該*總是*發佈你的編譯器/鏈接器錯誤*逐字*。 –

+3

「return C [] [];」 - 你打算通過這個獲得什麼? –

+3

忘記'malloc'的東西!不要在C++中使用它! – datell

回答

0

有幾個原因讓你的代碼無法編譯: 由於函數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作爲參考功能,所以變化的解決方案,你功能裏面也會影響它的功能

+0

當我們將整數傳遞給一個函數但在聲明中使用「&」時,這意味着什麼。像你一樣,傳遞給A,B,C是參數,但是當你定義了你使用的函數(&A),(&B),(&C)。他們爲什麼在括號裏。 – zaidjan1295

+0

該符號意味着您沒有複製參數,而是向它們發送引用,函數中的變量將引用與您作爲參數傳遞的變量完全相同的內存空間。它們在括號中以指定您不是發送引用數組,而是引用數組。 – Sacha

+0

如果您是發送參考資料(即地址),爲什麼當您完成所有相應的數學運算後,您是否解除A,B,C的引用? – zaidjan1295

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