你问如何将常量地址分配给指针,但这么做(a)极其不具移植性,(b)并不一定能实现你的目的,即查看指针递增时的效果。
下面是一个程序,可以满足你的好奇心,同时避免由于未定义行为而可能导致程序崩溃:
#include <iostream>
int main() {
const int len = 10;
char char_array[len];
int int_array[len];
char *cp = char_array;
for (int i = 0; i <= len; i ++) {
std::cout << "cp = " << static_cast<void*>(cp) << "\n";
cp ++;
}
std::cout << '\n';
int *ip = int_array;
for (int i = 0; i <= len; i ++) {
std::cout << "ip = " << static_cast<void*>(ip) << "\n";
ip ++;
}
}
我的(64位)系统输出如下:
cp = 0x7fffaa5ddc30
cp = 0x7fffaa5ddc31
cp = 0x7fffaa5ddc32
cp = 0x7fffaa5ddc33
cp = 0x7fffaa5ddc34
cp = 0x7fffaa5ddc35
cp = 0x7fffaa5ddc36
cp = 0x7fffaa5ddc37
cp = 0x7fffaa5ddc38
cp = 0x7fffaa5ddc39
cp = 0x7fffaa5ddc3a
ip = 0x7fffaa5ddc00
ip = 0x7fffaa5ddc04
ip = 0x7fffaa5ddc08
ip = 0x7fffaa5ddc0c
ip = 0x7fffaa5ddc10
ip = 0x7fffaa5ddc14
ip = 0x7fffaa5ddc18
ip = 0x7fffaa5ddc1c
ip = 0x7fffaa5ddc20
ip = 0x7fffaa5ddc24
ip = 0x7fffaa5ddc28
以下是一些注意事项:
指针的增量是有效的,因为每个指针始终指向正确类型的数组元素或其末尾紧接着的位置。 (您可以构造一个刚好位于数组末尾的指针; 但是,您不可以对此类指针进行解引用。)
打印类型为void*
的指针时,输出结果由具体实现定义。在我的系统上,它恰好是将指针值解释为整数的十六进制表示形式-这可能是最常见的实现方法。
您可以看到,char*
指针似乎每次增加1,而int*
指针增加4。在我的系统(以及您的系统)中,指针被存储为字节地址。指针算术运算按照指向的类型单位定义,而不是按字节定义。增加一个int*
指针会导致它指向前一个位置后sizeof(int)
字节的内存位置-在这种情况下,是4个字节。所有指针算术运算都是这样定义的; ptr2 - ptr1
给出了两个地址之间的元素数量(ptr1
和ptr2
指向的任何类型)。
打印的特定值告诉您关于如何在您的系统上管理内存地址的一些信息。指针和整数之间的映射通常会反映系统的内存模型。该模型在很大程度上是与实现相关的。
cout << "char pointer" << c << endl;
将c
解释为指向以零结尾的字符数组的第一个元素的指针。使用cout << "char pointer" << static_cast<void*>(c) << endl;
来打印地址。 - Daniel Fischer