基础知识
int func(int a,double b,char c); //函数原型
int main()
{
func(); //函数调用
}
int func(int a,double b, char c) //函数定义,
{
...
}
C++可以返回任何类型的数据,除了数组之外,可返回结构或对象(可以思考,如果结构体或对象内含有动态分布的内存,该如何处理?)。
在函数内部声明的变量是函数私有的,在函数结束时,计算机将释放这些变量使用的内存。(通过new语句实现的定义,是不被释放的)
处理数组的函数
数组不可直接传入函数,而是通过地址进行传递的。
以数组arr[10],指针ar为例,&arr[0],arr均表示数组首元素的地址。
数组的形参可有两种表示:
int func1(int a[]); //数组表示
int func2(int *a); //指针表示
恒等式:
arr[i]=*(ar+i)
&arr[i]=ar+i
传递常规变量时,函数将使用该变量的拷贝,但传递数组(地址)时,将对原来的数组进行操作
传递数组一般需要传递数组的长度
为防止数组的变量被修改,一般在声明函数的形参时使用关键字const修饰数组。该const表明在这个函数内不能修改该数组,但在该函数之外,仍然可以修改。
const指针
类型 | 是否可修改 | 指向或被指向 |
---|---|---|
const数据 | 不可修改(by 指针,自身) | 不可被非const指针指向 |
非const数据 | 可修改(by 非const指针,自身) 不可修改(by const 指针) | 均可被指向 |
const指针 | 不可修改(by 指针,自身) | 均可指向 |
非const指针 | 可修改(by 非const指针,自身) 不可修改(by const 指针) | 不可指向非const变量 |
int temp=0;
const int *p=&temp; //非const指针,但不可修改temp
int const *q=&temp; //const指针,不可修改指针值,但可以修改temp
处理字符串的函数
字符串与char数组,存在一个最基本的区别:字符串有内置的结束字符。
返回字符串的方法:
在函数内,采用new的方法,返回一个一个指针型变量(地址)即可。
处理结构体的函数
传入值方式:
- 依次传入变量
- 以结构为整体传递 (效率低下,且无法对原结构变量做修改)
- 传递结构的地址
传出值时,可以直接返回一个结构。结构可以相互直接赋值(不同于数组)。
具体实例:
#include<iostream>
using namespace std;
struct str
{
int *p;
int len;
};
void input(str *temp); //输入
void show(str temp); //显示
float aver(str temp); //求平均
int main()
{
str build;
input(&build);
show(build);
float average;
average=aver(build);
cout<<average;
}
void input(str *temp) //传递地址,可以修改原变量
{
cout<<"pleas input no more than ten numbers,please any char can escape"<<endl;
temp->p=new int [10]; //指针引用结构体,使用->,对象引用结构体,使用.
int i;
for (i=0;i<10;i++)
{
cin>>(temp->p)[i];
if (cin.fail()==true) //输入是否出错
{
(temp->p)[i]=0;
break;
}
}
if (cin.fail()==true)
{
temp->len=i;
cin.clear();
}
else
{
temp->len=10;
}
}
void show(str temp) //传递拷贝,不可以修改
{
for (int i=0;i<temp.len;i++)
{
cout<<temp.p[i]<<" ";
}
}
float aver(str temp)
{
long sum=0;
for(int i=0;i<temp.len;i++)
{
sum+=temp.p[i];
}
return sum/(1.0*temp.len);
}
递归函数
void func(int a)
{
statements1;
if(test)
{
func(a-1);
}
statements2;
}
可以理解为,先顺序执行statements1的语句n次,而后以相反的顺序执行statement2的语句n次。
#include<iostream>
using namespace std;
void countdown(int n);
int main()
{
countdown(4);
return 0;
}
void countdown(int n)
{
cout<<"Counting down"<<n<<endl;
if(n>0)
{
countdown(n-1);
}
cout<<n<<":kaboom"<<endl;
}
结果为:
函数指针
主要用途为调用其他的函数。
要完成的工作:
- 获取函数的地址
- 声明一个函数指针
- 使用函数指针调用函数
函数名即为函数的地址,
函数指针的定义,可以依据函数的原型,直接用(*p)代替其中的函数名即可,
调用时,可以直接通过指针名调用,也可以通过(*p)的方式进行调用。
一般不建议对参数很复杂的函数使用函数指针。(auto p=&func,或者使用typedef)
#include<iostream>
using namespace std;
double conculate(double a,double b,double (*p)(double,double));
double add(double a,double b);
int main()
{
cout<<conculate(0.2,10,add);
}
double conculate(double a,double b,double (*p)(double x,double y)) //函数指针尽量加上括号 以确保优先级
{
double temp=(*p)(a,b);
return temp;
}
double add(double a,double b)
{
return a+b;
}