簡體   English   中英

為什么我們需要一個指針

[英]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::stringstd::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM