为什么 strstr() - char pointer = number?

Why strstr() - char pointer = number?

我有这个程序:

#include <iostream>
#include <conio.h>
#include <string.h>

using namespace std;

int main()
{
  char char1[30] = "ExtraCharacter", char2[30] = "Character", *p;

  p = strstr(char1, char2);
  cout << "p: " << p << endl;
  cout << "char1: " << char1 << endl;
  cout << "(p-char1): " << (p-char1) << endl;

  return 0;
}

当我 运行 它时,我得到:

p: Character
char1: ExtraCharacter
(p-char1): 5

符合预期。

但这不是问题,我不确定为什么"Character" - "ExtraCharacter"是一个整数(5)?也许不是整数,而是 number/digit 无论如何。 其实我不明白为什么"Character"存储在p,而不是内存地址

如果我从书上理解的很好,strstr() returns一个内存地址,是不是应该更像一个奇怪的值,像一个十六进制(0x0045fe00)或类似的东西?我的意思是,显示该内存地址的实际值是 cout << p 而不是 cout << *p

谁能给我解释一下它是如何工作的?

P.S.: 如果标题不连贯,我深表歉意。

要显示地址,您必须将 char* 转换为 void*:

std::cout << "p: " << static_cast<const void*>(p) << std::endl;

Demo

But this is not the problem, I'm not sure why "Character" - "ExtraCharacter" is an integer (5)?

您从一个指针中减去另一个指针,结果 - 数字,从 char char1 指向到 char p 指向的距离。这就是指针算法的工作原理。

注意:只有当两个指针都指向同一个数组(或最后一个元素之后)时,此减法才有效,这在您的代码中就是这种情况,但您需要小心。例如,如果 strstr() 没有找到 susbtring 那么它将 return nullptr 并且你的减法将有 UB。所以至少在减去之前检查 p (并且将 nullptr 传递给 std::cout 也会有 UB)

If I understood well from a book, strstr() returns a memory address, shouldn't it be more like a strange value, like a hex (0x0045fe00) or something like that? I mean, it's cout << p not cout << *p to display the actual value of that memory address.

是的 p 是一个指针,也就是内存地址。 std::ostream 有特殊规则如何将指向 char 的指针打印为字符串,因为 C 中的字符串以这种方式存储。如果您想将其视为指针,只需将其转换为:

std::cout << static_cast<void *>( p );

然后你会看到它是一个地址。

对于 std::basic_ostream(cout 的类型),字符和字符串参数(例如,char 或 const char* 类型)由 operator<< 的非成员重载处理,它们被视为字符串。 char[30] 将衰减为 const char* 参数,basic_ostream 将在指针的地址输出空终止字符串。

至于(p-char1),两个指针相减的结果是一个std::ptrdiff_t。它是一个实现定义的有符号整数。这就是为什么输出是 5