简体   繁体   English

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

[英]Confusion about assigning value to a pointer with offset in C

I was manually assign integer value to a pointer with offset, it appears that ptr+1 was not actually pointed at second_int , or it was because the printf function didn't know the size of ptr+1 ? 我手动将整数值赋给一个带偏移的指针,看来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;
}

And the output is: 输出是:

42
1

Shouldn't it be 42 and 23? 不应该是42和23吗?

And I found that each time I print the *(ptr+1) , it increments by 1. 我发现每次打印*(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;
}

And the output is: 输出是:

0
1
2
3
4
5
6
7
8
9

What happened? 发生了什么?

EDIT: 编辑:
I'm only allowed to use pointer but not array (doing Learn C the Hard Way excercise). 我只允许使用指针但不允许使用数组(使用Learn C the Hard Way练习)。 So I manually allocated memory for the ptr by int *ptr = malloc(sizeof(int) * 2); 所以我通过int *ptr = malloc(sizeof(int) * 2);手动为ptr分配了内存int *ptr = malloc(sizeof(int) * 2); , then I assign value to ptr and ptr + 1 , and the code run as expected. ,然后我将值赋给ptrptr + 1 ,代码按预期运行。

When you have a pointer to a single value, you're only allowed to dereference it to access that specific value, not other ones. 当您有一个指向单个值的指针时,您只能取消引用它以访问该特定值,而不是其他值。 To be able to increment a pointer it has to point to an object inside of an array. 为了能够递增指针,它必须指向数组内的对象。

Eg this would be valid: 例如,这将是有效的:

int integers[2];
int *ptr = &integers[0];

*(ptr + 1) = 2; // Sets integers[1].

You seem to want set *(ptr + 1) to point at second_int . 你似乎想要设置*(ptr + 1)指向second_int The only way you can make something point to a single value variable in C is to use the address operator, thus &second_int . 你可以在C中指向单个值变量的唯一方法是使用地址运算符,因此使用&second_int But the type of that value is int* , not int . 但是该值的类型是int* ,而不是int I think maybe what you wanted is something like this: 我想也许你想要的是这样的:

int first_int = 42;
int second_int = 23;

int *array[2];
array[0] = &first_int;
array[1] = &second_int;
int **ptr = &array[0];

Now you can use **ptr or *ptr[0] to access first_int , and **(ptr + 1) or *ptr[1] to access second_int . 现在您可以使用**ptr*ptr[0]访问first_int ,使用**(ptr + 1)*ptr[1]来访问second_int

In your code, ptr+1 is not memory managed by you. 在您的代码中, ptr+1不是由您管理的内存。
It could be used by another program, or for any part or your program. 它可以被其他程序使用,也可以用于任何部分或程序。 What happens here is that the compiler optimizes away the second_int , as only its value is used. 这里发生的是编译器优化了second_int ,因为只使用了它的值。 So no memory is allocated for it. 所以没有为它分配内存。
The next int in memory is fortunately also managed by you, and it is the index of your loop. 幸运的是,内存中的下一个int也由您管理,它是循环的索引。
You thought memory layout was like this: 你以为内存布局是这样的:
first_int | second_int | i

But it's like so: 但它是这样的:
first_int | i

If you want to be able to refer to both int with a pointer + offset, then you have to declare them as an array, to make sure that they are contiguous in memory: 如果你想能够用指针+偏移量引用int,那么你必须将它们声明为数组,以确保它们在内存中是连续的:
int my_ints[2] = { 42, 0};
int *ptr = my_ints;
*(ptr+1) = second_int;
Then your code will work as intended. 然后您的代码将按预期工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM