数组名、指针、取地址
首先给出一个测试程序:
int a[]={2,3,4,5};
cout<<"addr a "<<a<<endl;//数组名是一个常量,无法对其进行赋值操作;而指针是一个变量,可以修改指针指向的内存
cout<<"addr a+1 "<<a+1<<endl;//数组名是数组第一个元素的首地址 后推一个元素 +sizeof(int)
cout<<"addr &a "<<&a<<endl;
cout<<"addr &a+1 "<<&a+1<<endl;//+sizeof(a)
cout<<"addr *a "<<*a<<endl;
cout<<"addr *a+1 "<<*a+1<<endl;//后推一个元素
cout<<"addr *(a+1)"<<*(a+1)<<endl;//后推一个元素
程序运行结果如下:
接下来我们一点一点来分析结果:
1.a
a是数组名,数组名是数组第一个元素的地址
2.a+1
相当于a的第一个元素后推一个元素的地址
3.&a、&a+1
在这里要尤其注意,虽然&a和a的输出结果相同,但其本质截然不同。
a的类型是int,&a的类型是int( * )[4],即整个数组的地址
所以对于a+1,是向后推移一个int,而对于&a+1,则是向后推移4个int
4.* a、* a+1
从对应的地址中取数,这个比较好理解
5. * (a+1)
这个表达式的输出和*a+1是相同的,我为什么要写这个呢,因为在测试的过程中,我发现&(a+1)这种写法是会报错的,报错的内容是 error C2102: ‘&’ requires l-value
我去查了一下这个错误的含义,是说&只能接受左值。
那么问题来了,左值是什么?
临时表达式,即没有专属变量名的表达式是右值,那么与之相反的就是左值了。a+1由于只是一个临时的表达式,是右值,所以编译器报错了。
数组作为参数传递
以下是我在敲代码的时候遇到的一些问题,总结下来,希望以后能够少走些弯路。
1.在C++中,数组是不能作为函数的返回值的,需要返回数组时,返回指针即可
2.数组名是一个常量,不可被更改
3.数组作为参数有两种传递方法,一种是int f(int a[]),一种是int f (int *a),第一种方法只是把数组的首元素地址作为参数传了进来,第二种方法很明显是传址。
注:如果函数需要数组和数组长度两个输入参数时,把数组长度先算好了再作为函数参数传入。否则要是按照如下方法在函数内部求数组长度,如果输入参数是数组,那么没有传入所有元素,如果输入参数是指针,那么传入的参数就是指针,也没有传入所有元素,这样求出来的长度就总是错的了(长度为1)。
length=sizeof(a)/sizeof(a[0])//a是数组名