我手动将整数值分配给具有偏移量的指针,看起来ptr+1
实际上并未指向second_int
,或者是因为printf
函数没有知道ptr+1
的大小?
#include <stdio.h>
int main(void)
{
int first_int = 42;
int second_int = 23;
int *ptr = &first_int;
*(ptr + 1) = second_int;
int i = 0;
for (i = 0; i < 2; i++) {
printf("%d\n", *(ptr+i));
}
return 0;
}
输出是:
42
1
不应该是42和23吗?
我发现每次打印*(ptr+1)
时,它都会增加1。
#include <stdio.h>
int main(void)
{
int first_int = 42;
int second_int = 23;
int *ptr = &first_int;
*(ptr + 1) = second_int;
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d\n", *(ptr+1));
}
return 0;
}
输出是:
0
1
2
3
4
5
6
7
8
9
发生了什么事?
修改
我只允许使用指针但不允许使用指针(使用Learn C the Hard Way练习)。所以我按ptr
为int *ptr = malloc(sizeof(int) * 2);
手动分配内存,然后将值分配给ptr
和ptr + 1
,代码按预期运行。
答案 0 :(得分:2)
如果您有指向单个值的指针,则只允许取消引用它以访问该特定值,而不是其他值。为了能够增加指针,它必须指向数组内的对象。
E.g。这是有效的:
auto
您似乎希望将int integers[2];
int *ptr = &integers[0];
*(ptr + 1) = 2; // Sets integers[1].
设置为*(ptr + 1)
。在C中指向单个值变量的唯一方法是使用地址运算符,即second_int
。但该值的类型为&second_int
,而不是int*
。我想也许你想要的是这样的:
int
现在,您可以使用int first_int = 42;
int second_int = 23;
int *array[2];
array[0] = &first_int;
array[1] = &second_int;
int **ptr = &array[0];
或**ptr
访问*ptr[0]
,first_int
或**(ptr + 1)
访问*ptr[1]
。
答案 1 :(得分:1)
在您的代码中,ptr+1
不是由您管理的内存
它可以被其他程序使用,也可以用于任何部分或程序。这里发生的是编译器优化掉second_int
,因为只使用了它的值。所以没有为它分配内存
幸运的是,内存中的下一个int也是由你管理的,它是你循环的索引
你以为内存布局是这样的:
first_int | second_int | i
但它是这样的:
first_int | i
如果你想能够用指针+偏移量引用int,那么你必须将它们声明为数组,以确保它们在内存中是连续的:
int my_ints[2] = { 42, 0};
int *ptr = my_ints;
*(ptr+1) = second_int;
然后您的代码将按预期工作。