1.对于int[]数组
sizeof(arr)=4*元素数量
猜测:可能与int型占4个位有关
若:将sizeof(arr)用于int型数组的遍历输出
则:前n项会输出正确的元素值,后(4*n-n)项(没有实际值的存储位)会输出随机值,但不会中断程序的运行,也不会报数组越界的错。
若:用for each语句遍历,采用类似C#的手法输出。
则:只会输出正确的有效项。
2.对于char[]数组,有一种特殊的函数
strlen(arr)=元素数量+?;
猜测:n的不定性很大,可能受数字,中英文字符,中文字符的单引号/双引号的使用影响。
可以确定它将字符串结束符‘\0’也纳入了长度统计。
若:用strlen(arr)遍历char[]数组元素
则:会正确输出前n个字符,但后续输出“空”,因此不能将strlen(arr)当作常用遍历方式
若:采用sizeof(arr)遍历字符数组
则:中文字符‘呀’和双引号“啊”,居然有些算作1(单引中文)或3(双引中文)单位,以前学习到记得统一都是2单位,原因未知。
但是输出结果中只有数字和英文,中文字符‘啊’由于未知原因被吞了。
若:用for each遍历输出char[]
则:可行,但中文字符‘呀’和双引号“啊”,依旧被吞。
在:cout输出中,‘呀’显示为53693,而双引“啊”正确显示为啊
3.关于C++中的foreach语法糖语句测试
语法糖:简化代码语法的一种新颖的代码用法
可以通过外部计数器变量返回索引值,外部变量在foreach内部允许count++;
与C#不同的是,C++中的foreach允许直接对遍历到的当前对象赋值,如:i=i*3;
在C#中,foreach在迭代过程中会产生readonly的数据副本,导致不能进行绝大部分的常规赋值操作。
建议:习惯使用Java或C#语系的同僚可以手动为foreach语句加入计数器,由于在C++中可以赋值,使用反而更加便捷。
4.关于获取数组的长度
常规方式:arr.length = sizeof(array)/sizeof(array[0]);//伪代码
若:用len走for循环遍历
则:对于规模统一的数字型数组可行,对于含有中文字符的char[]不可行,且依旧无法输出中文字符。
5.关于字符数组内包含中文字符输出问题
include了以下包:string/string.h/ctsring,依然无效
经测试,对于char[],只接受“啊”,可以确定,但凡中文字符,其实都视为2单位的字符串,所以都要“”
此外,若在输出中单项输出后直接endl,由于汉字2占2单位,输出流会被切断,导致汉字无法输出。
同样道理,对于char[]来说,汉字字符是其中的一段,而不是单个元素,所以对于汉字字符操作应该想办法嫁接到string[]中。
或者vector[char[]]/list[char[]]中。
6.关于二维数组的一些问题
二维数组遍历好像不能使用foreach语句,原因在于,其二维数组的类型表达不出来
C++允许class对象带着它的int[][]属性走,但好像必须规定好int[][5],这种底层维度的容量,
否则会报错说数组不能包含此类型元素,即,不能有包含数组的数组
此外,int a[[]]是不报错的,但是在遍历中,出现a[i][j],却会报错
建议用其他容器层层包裹数据,C++对与数组的使用有较大的限制
7.一个神奇的错误
vector<double[3]>对象,赋值并装载到自定义的vector<P3对象>(内含一个double[3],表示点在三个轴上的值)时,
会产生报错缺‘&’的情况,但根本原因是vector类型容器对指针地址的转移操作有一定限制,使用时尽量避免vector容器间数据互传。
猜想:如果换成List会怎样?
8.关于C++中的List
需要头文件<list>
C++中的list是不允许随机访问的,像数组或者vector之类的容器,可以使用下标访问,list并没有提供下标访问
并非顺序容器都支持随机访问,这是完全两个不同的概念,尤其是C++中的list是双向链表的存储结构,一般用指针操作比较合适
9.关于vector
vector的元素个数:vec.size;
vector<vector<P3对象>>嵌套,是可行的,但是输出的时候,注意,v3[0][0],指的是第一号对象,对象无法输出
要取到具体的值为止v3[0][0].x,这样就对了,毕竟vector是容器,不仅仅能放数字,放对象的情况基本上都需要点取具体数据
10.关于报错:非标准语法;请使用&来创建指向成员的指针
这类错误的普遍原因是有一个/多个应该是函数的地方,漏掉了括号
有时候说找不到某个函数名或者变量的标识符,很可能是要求你把函数或者变量声明在这个报错位置前面
//第2栏补充
1.关于如何使用迭代器遍历vector容器
声明迭代器的格式:迭代器所服务的数据类型::iterator 迭代器的名称;例如:vector<Peak>::iterator it;
迭代器比较类似于指针,因此使用的时候需要赋予地址,比如可以这样使用:it=peakList.begin();
让迭代器指向peakList的开始位置,同样的,如果应用在for循环中的条件就可以和.end()对比。
比如:for(vecrotr<Peak>::iterator it =peakList.begin();it!=peakList.end();it++)
那么当迭代器it指向的对象需要被输出或作一些数值交互时,该怎么写?方式和使用数组下标点取属性略有不同
要使用到一个->符号,例如:it->height,表示的就是当前迭代器it指向的对象的height属性值。
2.关于string库的功能
str.compare(str02);返回的不是bool,而是-1,0,1,返回0就表示两个字符串完全相同,返回+-1说明有区别,具体未知
3.关于找不到core crt.h的问题
除了网上普遍反映的项目属性->包含目录与库目录的问题,还可能是项目属性->配置管理器的目标平台错误所导致的
4.在编程规范中看到一个神奇的词汇“魔鬼数字”
魔鬼数字是指看不懂实际意义的数值,常常会用于传达指令或表达某种状态,是一种不好的编程习惯的产物。
所以在日常编程中,禁止使用让人摸不着头脑的魔鬼数字。
5.关于模板的使用
template <typename 自己定义的名字(一般为T)=默认类型(比如double)>
就可以置换下一个声明的函数中希望被随机传入类型的变量类型名
6.关于一个警告
C4018:有符号/无符号不匹配
原因:使用了vector容器的同时,对其进行了for循环遍历,其中的遍历因子i通常为int型。
解决:此处应改为unsigned int更合适。
7.关于类型强制转换
直接在变量前面加上(类型)即可,例如float f=1.0f;double d=(double)f;
8.关于报错
C4430缺少类型说明符 - 假定为 int。 注意:C++不支持默认 int
原因:有哪个地方缺少了类型说明符
解决:在应该加上类型的地方,如:函数名前,变量前加上类型说明符
在使用运算符重载的时候,如果有一侧出现浮点,另一侧出现0,不要以为不需要加小数点,本质上和1一样,需要变成1.0/0.0形式
9.VS2015的天秀小操作
Alt+鼠标左键拖动可以竖着选择一列数据,而且还能横向拉
CTRL + M折叠/展开代码切换
CTRL + M + O折叠代码
CTRL + M + L展开代码
10.C++编程中的一种传值技巧
一般来说,我们习惯于在函数末尾return一些数据对象/容器,
但如果在参数列表中,参数名之前写取地址符&,
就会产生直接对参数本身做修改的现象,这样一来,即使函数不返回任何信息,处理也成功的完成了
这样编写的好处是,数据和操作可以割裂开,在主要控制函数中,可以让逻辑关系更加清晰