2014-11-04 53 views
0

此代碼由我的C++教師在樣本期中提供。我們在一個非常基礎的層面上覆蓋了argc和argv,所以我理解這些表達式的含義。然而,像解引用運算符和'++'之類的任何附加內容都會讓我困惑,而我所搜索的內容還不夠清晰,因此無法將其應用於此特定示例。此外,當我嘗試編譯,它提供了這樣的錯誤:什麼是++ argv? &令人困惑的編譯器錯誤

In function 'int summer(int*, char**)': 
Line 9: error: cannot convert 'char**' to 'const char*' for argument '1' to 'int atoi(const char*)' 
compilation terminated due to -Wfatal-errors. 

我們還沒有正式覆蓋的指針,但我想我明白他們不夠好。 char **意味着你解除引用兩次,所以指針char的值是一個指向別的東西的指針,所以第二個*意味着我們需要這個值。它是不變的,因爲我們依靠命令行中的某些輸入並且無法更改?我不明白這一點。

#include <iostream> 

using namespace std; 

int summer(int *acc, char * ptr[]) 
{ 
    register int n; 

    n = atoi(ptr); 
    *acc = *acc + n; 
} 

main(int argc, char * argv []) 
{ 
    int sum = 0; 

    while (--argc) 
    summer(&sum, *++argv); 

    cout << "sum is " << sum << endl; 
} 

另一個問題:當* ++ argv傳遞給summer()時,這是否意味着(argv [] + 1)的值?那甚至會是什麼?將值1添加到整個矢量?我知道atoi(數組)意味着將字符串轉換爲數值,然後將其存儲在int'n'寄存器中,然後將其添加到main中直接改變的和中。這就是我真正理解的這段代碼的唯一部分。對不起,如果我的問題/這個帖子有點亂。

要總結一下我的問題是:

  1. 什麼是編譯錯誤信息是什麼意思?
  2. ++ argv是做什麼的?

謝謝。


編輯:

好吧,我做你們建議的修改(謝謝!!):

#include <iostream> 

using namespace std; 

int summer(int *acc, char * ptr) 
{ 
    register int n; 

    n = atoi(ptr); 
    *acc = *acc + n; 

    return 0; 
} 

int main(int argc, char * argv[]) 
{ 
    int sum = 0; 

    while (--argc) 
    summer(&sum, *++argv); 

    cout << "sum is " << sum << endl; 

    return 0; 
} 

我還增加了收益,因爲編譯器給了一個新的由於函數類型沒有返回值而導致錯誤。在鍵盤上,它編譯和打印「總和爲零」,但是,它仍然不能在Dev C++ 5.7.1上編譯,這正是我正在使用的。它不顯示錯誤消息(我一直在閱讀的是從Codepad在線編譯器),或者至少我無法找到將它們打開的位置。它只是突出了它似乎有問題的線條,而這仍然是atoi(ptr)的界線。

+0

我很難相信你的教師會給你不可編譯的代碼。 – user657267 2014-11-04 00:06:01

+0

那麼人們不是完美的哈哈,這不是他第一次這樣做。這也可能是我缺少的東西。我給他發了一封電子郵件,但我希望這個網站能提供更快的反饋。 @ user657267 – Sarah 2014-11-04 00:08:39

+1

更不用說'main'應該是'int main',並且聲明一個'register'變量對於當代編譯器來說通常是毫無意義的。指針繁重的代碼也很奇怪,因爲這是一個C++類。 – user657267 2014-11-04 00:11:47

回答

2

*argv相當於argv[0],所以++argv;將使*argv相當於原來的argv[1]。因此,*++argv的計算結果與argv[1](程序本身的名稱後的第一個命令行參數)的計算結果相同,除了它增量爲argv,而argv[1]顯然沒有。

爲你的錯誤,你應該改變:

int summer(int *acc, char * ptr[]) 
{ 

到:

int summer(int *acc, char * ptr) 
{ 

當取消引用char **,這是argv的類型,你會得到一個char *char *atoi()期待的。

你的程序本質上是相同的:

#include <iostream> 
#include <cstdlib> 

using namespace std; 

void summer(int * acc, char * ptr) 
{ 
    *acc += atoi(ptr); 
} 

int main(int argc, char * argv []) 
{ 
    int sum = 0; 

    for (int i = 1; i < argc; ++i) { 
     summer(&sum, argv[i]); 
    } 

    cout << "sum is " << sum << endl; 
} 

除了你的不檢查的argc麻煩值。

+0

'char * ptr []'不能被'char * ptr'替代。它們是完全不同的類型。 – 2014-11-04 00:13:17

+0

@CrazyEddie它們確實是不同的類型,這就是它不能編譯的原因。關於代碼的一切都表明'char * ptr'是正確的 - 調用'atoi()'以及調用'summer()'時提供的實際參數。 – cdhowie 2014-11-04 00:14:07

+0

@CrazyEddie:這正是OP爲什麼要取代它的原因。 – 2014-11-04 00:14:13

0

++被稱爲增量運算符。它通常會增加1。

argv衰減爲指向程序參數容器的指針。

表達式++argv指向下一個參數,如果有的話。

+2

其實'argv'不會衰減到一個指針,它已經是一個了。 'type param []'語法只是在函數參數的上下文中說'type * param'的另一種方式。 – 2014-11-04 00:08:51

0

遞增指針意味着指向列表中的下一個項目。

argv具有類型char **don't be distracted by the square brackets),這意味着它指向一個char *這是在相鄰char * s的列表。 argc參數讓我們知道在哪裏找到所述列表的結尾。

因此,在做++argv意味着argv現在將指向列表中的下一個char *。將*應用於(並將結果傳遞給函數)意味着我們將列表中下一個char *的值發送給該函數。

所有這一切的結果是,該函數被調用一次爲每個參數,不包括第一個(因爲我們++'d之前解引用第一次)。

注意:這段代碼實際上有一個錯誤;如果argc == 0它將進入la-la land。它應該在進入循環之前檢查這種情況。

+0

非常感謝你馬特! – Sarah 2014-11-04 00:46:02

0

Is it constant because we are relying on something input in the command line and that can't be changed?

否,const char *位指論點,即atoi()接受的類型。它是一個指向常數char的指針。請注意,char *可以隱式轉換爲const char *,但不是相反。

所有這一切意味着atoi()接受一個指向一個字符的指針,它承諾它不會修改指針的目標。

我的猜測是ptr參數應該是char * ptr而不是char * ptr[]。如果你改變它,代碼應該編譯。

+0

非常感謝您的幫助!我做了你所建議的改變,但它仍然不能編譯。 (詳細信息見編輯的原文) – Sarah 2014-11-04 00:44:33