1、 数组降阶:
“数组引用”以避免“数组降阶”
这是因为void Test(char array[20])被降阶处理了,void Test(char array[20])等同于void Test(char * const array),也等同于void Test(char array[])
即:
a、 做个结构体,其中仅含有char array[20],然后用这个结构体指针代替array[20]
b、 在Test内部使用_msize 来计算array的长度。这更不行,首先它使得错误的发现被推迟到运行期,而不是编译期。其次,_msize 长度/元素大小 >= array的长度,也就是说new char[19]与new char[20]分配的大小是一样的,这样一来,虽不至于导致程序崩溃,但运算结果却不正确。
(2) 使用C++中的“数组引用”
(1)
a) 传递引用给函数和传递指针是一样的。在被调用函数中对形参的操作其实就是对其相应的目标对象(在主调函数中)的操作。
b) 引用传递参数,在内存中没有残生实参的副本。而使用指针同样要给形参分配存储单元。
(2) 常引用:
(3) 引用作为返回值:
a) 引用作为返回值作为赋值表达式的右值 (X)
b) 引用作为返回值:
a、不能返回局部变量的引用
b、不能返回函数内部new分配的内存的引用
c、 可以返回类成员的引用,但最好是const类型
“数组引用”以避免“数组降阶”
#include <iostream>
using namespace std;
void Test(char array[20])
{
cout<<sizeof(array)<<endl; //输出4
}
int main()
{
char array[20]={0};
cout<<sizeof(array)<<endl; //输出20
Test(array);
}
这是因为void Test(char array[20])被降阶处理了,void Test(char array[20])等同于void Test(char * const array),也等同于void Test(char array[])
即:
viod Test(char array[20])
{
cout<<sizeof(array)<<endl;
}
被降阶成了
void Test(char* const array)
{
cout<<sizeof(array)<<endl; //既然是char* ,当然输出为4
}
(1) 那么在c语言中是怎样解决这个问题
a、 做个结构体,其中仅含有char array[20],然后用这个结构体指针代替array[20]
b、 在Test内部使用_msize 来计算array的长度。这更不行,首先它使得错误的发现被推迟到运行期,而不是编译期。其次,_msize 长度/元素大小 >= array的长度,也就是说new char[19]与new char[20]分配的大小是一样的,这样一来,虽不至于导致程序崩溃,但运算结果却不正确。
(2) 使用C++中的“数组引用”
#include <iostream>
using namespace std;
void Test(char (&array)[20]) //很像char *p[20] 和char (*p)[20]的区别
{
cout<<sizeof(array)<<endl;
}
举例:
int a[3]={10,20,30};
int (&b)[3]=a; //数组引用
2、 C++中的引用:
(1)
a) 传递引用给函数和传递指针是一样的。在被调用函数中对形参的操作其实就是对其相应的目标对象(在主调函数中)的操作。
b) 引用传递参数,在内存中没有残生实参的副本。而使用指针同样要给形参分配存储单元。
(2) 常引用:
const 类型标识符 &引用名 = 目标变量名
string foo();
void bar(string &s);
则下面的表达式将是非法的:
bar(foo());
bar(“hello world”);
原因在于foo()和”hello world”串都会产生一个临时对象,而在C++中,这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型,这显然是非法的。
**引用类型参数在能被定义为const的情况下,尽量定义为const(3) 引用作为返回值:
a) 引用作为返回值作为赋值表达式的右值 (X)
b) 引用作为返回值:
a、不能返回局部变量的引用
b、不能返回函数内部new分配的内存的引用
c、 可以返回类成员的引用,但最好是const类型