1.和常量引用一样,所谓的指向常量的指针或者引用没有规定其所指的对象一定要是个常量。所谓指向常量的指针仅仅要求不能通过该指针改变对象的值,但是并没有规定那个对象的值不可以通过其他的方式改变。
2.常引用可以对数值进行引用,而引用不可以
int i = 10;
int &r = i; //ok
int &r = 0 //no
const in &r = 0; //ok
有关const
int i = -1, &r = 0; // illegal, r must refer to an object.
int *const p2 = &i2; // legal.
const int i = -1, &r = 0; // legal.
const int *const p3 = &i2; // legal.
const int *p1 = &i2; // legal
const int &const r2; // illegal, r2 is a reference that cannot be const.
const int i2 = i, &r = i; // legal.
int i, *const cp; // illegal, cp must initialize.
int *p1, *const p2; // illegal, p2 must initialize.
const int ic, &r = ic; // illegal, ic must initialize.
const int *const p3; // illegal, p3 must initialize.
const int *p; // legal. a pointer to const int.
3.迭代器不能计算两个加运算
mid = beg+(end-beg)/2; //这样是合法的
mid = (beg+end)/2 ; //这样是非法的,因为迭代器没哟定义加法运算,减法为两个迭代器之间的距离,
可以计算
4.数组的维度必须是一个常量表达式
int cnt = 10;
int ans[cnt]; //不可以,因为cnt不是一个常量
const int cnt2 = 19;
int ans[cnt]; //可以,因为cnt2是一个常量表达式
5.确定一个值的引用还是指针
一般来讲,简单的类型从右往左读,对于复杂的类型,从中间往两边阅读
int *ptrs[10]; //ptrs是一个含有是个整型指针的数组
int (*parray)[10] = &arr; //parray是一个指针,指向的是含有10个整数的数组
int *(&array)[10] = ptrs; //array 是一个数组的引用,该数组含有10个指针
6.全局变量int类型的被初始化为0,局部变量不会被初始化
7.声明规定了变量的名字,定义还申请了储存空间。如果只是声明一个变量而并非定义它,就只需要在前面添加关键字extern
extern int i //声明一个变量
int j // 定义一个变量
8.引用是另一个对象的别名,而指针本身就是一个对象。
9.引用必须初始化,并且一旦定义了引用就无法再绑定到其他对象。而指针无须在定义时赋初值,也可以重新赋值让其指向其他对象
10.如果你是想在多个文件之间公用一个常量,const 定义之后的值,
extern const int bufsize = 100;//在.cpp的文件中定义并初始化了一个常量
extern const int bufsize ; //在.h文件中与.cpp中的值是一个值
11.内置的下标运算符所用的索引值不是无符号类型,这一点与vector和string完全不同
int *p = &ia[2]; //p为指向索引为2的元素
int j = p[1]; //p[1]等价于*(p+1),也就是ia[3]的那个元素
int k = p[-2]; //p[-2]是ia[0]表示的那个元素
12.
char ca[] = {'c','+','+'}; //不以空字符结束
cout<< strlen(ca)<<endl; //严重错误,ca没有以空字符结束
C++继承C风格的字符串,末尾必须以空字符结束,才能计算字符串的长度。
13.
char *str = s //错误,不能用string对象初始化char*
const char *str = s.c_str(); //正确
//c_str函数返回值是一个C风格的字符串,也就是函数返回的结果是一个指针,该指针指向一个空字符结束的字符数组
14.
//begin() 和 end() 获取数组的头尾指针
int a[] = {1,2,3,4,5,566,6};
for(int *i = begin(a);i!=end(a);i++)
{
*i = *i+1;
}
15.
当一个对象被用作右值的时候,用的是对象的值(内容);
当一个对象被用作左值的时候,用到是对象的身份(在内存中的位置);
16.一般情况下对于一个不知道大小的整数,用size_t,不用int,他会根据平台的不同选择不同的大小的内存
因为与int固定四个字节不同有所不同,size_t的取值range是目标平台下最大可能的数组尺寸,一些平台下size_t的范围小于int的正数范围,又或者大于unsigned int. 使用Int既有可能浪费,又有可能范围不够大。
17.
静态局部对象在程序的执行路径第一次经过的时候对他进行初始化,并且直到程序终止才被销毁,在此期间即使对象所在的函数结束执行也不会对他有影响。
size_t count_calls()
{
static size_t ctr = 0;
return ++ctr;
}
int main()
{
for(size_t i = 0;i!=10;i++)
cout<<count_calls()<<endl;
return 0;
}
17.通过传入引用,隐式的返回其中的参数
//通过传入引用occurs,最后将occurs隐式的返回
string::size_type find_char(const string& s, char c, string::size_type& occurs)
{
auto ret = s.size();
occurs = 0;
for (auto i = 0; i != s.size(); ++i)
{
if (s[i] == c)
{
if (ret == s.size())
ret = i;
++occurs;
}
}
return ret;
}
int main()
{
string s ="asdsfasdf";
int ctr = 0;
auto index = find_char(s,'s',ctr);
cout<<ret<<endl;
}
18.指针或者引用参与const,C++ 允许我们用字面值初始化常量引用
19
如果一个函数的定义为
string::size_type find_char(string &s,char c,string::size_type &occurs);
这样只能将find_char 函数作用于string类型的对象,类似于下面这样的调用将发生错误。
find_char("Hello World",'o',ctr)//因为字面值不能赋值给传递给普通引用形参,const的对象也不能传值
给普通的引用。
20.
不能够返回局部对象的指针或者引用
const string &manip()
{
string ret;
if(!ret.empty()) //错误:返回局部对象的引用!
return ret;
else
return "Empty"; //错误:“empty”是一个局部临时对象
}
可以这样用
const string &shortstring(const string &s1,const string &s2)
{
return s1.size() <= s2.size()?s1:s2;
}