关于为C指定偏移量的指针赋值的困惑

时间:2016-10-22 08:13:30

标签: c

我手动将整数值分配给具有偏移量的指针,看起来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练习)。所以我按ptrint *ptr = malloc(sizeof(int) * 2);手动分配内存,然后将值分配给ptrptr + 1,代码按预期运行。

2 个答案:

答案 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;
然后您的代码将按预期工作。