为什么我不必给函数提供数组的地址
Why don't I have to give the function the address of the array
嗨,我是C的新手,正在学习指针。我正在编写一个简单的递归函数来测试它,它使用参数int *a
和int size
。在我的主要方法中,我预先使用&
向print_array
发送数组的第一个字符的地址。
这似乎不起作用,我在编译时收到了一个"不兼容的指针类型"错误。我知道我可以删除&程序运行良好。我有个问题:
为什么我不能用&从main传入my_array的内存地址;?难道我不应该只给函数一个数组第一个元素的内存地址,它就可以处理剩下的吗?
谢谢,希望这个问题不要太无聊。
#include <stdio.h>
#include <stdlib.h>
void print_array(int *a, int size){
if (size>0){
printf("%dn", 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 arrayn");
for (i=0; i < 20; i++){
printf("%dn", my_array[i]);
}
printf("The recursive method printn");
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字节的int,my_array的基地址为1000。在这种情况下,my_array+1
将产生1004,因此它保存数组中第二个int的地址(正如您所希望的那样)。相比之下,&my_array
将获取整个数组的地址,类型为"指针到20 int的数组"。当您向其中添加一个时,将向地址添加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.cFAQ 第6节
由于数组会自动衰减为指针,因此从n1570草案中提取了以下内容
6.3.2其他操作数
6.3.2.1值、数组和函数指示符
- 除非它是
sizeof
运算符、_Alignof
运算符或一元&
运算符,或是用于初始化数组的字符串文字,该表达式具有类型为"的类型"数组转换为类型为"pointer to type"的表达式,该表达式指向到数组对象的初始元素,并且不是左值。如果数组对象具有注册存储类,行为未定义
- 将数组的地址分配给变量并删除
- 从 C++ 中的函数返回数组地址问题
- 打印字符数组地址的正确方法
- 字符数组地址和整数数组地址
- C++返回静态数组地址的函数
- C++ 在 64 位平台中传递字符数组地址
- 获取字符数组地址,然后转换为指针字符
- 如何指向实际元素而不仅仅是数组地址
- 如何使用数组地址反转数组
- 链表数组 – 地址簿
- 数组地址的地址
- 缺少存储数组地址的内存
- 将指针数组地址传递给函数并更新地址中的数据
- 通过复制将数组地址传递给匿名函数失败
- 数组地址不可见
- 不了解示例中的行为 - strcpy() 和返回本地数组地址的函数
- 保存数组地址的指针的地址是相同的
- 动态数组地址
- 在C++(代码块)中显示数组地址
- C++ 将数组地址分配给指针