数组形参
当我们为函数传递一个数组时,实际上传递的是指向数组首元素的指针
数组形参不能以值传递的方式传递数组
以下三种写法等价,每个函数唯一的形参都是const int *
void print(const int *)
void print(const int[])
void print(const int[10])
当传入一个数组给print函数,实参会自动地转换为指向数组首元素的指针
使用数组形参时,必须确保使用数组时不会越界
管理指针形参,常用的3种技术
使用标记指定数组长度
void print(const char* cp) {
if (cp)//如果指针不为空
while (*cp)//如果指针所指对象不为空
cout << *cp++;//输出当前字符并将指针向后移动一个位置
}
int main(){
char c[] = { 'a','b','c','d' };
print(&c[0]);//传入数组的首元素指针
print(begin(c));//这种传入方式也可以
//需要注意数组的尾后元素\0
return 0;
}
使用标准库规范
void print(const int* beg, const int* end) {
//输出beg到end(不包含end)之间的所有元素
while (beg != end) {
cout << *beg++ << endl;//输出当前元素并将指针向后移动一个位置
}
}
int main()
{
int a[] = { 1,2,3 };
print(&a[0], &a[3]);//第一种调用方式
print(begin(a), end(a));//第二种调用方式
return 0;
}
显示传入一个表示数组大小的形参
void print(const int ia[], size_t size) {
//const int* ia 等价于 const int ia[]
for (size_t i = 0; i != size; ++i) {
cout << ia[i] << endl;
}
}
int main()
{
int a[] = { 1,2,3 };
print(a,3);
//在不知道a的大小的情况下可以用以下两种方式
print(a, end(a)-begin(a));
print(a, sizeof(a)/sizeof(a[0]));
return 0;
}
以上的例子都是不需要修改数组中的值,所以都用了指向const的指针,如果函数需要修改值就用非常量指针(就是不带const的普通指针)
C++允许将变量定义成数组的引用,基于同样的道理形参也可以是数组的引用
void print(int(&arr)[10]) {//引用数组作为形参一定是(&arr)[10]这种写法
for (auto i : arr) {
cout << i << endl;
}
}
int main(){
int x[10] = { 1,2,3,4,5,6,7,8,9,10 };
print(x);//这个函数只能传入10个大小的数组
return 0;
}
需要注意,作为函数形参数组的引用
&arr必须加()
f(int &arr[10])//错误这是将arr声明成了引用的数组
f(int (&arr)[10]//正确,arr是有10个整数的整数数组的引用
传递多维数组
C++没有真正的多维数组,多维数组只是数组的数组
所以多维数组在传递时,传递的是数组的数组的首元素
void print(int(*matrix)[10], int rowSize);//这里一定是(*matrix)[10]
//等价与
void print(int matrix[][10],int rowSize);
int *matrix[10] //10个指针构成的数组
练习6.21
int func(const int &x, const int *const y) {
return x > *y ? x : *y;
}
int mian(){
int a = 1;
int b = 2;
int* c = &b;
cout<<func(a, c)<<endl;
return 0;
}
练习6.22
void func2( int* x, int* y) {
int* temp = x;
x = y;
y = temp;
}
int main(){
int a = 0;
int *i = &a;
cout << *i << endl;
cout << i << endl;
int b = 1;
int* j = &b;
cout << *j << endl;
cout << j << endl;
func2(i, j);
cout << *i << endl;
cout << i << endl;
cout << *j << endl;
cout << j << endl;
return 0;
}
练习 6.23
#include<string>
#include <iostream>
#include<cctype>
using namespace std;
void print(const int ia[], size_t size) {
//const int* ia 等价于 const int ia[]
for (size_t i = 0; i != size; ++i) {
cout << ia[i] << endl;
}
}
void print(const int* beg, const int* end) {
//输出beg到end(不包含end)之间的所有元素
while (beg != end) {
cout << *beg++ << endl;//输出当前元素并将指针向后移动一个位置
}
}
void print(const char* cp) {
if (cp)//如果指针不为空
while (*cp)//如果指针所指对象不为空
cout << *cp++;//输出当前字符并将指针向后移动一个位置
}
void print(int* const p) {
cout << *p << endl;
}
int main()
{
int i = 0, j[2] = { 0,1 };
char c[5] = { 'a','b','c','d','e' };
print(&i);
print(c);
print(begin(j),end(j));
print(j, end(j) - begin(j));
system("pause");
return 0;
}
练习6.24
当我们传递一个数组给一个函数时,实际上是在传递一个指向数组第一个元素的指针。这题,参数中的const int ia[10]实际上和const int*是一样的,数组的大小是无关的,const int ia[3]或const int ia[255],没有区别。所以如果我们传入的实参数组是int ia[5],那么在该函数中的for循环里访问ia[5]时就会出错,数组越界。如果我们想要传递一个大小为10的数组,我们应该像这样使用引用:
void print(const int (&ia)[10]) {
for (size_t i = 0; i != 10; ++i) {
cout << ia[i] << endl;
}
}