例如:
int *p;
int a[2] = {1, 2};
p1 = a;
我想知道c ++在哪里存储每个元素的内存空间信息?我的意思是,当我这样做时:
cout << p << endl;
我只能获得该数组的内存地址,显然没有与&#34;内存长度相关的信息&#34;单个元素。但我认为应该有一些语言可以引用每个元素的内存空间。因为如果我继续这个电话:
cout << *++p << endl;
无论该数组中的元素类型和单个元素的相应内存空间,我都可以得到该数组的第二个元素。该语言能够自动跳过某个空间内存,以获得下一个元素及其地址的正确起始位置。
所以,同样,我的问题是:该数组中元素的内存空间信息存储在哪里?或者在每个元素的末尾有"\0"
之类的东西来表示该数组中一个元素的结尾,因此*++p
即将到达下一个正确的位置?
答案 0 :(得分:6)
该数组的每个元素的内存空间信息存储在哪里?
使用时:
int *p;
int a[2] = {1, 2};
p = a;
a
元素的内存位于堆栈中。他们的记忆是连续的。 p
指向a
的第一个元素。
关于:
无论该数组中的元素类型和单个元素的相应内存空间,我都可以得到该数组的第二个元素。该语言能够自动跳过某个空间内存,以获得下一个元素及其地址的正确起始位置。
是的,这是正确的。
从纯数字的角度来看,
p+1 == p + sizeof(*p)
sizeof(*p)
可以在编译时计算。不需要任何运行时信息。标记不需要表示元素的结尾。
答案 1 :(得分:3)
数组中的内存是连续的,所以增加指针会使你从一个元素到下一个元素。
它知道内存到达下一个元素的距离的方式是指针的类型,在这种情况下它是int*
,所以它知道增加sizeof(int)
以获得下一个元素。
答案 2 :(得分:0)
它没有。 C ++没有关于变量类型的运行时信息。它只是将指针后面的数据解释为源代码中给出的类型。以下面的代码为例:
void f(int *) { std::cout << "Integerpointer" << std::endl; }
void f(char *) { std::cout << "Charpointer" << std::endl; }
int i = 9;
int * p = &i;
f(p);
这将打印 Integerpointer ,因为编译器在编译时知道p
的类型是int *
。以下代码将打印 Charpointer ,因为类型已更改(编译器将指针解释为不同):
void f(int *) { std::cout << "Integerpointer" << std::endl; }
void f(char *) { std::cout << "Charpointer" << std::endl; }
int i = 9;
int * p = &i;
f(reinterpret_cast<char *>(p));
编译器将f()
替换为源代码中的匹配函数调用。因此,底层数据的解释是在编译时完成的。
解决您的阵列问题: 编译器在编译时知道元素的大小。然后,它在访问元素时调整指针添加,并将大小硬编码到您的机器代码中。如果你知道一点点组合,你可以看看这个组合代码并看到这个效果。