char** argv
和char* argv[]
有什麼區別?在int main(int argc, char** argv)
和int main(int argc, char* argv[])
?C++ - char ** argv與char * argv []
他們是否一樣?特別是第一部分沒有[]
。
char** argv
和char* argv[]
有什麼區別?在int main(int argc, char** argv)
和int main(int argc, char* argv[])
?C++ - char ** argv與char * argv []
他們是否一樣?特別是第一部分沒有[]
。
它們完全相同。 char *argv[]
必須讀取爲指向char
的指針數組,並將數組參數降級爲指針,因此指向指向char
或char **
的指針。
這與C中的相同。
對於所有實際用途,它們都是相同的。這是由於C/C++對作爲參數傳遞的數組的處理,其中數組衰減爲指針。
對於問題的第一部分:
所以問題是指向C類型的指針和數組C []是否是相同的東西。他們一般都不是,但他們是equivalent when used in signatures。
換句話說,在你的例子中沒有什麼不同,但重要的是要記住指針和數組之間的區別。
鏈接到C FAQ,但問題是標記爲C++。 – 2011-03-04 09:52:14
C++是C的擴展...因此,適用於C的所有內容都與C++相關。 – 2011-03-04 09:54:14
沒有。有人認爲在C中是非法的,並允許在C++中使用,所以當有些來源說「這是非法的......」並不意味着這適用於C++。 – Mephane 2011-03-04 10:09:45
它們確實完全一樣。
陣列要記住的黃金規則是:
「的陣列的名稱是一個指針數組的第一元素」。
所以,如果你聲明如下:
char text[] = "A string of characters.";
然後變量「文本」是指向你剛剛宣佈的字符數組的第一個字符。換句話說,「文本」是char *
。當你使用[索引]訪問數組的一個元素時,你實際上做的是將索引的偏移量添加到指向數組第一個元素的指針,然後取消引用這個新指針。因此,下面兩行將初始化兩個變量「T」:
char thirdChar = string[3];
char thirdChar2 = *(string+3);
使用方括號是通過使代碼更可讀的語言提供一個便於學習。但是,當你開始思考更復雜的事情時,這種方式非常重要,例如指向指針的指針。 char** argv
與char* argv[]
相同,因爲在第二種情況下,「數組的名稱是指向數組中的第一個元素的指針」。
從這裏你也應該能夠看到爲什麼數組索引從0開始。指向第一個元素的指針是數組的變量名稱(黃金法則再次)加上偏移量...什麼都不是!
我和我的一位朋友曾經討論過哪個更適合在這裏使用。使用char* argv[]
表示法,讀者可能會更清楚地知道,這實際上是「指向字符的指針數組」,而不是可以被讀作「指向字符指針的指針」的表示法。我的觀點是,後面的這個表示法並沒有向讀者傳達太多的信息。
很高興知道它們完全相同,但爲了可讀性,我認爲如果意圖是一系列指針,那麼char* argv[]
表示法會更清楚地表達這一點。
感謝您的回覆。你能告訴我這兩種形式怎麼樣? – Simplicity 2011-03-04 10:10:27
我編輯了我的答案,應該給出更詳細的解釋。 – 2011-03-04 11:09:14
+1方括號 – 2014-09-24 08:39:18
兩者都同樣爲您的使用,除了以下細微的差別:
什麼?在OP的要求中,每一個都是incorerct。 – 2012-06-26 21:20:02
支架形式是僅在聲明聲明等是有用的:
char *a[] = {"foo", "bar", "baz"};
printf("%d\n", sizeof a/sizeof *a);
// prints 3
,因爲它知道在編譯時該陣列的大小。當你將一個括號形式作爲參數傳遞給一個函數(主函數或其他函數)時,編譯器不知道在運行時數組的大小是多少,所以它和char ** a完全一樣。我更喜歡char ** argv,因爲它更清晰,sizeof不會像在聲明聲明表單上那樣工作。
C和C++中的TYPE * NAME
和TYPE NAME[]
之間有所不同。在C++中,這兩種類型都不可互換。例如下面的函數是非法的在C(你會得到一個錯誤)++,但法律在C(你會得到警告):
int some (int *a[3]) // a is array of dimension 3 of pointers to int
{
return sizeof a;
}
int main()
{
int x[3][3];
std::cout << some(x)<< std::endl;
return 0;
}
爲了使法律只是改變簽名int some (int (*a)[3])
(指針的3個整數數組)或int some (int a[][3])
。最後方括號中的數字必須等於參數的數字。從數組數組轉換爲指針數組是非法的。從指針轉換爲指向數組數組也是非法的。但是將指針轉換爲指針數組是合法的!
所以請記住:只有最接近解除引用類型簽名並不重要,其他人做(在指針和數組的上下文中,肯定)。
考慮我們有一個爲指針指向INT:
int ** a;
&a -> a -> *a -> **a
(1) (2) (3) (4)
int ***
。可通過功能int **b[]
或int ***b
。最好的是int *** const b
。int **
。可以通過功能作爲int *b[]
或int ** b
。數組聲明的括號可以是空的或包含任何數字。int *
。功能可能爲int b[]
或int * b
或甚至void * b
回答你的問題:在主要功能的真正的類型變元的的是char ** argv
,所以它可以很容易地表示爲char *argv[]
(但不作爲char (*argv)[]
)。另外argv
的主要功能名稱可能會改爲safely。 您可以輕鬆地檢查:std::cout << typeid(argv).name();
(PPC =指針p來燒焦。)
順便說一句:還有一個很酷的功能,帶有數組引用:
void somef(int (&arr)[3])
{
printf("%i", (sizeof arr)/(sizeof(int))); // will print 3!
}
此外指針什麼可能會被函數隱式接受(轉換)爲空指針。但只有單個指針(不指向指針等)。
延伸閱讀:
感謝您的答覆。你能解釋一下嗎:'...和一個數組參數被降爲一個指針,所以指向指向char或char **的指針。' – Simplicity 2011-03-04 10:03:28
@user:這是一條語言規則。當你用語法'X foo(Y a [])'聲明或定義一個函數時,它實際上變成了'X foo(Y * a)'。看起來像一個函數的數組參數實際上是一個指針。由於'argv'被聲明爲一個數組(指針),它成爲一個指針(指針)。 – 2011-03-04 10:08:10
* char * argv'清除* char *部分的指針。但是,第一個指針從哪裏來? – Simplicity 2011-03-04 10:21:27