函数和二维数组
在C/C++中多维数组做参数的时候必须明确二维及以上的大小,第一位的大小可省略。例如:
void func(int arr[][4], int row) ;
void func(int (*arr)[4], int row) ;//注意[]优先级高于*
如果在形参中写上了行数,调用函数时没有强制的行数限制。编译器会无视它。
函数和C风格字符串
由于C类型的字符串有既定的结束字符,所以设置形参的时候可以不设置代表字符串长度的形参。
函数和结构体
结构体可直接作为函数的形参或实参,用法与普通变量一致 。
函数调用时会创建结构体的完整副本。若结构体体积较大,会导致程序效率下降,可以考虑使用结构体指针。
函数和string对象
-
形参使用
const string& s。- 传递的是原对象的引用,不允许修改。
-
形参使用
string& s- 传递的是原数据的引用,并且可以修改。
-
const string s/string s,- 使用的原数据的副本。
函数与arrray对象(C++11)
优先使用「const 引用」尽量避免「按值传递」
-
按 const 引用传递(
const array<T, N>& arr)- 传递 array 对象的只读引用,无拷贝(仅传地址),禁止修改数组内部数据
-
按非 const 引用传递(array<T, N>& arr)
-
按值传递(array<T, N> arr)
| 组成部分 | 作用 |
|---|---|
| array | 容器模板名 |
| <T, N> | T为数值类型,N为固定大小 |
| arr | 变量名 |
array并非只能存储基本类型,还可以存储对象。
递归
和C\C++语法上允许main()函数调用自己,但极不推荐。
#include <iostream>
const int Len = 66;
const int Divs = 6;
void subdivide(char ar[], int low, int high, int level);
int main()
{
char ruler[Len];
int i;
for (i = 1; i < Len - 2; i++)
ruler[i] = ' ';//把1~64标记为' '
ruler[Len - 1] = '\0';
int max = Len - 2;
int min = 0;
ruler[min] = ruler[max] = '|';//把边缘标记为'|',0和64
std::cout << ruler << std::endl;//打印数组,屏幕第一行
for (i = 1; i <= Divs; i++)//
{
subdivide(ruler, min, max, i);
std::cout << ruler << std::endl;
for (int j = 1; j < Len - 2; j++)//清空数组
ruler[j] = ' ';
}
return 0;
}
//当递归至level为0时,停止递归。会把中间,中间的中间……,标记为'|'
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);
}
函数指针
和数据类似,函数也有地址。
函数指针的语法是 返回值类型 (*指针变量名)(参数类型列表),括号不能省略,否则为指针函数。
函数名(pt())和函数指针((*pt)())等价,和数组名与数组首地址类似。
函数指针数组
函数指针数组是「存储多个函数指针的数组」
语法:返回值类型 (*数组名[数组大小])(参数类型列表)
注:auto 不能直接定义数组类型。
使用typedef
typedef可以用来创建类型别名,只能用来操作类型,不能操作实体/标识符。
int (*func_arr[4])(int, int);//等价于int (*(func_arr[4]))(int, int)
// 简化写法1:typedef别名(C/C++通用)
typedef int (*CalcFunc)(int, int);
//补充: 简化写法2:using别名(C++11+,更直观)
using CalcFunc = int (*)(int, int);