2010-10-13 182 views
4

大約3周前,我在2年的java開始學習C++。它看起來很不同,但即時到達那裏。我的講師是一個可愛的傢伙,但任何時候我都會問一個問題,爲什麼這樣或者那樣。他只是迴應「因爲它」。我有很多關於C++的問題,讓我很困惑

Theres在下面的代碼中有很多註釋,有一些隨機問題,但主要問題是即時獲取兩個構建錯誤,一個說arraytotal還沒有初始化(即使我找到了它的值),另一個說主要的外部參考。

任何人都不會介意閱讀代碼並回答內部的一些評論,也許我的整體問題有?

#include<string> 
#include<fstream> 
#include<ostream> 

using namespace std; 

//double decimals[5] ={2,4,6,8,10}; 

const int arraySize = 5; 
// does an arraySize have to be const always? is it so it doesnt channge after the array has been created? 

//double decimals[arraySize]; 

/* 
    this array is being created in the function averageN() but why? 
    cant i just create it up top and reference it in? 
*/ 

// why do you have to write the name of the function up here before you even create it? 
double averageN(); 

int main() 
{ 
    averageN(); 
    return 0; 
} 

// why does the array have to be created here? 
double averageN(double decimals[arraySize]) 
{ 

    double average; 
    double arrayTotal; 
    for (int i = 0; i<5;i++) 
    { 
     // fills with random numbers from 0 - 10 
     decimals[i] = (0+(rand()%10)); 
    } 

    // find the total of all the elements in the array 
    for (int i = 0; i < arraySize;i++) 
    { 
     double currentElement = decimals[i]; 
     arrayTotal = (currentElement+arrayTotal); 
     //arrayTotal +=decimals[i]) ; 
    } 
    // return the average 
    average = (arrayTotal/arraySize); 
    return 0.0; 
} 
+1

是否會編譯代碼?它似乎沒有。先編寫一段可編譯的代碼以更好地理解 – 2010-10-13 13:31:15

+0

請檢查一下您的文章。我認爲你需要格式化文本。我可以看到#include #include #include。頭文件名稱丟失。 – 2010-10-13 13:33:58

+0

這就是問題的一部分。我不知道爲什麼它不會建立。 – OVERTONE 2010-10-13 13:34:19

回答

0

我快速解答沒有雙重檢查(其已一段時間,因爲我用C已經開發++)是:

  1. arraytotal尚未初始化

    我懷疑你的編譯器將其標記爲錯誤確保你做到了。如果你不這樣做,你不能確定它將被初始化爲什麼。傳統上,對於調試版本,C/C++將內存初始化爲一些調試值以幫助識別未初始化的變量。初始化時設置arrayTotal = 0,應該消失。 (最佳實踐)

    例如double arrayTotal = 0;在主

  2. 外部參考我懷疑這是因爲你的原型averageN不符後來定義的方法。原型需要包括參數的類型以及返回類型。將原型從改爲double averageN();double averageN(double []);,我相信會解決這個問題。

  3. 做一個arraySize必須是常量const?是這樣,它沒有channge陣列創建後?

    由於您使用它來定義傳遞到averageN的數組的大小,是的。像這樣設置數組的大小需要一個常數值。

  4. 這個數組是在函數averageN()中創建的,但爲什麼? 我不能創建它頂部並引用它?

    它並沒有被創建在averageN。它是averageN的一個形式參數。averageN的調用者需要提供相應的變量並將其傳入。然後從該方法內部,通過小數點訪問它。

  5. 爲什麼在創建它之前你必須寫出函數的名字?

    這是函數原型。在函數定義之前,如果函數在代碼中被引用,這是必要的。這也可以通過其他方式解決,比如在所有使用它之前移動averageN的定義。

2
  • 常量使編譯器的線索,該項目不應該被改變,如果代碼嘗試它,然後編譯器可以標記一個錯誤。

  • 函數名稱在實際聲明之前被提及過,main()函數在編譯器實際編譯它之前需要引用它(就像它在代碼文件中那樣)。你可以在main()之前移動整個函數來避免這種情況。

  • double averageN(double decimals [arraySize])是說這個函數需要一個數組。它並沒有說它創建了這個數組。如果您查看該函數,它將採用該數組,並將計算值添加到該數組中(decimals[i] = (0+(rand()%10)))。該函數還計算數組上的平均值並將其作爲雙精度返回。

因此,要回答你的大問題什麼是錯的 - 閱讀的最後一個點,看看你正在進行的呼叫 - averageN(); - 你可以看到這是不是正確的電話嗎?

6
  1. //做一個arraySize必須是const常量嗎?是這樣,它沒有channge陣列創建後? 是的,它必須是const,而且它必須是一個常量表達式,這意味着它的大小在編譯時(而不是在運行時)必須已知。 如果你想調整數組大小,那麼最好是使用標準容器std :: vector。或使用動態分配的數組,如果你想有一個固定大小的數組,但大小不知道,直到運行時

  2. /* 在功能averageN(),但爲什麼要創建這個數組? 我不能創建它頂部並引用它? */ 如果你說小數,那麼不,它是一個全局變量,你可以在任何地方使用它。

  3. //爲什麼在創建它之前你必須寫出函數的名字? 您必須在使用C++之前聲明任何名稱。既然你在main中調用了這個函數,它至少必須事先聲明。你也可以在main之前提供定義(body)。

  4. //爲什麼數組必須在這裏創建?

糟糕,看起來你的代碼有很大的混淆。事實上,你有2個函數名爲averageN,一個是averageN,不帶參數,另一個是AveraeN,取一個double數組。你從來沒有定義第一個,只是宣佈。

錯誤:

  1. doubleTotal未初始化。那麼它不是 double arrayTotal;更改爲

    double arrayTotal = 0.0;

  2. 主要的未解決的extenal - 這是您正在調整的主要的AverageN函數。你從來沒有爲它寫過身體。你創建了一個接受數組的函數,因爲你的數組是全局的,所以這沒有用。只需從AverageN定義中刪除數組參數即可。

HTH

附:閱讀S. Lippmann的C++入門。對於初學者來說,它是C++最好的書。 IMO :)

+0

是的,我同意C++入門是一本非常好的初學者書籍 – Vinzenz 2010-10-13 15:17:56

1

OK,這裏是你的唯一分配到arrayTotal:

arrayTotal = (currentElement+arrayTotal); 

現在,什麼是arrayTotal這個分配後的價值?那麼,這取決於它在賦值之前的價值。在第一次任務之前它的價值是什麼?你不知道。它可能是什麼,因爲你從來沒有給它一個初始值。

0

兩個問題:

  • 你averageN的向前聲明是不正確的

代碼:

double averageN(); 

下提供的版本需要的參數。

  • 你averageN的聲明完全不是那麼回事
    聲明數組類型的參數是不直觀明顯。
    通常,人們讓數組退化爲一個指向數組的指針並傳遞一個長度作爲第二個參數。

代碼:

double averageN(double *decimals, int arraySize) 

如果你只想通過你需要參考這麼做特定大小的數組:

double averageN(double (&decimals)[arraySize]) 
  • 您對averageN()調用中主要。
    您正在傳遞零參數。現在這符合前向聲明,但不符合實際定義。

結果我想改變這樣的代碼:

extern double averageN(double (&decimals)[arraySize]); 

int main() 
{ 
    double data[arraySize]; 
    averageN(data); 
    return 0; 
} 

// why does the array have to be created here? 
double averageN(double (&decimals)[arraySize]) 
{ 
+0

我不能這樣做。如果我這樣做,那麼當我去用隨機變量填充數組時,它無法訪問它,因爲數組是definied int他主。 – OVERTONE 2010-10-14 14:23:55

+0

@OVERTONE:我不明白你的意見:是的,數組是在main()中定義的。您還將它作爲參數傳遞給函數averageN(),因此它在那裏也可以訪問。 – 2010-10-14 15:27:58

1
const int arraySize = 5; 
// does an arraySize have to be const always? is it so it doesnt channge after the array has been created? 

C++基本上支持兩種陣列:固定大小的數組,其被聲明爲type name[size],和被分配動態數組與new[]
對於固定大小的數組,您必須將其大小提供給編譯器,以便它可以爲數組留出足夠的內存。由於編譯器必須知道大小,因此只能使用const變量或文字來指定大小。
儘管可以通過調用new[]自己創建動態分配的數組,但這會給您帶來一些令人頭疼的問題,從而導致內存管理權限。最好使用現有的類來爲你做這個,比如std::vector

//double decimals[arraySize]; 

/* 
this array is being created in the function averageN() but why? 
cant i just create it up top and reference it in? 
*/ 

您可以在這裏創建它,但那會讓任何人訪問該數組。對於這樣的小程序來說,這不是一個大問題,但考慮到有十幾個其他文件也可以訪問該陣列並在意外時刻對其進行更改。

這與你爲什麼不讓所有類和成員在Java中公開是基本相同的問題:限制誰有權訪問。

// why do you have to write the name of the function up here before you even create it? 
double averageN(); 

您必須先聲明該函數,然後才能使用它。 C++要求您使用的所有名稱在第一次使用之前必須已經向編譯器聲明,並且編譯器將按從頂部到底部的順序讀取文件。

請注意,該聲明與您在下面給出的函數定義不匹配。如C++支持函數重載,兩個被認爲是不同的功能,因爲它們接受不同的參數(無對指針)

int main() 
{ 
    averageN(); 
    return 0; 
} 

// why does the array have to be created here? 
double averageN(double decimals[arraySize]) 
    { 

這並不創建的陣列。相反,它指定函數期望用指針參數調用(arraySize被完全忽略,並且不能將數組傳遞給C++中的函數,因此參數被調整爲讀取double *decimals)。

爲了得到一個工作程序,您需要更改上面

double averageN() 
    { 
    double decimals[arraySize]; 

double average; 
double arrayTotal; 

兩個averagearrayTotal沒有初始化的兩行。這意味着他們將以一些未知的價值開始。
對於average,這不是一個問題,因爲你用它做的第一件事是分配一個新的值。但是對於arrayTotal,您正在爲其添加值,因此您必須讓它以已知值開始。

for (int i = 0; i<5;i++) 
{ 
    // fills with random numbers from 0 - 10 
    decimals[i] = (0+(rand()%10)); 
} 

// find the total of all the elements in the array 
for (int i = 0; i < arraySize;i++) 
{ 
    double currentElement = decimals[i]; 
    arrayTotal = (currentElement+arrayTotal); 
    //arrayTotal +=decimals[i]) ; 
} 
// return the average 
average = (arrayTotal/arraySize); 
return 0.0; 
} 
+0

它足以說arrayTotal = NULL? – OVERTONE 2010-10-14 12:55:51

+1

@OVERTONE:不,最好說'arrayTotal = 0.0'。 NULL應該只用於指針。 – 2010-10-14 13:27:14

0

除了其他的答案的技術細節,而不是回答你的第一個段落投訴:一種途徑獲得高質量的回答「爲什麼」的C++的問題是要問在Usenet新聞組中的一個,因爲,就像使用StackOverflow那裏有真正的專家在那裏掛起,但不像StackOverflow甚至初學者的問題是可能得到標準化委員會成員的答案,如果你是幸運的,甚至從那些誰已經寫了標準像Andrew Koenig或現在的Pete Becker)。在早些時候,Bjarne也在那裏。但近年來他並沒有發表太多。

基本新手「爲什麼」問題:alt.comp.lang.learn.c-c++。弗朗西斯·斯博伯博在那裏掛了。他是一名成功的C++入門書籍的作者和作者。他也知道一些數學知識,並且由於發佈頻率很低(StackOverflow是什麼!),所以幾乎可以確定,任何半路有趣的問題都會立即 - 正確地 - 被Francis迅速回答。 :-)

關於C++語言的一般問題:comp.lang.c++和/或comp.lang.c++.moderated。後者是主持人,有章程。適度減少噪音 - 例如沒有垃圾郵件 - 但增加了延遲。一些委員會成員更願意主要在未受管制的團體(例如James Kanze)中發帖,有些人,如Pete Becker和Howard Hinnant,都在這兩個團體中發帖,還有一些知名的專家,例如,現在,安德烈亞歷山德雷斯庫顯然只在緩和組中發帖。

關於標準意味着什麼的問題,關於標準錯誤的報告等等(在早些時候,這也是您正式報告標準缺陷的地方):[comp.std.C++]。這也是一個慢節奏的小組,不幸的是mod延遲現在幾乎無法忍受。但作爲一個新手,你可能對形式細節不太感興趣,並且對[comp.lang.C++]和[comp.lang.C++。moderated]都是很棒的組合(我認爲StackOverflow的main好處是當你想知道「這段代碼中的錯誤是什麼」或原則上可以通過閱讀相關文檔來解決的問題時)。

最後,我鏈接到Google Groups,它提供了基於Web的界面,但您可以更直接地從諸如Thunderbird的Usenet客戶端(或例如Opera瀏覽器,它具有內置客戶端)訪問這些組。爲了通過本地客戶端訪問Usenet,您所要做的就是配置客戶端,告訴它有關服務器的信息,如免費的EternalSeptember。或者AIOE。 -

乾杯&心連心,

阿爾夫

+0

謝謝。我選擇在這裏發佈,因爲代碼沒有編譯膨脹作爲所有其他問題,但我肯定給這些組看一看 – OVERTONE 2010-10-14 12:52:43

0

有一件事似乎沒有人上都評論:您的return語句在averageN到底是錯的。你說你正在返回平均值,然後你計算半徑,然後return 0.0;。試試return average;return arrayTotal/arraySize;

+0

Thronley我打算在cout聲明中打印出平均值。我的講師堅持我們一直返回0來表明它的正確執行。可能會讓人更容易判斷它是否適合他。我確定他會最終改變它 – OVERTONE 2010-10-14 12:50:47

+0

@OVERTONE:啊,其中的一個問題。你的講師是錯誤的,這不是一個好習慣。儘量不要養成習慣。計算某個東西的函數應該返回它計算的值,而不是任意的成功值。至少在你接受講師要求的時候,考慮正確的做法。 – 2010-10-14 13:56:47