繁体   English   中英

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

[英]Why don't I have to give the function the address of the array

嗨,我是C的新手并且学习指针。 我正在编写一个简单的递归函数来测试它需要参数int *aint size 在我的main方法中,我使用& print_array发送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;

}

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

print_array(my_array, 20);

...要么:

print_array(&my_array[0], 20);

不幸的是,虽然&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运算符的操作数时或运营商的地址(就像你在这里所做的那样)。 在这两种情况下,数组的名称仍然引用整个数组而不是指向第一个元素的指针。

您的函数需要一个指向int的指针,特别是数组的第一个(第0个)元素的地址。

通过调用print_array(&my_array, 20); ,你试图传递整个数组的地址,类型为int(*)[20] ,它与int*不同。 它指向相同的内存位置,但它是不同的类型。

要传递第一个元素的地址,您可以编写:

print_array(&my_array[0], 20);

或者,等效地:

print_array(my_array, 20);

后者的工作原理是,在大多数但不是所有上下文中,数组的名称被隐式转换为指向其第一个元素的指针。

C和C ++中数组和指针之间的关系可能令人困惑。 推荐阅读: comp.lang.c FAQ的第6部分

因为数组会自动衰减为指针,所以从n1570草案中提取以下内容

6.3.2其他操作数

6.3.2.1左值,数组和函数指示符

  1. 除非它是sizeof运算符, _Alignof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则将具有类型''数组类型''的表达式转换为表达式输入''指向类型'的指针,指向数组对象的初始元素,而不是左值。 如果数组对象具有寄存器存储类,则行为未定义。

暂无
暂无

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

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