[英]Why do we need a pointer here
我是 C++ 的新手,在瀏覽指針時我不太明白為什么我需要在下面的while
循環條件檢查中使用*p
。
這是一個非常簡單的函數,用於計算數組中字符x
的出現次數,調用示例如下面的main()
函數。 我們在這里假設p
將指向一個字符數組。 純粹為了演示。
int count(char* p, char x) {
int count = 0;
while (*p != NULL) { // why *p requried here if p is already a pointer?
if (x == *p) count++;
p++;
}
return count;
}
int main(){
char a[5] = {'a','a','c','a',NULL};
char* p = a;
std::cout << count(p, 'a') << std::endl;
}
為什么我需要
while (*p != NULL)
由於p
已經是一個指針,我想
while (p != NULL)
應該足夠了,但是程序崩潰了。
遞增指針將使它指向字符數組中的下一個元素。 遞增指針永遠不會使其等於空指針或NULL
。
C 字符串以 nul 結尾。 字符串的末尾用值為'\0'
的元素標記。 在 main 中,這是數組的最后一個元素,函數中的循環將在到達最后一個元素時停止。
p
是指向元素的指針。 *p
是元素。
在該條件下使用NULL
具有誤導性。 NULL
不應再在 C++ 中使用。 空指針是nullptr
,字符串中的終止符是'\0'
。 盡管如此,該代碼仍然有效,因為NULL
恰好等於0
和'\0'
。 很難,它是用於指針,而不是用於char
。
代碼可以這樣寫:
int count(char* p, char x) {
int count = 0;
while (*p != '\0') { // why *p requried here if p is already a pointer?
if (x == *p) count++;
p++;
}
return count;
}
int main(){
char a[5] = {'a','a','c','a','\0'};
std::cout << count(a, 'a') << std::endl;
}
或者更好,使用std::string
和std::count
:
#include <string>
#include <algorith>
int main() {
std::string s{"aaca"};
std::cout << std::count(s.begin(),s.end(),'a');
}
請注意,字符串文字會自動包含終止符。 所以"aaca"
是一個const char[5]
,一個 5 個字符的數組,最后一個是'\0'
。 使用std::string
的細節有點復雜,但s[4]
也是'\0'
。 請注意,這與其他容器形成對比,其中container[container.size()]
是越界和錯誤的。
p
是指向char
的指針。 因此,如果您檢查p
的值,它將是該char
的地址(字符串或數組中的第一個char
)。 因此,無論您指向第一個字符還是最后一個字符,該地址都將是非零的。
在 C 或 C++ 中,字符串傳統上以 null 終止,這意味着字符串的結尾由 null 終止符標記,它是值為 0 的單個字符。要檢查指針p
指向的char
的值,您需要取消引用它。 取消引用是通過在表達式前加上*
來完成的。 在這種情況下,我們提取p
指向的值而不是p
指向的地址。
你基本上有一個char
數組,作為一個例子,它在內存中可能看起來像這樣:
地址 | ASCII 值 | 價值 |
---|---|---|
1000 | 97 (0x61) | 一種 |
1001 | 97 (0x61) | 一種 |
1002 | 99 (0x63) | C |
1003 | 97 (0x61) | 一種 |
1004 | 0 (0x00) | 無效的 |
首先將指向第一個字符,即地址1000,因此p
的值為1000, *p
的值為97或'a'。 當您遞增p
時,它將變為 1001、1002 等,直到達到 1004,其中p
的值為 1004, *p
的值為 0。
如果你寫while (p != NULL)
而不是*p
你基本上會檢查1004 != 0
是否為真,並且你會繼續超過字符串的末尾。
我知道很多(較舊的)教程都是從(裸)指針和“C”樣式數組開始的,但它們實際上並不是您應該首先使用的東西。 如果可能,在 C++ 中嘗試編寫不依賴於指針的解決方案。 要保存文本,請使用 std::string。
#include <string> // stop using char* for text
#include <algorithm> // has the count_if method
#include <iostream>
int count_matching_characters(const std::string& string, char character_to_match)
{
int count{ 0 };
// range based for loop, looping over al characters in the string
for (const char c : string)
{
if (c == character_to_match) count++;
}
return count;
// or using a lambda function and algorithm
/*
return std::count_if(string.begin(), string.end(), [&](const char c)
{
return (character_to_match == c);
});
**/
}
int main()
{
int count = count_matching_characters("hello world", 'l');
std::cout << count;
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.