数组地址和数组首元素地址问题
大佬们,对于数组,我一直理解的是 数组本身的地址和首元素地址是不一样的,比如 若 int a&a表示数组本身的地址,而 a 表示数组首元素的地址,即 a 的地址,两个地址是不一样的。
可是我今天用代码试了一下,在主函数中主函数中 &a ,a,&a 表示的地址一样,而在其他函数中却不一样。这让我搞的有点懵。
还有就是函数实参只要吧数组的首地址传过去就可以了吗,我用&a,a,a 都能传过去,在函数中都能使用这个数组。
希望大佬们可以解答一下疑惑,十分感谢! 首先声明:你的理解完全正确,但是如下:
void show(int array[])//传的是指针,但是这个array是这个函数的局部变量,不同于主函数的array,而是一个新的变量,虽然传指针,但是传的是数组元素的指针,不是数组整体(也就是主函数array)的
{
printf("array: %p+++\n", array);
printf("==========\n");
printf("array: %p\n", array);
printf("&array:%p\n", &array);
printf("&array :%p\n", &array);
printf("&array :%p\n", &array);
} 本帖最后由 howzyao 于 2020-4-12 00:29 编辑
int a;
&a;
a == 一个int,同时是首个元素
a没有实际int意义,只有关联int的意义,a就是一个指针,指向int ~这组数组的意思,我把它叫做数组头,a指一组 被连续占用的 内存的 一个标签.
cout<< a<< " "<<&a<<endl; //一定是一样的.
另外,当指针入实参时,地址发生变化,是由于函数机制造成的:
当array[]入参时,系统把array的实际地址中的值,也就是所有的0~9的这些内存中的一串值,一并复制到一个新的地址,且在当前函数作用域有效,当函数结束时,
这些临时复制过来的所有值,都将被释放,而array[]这个实参,所指向的这片连续内存中的值,是原封不动地不受破坏.
实际上array[]或写成*array 也值得一试,
这样效果也应当是一样,*号,就是解除引用操作符,它解除指针array所指向的内存地址, 而引用这个地址中的值,我是这么理解它的意思的,供大家指正.
0~9这10个下标的10个元素,可以看作独立的int它们分别处于不同的内层中,由于是数组,所以,两个相邻int的内存地址,是有意义的存在,
需要我们自己去想,这是学习C++内存管理的一种常识性基础,看多了,就可以看出一些规律来.这不会太难明白.
这下明白了一切没有?可以的话,赏个分?{:10_256:} 在定义数组的函数(不一定是主函数)中,数组名可以把自身当做指针,数组名即数组的首地址,数字首元素的地址也是数组首地址,当然取数组本身地址也是一样的。
虽然这三者的地址是一样的。但是含义不一样。尤其是数组名和数组名取地址。数组名取地址实际上是一个数组指针,数组名是一个指针,两者的区别在+1时能看出来,数组名取地址 +1跳过的是整个数组的长度,数组名+1跳过的是一个元素的长度。
#include<stdio.h>
#include<math.h>
void fun(int a[])
{
printf("a :%p\n",a);
printf("&a :%p\n",&a);
printf("&a:%p\n",&a);
}
int main()
{
int a={1,2,3,4,5};
printf("a :%p\n",a);
printf("a+1:%p\n",a+1);
printf("&a+1 :%p\n",&a+1);
printf("&a:%p\n",&a+1);
fun(a);
return 0;
}
然而当数组以参数的形式传进函数时,实际上它就是一个新的指针了,只是该指针指向了那个数组的首地址,
由于数组与指针的特殊性,仍然可以以数组的形式使用其对应的元素,但是该指针有自己的空间,也有自己的地址。
看一下下图,这是我之前做的一张图,刚好能表达这个意思
在定义数组的函数内,&temp、temp和&temp都是该数组的首地址;
在调用数组的函数内,&p和p都是数组的首地址,但是&p就是指针的地址了。
将数组作为参数传递时,只要把数组首地址传过去就可以了。这句话是对的。
但是你写的有一点是不对的,传该地址只能是数组名或者数组首元素的地址,即a或者 &a , 不能传&a更不能传 a howzyao 发表于 2020-4-12 00:27
int a;
&a;
a == 一个int,同时是首个元素
当array[]入参时,系统把array的实际地址中的值,也就是所有的0~9的这些内存中的一串值,一并复制到一个新的地址,且在当前函数作用域有效,当函数结束时,
这些临时复制过来的所有值,都将被释放,而array[]这个实参,所指向的这片连续内存中的值,是原封不动地不受破坏.
这句话是不对的。数组作为参数传递时,传递的是地址,不是传递原数组的值,在函数中修改数组内容也就是修改原数组的内容。,并不是你所说的不会破坏原数组。
你所说的是一般变量的值传递,歘递过来的是一个原值的复制,函数结束释放掉,不会影响原值 楼上说的非常全面,全部读透肯定能理解这个知识点。 sunrise085 发表于 2020-4-12 00:34
在定义数组的函数(不一定是主函数)中,数组名可以把自身当做指针,数组名即数组的首地址,数字首元素的地 ...
其实数组传地址时可以传&a,不用数组指针而是普通指针接收即可。 sunrise085 发表于 2020-4-12 00:34
在定义数组的函数(不一定是主函数)中,数组名可以把自身当做指针,数组名即数组的首地址,数字首元素的地 ...
好的,谢谢,我理解了大部分,解释的非常仔细。
但是我用了&a,也能吧数组传过去。
还有就是我在调用的函数中修改数组元素,到主函数中值也改变了。
实参传递过去的数组的首地址吧,相当于传递的指针过去,不是把原来的数组内容复制一份,以值传递的形式传过去的吧。
希望大佬在给我解答一下疑惑!
非常感谢!
#include <stdio.h>
void show(int array[])
{
int i;
printf("show函数中改变前:\n");
for(i=0;i<5;i++)
{
printf("%d",*(array+i));
}
printf("\n\n");
printf("改变array的值:");
scanf("%d",&array);
printf("show函数中改变后:\n");
for(i=0;i<5;i++)
{
printf("%d",*(array+i));
}
printf("\n\n");
}
int main()
{
int a={1,1,1,1,1};
int i;
printf("主函数中,改变前:\n");
for(i=0;i<5;i++)
{
printf("%d",*(a+i));
}
printf("\n\n");
show(&a);
printf("主函数中,改变后:\n");
for(i=0;i<5;i++)
{
printf("%d",*(a+i));
}
printf("\n\n");
return;
}as 终于看到杨左使麾下坛主李坛主了,感谢sunrise纠正,传入&a确实比较好,10长度整个40字节全部传入,以供编辑,好。 依据入参数组的用途,如果只读,就想要避免不经意的破坏,对传入数组来说,就要被保护起来,请使用限定常量const int &做为函数原型吧
页:
[1]