#include <stdio.h>
int my_array[] = {1,23,17,4,-5,100};
int *ptr;
int main(void)
{
int i;
ptr = &my_array[0]; /* point our pointer to the first
element of the array */
printf("\n\n");
for (i = 0; i < 6; i++)
{
printf("my_array[%d] = %d ",i,my_array[i]); /*<-- A */
printf("ptr + %d = %d\n",i, *(ptr + i)); /*<-- B */
printf("ptr + %d = %d\n",i, *ptr++);
printf("ptr + %d = %d\n",i, *(++ptr));
}
return 0;
}
ptr ++应该打印ptr值而不是增量,而++ ptr在ptr中执行第一次增量而不是打印ptr的值..但是当我编译代码时它会给我相同的结果,什么是void指针。有什么用呢。
答案 0 :(得分:2)
这些行:
printf("ptr + %d = %d\n",i, *ptr++);
printf("ptr + %d = %d\n",i, *(++ptr));
修改指针值。因此,在每次迭代中,您将在当前位置i之外添加2个偏移量。当你的for循环到达第6次迭代时,你将尝试从数组的末尾打印内存位置到6(迭代)* 2(偏移)* 4(int size)=超出48个字节。
答案 1 :(得分:2)
表达式*ptr++
被解析为*(ptr++)
,并按如下方式进行评估:
ptr
sizeof *ptr
添加到ptr
。大致等同于写作
x = *ptr;
ptr = ptr + sizeof *ptr;
除了更新ptr
的副作用可能在下一个序列点之前的任何时间发生(从不假设以特定顺序应用副作用); IOW,序列可能是
tmp = ptr;
ptr = ptr + sizeof *ptr;
x = *tmp;
在这种情况下,序列点位于printf
函数调用的末尾。
表达式*(++ptr)
被解析为书面形式,并按如下方式计算:
ptr + sizeof *ptr
sizeof *ptr
添加到ptr
大致等同于写
tmp = ptr + sizeof *ptr;
x = *tmp;
ptr = ptr + sizeof *ptr;
同样,更新ptr
的值的副作用可能发生在下一个序列点之前的任何点; IOW,序列可能是
tmp = ptr + sizeof *ptr;
ptr = ptr + sizeof *ptr;
x = *tmp;
这是程序启动时的假设存储器映射(假设32位地址和16位整数):
Item Address 0x00 0x01 0x02 0x03 ---- -------- ---- ---- ---- ---- my_array 0x08000000 0x00 0x01 0x00 0x17 0x08000004 0x00 0x11 0x00 0x04 0x08000008 0xff 0xfb 0x00 0x64 ptr 0x0800000C 0x00 0x00 0x00 0x00 i 0x10008000 0x?? 0x?? 0x?? 0x??
0x??
表示随机字节值。由于ptr
在文件范围内声明,因此它具有静态范围并隐式初始化为NULL。由于i
被声明为auto
,因此它未初始化并包含随机垃圾。
执行语句ptr = &my_array[0]
后,ptr
的值为0x08000000
。
执行
行时printf("ptr + %d = %d", i, *ptr++);
表达式*ptr++
取消引用地址0x08000000
的内存,其中包含值1,因此输出为
ptr + 0 = 1
++
运算符的副作用会将ptr
的值更新为0x08000002
。
执行
行时printf("ptr + %d = %d, i, *(++ptr));
由于表达式*(++ptr)
的计算结果为0x08000004
,因此表达式0x08000002
会对 ++ptr
而非ptr + sizeof *ptr
的记忆产生差异。所以这一行的输出是
ptr + 0 = 17
并且++
运算符的副作用会将ptr
的值更新为0x08000004
。
当你循环时,你的输出看起来像
my_array[0] = 1 /* ptr = 0x08000000 */
ptr + 0 = 1
ptr + 0 = 1 /* ptr = 0x08000002 after */
ptr + 0 = 17 /* ptr = 0x08000004 after */
my_array[1] = 23
ptr + 1 = 4
ptr + 1 = 4 /* ptr = 0x08000006 after */
ptr + 1 = -5 /* ptr = 0x08000008 after */
答案 2 :(得分:1)
经过几次循环之后,你将开始引用超出数组末尾的内存;除此之外,你的程序看起来很有意义。
答案 3 :(得分:0)
你可能只看输出的最后一部分,因为当我编译它时,它会显示数组的每个值,然后在你完成代码的整个部分之后显示0。
至于无效指针:
它们也称为通用指针,因为您可以将它们分配给任何数据类型。
答案 4 :(得分:0)
首先像Ignacio指出的那样,这都是C代码。不是c ++。 C ++是C的超集。
1)我想指出你的for循环不安全。因为您在每次迭代中将循环内部的指针递增两次。因此,您将在第4次迭代时结束在分配的数组之外。
2)任何C问题请参考优秀的c faq和c ++ faq。这是您问题的相关答案。 http://c-faq.com/ptrs/unopprec2.html。 它与运算符优先级有关。 * ptr ++相当于*(ptr ++)。
第一次迭代的输出应该是 1 1 1 17
void指针是通用指针。你不能对它做算术。它只是用于传递位置,粗略地说。另外,重要的是你不能对它进行算术运算。因为,你不知道它指向的是什么。