指针形参
void reset(int *p)
{
*p=0;//p指向的整型对象变为0
p=0;//只是对形参改变p,使其为空指针
}
int i=42;
reset(&i);//i变为0,但地址仍为i的地址
使用引用拷贝
bool isShorter(const string &s1,const string &s2)
{
return s1.size()<s2.size();
}
以上需要传入string可能很大,不适合用值传递,拷贝耗空间
不需要修改,最好用const
Const 形参实参
底层const:指向的对象是一个常量,不允许用指针修改
顶层const:只允许指向一个对象
P57 有时间详细整理
const int ci=42;//顶层const ci是常量不可变
int i=ci;//正确,把const赋值给i !!!相当于i=42;
int * const p=&i;//顶层const p只允许指向i的地址
*p=0;//正确,可通过p改变
const int *const pt=&i;//既不可修改,也不可指向其他
const int *cp=&i;
int *p=cp;//错!!!p有修改i的风险
尽量使用常量引用
string::size_type find_char(string &s,char c,string ::size_type occurs)
{}
此函数若传入("hello world",'o',ctr)会发生错误
类型不匹配
若传入的是const string 类型的变量时也会报错
不用const限制传入实参范围
数组形参
传入数组首元素地址
void print(const int*);
void print(const int[]);
void print(const int[10]);
三者等价,无法传递个数,第三个10还是多少都无影响
管理大小三种方式
1.使用标记指定(c风格字符数组)
void print(const char *cp)
{
while(cp)
{
cout<<*cp++;
}
}
只对char数组带'\0'有效,其余无法有合理标记
2.使用标准库规范
void print(const int* beg,const int *end)
{
while(beg!=end)
{
cout<*beg++<<endl;
}
}
int j[2]={0,1};
print(begin(j),end(j));
用标准库begin,end提供指针 end是指向最后一个元素下一位
3.传入数组大小
void print(const int ia[],size_t size)
{
for(size_t i=0;i!=size;i++)
cout<<ia[i]<<endl;
}
int j[]={0,1};
print(j,end(j)-begin(j));//!!!计算长度方法
数组引用形参
f(int (&arr)[10]);形参是数组引用
f(int &arr[10]);形参是大小为10的数组,每一个元素是int类型的引用
个数必须对应,传入数组必须也是10个元素才可以
传递多维数组
记住,多维数组就是数组的数组
若为2维数组,传入数组首元素地址(这个数组首元素也是数组,第一行),再传入个数(多少行)
void printf(int (*matrix)[10],int rowsize);//要加括号,不加括号则变成指针的数组了
void printf(int matrix[][10],int rowsize)
向main函数传参数
int main(int argc,char *argv[]){}//指针数组,每个元素都是char类型的指针
int main(int argc,char **argv){}//等价,数组转为指针
在命令行里g++ mymain.cpp a b
则argv[0]是程序名
argv[1]是a argv[2]是b
含有可变形参的函数
无法提前预知应该向函数传递几个实参
解决办法:1.initializer_list 标准库类型
2.可变参数模板P618
initializer_list:函数实参数量未知但全部实参类型相同,需添加同名头文件
操作 | 解释 |
---|---|
initializer_list lst; | 默认初始化类型为T的空列表 |
initializer_list lst{a,b,c…} | 初始化lst列表,元素为const |
lst2(lst),lst2=lst | 拷贝,赋值 不会拷贝元素,是共享元素 |
lst.size() | 列表中的元素数量 |
lst.begin() | 返回首元素指针 |
lst.end() | 返回尾元素下一位置指针 |
initializer_list 对象中的元素永远是常量值,无法改变文章来源:https://www.toymoban.com/news/detail-782106.html
void erroe_msg(initializer_list<string> il)
{
for(auto beg-il.begin();beg!=il.end();++beg)//!!!注意此时beg不是迭代器类型,是指针
cout<<*beg<<" ";
cout<<endl;
}
练习题
6.22 三个swap,分别什么都不变,变值,交换指针
#include<iostream>
using std::cout;
using std::endl;
void swap0(int *pt1,int *pt2);
void swap1(int *pt1,int *pt2);
void swap2(int *&r1,int *&r2);
int main()
{
int a=100;
int b=200;
int *pa=&a;
int *pb=&b;
cout<<"swap0"<<endl;
cout<<"before"<<endl;
cout<<"pa="<<pa<<" pb="<<pb<<endl;
cout<<"*pa="<<*pa<<" *pb="<<*pb<<endl;
swap0(pa,pb);
cout<<"after"<<endl;
cout<<"pa="<<pa<<" pb="<<pb<<endl;
cout<<"*pa="<<*pa<<" *pb="<<*pb<<endl;
cout<<endl;
cout<<"swap1"<<endl;
cout<<"before"<<endl;
cout<<"pa="<<pa<<" pb="<<pb<<endl;
cout<<"*pa="<<*pa<<" *pb="<<*pb<<endl;
swap1(pa,pb);
cout<<"after"<<endl;
cout<<"pa="<<pa<<" pb="<<pb<<endl;
cout<<"*pa="<<*pa<<" *pb="<<*pb<<endl;
cout<<endl;
cout<<"swap2"<<endl;
cout<<"before"<<endl;
cout<<"pa="<<pa<<" pb="<<pb<<endl;
cout<<"*pa="<<*pa<<" *pb="<<*pb<<endl;
swap2(pa,pb);
cout<<"after"<<endl;
cout<<"pa="<<pa<<" pb="<<pb<<endl;
cout<<"*pa="<<*pa<<" *pb="<<*pb<<endl;
return 0;
}
void swap0(int *pt1,int *pt2)
{
int *tmp=pt1;
pt1=pt2;
pt2=tmp;
}
void swap1(int *pt1,int *pt2)
{
int tmp=*pt1;
*pt1=*pt2;
*pt2=tmp;
}
void swap2(int *&r1,int *&r2)
{
int *tmp=r1;
r1=r2;
r2=tmp;
}
待更新
1.const顶层底层
2.副本拷贝值内存
3.引用和指针文章来源地址https://www.toymoban.com/news/detail-782106.html
到了这里,关于C++ Primer 6.2参数传递 知识点+练习题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!