知识点:
1.尽量使用常引用,而把函数不会改变的形参定义成引用是一种比较常见的错误,
我们不能把const对象, 字符值,或者需要类型转换的对象传递给普通的引用形参。
2.数组的两个性质:1不允许拷贝数组;2使用数组时会将其转换成指针。
3
.数组是以指针的形式传递给函数的,所以一开始函数并不知道数组的确切尺寸,调用者应该为此提供一些额外的信息。一般有三种方法:
a
一般常见于C风格字符串,函数处理到最后一个空字符串时停止。但是有时对于int这样所有的取值都是合法值的数据就不太有效。
b
第二种传递指向数组首元素的尾元素的指针 如:
void print(
const int *beg,
const int *end)。当不需要对数组元素执行写操作的时候,数组形参应该是指向const的指针,只有当函数确实要改变元素值的时候,才把形参定义成指向非常量的指针。
c
第三种管理数组实参的方法是在传送数组首地址后,在另外传一个形参专门表示数组大小的形参。
4.请记住,在C ++中没有数组类型的值,所以数组类型不能是函数参数或返回类型。数组的大小对函数的调用没关系。
5.但是C++语言允许将变量定义成数组的引用,所以形参也可以是数组的引用。此时引用形参绑定到对应的实参上,也就是绑定到数组
上。
6.C++11新标准引入了两个名为begin和end的函数,这两个函数与容器中的两个同名成员功能类似,但不是成员函数,是标准库函数。(主要用于返回数组的首尾指针)。
7.当我们需要给main函数传参时,需要注意到int main(int argc,char* argv []) 第二个形参是C风格数组,存放字符命令的地址,数量等于字符串的数量(argc)。当实参传给main函数之后,argv的第一个元素指向程序的名字或者一个空字符串,接下来的元素依次传递命令行提供的实参,
记住最后一个指针指针之后的元素为0(eg p197)。
8.当使用argv中的实参时,一定要记得可选的实参从argv[1]开始; argv[0]保存程序的名字, 而非用户输入。
9.为了能出列不同数量实参的函数,C++11标准提供了两种主要的方法,1实参类型相同可以传递initializer_list的标注库类型(模板类型)个人觉得和传参数组引用很相似;2类型不同可以编写可变参数模板。还有一种只用于与C函数交互的接口程序省略符形参。
10.return 语句;主要是
终止当前函数的执行,将控制权返还到调用该函数的地方。void 函数可以使用两种return 1是当提前终止函数,加"return;"语句即可; 另一种是return expression; expression必须是另一个返回void的函数。
11.函数的返回类型决定函数的调用是否是左值。
疑问:
1. 今天才编写6.17时,没弄懂记录在这里
环境:VS2010 //刚开始 使用迭代器访问一直出错,调试是错误的指针,换成用下标访问依然有错。
string word(
"hello Everybody"
);
fun6_17(word);
void fun6_17(const string &word1) //因为传进来的是常量,所以这里必须加const
{
/*
for(auto it=word1.begin(); it!=word1.end(); ++it)
{
if(isupper(*it))
{
cout<<"含有大写字母!"<<word1[i]<<endl;
break;
}
}
*/
int
len = word1.size();
for
(
int
i=0; i<len; ++i)
{
if
(isupper(word1[i]))
{
cout<<
"含有大写字母!"
<<word1[i]<<endl;
break
;
}
}
}
好奇怪;去吃中午饭前,有调试了下这段程序;莫名奇妙的好了;连原因不知道在哪里
/*6.25及6.26
这个是参考别人的,感觉在IED下不是很好理解,在Linux有命令参数下编程,会好理解些
int main(int argc, char *argv[])
{
cout<<"输入参数:";
string str;
cin>>str;
for(int i = 0; i<argc; ++i)
{
str += argv[i];
str += " ";
}
cout<<str<<endl;
return 0;
}
*/
习题:
6.16 答:当实参是const对象,字符值等时,会发生错误。改为
bool is_empty(const string &s)
618 答:(a)
bool
compare
(
const
matrix &m1,
const
matrix &m2);
(b)
vector<
int
>::iterator
change_val
(
int
, vector<
int
>::iterator);
6.19 答:(a) 不合法; (b) 合法 (c) 合法 (d) 合法 但有警告;
6.20 答:当传入是字符面值常量, 或者是用const修饰的字符,或者调用者就需要关心传入的 Student 对象有可能会被修改形参一般是常量引用。看编译器执行标准吧, 如果必须用const而形参没加肯定会报错,如果不太需要const,编译不会报错。
6.24 答:这段程序是想接受一个含有10个const int 类型的数, 但是C++编译器会将带有[]类型的统一解释成指针,所以数组大小是不相关的,如const int ia[5]与const int ia[255] 没有 区别。
(关于本节知识点4,5)
void print(const int ia[10])
{
for (size_t i = 0; i != 10; ++i)
cout << ia[i] << endl;
}
应该这样做:
void print10(const int (&ia)[10]) { /*...*/ }
6.28 答:原型:void error_msg(ErrCode e, initializer_list<string> il) 因为il是个<string> 类型的数组,所以范围for语句elem 是string& 类型。范围for循环中auto推导出来的是值,而非迭代器。
6.29 答:看是否追求效率。
程序题:
#include
<iostream>
#include
<vector>
#include
<string>
using
namespace
std;
//判断string中是否含有大写字母
void
fun6_17(
const
string &word1)
//因为传进来的是常量,所以这里必须加const
{
//int len = word1.size();
for
(
auto
it=word1.begin(); it!=word1.end(); ++it)
{
if
(isupper(*it))
{
cout<<
"含有大写字母!"
<<*it<<endl;
break
;
}
}
}
//将单词改为小写
void
fun6_17(string & s)
{
for
(
auto
it=s.begin(); it!=s.end(); ++it)
{
if
(isupper(*it))
*it = *it+32;
}
cout<<s;
}
//返回较大的数
int
fun6_21(
int
in,
int
*jn)
{
return
(in>*jn) ? in:*jn;
}
void
fun6_22(
int
* &pp,
int
* &qq)
//采用引用方便,指针麻烦易出错
{
int
*tmp;
tmp = pp;
pp = qq;
qq = tmp;
}
//采用第一种方式访问数组内容(访问到空字符串,自动停止)
void
fun6_23print(
char
(&ch1)[6])
//注意这里的括号
{
cout<<
"采用第一种方式:"
<<ch1<<endl;
}
//采用第二种方式,传送数组的首尾指针
void
fun6_23print(
const
char
*p,
const
char
*q)
//因为不牵扯修改数组内容,建议const修饰
{
cout<<
"采用第二种方式"
<<endl;
while
(p != q)
{
cout<<*p++;
}
}
//采用第三种方式,传递数组首地址以及数组元素个数
void
fun6_23print(
char
*p,
int
num)
{
cout<<
"采用第三种方式"
<<endl;
//用for是为了加深数组名与地址的转换, 编译器对char *p的解释与char p[] 相同。
for
(
int
i = 0; i<num; ++i)
{
cout<<p[i];
++p;
}
/*
while(num)
{
cout<<*p++;
--num;
}
cout<<endl;
*/
}
//采用initializer_list计算传过来的所有参数的值,vs2010不支持新特性,win7
/*
int fun6_27_sum(const std::initializer_list<int>& il)
{
int sum = 0;
for (auto i : il) sum += i;
return sum;
}
*/
//关于编译器对rentrun 报错的反应结果:
//“fun6_30str_subrange”: 函数不接受 0 个参数,fun6_30str_subrange”: 函数必须返回值
bool
fun6_30str_subrange(
const
string &str1,
const
string &str2)
{
if
(str1.size() == str2.size())
return
str1 == str2;
auto
size = (str1.size() < str2.size()) ? str1.size() : str2.size();
for
(
int
i = 0; i<size; ++i)
{
if
(str1[i] != str2[i])
return
;
}
}
int
main()
{
/*
string word("hello Everybody");
//fun6_17(word);
//cout<<"请输入单词:"<<endl;
//string word;
//cin>>word;
//fun6_17(word);
int i = 10,j = 20;
cout<<fun6_21(i,&j);
int *p = &i;
int *q = &j;
cout<<*p<<'\t'<<*q<<endl;
fun6_22(p,q);
cout<<*p<<'\t'<<*q;
int i = 0,j[2] = {0,1};
char ch[6] = "hallo";
//fun6_23print(ch);
//fun6_23print(begin(ch),end(ch));//c++ 标准库函数,返回数组首尾指针
//fun6_23print(ch, 6);
*/
//fun6_27_sum({1,2,3,4,5,6,7});
fun6_30str_subrange(
"abc"
,
"hallo"
);
return
0;
}