6 注意case里面的大括号
case true:
string file_name = getname();
break;
case false:
//
….
这个代码不行,想想,如果先执行了false,然后false里面用到了file_name怎么办???
会提示没有定义!!!(并且编译器会报错,Dev C++尝试了)
因此要在true后添加大括号,表明局部作用域, 或者在switch外面定义变量.
7 ++*pi和*++pi?
#include <iostream>
using namespace std;
int main()
{
int j = 2, i =3 , i2 =4;
int *pi = &i;
//int *pi2 = pi+1;
//pi2 = &i2;
++*pi;
cout<<pi<<endl;
int c = *pi++;
cout<<pi<<endl;
int b = ++*pi;
cout<<i<<'/t'<<b<<'/t'<<c<<endl;
cin.get();
}
0x22ff70
0x22ff74
4 3 4
8 非const引用形参只能和非const对象匹配
如:string::size_type find_char(string& s, char c)
{
…
}
则find_char(“hello world”, ‘h’)用不了,因为hello..是字符串常量 是const对象
9 引用占多少字节
声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。故:对引用求地址,就是对目标变量求地址。&ra与&a相等。
另外取sizeof(rn)与其原来的值一样,sizeof(rd)==8,rd是一个double的引用!!!
不能建立数组的引用。因为数组是一个由若干个元素所组成的集合,所以无法建立一个数组的别名。
10 指向指针的引用
不能建立引用的引用,不能建立指向引用的指针。因为引用不是一种数据类型,所以没有引用的引用,没有引用的指针。
例如:
int n;
int &&r=n;//错误,编译系统把"int &"看成一体,把"&r"看成一体,即建立了引用的引用,引用的对象应当是某种数据类型的变量
int &*p=n;//错误,编译系统把"int &"看成一体,把"&p"看成一体,即建立了指向引用的指针,指针只能指向某种数据类型的变量
值得一提的是,可以建立指针的引用
例如:
int *p;
int *&q=p;//正确,编译系统把"int *"看成一体,把"&q"看成一体,即建立指针p的引用,亦即给指针p起别名q。
注意:学会这种分析方法,把什么看成一体,又把什么看成一体
11 最大公约数的递归函数
怎么做?会吗?
// 最大公约数的递归函数
#include <iostream>
using namespace std;
int maxFactor(int n, int m);
int main()
{
cout << maxFactor(18,8) <<endl;
cout << maxFactor(15,14) <<endl;
system("pause");
}
int maxFactor(int n, int m)
{
if(n%m == 0)
return m;
else // else可以不要!!!!!!!!!!!!!!!!!!!!!!!!!!!
return maxFactor(m, n%m);
/*
if(m!=0)
return maxFactor(m, n%m);
return n;
*/
/*
if(n!=0)
return maxFactor(m%n, n);
return m;
*/
}
后面两种参考C++ primer的算法,前面是自己的
12 输出缓冲区的刷新
cout<<”his”<<flush; 不做任何操作,只刷新
cout<<”his”<<ends; 插入NULL
cout<<”his”<<endl; 插入新行
#include<iostream>
using namespace std;
int main()
{
cout<<"FLUSH"<<flush;
cout<<"ends"<<ends;
cout<<"ENDL"<<endl;
。。。
}
FLUSHends ENDL
上面空格处有一个NULL,在运行结果窗口赋值进来时后面的ENDL复制不了了,因为字符串已经结束, 自己添加的, 显示运行结果!!!
13 容器元素类型的要求
1) 必须支持赋值运算符
2) 必须可以复制
3) 引用类型不可以
4) 输入输出IO标准库类型不可以
14 容器避免存储end操作符返回的迭代器 P276
while(first != end)
do
{
…
}
15 容器大小类型size_type用int代替行吗 P285
vector <int> vec;
vector<int>::size_type ix;
cout<<"vec size: "<<vec.size()
<<" capacity: "<<vec.capacity()<<endl;
//for(int i=0; i<10; i++) 这个也行,当然可以使用整型啊
for( ix=0; ix<10; ix++)
vec.push_back(ix);
// for(int i =0; i!=10; i++)
cout<<"vec size: "<<vec.size()
<<" capacity: "<<vec.capacity()<<endl;
while(vec.size()!=vec.capacity())
vec.push_back(10);
cout<<"vec size: "<<vec.size()
<<" capacity: "<<vec.capacity()<<endl;
vec.push_back(100);
cout<<"vec size: "<<vec.size()
<<" capacity: "<<vec.capacity()<<endl;
结果:
vec size: 0 capacity: 0
vec size: 10 capacity: 16
vec size: 16 capacity: 16
vec size: 17 capacity: 32
请按任意键继续. . .
16 this指针是什么
在普通的非const成员函数中,this指针类型是一个指向类类型的const指针,在const成员函数中,this指针是一个指向cosnt类类型的cosnt指针。
17 函数返回类型不一定在类作用域中 P381
18 必须在构造函数中初始化的成员 P388
1) 引用类型
2) cosnt成员
3) 缺少默认构造函数的类类型成员(如果没有构造函数,系统默认提供一个,就算有默认构造函数; 只在定义了非默认构造函数,但是又没有重载默认构造函数的情形)
解释原因:可以初始化const对象或引用类型的对象,但是不能对它们赋值!!!!
19 重载++后缀和前缀 P449
1) 调用方式:
pair.operator++(0); // 后缀形式,加了一0
pair.operator++(); // 前缀形式
2) 原型:
class Check
{
public:
Check operator++(); // 前缀形式
Check operator++(int); //后缀形式
…
private:
int* beg;// 指向数组开始处
int* end;// 指向数组尾部
int* curr;// 指向数组当前位置
…
}
3) 实现:
// 前缀的实现
Check Check::operator++()
{
if ( curr == end )
throw out_of_range(“increment past the end of Check”);
++curr;
return *this; // 返回之前保存的值!!!!!
}
//后缀的实现:
Check Check::operator++(int)
{
Check ret(*this); // 保存当前的值!!!!
++*this;// 调用自己的前缀操作符进行加一(减一)!!!!
return ret; // 返回之前保存的值!!!!!
}
20 用作基类的类必须是已定义的 P478
已经定义的类才可以做基类。如果声明了Item_base类,但是没有定义它,不能用它作为基类:
class Item_base;
class Bulk_item: public Item_base{…}
这就是错误的!!!
21栈展开(stack unwinding)过程 P582
22 析构函数不应抛出异常 P583
23 命名空间 P604
全局命名空间(默认,没有名字,调用方法 :: ) 在main之外!
未命名空间,用来取代文件中的静态声明