如何使用函数推进阵列基地址?

时间:2016-10-04 17:53:49

标签: c linux pointers

我正在尝试编写一个函数,以指定的大小(以字节为单位)转发指针。

void
increment_ptr(void **_ptr, int size){
    *_ptr = (char *)(*_ptr) + size;
}

int
main(int argc, char **argv){
    int arr[] = {11,20};
    printf("%d\n", arr[0]);
    increment_ptr((void **)&arr, sizeof(int));
    printf("%d\n", arr[0]);
    return 0;
}

我得到的输出是:

vm@vm:~$ ./a.out
11
15

我期待输出为11和20。

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:4)

arr不是您可以更改的普通变量。它不是指针 - 它的类型是int[2]

试试这段代码:

#include <stdio.h>
void
increment_ptr(void **_ptr, int size){
    *_ptr = (char *)(*_ptr) + size;
}

int
main(int argc, char **argv){
    int arr[] = {11,20};
    int* arr1 = arr;

    printf("arr  is %p\n", (void*)arr);
    printf("arr1 is %p\n", (void*)arr1);
    printf("arr gives  %d\n", arr[0]);
    printf("arr1 gives %d\n", arr1[0]);

    increment_ptr((void **)&arr, sizeof(int));
    increment_ptr((void **)&arr1, sizeof(int));

    printf("arr  is %p\n", (void*)arr);
    printf("arr1 is %p\n", (void*)arr1);
    printf("arr gives  %d\n", arr[0]);
    printf("arr1 gives %d\n", arr1[0]);

    return 0;
}

可能的输出:

arr  is 0xfff1d1b8
arr1 is 0xfff1d1b8
arr gives  11
arr1 gives 11
arr  is 0xfff1d1b8   // Notice arr isn't changed
arr1 is 0xfff1d1bc   // arr1 works as expected
arr gives  15
arr1 gives 20

换句话说:你不能推进这种阵列的基地址

您可能还会发现此代码很有趣:

#include <stdio.h>

int main(int argc, char **argv){
    int arr[2] = {11,20};
    printf("arr  is %p\n", (void*)arr);
    printf("arr  is %p\n", (void*)&arr);
    return 0;
}

可能的输出:

arr   is 0061FED8
&arr  is 0061FED8

请注意如何将arr打印为指针与打印&arr

相同

那么代码中发生的是数字11(又名arr [0])被读作指针(转换为char *),然后添加4(所以你有{{} 1}})覆盖当前15。注意:此结果表明指针和11都是系统上的4个字节。

答案 1 :(得分:2)

代码

int arr[2];

声明一个内存空间。因此,当您获取其地址时,它将返回此内存空间的基址,该地址与arr。

相同

这与声明指针的情况不同。指针是保存地址的变量,但数组只是内存空间。

答案 2 :(得分:0)

当你声明一个变量(数组与否)时,它的地址在该变量的生命周期的其余部分没有变化。无法将变量移动到新地址。

您的代码只会导致未定义的行为(严格别名冲突 - *_ptr使用类型void *的左值来访问声明为int的内存。)