C++学习——函数

一、函数声明(函数原型)
1.需要函数原型的原因
(1)原型告诉编译器,函数有某个参数,如果如果程序没有提供这种参数,就提示报错。
(2)当函数完成计算时,将把返回值放在指定的位置,可能是CPU寄存器,也可能是内存,然后调用函数从这个位置取得返回值。
(3)原型指出了函数类型,编译器知道应该检索多少个字节
2.原型的功能
(1)编译器正确处理返回值
(2)编译器检查参数数目是否正确
(3)编译器检查参数类型是否正确,如果不正确就转化为正确的类型
二、函数与数组
多数情况下,数组名和指针灵活转换,C++将数组名解释为第一个元素的地址,但也有一些例外:
1.对数组名使用sizeof得到整个数组的长度
2.地址运算符&用于数组名,将返回整个数组的地址

#include <iostream>
using namespace std;
const int arsize=8;
int sum_arr(int arr[],int n);
/*
当且在函数头和函数原型中,int *arr 和int arr[]是相同的,arr是一个int指针
但是在函数体中,arr还是可以看作数组
将cookies的位置、元素类型、元素的数量传给sum_arr函数
*/
int sum_arr(int *arr,int n)
{
    int total=0;
    cout<<arr<<" arr"<<endl;
    cout<< sizeof(arr)<<"=sizeof arr"<<endl;//指针的大小,为8
    for (int i=0;i<n;i++)

        total=total+arr[i];
    return  total;

}
int main(int argc, char* argv[])
{
    int cookies[arsize]={1,2,3,4,5,6,7,8};
    cout<<cookies<<" array address"<<endl;
    cout<<sizeof(cookies)<<"=sizeof cookies"<<endl;//32,数组的大小
    int sum=sum_arr(cookies,arsize);
    cout<<sum<<endl;
    return 0;
}
注意点:C++里,调用函数时要把数组类型和元素数量都通过参数传递

三、函数和二维数组

#include <iostream>
using namespace std;
const int arsize=8;
int sum(int (*arr)[4],int size)//int sum(int arr[][4],int size)也可以
'''
data是一个有三个元素的数组,每个元素是一个数组,有4和元素
通过指针传递时,指针指向的是由4个int组成的数组,因此指针需要指定列数4
也就是说sum只接受由4列组成的数组,而接受的行数由另一个参数指定
'''
{
    int total=0;
    for (int r=0;r<size;r++)
    {
        for (int c=0;c<4;c++)
            total=total+arr[r][c];
    }
    return total;

}
int main(int argc, char* argv[])
{
    int data[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
    int ans=sum(data,3);
    cout<<ans;
}

四、常见的函数使用方法——值传递、引用传递、指针传递
1、值传递:形参时实参的拷贝,改变函数形参并不影响函数外部的实参,这是最常用的一种传递方式,也是最简单的一种传递方式。只需要传递参数,返回值是return考虑的;使用值传递这种方式,调用函数不对实参进行操作,也就是说,即使形参的值发生改变,实参的值也完全不受影响。

#include <iostream>
using namespace std;
void swap(int,int);
int main()
{
   int a=1,b=2;
   cout<<"a="<<a<<",b="<<b<<endl;
   swap(a,b);
   cout<<"a="<<a<<",b="<<b<<endl;//a和b的值不变
   return 0;
}
 void swap(int x,int y)
{
   int p=x;
   x=y;
   y=p;
}

2、指针传递:指针传递其实是值传递的一种,它传递的是地址。值传递过程中,在函数的栈中有开辟了内存空间来存放主调函数放进来实参的值,从而成为一个副本。因为指针传递的是外部参数的地址,当调用函数的形参发生改变时,自然外部实参也发生改变。

#include <iostream>
using namespace std;
void swap(int *x,int *y);
int main()
{
   int a=1,b=2;
   cout<<"a="<<a<<",b="<<b<<endl;
   cout<<"&a="<<&a<<",&b="<<&b<<endl;
   cout<<"********1**********"<<endl;
   swap(&a,&b);//a,b的值改变。指针在传参的时候,必须传变量的地址过去,否则不能改变变量的值。
   cout<<"a="<<a<<",b="<<b<<endl;
   cout<<"&a="<<&a<<",&b="<<&b<<endl;
   cout<<"********3**********"<<endl;
   return 0;
}
 void swap(int *x,int *y)
{
   int p=*x;   //int p; p=*x;
   *x=*y;
   *y=p;
   cout<<"x="<<x<<",y="<<y<<endl;
   cout<<"*x="<<*x<<",*y="<<*y<<endl;
   cout<<"&x="<<&x<<",&y="<<&y<<endl;
   cout<<"********2**********"<<endl;
}

在这里插入图片描述在这里插入图片描述
3、引用传递:被调函数的形参虽然也作为局部变量在栈中开辟了内存空间,但在栈中放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被间接寻址,即通过栈中的存放的地址访问主调函数中的中的实参变量(相当于一个人有两个名字),因此形参在任意改动都直接影响到实参,与指针类似。

#include <iostream>
using namespace std;
void swap(int &x,int &y);
int main()
{
   int a=1,b=2;
   cout<<"a="<<a<<",b="<<b<<endl;
   cout<<"&a="<<&a<<",&b="<<&b<<endl;
   cout << "*******1**********"<<endl;
   swap(a,b);//引用在函数传参的时候,只需要传变量名过去,函数形参用引用接即可。
   cout<<"a="<<a<<",b="<<b<<endl;
   cout<<"&a="<<&a<<",&b="<<&b<<endl;
   cout << "*******4**********"<<endl;
   return 0;
}
 void swap(int &x,int &y)
{
   cout<<"x="<<x<<",y="<<y<<endl;
   cout<<"&x="<<&x<<",&y="<<&y<<endl;
   cout << "*******2**********"<<endl;
    int p=x; 
    x=y;
    y=p;
   cout<<"x="<<x<<",y="<<y<<endl;
   cout<<"&x="<<&x<<",&y="<<&y<<endl;
   cout << "*******3**********"<<endl;
}

五、附指针和引用的区别
1.引用与指针的区别
(1)指针是一个实体,需要分配内存空间。引用只是变量的别名,不需要分配内存空间。
(2)引用在定义的时候必须进行初始化,并且不能够改变。指针在定义的时候不一定要初始化,并且指向的空间可变。(注:不能有引用的值不能为NULL)
(3)有多级指针,但是没有多级引用,只能有一级引用。
(4)指针和引用的自增运算结果不一样。(指针是指向下一个空间,引用时引用的变量值加1)
(5)sizeof 引用得到的是所指向的变量(对象)的大小,而sizeof 指针得到的是指针本身的大小。
(6)引用访问一个变量是直接访问,而指针访问一个变量是间接访问。
(7)不能引用数组
2.在函数中的使用指针和引用
(1)引用在函数传参的时候,只需要传变量名过去,函数形参用引用接即可。而指针在传参的时候,必须传变量的地址过去,否则不能改变变量的值。
2)引用没有分配内存空间,所以访问函数形参就是访问引用的变量,是直接访问。而指针分配了内存空间用来保存变量的地址,需要通过保存的地址找到指向的变量,是间接访问。
参考文献:
https://www.cnblogs.com/happying30/p/9484860.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值