[英]What is ++argv? & confusing compiler error
該代碼由我的c ++講師在一個示例中期課程中提供。 我們在一個非常基本的層次上介紹了argc和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)的值? 那會是什么? 將值一加到整個向量上? 我知道atoi(array)意味着將字符串更改為數值,然后將其存儲在寄存器int'n'中,然后將其添加到main中直接更改的總和中。 那是我真正理解的代碼的唯一部分。 抱歉,如果我的問題/這篇文章有點混亂。
總結一下我的問題是:
謝謝。
編輯:
好的,我已經做了你們建議的更改(謝謝!):
#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;
}
我還添加了返回值,因為由於函數類型沒有返回值,編譯器給出了一個新錯誤。 在Codepad上,它可以編譯並輸出“和為零”,但是,在我正在使用的Dev C ++ 5.7.1上,它仍然不能編譯。 它不會顯示錯誤消息(我正在閱讀的錯誤消息來自Codepad在線編譯器),或者至少我找不到在何處打開它們。 它只是突出顯示了似乎有問題的行,而那仍然是atoi(ptr)的行。
*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)
{
取消引用argv
類型的char **
,會得到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
麻煩值。
++
稱為增量運算符。 通常將1加1。
argv
衰減到一個指針,該指針指向程序的參數容器。
表達式++argv
指向下一個參數(如果有)。
遞增指針意味着使其指向列表中的下一項。
argv
具有類型char **
( 不通過的方括號分心 ),這意味着它指向一個char *
這是在相鄰的列表char *
秒。 argc
參數讓我們知道在哪里可以找到所述列表的末尾。
因此,執行++argv
意味着argv
現在將指向列表中的下一個char *
。 將*
應用於該值(並將結果傳遞給函數)意味着我們將列表中的下一個char *
的值發送給該函數。
所有這些的結果是該函數為每個參數調用一次,但第一個參數除外(因為在第一次取消引用之前我們已經++
'd了)。
注意 這段代碼實際上有一個錯誤。 如果argc == 0
,它將進入la-la land。 進入循環之前,應檢查這種情況。
它是否恆定,是因為我們依賴命令行中的某些輸入,並且無法更改?
不, const char *
位表示atoi()
接受的參數類型。 它是指向常量char
的指針。 請注意, char *
可隱式轉換為const char *
,但並非相反。
這一切意味着atoi()
接受了指向字符的指針,並承諾不會修改指針的目標。
我的猜測是ptr
參數應該是char * ptr
而不是char * ptr[]
。 如果您對此進行更改,則應編譯代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.