函数返回类型和形参

来源:互联网 发布:javascript and or 编辑:程序博客网 时间:2024/06/06 09:17

函数返回类型

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);}