繁体   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