函数
函数的基本知识
- 函数的原型描述了函数到编译器的接口,将函数返回值的类型以及参数类型和数量告诉了编译器。编译器得到这些信息,如果没有传参,编译器能够捕获到错误,返回的时候,知道返回多少字节的内容
- 当调用到该函数的时候再去找该函数的定义,编译器要停止对main()的编译,去寻找函数的定义,影响定义;调用的函数不在同一个文件夹中,编译器编译main()的时候,可能无权访问函数代码。除非是在main()前定义好函数
对编译器的作用- 正确处理函数的返回值
- 检查使用的参数数目是否正确
- 检查使用的参数类型是否正确;不正确则转换为正确的类型
函数参数和按值传递
- 函数中声明的变量和参数为函数私有。在函数被调用时,计算机为变量分配内存;函数结束时,计算机会释放该变量使用的内存。即局部变量
函数和数组
-
如果函数传进去的参数是数组,c++会把数组名视为指针,把该数组第一个元素的地址传到函数当中去
int sum(int arr[]); // 可以传指针和数组 int sum1(int *arr); // 只能传指针
-
指针和const,尽可能的使用const,可以避免由于无意间修改数据而导致的编程错误;使用const使得函数能够处理const和非const实参,否则只能接受非const数据
- 可以改变const指针指向的地址,不可改变const指针指向的地址的值
int age = 39; int test = 60; const int *pt = &age; *pt += 1; // 不可行 pt = &test; //可行
函数和二维数组
- 函数的参数不能是数组
int data[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {1, 3, 4, 6}};
int sum(int arr[][4], int size);
int sum(int (*arr)[4], int size);
- int arr[][4]中的4指的是声明一个由4个指向int的指针数组,固定了传进去的二维数组只能有4列的长度
函数和字符串
- c-风格字符串
- const和指针的原理同样使用,指针地址指向的是字符串的第一个字符,直到遇到空值字符('\0)
- 返回字符串,也是返回一个存放了字符串的指针地址
- pstr在buildstr结束时,内存就被释放了
int times = 10;
char ch = 'w';
char* ps = buildstr(ch, times);
char* buildstr(char c, int n)
{
char* pstr = new char[n + 1];
pstr[n] = '\0';
while (n-- > 0)
{
pstr[n] = c;
}
return pstr;
}
- string对象
- 和内置类型(int)一样使用string对象即可
函数和结构
- 传递和返回结构
struct travel_time
{
int hours;
int time;
}
void show_time(travel_time);
int main
{
return 0;
}
void show_time(travel_time t)
{
return t;
}
- 也可以传递结构的地址来使用
void show_time(const travel_time *t)
{
cout << t->hours << endl;
return
}
函数与array对象
- 模板array并非只能存储基本数据类型,也能存储类对象
使用方法与数组一样
void show(array<int, 4>, *pa);
void show1(array<int, 4>, da);
void show(array<int, 4> *pa);
void show1(array<int, 4> da);
递归
- 自己调用自己,将无限循环下去,需要给出一个结束条件。
- 若是包含多个递归调用的递归时需要注意的是调用的次数,每调用一次递归存储的变量数都是以几何倍数增长
void subdivide(char ar[], int low, int high, int level)
{
if (level == 0)
return;
int mid = (high + low) / 2;
ar[mid] = '|';
subdivide(ar, low, mid, level - 1);
subdivide(ar, mid, high, level - 1);
}
函数指针
- 与数据项一样,函数也有地址。函数的地址是其机器语言代码内存的开始地址
- 用处可以是在一个函数中通过函数指针找到第二个函数并运行它
- 获取函数地址,只要使用函数名即可(不需要跟参数)
- 声明函数指针,声明指定函数的返回类型以及函数的参数列表
- 使用指针来调用函数,(*pf)看做是函数名来使用
void estimate(int lines, double (*pf)(int));
double test(int);
int main()
{
using namespace std;
int code = 10;
estimate(code, test);
return 0;
}
double test(int lns)
{
return lns * 0.5;
}
void estimate(int lines, double (*pf)(int))
{
using namespace std;
cout << lines << "lines will take ";
cout << (*pf)(lines) << "hours" << endl;
// 相当于是test(lines)
}
- 在函数原型中,可以省略标识符。下面三个函数的原型含义相同
const double * f1(const double ar[], int n);
const double * f2(const double [], int);
const double * f3(const double *, int);