为什么我不必给函数提供数组的地址

mag*_*_nz 2 c c++ arrays pointers

嗨,我是C的新手并且学习指针.我正在写一个简单的递归函数来测试它需要参数int *aint size.在我的main方法中,我print_array使用&事先发送我的数组的第一个字符的地址.

这似乎不起作用,我在编译时得到"不兼容的指针类型"错误.我知道我可以删除&和程序工作正常.我有个问题:

为什么我不能通过&传递my_array的内存地址?我不应该只给函数数组的第一个元素的内存地址,它可以处理其余的吗?

谢谢,希望这个问题不是太棒了.

 #include <stdio.h>
 #include <stdlib.h>


void print_array(int *a, int size){
    if (size>0){
            printf("%d\n", a[0]);
            print_array(a+1, size-1);
    }
}

int main(void){
    int my_array[20];
    int i;

    for (i=0; i < 20; i++){
            my_array[i] = rand() % 20;
    }

    /*the contents of the array*/
    printf("The contents of the array\n");
    for (i=0; i < 20; i++){
            printf("%d\n", my_array[i]);
    }

    printf("The recursive method print\n");

    print_array(&my_array, 20);

    return EXIT_SUCCESS;

}
Run Code Online (Sandbox Code Playgroud)

Jer*_*fin 6

是的,您可以为函数提供第一个元素的地址,并让它处理其余元素.您可以这样做:

print_array(my_array, 20);
Run Code Online (Sandbox Code Playgroud)

...要么:

print_array(&my_array[0], 20);
Run Code Online (Sandbox Code Playgroud)

不幸的是,虽然&my_array是合法代码,但它会生成一个指向整个数组的指针,而不是指向数组第一个元素的指针.那些具有相同的地址,但是不同的类型,这是导致错误的原因.

指针的类型决定(除此之外)该指针上的算术将如何工作.在您的情况下,print_array打印数组中的第一个int,然后将一个添加到指针.由于它是指向int的指针,因此该添加实际上将int的大小添加到指针中的地址.

如果您使用指向整个数组的指针,那么添加一个指针会将整个数组的大小添加到地址中.例如,假设4字节的整数和my_array的基地址为1000.在这种情况下,my_array+1将产生1004,因此它保存数组中第二个int的地址(正如您无疑想要的那样).相比之下,&my_array将获取整个数组的地址,类型为"指向20个整数的数组的指针".当你向它添加一个时,它会将指向类型的大小加1到地址,所以你会得到1080(即整个数组是20*4 = 80字节).这显然不是你想要的东西-而不是x+1指向第二项的阵列,它指向过去的数组的结尾,并试图取消引用指针会给未定义的行为.

所以,只需切换到上面(my_array&my_array[0])表格之一.更一般的观点是,在大多数情况下,要意识到数组的名称作为指向数组第一个元素的指针 - 值得注意的例外是当您使用数组的名称作为sizeof运算符的操作数或运营商的地址(就像你在这里所做的那样).在这两种情况下,数组的名称仍然引用整个数组而不是指向第一个元素的指针.