2012-03-09 93 views
0

我寫,其計算該隨機填充有0和1我必須寫兩個功能之間的值的陣列的組分的總和的碼,一個是迭代的,並且另一個是遞歸的。兩者都應該做同樣的工作。當我只打電話時,我寫的兩個功能工作正常。但是,如果我嘗試調用主函數中的兩個函數,則只能看到一個函數的結果,但看不到另一個函數的結果。另外,我的遞歸函數往往被稱爲一個額外的時間。我注意到,如果我把getch()作爲recursive_function()中的註釋。我知道我錯過了一些東西,但我無法弄清楚。謝謝你的幫助。這裏是代碼。我正在使用Dev-C++。不能顯示我的功能中的每一個的結果

#include <iostream> 
#include<conio.h> 
#include <stdlib.h> 

using namespace std; 

//headers of the thre functions 
int random_value(int array[], int size); 
int iterative_function (int array[], int size, int sum); 
int recursive_function (int size, int array[], int index, int sum); 



int main() 
{  
    int size;int array[size]; int sum=0; 
    int index=0; 
    cout<<"enter the size of the array"<<endl; 
    cin>>size;    //enter the size ofthe array... 
    random_value(array, size); 
    iterative_function (array, size, sum); 
    recursive_function (size, array, index, sum); 
    getch(); 
    return 0; 
} 

int random_value(int array[], int size) 
{ cout<<"here is the value returned by rand()"<<endl; 
    for(int i=0;i<size;i++) 
    { array[i]=(rand() % (0-2)); 
    cout<<array[i]<<endl; 
    } 
} 

int iterative_function (int array[], int size, int sum) 
{ 
    int i,j, number, value; i=0; 
    cout<<"from the iterative function"<<endl; 
    cout<<"------"<<endl; 
    for(i=0;i<size;i++) 
    sum=sum+array[i]; 
    cout<<"sum of the array="<<sum<<endl;   
    getch(); 
    return 0;  //exit the function. Program terminated succesfully. 
} 

int recursive_function (int size, int array[], int index, int sum) 
{ 
    if(size>index) 
    { 
    sum=sum+array[index]; 
    index++; 
    recursive_function(size, array, index, sum); 
    } 
    cout<<"from the recursive function"<<endl; 
    cout<<"------"<<endl; 
    cout<<"new sum= "<< sum<<endl; 

    getch(); 
    return 0; 

} 
+0

只是一個提示:在調用你的兩個函數之間忘記重置'sum'變量爲零。 – 2012-03-09 11:33:03

+0

注意:調試器/跟蹤是你的朋友... – 2012-03-09 11:35:05

+1

@KarolyHorvath注意:單元測試是你的朋友。 – 2012-03-09 11:51:21

回答

1
#include <iostream> 
#include<conio.h> 

<conio.h是不是一個標準的頭,即它不是適用於所有的編譯器,你不需要它。

要查看程序的結果輸出:

  • 從命令行運行它,或

  • 在Visual Studio中通過按鍵運行一個[Ctrl F5](沒有調試),或

  • main的右大括號處設置斷點,然後在調試器(例如,通過按鍵[F5])在Visual Studio中運行它。

#include <stdlib.h> 

至於我可以看到你’再沒有使用任何從這個頭。但是,它確實提供了符號常量EXIT_SUCCESSEXIT_FAILURE,其目的爲return聲明main。例如,在那裏寫EXIT_SUCCESS比寫0更清楚,因爲很多人誤解了在這種情況下的含義。

using namespace std; 

對於短程序或命名空間中的這是可以的。

但是,請記住,短節目往往最終成爲不那麼短期課程。

然後一個using namespace std;很容易造成名稱衝突,特別是與名稱std::distance

//headers of the thre functions 
int random_value(int array[], int size); 
int iterative_function (int array[], int size, int sum); 
int recursive_function (int size, int array[], int index, int sum); 

雖然這部分是喜好問題,沒有優勢在前置聲明功能main之前,它是更多的工作,這有時會導致問題當正向聲明唐’與定義–一樣,與任何不必要的冗餘一樣,違反了原則(不要重複自己)。

相反,只需在main之前放置函數定義即可。

通過這種方式,更容易看出什麼是指什麼,因爲其他人使用的功能必然會出現在其他功能之前。

int main() 
{  
    int size;int array[size]; int sum=0; 

這不應該編譯,因爲在C++中只有一個動態分配的陣列可以具有一個大小是在編譯時未知的。

但是,C99支持「可變長度數組也被稱爲具有上述語法的VLA,並且作爲g ++編譯器支持的語言擴展。

在第三和握持手,即使有克++語言擴展上述聲明不定長度的陣列,因爲size變量還沒有被初始化,並且具有一個不確定的值。

使用g ++編譯器,該值最可能爲0,但它可以很容易地爲任何其他值。

要關閉G ++ VLA語言擴展,和其他一些語言擴展,使用下面的G ++選項:

 
-pedantic -std=c++0x -Wall 

對於標準C++,而不是C99 VLA你應該使用C++ std::vector<int>

爲了獲得std::vector類模板的聲明,請包含標準庫標題<vector>

int index=0; 
    cout<<"enter the size of the array"<<endl; 
    cin>>size;    //enter the size ofthe array... 

當您使用的是std::vector,那麼在這裏,知道它的大小,將宣佈向量的地方。或者,如果早些時候宣佈,這裏將是調整其大小的地方。

random_value(array, size); 

這最好是一個函數,返回隨機值的向量。

然後,您將使用它來初始化聲明的向量。

iterative_function (array, size, sum); 
    recursive_function (size, array, index, sum); 
    getch(); 

關於getch()通話,請參閱有關<conio.h>上述評論。

return 0; 

關於這裏的價值0,看到<stdlib.h>上述評論。

} 

int random_value(int array[], int size) 
{ cout<<"here is the value returned by rand()"<<endl; 
    for(int i=0;i<size;i++) 
    { array[i]=(rand() % (0-2)); 

這裏有未定義行爲,訪問可能大小爲零的數組的元素。

 cout<<array[i]<<endl; 
    } 
} 

int iterative_function (int array[], int size, int sum) 
{ 
    int i,j, number, value; i=0; 
    cout<<"from the iterative function"<<endl; 
    cout<<"------"<<endl; 
    for(i=0;i<size;i++) 
    sum=sum+array[i]; 

在這裏,你將再次調用未定義行爲,通常被稱爲只是「 UB 」,通過訪問不存在的數組元素。另外,即使該數組的大小非零,它也沒有被初始化,因此只包含零或任意值(由聖經標準名爲「的不確定值」)。

cout<<"sum of the array="<<sum<<endl;   
    getch(); 

查看關於<conio.h>的上述評論。

return 0;  //exit the function. Program terminated succesfully. 
} 

讓上述函數總是返回相同的值沒有意義。從信息理論的角度來看,該返回值攜帶零位信息。取而代之的是讓函數’的結果值爲void

int recursive_function (int size, int array[], int index, int sum) 
{ 
    if(size>index) 
    { 
    sum=sum+array[index]; 
    index++; 
    recursive_function(size, array, index, sum); 
    } 

相反遞增index,這是不地道的,因此很難被發現的經驗的讀者,只需使用index + 1在遞歸調用。

const添加到幾乎所有可能的聲明中是一個好主意。

例如,這會迫使您使用index + 1。 :-)

cout<<"from the recursive function"<<endl; 
    cout<<"------"<<endl; 
    cout<<"new sum= "<< sum<<endl; 

    getch(); 

查看關於<conio.h>的上述評論。

return 0; 

查看關於函數總是返回相同的值的上述評論。

} 

總結,所有的未定義的行爲,只是偶然,如果事情似乎工作。

首先解決UB的問題(特別是將C99 VLA替換爲std::vector),然後或許問一個新的問題,如果它仍然不能正常工作。 ;-)

+0

好吧,我會按照你的建議修復這些錯誤。感謝深入分析。但我仍然使用遞歸函數多次顯示相同的顯示。我看不到我做錯了什麼,但我知道我的代碼中有些東西不對。非常感謝! – T4000 2012-03-09 12:35:24

1

你使用大小來創建你的數組,但它在之後被初始化。您只需獲得隨機東西... 申報INT指針,讀取大小,分配與new數組然後再試一次(不要忘記delete)。

0

所有你已經聲明是未知大小的數組首先,聲明讓輸入大小

0

陣列後,請記住,在recursive_function()調用本身很多次 - 和時間,它是所謂的(通過主()或本身)將運行在它的身上所有命令(因爲你永遠不提前返回)... 現在可以看到一個問題的殘培()在那裏?

+0

在遞歸函數中我仍然沒有看到getch()的問題。我認爲遞歸函數中的if(size> index)應該通過避免遞歸函數調用自身超出預期來處理該問題。 – T4000 2012-03-09 12:00:52

+0

這並不是說它會導致函數被調用超過預期 - 它是每調用一次它就會等待按鍵,而不是先完成所有遞歸,然後等待最後一個按鍵,這是我懷疑你想要什麼。 – JTeagle 2012-03-09 12:10:28

+0

確切的,但即使我得到getch()的騎乘時,我仍然有相同的顯示多次,實際上我想在所有遞歸發生後只有一個顯示。 – T4000 2012-03-09 12:33:48