本文共 2675 字,大约阅读时间需要 8 分钟。
1、范围for语句
C++11新标准提供:范围for语句。遍历给定序列中的每个元素,并对序列中每个值执行某种操作。
for ( declaration :expression )
statement
expression:用于表示一个序列,是一个对象;
declaration:将被用于访问序列中的基础元素,负责定义一个循环控制变量,将该变量和序列联系起来。并且每次迭代,declaration部分的变量都会被初始化为expression序列的下一个元素值。void main(){ string s("Hello World!!!"); decltype(s.size()) punt_cnt = 0; //punt_cnt的类型是s.size()函数的返回值类型,也就是string::size_type for (auto str : s) //如果想要改变string对象中的值,必须把循环变量定义成引用类型 if (ispunct(str)) //判断该字符否是标点符号 ++punt_cnt; cout << punt_cnt << " punctuation characters in " << s << endl;}特别提醒:使用范围for语句时,无需用户考虑索引问题,但是在用范围for语句处理“多维数组”时,除了最内层的循环外,无论是否修改数组元素的值,其他循环的所有控制变量都必须定义成引用类型。原因解释:因为只有在最内层循环,循环访问控制变量访问的基础元素才是真正的数组元素,而不是“伪数组”。
void main(){ const size_t rowCnt = 3, colCnt = 4;//VS2013不支持constexpr int ia[rowCnt][colCnt]; for (const auto &row : ia)//该循环并没有任何写操作,但是仍需要把外层的循环控制变量声明成引用类型。具体详解见下面关于“数组自动转换成指针”等 for (auto col : row) cout << col << endl;}关于“数组自动转换成指针”的知识点:
数组有一个特性,在很多用到数组的地方,编译器都会自动地将其替换为一个指向数组首元素的指针:string *p = nums——等价于——p = &nums[0],也就是说在一些情况下对数组的操作实际上是对指针的操作,比如当使用数组作为一个auto变量的初始值时,推断得到的类型是指针而不是数组。而使用decltype时,上述转换不会发生。
//auto int ia[] = { 1, 2, 3, 4, 5 };//ia是一个含有五个元素的数组 auto ia1(ia);//此时编译器执行的初始化过程是auto ia1(&ia[0]),ia1的类型显然是一个int* ia1 = 42; //该句自然也就报错,不能用int值给int*赋值 //decltype decltype(ia) ia2 = { 1, 2, 3, 4, 5 }; ia2 = p; //错误:不能用整型指针给数组赋值 ia2[4] = i; //正确:把i值赋给ia2的一个元素回到上述话题,假设不用引用类型,则循环为:
for (const auto row : ia)
for (auto col : row) cout << col << endl;程序将无法编译通过。因为在第一个循环中实际上遍历的是大小为4 的数组。因为此时row不是引用类型,所以编译器auto初始化row时会自动将这些数组形式的元素转换成指向该数组内首元素的指针,所以此时的row类型就是int *类型(原因见上面),显然内层的循环不再合法,编译器将试图在一个int *内遍历。
2、常量引用、常量指针
指向常量的指针不能用于改变其所指的对象的值,要想存放常量对象的地址,只能使用指向常量的指针。但是允许令一个指向常量的指针指向一个非常量对象。常量引用、常量指针都没有规定其所指的对象必须是一个常量!
所谓指向常量的指针,仅仅要求不能通过该指针改变对象的值,而没有规定那个对象的值不能通过其他途径改变!(当婊子立牌坊)!
所谓的指向常量的指针或引用,不过是指针和引用的“自以为是”,他们觉得自己指向了常量,所以自觉地不去改变所指对象的值。
3、顶层const和底层const
指针本身是一个对象,而引用不是,允许把指针本身定义为常量。指针本身是一个对象,他又可以指向另外一个对象,所以,指针本身是不是常量以及所指的是不是一个常量是两个相互独立的问题。
顶层const:表示指针本身是个常量。
int i = 0 ;
int *const p1 = &i;//常量指针,这是一个顶层const,指针本身会是一个常量,不能修改p1的值(存放在指针中的地址值)
底层const:表示指针所指的对象是个常量。
const int ci = 42; //这是一个顶层const,不允许改变ci的值。
const int *p2 = &ci;//指针常量,这是一个底层const,指针所指的对象是一个常量,允许改变p2 的值。
当执行对象的拷贝操作时,拷入和拷出的对象必须具有相同的底层const资格。或者两个对象的数据类型必须能够转换。一般,非常量可以转换为常量,反之则不行。
int &r = ci;//错误:普通的int&不能绑定到int常量上
const int &r2 = i;//正确:const int &可以绑定到一个普通的int上
道理很简单,原来你是可以改变的,现在我让你不能改变,这是可以的。而如果说,原来你是不能改变的,现在要让你可以改变,这显然不行。
4、在整个项目中查找某个字段:快捷键Ctrl+f,选择在整个项目中查找
快捷键大全:http://www.cr173.com/html/25917_all.html 5、查看VS2013的代码修改记录:AutoHistory http://jingyan.baidu.com/article/d621e8da3218612865913fbc.html 下载AutoHistory:https://visualstudiogallery.msdn.microsoft.com/dfcb2438-180c-4f8a-983b-62d89e141fe3?SRC=VSIDE转载地址:http://lzopi.baihongyu.com/