指针的值是变量的地址。为什么在int指针增加1之后,int pointer
的值增加了4个字节。
在我看来,我认为指针(变量地址)的值仅在指针递增后增加1个字节。
测试代码:
int a = 1, *ptr;
ptr = &a;
printf("0x%X\n", ptr);
ptr++;
printf("0x%X\n", ptr);
预期产出:
0xBF8D63B8
0xBF8D63B9
实际输出:
0xBF8D63B8
0xBF8D63BC
修改:
另一个问题 - 如何访问int
逐个占用的4个字节?
答案 0 :(得分:96)
当你增加T*
时,它会移动sizeof(T)
个字节。†这是因为移动任何其他值没有意义:如果我指向例如,在int
大小为4个字节的情况下,增加小于4的东西会让我失望?部分int
与其他一些数据混合在一起:荒谬。
在内存中考虑这个:
[↓ ]
[...|0 1 2 3|0 1 2 3|...]
[...|int |int |...]
当我增加指针时哪个更有意义?这样:
[↓ ]
[...|0 1 2 3|0 1 2 3|...]
[...|int |int |...]
或者这个:
[↓ ]
[...|0 1 2 3|0 1 2 3|...]
[...|int |int |...]
最后一个实际上并没有指出任何类型的int
。 (从技术上讲,使用该指针是UB。)
如果确实想要移动一个字节,请增加char*
:char
的大小始终为1:
int i = 0;
int* p = &i;
char* c = (char*)p;
char x = c[1]; // one byte into an int
†这样做的一个推论是你不能增加void*
,因为void
是一个不完整的类型。
答案 1 :(得分:8)
指针增量基于指向的类型的大小。如果int是4个字节,则将int *递增1会使其值增加4。
如果short为2个字节,则将short *递增1会使其值增加2。
这是C指针算法的标准行为。
答案 2 :(得分:2)
指针按指定类型的大小增加,如果指针指向char,pointer++
将指针递增1,如果指向1234字节结构,pointer++
将递增指针由1234。
第一次遇到它可能会让人感到困惑,但实际上它很有意义,这不是一个特殊的处理器功能,但编译器在编译期间计算它,所以编写pointer+1
时编译器编译它为pointer + sizeof(*pointer)
答案 3 :(得分:1)
这个想法是在递增之后,指针指向内存中的下一个int。由于int是4字节宽,因此增加4个字节。通常,指向类型T的指针将增加sizeof(T)
答案 4 :(得分:1)
正如您所说,int pointer
指向int
。 int
通常占用4个字节,因此,当您递增指针时,它指向存储器中的“下一个”int
- 即增加4个字节。它以任何大小的类型行事。如果您有一个指向A
的指针,那么递增A*
它将增加sizeof(A)
。
考虑一下 - 如果你只将指针增加1个字节,而不是指向int
的中间位置,我就不会想到一个需要它的机会。
例如,当迭代数组时,这种行为非常舒服。
答案 5 :(得分:0)
指针指向内存中某物的开始。一个INT占用4个字节(32位),而一个DOUBLE占用8个字节(64位)。因此,如果您存储了一个DOUBLE号,并且希望以非常低的级别指向下一个可用的存储位置,则指针将增加8个字节。如果出于某种原因您从DOUBLE值的开头指向+ 4bytes,则可能会破坏其值。内存是一个非常大的扁平区域,它本身没有良心,因此,软件必须适当地对其进行划分,并“尊重”该区域中项目的边界。