我在学习 cpp 中的指针并编写了这段代码,但是当我运行这段代码时,结果与我预期的不同,但为什么?
#include <iostream>
using namespace std;
int main()
{
char chars[] = {'a','b','g','j','z'};
char *ptr1 = chars;
cout << ptr1 << endl;
int arr[] = {1,2,3,4,5};
int *ptr2 = arr;
cout << ptr2;
return 0;
}
这段代码的输出是:
abgjz
0x7ffd836e4360
为什么第一个指针打印了整个字符数组而第二个指针只打印了地址?
我想打印两个数组的地址。
他们是这样写的,主要是因为人们认为(我猜大部分是正确的)这样会有用。
至于要打印地址,一般要先转成
void *
。这对于打印出地址应该是相当可靠的(事实上,毫无疑问,它现在是如何打印出指向 int
的指针的,仅仅是因为它是唯一可以采用 int *
类型参数的可用重载)。
算子的实现<< with char* operands assumes that the operand points to a nil-terminated C string and prints the C string. For other pointer type operands it makes no assumptions and prints just the pointer itself. That’s how it is defined. Can’t change it. If you want to print the pointer value, cast it to void*.
std::cout << "hello world\n";
在上面的代码行中,
"hello world\n"
的类型是 13 char
的 const 数组,其值为 {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\n', '\0'}
.
除非你做一些额外的工作,否则像这样的数组会退化为指向第一个元素的指针。所以这个:
auto str = "hello world\n";
str
的类型为 char const*
,它指向 h
.
根据 C 的约定,指向字符的指针通常被视为指向 nul(非 NULL)终止缓冲区的指针并表示字符串。
以这种方式使用
char const*
s 是 C 语言中的常规约定,事实上,如果 char const*
没有包含在 typedef 中以使其模糊不清,那么不引用 nul 终止字符串将是不寻常的。
所以
std::ostream
被教导将这些 char const*
作为 nul 终止的字符串使用,并打印每个字符串,直到找到一个 '\0'
字符(其位值都是 0
)。
对于其他指针,它会打印它们的地址。
没有简单的方法来区分
char const*
是一个指向空终止缓冲区的指针和一个不是,所以他们选择了更常见的一个。