为什么指向 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;
顺便说一句,与您的问题无关,您是否在启用警告的情况下编译代码(例如,通过使用 Wall
和 Wextra
标志)?
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 类型。这应该可以正常工作。
我想了解指针在这里的工作原理。 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;
顺便说一句,与您的问题无关,您是否在启用警告的情况下编译代码(例如,通过使用 Wall
和 Wextra
标志)?
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 类型。这应该可以正常工作。