为什么指向 c 字符串 return 中元素的指针不只是元素?

Why doesn't a pointer to an element in a c-string return just the element?

我想了解指针在这里的工作原理。 findTheChar 函数在 str 中搜索字符 chr。如果找到 chr,它会 return 指向首次找到该字符的 str 的指针,否则 nullptr(未找到)。我的问题是为什么函数打印出 "llo" 而不是 "l"?而我在 main return 中编写的代码是 "e" 而不是 "ello"?

#include <iostream>
using namespace std;

const char* findTheChar(const char* str, char chr)
{
    while (*str != 0)
    {
        if (*str == chr)
            return str;
        str++;
    }
    return nullptr;
}

int main()
{
    char x[6] = "hello";
    char* ptr = x;
    while (*ptr != 0)
    {
        if (*ptr == x[1])
            cout << *ptr << endl; //returns e
            ptr++;
    }
    cout << findTheChar("hello", 'l') << endl; // returns llo
}
cout << findTheChar("hello", 'l') << endl; //returns llo

Return findTheChar 的类型是 const char *。当您尝试使用 std::cout it would print the character array pointed by the address upto terminating [=18=] character.

打印 const char *
str -> +---+---+---+---+---+---+
       | h | e | l | l | o | [=11=]|
       +---+---+---+---+---+---+
                 ^
                 |
         findTheChar(str, 'l')

如果您只需要一个字符,请取消引用地址(如果它不为空)。如果要打印 return 地址,可以将其类型转换为 void *.

while the code i wrote in main return an "e" instead of "ello"

cout << *ptr << endl; //returns e

此处您明确将 ptr 取消引用为 *ptr,因此您打印的是 char 而不是 const char *

由于您使用的是 C++,因此使用 std::string 和迭代器会更好。

// Returns offset of first occurance if found
// Returns -1 if not found
int findTheChar(const std::string& str, char chr );

C 字符串是由 '[=10=]' 字符终止的字符缓冲区。传递它们只需要传递一个指向第一个元素的 指针 .

所有库例程都知道它们可以从给定的地址开始读取字符,直到到达 '[=10=]'。由于这就是 operator<< for std::cout 的设计方式,它假定您将 C 字符串的起始地址传递给它。这就是合同。

如果要打印单个字符,则需要取消引用该指针。

My question is why does the function print out "llo" instead of "l"?

因为你要求它,当你打印什么函数时 returns.

你函数的return值是一个字符串:const char*.

因此,cout 将开始打印字符串,从指针指向 (a char) 的位置开始,直到遇到空 C 字符串终止符 ('[= 16=]').

如果您只想要字符,您应该在打印阶段取消引用 returned 指针,如下所示:

const char* ptr = findTheChar("hello", 'l');
if(ptr)
    cout << *ptr << endl; //prints l
else
    cout << "Character not found" << endl;

顺便说一句,与您的问题无关,您是否在启用警告的情况下编译代码(例如,通过使用 WallWextra 标志)?

In function 'int main()':
21:9: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
         if (*ptr == x[1])
         ^~
23:13: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
             ptr++;
             ^~~

来自这部分:

if (*ptr == x[1])
        cout << *ptr << endl; //returns e
        ptr++;

char* 类型的指针指向内存位置,内容被解释为单个字符。所以如果你写

char* x = "Hallo";

x 指向 'H'。如果你写

std::cout << *x << std::endl;

std::cout 的输出运算符用单个字符调用。

但是如果你写

std::cout << x << std::endl;

你有特殊情况,其中 std::ostream 的输出运算符将 char* 解释为指向 C 类字符串的指针,该字符串以 null 结尾。所以 x 指向单个字符,但 char* 的 ostream 运算符将其解释为指向字符串第一个字符的指针。

Return *str 并更改函数 return 类型。这应该可以正常工作。