函数返回类型
1、int *add—–return &c;
2、int add——return c;
3、局部变量不允许以引用(或者指针)形式返回,函数结束,局部变量生存期就到了
int &add(int a,int b)
{
int c=a+b;
return c;//=>return &c
}
void main()
{
int x=10,y=20;
int z=add(x,y);//z以值的形式接收数据,对地址不感兴趣,add返回c的值
int *p=&add(x,y);//&返回c的地址,把c的地址给p
int &a=add(x,y);// 以引用返回,以引用接收
printf("%d %d %d\n",z,*p,a);
}
什么情况下可以以引用返回?
1、返回值定义在全局
int c=0;
int & add(int a,int b)
{
c=a+b;
return c;
}
void main()
{
}
2,静态量
int c=0;
int & add(int a,int b)
{
static int x;
x=a+b;
return x;
}
void main()
{
}
静态数据成员只初始化一次,以后不会在调用,可见性在函数内,生存期在全局
void fun (int x)
{
static int a=10;//常量初始化
static int b=x;//变量初始化
printf("%d \n",b);
}
void mian ()
{
int num=100;
fun(num); //==>100
fun(num+100); //==>100
}
3.以引用接收,以引用返回
int & fun (int &a)
{
a=100;
return a;//a的生存期不受函数影响,a是x的别名,函数结束时x依旧存在,所以也可以返回&a
}
void main()
{
int x=0;
fun(x);
printf("%d\n",x);//==>100
}
函数形参
void fun1(int a);//传值
{}
void fun2(int &a);//引用=>fun2(int * const a)
{}
void main()
{
int x=10;
fun1(x);//x传值给a,a的改变不会影响x
fun2(x); //a的改变会影响x
}
==>
fun1(10);//编译通过
fun2(10); //编译不通过,不能把字面常量给指针,要给地址
字面常量
1. int a=10;整型字面常量
char x=’a’;整型字面常量
2. a=010;八进制字面常量
3. a=0x10;十六进制字面常量
4.float ft=12.33f;单精度浮点型字面常量
=12.23 双精度。。。
5.char *p=”qweq”字符串字面常量
char ch[]={“qwe”};//数组,非字面常量
char ch2[]=”qwe”;//数组,非字面常量
引用
1、常变量能力扩大—不行
void main ()
{
const int a=10;//常变量
int b=a;//编译通过
int &c=a;//编译不通过,若编译通过,则通过c可以改变a的值,但const int a为常变量值不可改变
const int &c=a;//通过
}
2、变量能力缩小—可以
void main()
{
int a=10;
int &b=a;//编译通过
const int &c=a;//常引用不能改变a,a的能力缩小,可以编译通过
}
3、
编译器不同,结果不同
void main ()
{
const int a=10;//常变量,a只能读值,不能写
const int &b=10;//在逻辑上,编译器可以通过编译,b为常引用,不会改变10
//编译器工作:定义一个临时变量tmp,把字面常量给临时量(把10给tmp),const int &b=tmp;(引用临时量)
const int &c=a;
//引用字面常量:在a为字面常量的前提下,编译器进行int tmp =a;const int &b=tmp(引用临时量)
const int &x=c;
}
why要用临时量作为过渡?
由于c++极其不安全(指针本身不安全),若把b的常性去掉,没有中间临时变量tmp,那b就可以直接改变a,而产生临时变量,即使改变b的常性,也不会对直接a造成影响
void fun3(int *a);//指针
区别于
viod fun2(int *const a)
void fun2(int &a)引用
传指针,自身可以改变,指向也可以改变
传引用,自身不能改变,指向不能改变
void fun4(int ar[]);//数组做形参,退化为指针
{
if(ar==NULL)return ;
}
int add(int a,int b)
{
int c=a+b;
return c; //mov eax,dword ptr[c]
}
void main()
{
int x=10,y=20;
int z=0;
z=add(x.y);//mov dword ptr[z],eax
printf("%d\n",z);
}
函数调用时,局部变量产生,当函数结束时局部变量销毁
把c给z,要建立临时变量(eax),不可存到内存中(若存到内存中,则需要内存地址,要找到存放的地址,则需要找到地址存放的地址,无穷无尽根本找不完)
int * add(int a,int b)
{
int c=a+b;
return &c; //编译通过
}
void main()
{
int x=10,y=20;
int z=0;
z=*add(x.y);//*和函数返回值结合
//(理论上:函数名和括号结合,调动函数,返回c的地址,在临时空间里放c的地址,*
//和&c结合=>*&c=z,但是c的生存期在局部,函数调动结束时释放c,则c的地址查找不到
//所以输出随机值。
printf("%d\n",z);
}
//==>输出随机值
void fun5(int (&br)[10]);//引用数组,对br不改变
//void fun1(int br[])
void fun1(int *s);
void fun2(int (*p)[10]);
void main()
{
int ar[]={12,23,34,45,56,67,78,89,90,100};
const int n=sizeof(ar)/sizeof(ar[10]);
fun1(ar);
fun2(&ar);
}