我正在尝试理解C指针,我设置了以下示例:
int main()
{
int temp[] = {45,67,99};
int* address;
address = &temp[0]; //equivalent to address = temp;
std::cout << "element 0: " << *address << std::endl;
address = (address + sizeof(int));
std::cout << "element 1: " << *address << std::endl;
std::getchar();
return 0;
}
现在,第一个元素正确打印,而第二个元素是垃圾。我知道我可以使用:
address = (address + 1);
为了将指针移动到数组的第二个元素,但我不明白为什么第一个方法是错误的。
答案 0 :(得分:6)
运算符sizeof
以字节为单位返回对象的大小。所以(取决于你的编译器)你可能刚刚完成了
address + sizeof(int) == address + 4
当您取消引用指针时,这显然会超出范围。问题是您尝试使用sizeof
的方式是已在pointer arithmetic中计入。当您向1
添加积分(例如int*
)时,它已知道将1 int
移到下一个地址。
答案 1 :(得分:4)
将指针递增N不会使其增加N
个字节,而是递增N * sizeof(pointed_type)
个字节。
所以当你这样做时:
address = (address + sizeof(int));
您正在递增地址(可能)是int大小的4倍,这超过了原始数组。
您打算做的是:
address = reinterpret_cast<int*>(reinterpret_cast<char*>(address) + sizeof(int));
这是非常可怕的。
答案 2 :(得分:1)
数组是一组相同类型的元素,它们在内存中一个接一个地映射到另一个中。
数组的大小为:
sizeof(any element) * the number of elements
所以可以通过以下方式获得数组元素的数量:
Number of elements = sizeof(array) / sizeof(any element).
这些元素是可寻址的,每个元素都用第一个字节的地址寻址。
int a[] = {1, 10, 100, 1000, 10000};
std::cout << sizeof(int) << std::endl; // 4
std::cout << sizeof(a) << std::endl; // 20: 5 * 4
地址:
cout << &a[0] << " : " << &a[1] << " : " <<
&a[2] << " : " << &a[3] << endl;
outPut:
0018FF38 : 0018FF3C : 0018FF40 : 0018FF44
正如您所看到的,地址按sizeof(int)// 4
递增要在途中这样做:
for(int* tmp = array; tmp <= a + nElement; tmp++)
cout << tmp << " : ";
结果:
0018FF38 : 0018FF3C : 0018FF40 : 0018FF44
如您所见,结果完全相同。
要从一个元素移动到另一个元素,只需像我上面那样递增/递减地址:
tmp++; // incrementing the address by 1 means moving to the next element, element means an integer which means 4 bytes. 1 here is not a single byte but a unit or element which is 4 byte here;
只需移动到n元素:
tmp += n;
在你的例子中:
address = (address + sizeof(int)); :
address = address + 4; // moving to the 0 + 4 element which means fifth element (here outbound).