我試圖理解用戶HS在這篇文章中撰寫的下面代碼行中使用的指標。誰能幫幫我?
for (char **pargv = argv 1; *pargv != argv[argc]; pargv )
整個代碼:
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc < 2) {
printf("ERROR: You need at least one argument.\n");
return -1;
}
for (char **pargv = argv 1; *pargv != argv[argc]; pargv ) {
/* Explaination:
* Initialization -
* char **pargv = argv 1; --> pargv pointer pointing second element of argv
* The first element of argument vector is program name
* Condition -
* *pargv != argv[argc]; --> *pargv iterate to argv array
* argv[argc] represents NULL
* So, the condition is *pargv != NULL
* This condition (*pargv != argv[argc]) is for your understanding
* If using only *pragv is also okay
* Loop iterator increment -
* pargv
*/
printf ("Vowels in string \"%s\" : ", *pargv);
for (char *ptr = *pargv; *ptr != '\0'; ptr ) {
if (*ptr == 'a' || *ptr == 'e' || *ptr == 'i' || *ptr == 'o' || *ptr == 'u'
|| *ptr == 'A' || *ptr == 'E' || *ptr == 'I' || *ptr == 'O' || *ptr == 'U') {
printf ("%c ", *ptr);
}
}
printf ("\n");
}
return 0;
}
問題:
使用第一個中的兩個解參考運算子
**pargv = argv 1是因為argv 是一個指標陣列,因此需要使用指向指標(**pargv) 的指標來參考它。 這個說法正確嗎?為什么有必要指向 argv 的地址
(argv 1)或(&argv[1])而不是其中的值 (*argv[1])?
在我看來,指向地址會帶來地址的整數,但我知道這樣的代碼是正確的。那么為什么要指向地址回傳里面的值呢?
我試圖通過替換argv 1for來更改下面的代碼片段,argv[1]因為在我看來我應該指向陣列內部的值而不是指向指向該值的地址,但我從編譯器 (GCC) 收到錯誤訊息。
for (char **pargv = argv 1; *pargv != argv[argc]; pargv )
uj5u.com熱心網友回復:
- 使用第一個中的兩個解參考運算子
**pargv = argv 1是因為argv 是一個指標陣列,因此需要使用指向指標(**pargv) 的指標來參考它。這個說法正確嗎?
部分正確。
**您指的不是兩個推導運算子。它是為變數宣告的型別的一部分pargv。整個型別是,指向指向的指標的指標。char **char
使用它是因為它與argv. 盡管將其argv視為陣列并非沒有道理,但更正確的理解是它實際上是指向陣列(指標)的第一個元素的指標,而不是陣列本身。在 C 中不可能將陣列作為函式引數傳遞——甚至無法表達它。
- 為什么有必要指向 argv 的地址
(argv 1)或(&argv[1])而不是其中的值 (*argv[1])?
這是沒有必要的。但是使用指向陣列元素的指標是迭代陣列的一種方法,這就是所提供的代碼所做的。并且回圈體確實通過運算式使用了指向(指標)的值*pargv。回圈可以重寫為:
for (int i = 1; argv[i] != argv[argc]; i ) {
char **pargv = argv i;
// ...
在我看來,指向地址會帶來地址的整數,但我知道這樣的代碼是正確的。那么為什么要指向地址回傳里面的值呢?
取消參考指標可以獲得它指向的物件,無論是什么型別。包括指向的物件本身是否是指標。這正是所提供代碼中發生的情況。
我試圖通過替換
argv 1for來更改下面的代碼片段,argv[1]因為在我看來我應該指向陣列內部的值而不是指向指向該值的地址,但我從編譯器 (GCC) 收到錯誤訊息。
argv 1不等于argv[1]. 曾經。簡單的型別分析可以告訴您:如果兩個運算式都被定義,那么它們具有不同的型別(在示例代碼中分別為char **和)。char *在這種情況下,根據定義argv[1]等同于,并且等同于。*((argv) 1) argv 1&argv[1]
uj5u.com熱心網友回復:
可怕的代碼
*pargv != argv[argc]是未定義的行為。如果出于某種原因你想使用指標,它應該是
for (char **pargv = argv 1; pargv <= argv argc -1; pargv ) {
第一個中使用的兩個解參考運算子 **pargv = argv 1
在這種情況下它不是取消參考運算子。它定義指向 char 變數的指標pargv
但是我從編譯器 (GCC) 得到一個錯誤。
因為argv[i] == *(argv i)不是argv i。索引取消參考指標。如果你想使用索引,你需要使用&運算子來參考它char **pargv = &argv[1];
uj5u.com熱心網友回復:
我在這里可能是錯的,但請允許我嘗試回答您的問題。
這里要注意,argv 不僅僅是一個指標陣列,而是一個指標到指標陣列。指標只是指向記憶體中的一個地址。你的說法是正確的。測驗這一點的一個很好的例子是,在 main 中,您可以用 char **argv 代替它,而不是使用 char *argv[] 的語法,并且什么都不會改變。宣告陣列時,會在記憶體中為陣列的開頭分配一個地址,并根據以位元組為單位的資料型別(char、int、long 等)的大小和陣列的長度分配空間。為了進一步說明,當您將引數傳遞給 main() 時,傳遞給 argv[0] 的第一個引數始終是呼叫檔案的引數。例如,如果您給出的代碼存盤在名為“myFile.cpp”的檔案中,則 argv[0] 將指向記憶體中的一個地址,其中將存盤字符陣列“myFile.cpp”(當然以空字符結尾) ).
2 的答案直接來自問題 1。您必須指向 argv 當前所在位置的值,因為如果您只是獲取 (*argv[1]) 的值,它實際上會回傳一個地址,指向您所在的 char 陣列'尋找實際上開始!(argv 1) 將回傳第一個 char[] 陣列引數開始的地址。
回答你最后的問題:argv 1 指的是 argv,它是一個 char**。argv[1] 訪問 argv 的第二個元素,它是指向 char 陣列的指標: char* 。編譯器根據型別定義注意到這一點并回傳錯誤。這就是為什么您需要對當前的實作執行 (argv 1) 和 (&argv[1]) ,它們是相同的。argv 1 是一個 char**,argv[1] 的地址是 char** 型別,但是 argv[1] 指向的 VALUE 是 char*。
我希望這有幫助。我以前從未在 StackOverflow 上回答過問題。請任何人隨時糾正任何錯誤!
編輯:請參考Andreas Wenzel 的評論以澄清陣列宣告和陣列指標宣告。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/537838.html
標籤:数组C指针
上一篇:如何將TreeData制作成陣列
