对于编程语言,我一直认为它只是一种工具,就像锤子,斧头一样,每种语言都用自己比较适用的地方,用的时候拿来就可以了。这种思想让我对语言没有做过很仔细的学习,虽然频繁使用过C,C++,java,C#,Delphi,python,perl,javascript等,但是让我对某种语言提出我的一些想法和见解,理解的就比较少了,所以我一直是一个工具的使用者,甚至连一个熟练的技术工都不算。近一段时间,将会频繁使用C++,所以抽出一段时间,对C++做一个相对仔细的学习,在以后陆续作出分享,希望同我有一样经历的同学能够从中得到学习...
回到正题
(1)“定义问题”
C++是一种静态语言,对定义的要求很严格,每个对象使用前要声明或者定义,对重复定义和未定义行为会报错;
1)一般的内置类型或者库类型的声明和定义:因为一般的程序都不会只是单独一个文件,多个文件交互中经常会有变量的传递和处理。这个时候,对变量的声明和定义就显得很重要,可以在多个文件里声明同一个变量,但是只能在一个文件里对其定义。这样多个文件可以访问同一个变量,而这个变量的值是由定义它的那个文件给出的。
非const变量的声明和定义:
//one.cc
int Val; //define
//two.cc
extern int Val; //declaration
const变量的声明和定义:
//one.cc
extern const int Val=5; //define
//two.cc
extern const int Val; //declaration
2)防止头文件的重定义:使用预处理器变量
用一个简单的例子来说明:假如我自己写了两个头文件one.h,和two.h。其中one.h包括的是一个类的定义;two.h由于也要用到这个类,所以这个头文件里面必然要有一行程序:#include“one.h”。
而我们的主程序里面,开始必然要把我们自己定义的头文件给加进去,必然应该有两行程序:#include“one.h”和#include“two.h”,这样实际上one.h这个头文件被包含了两次,那个类的也相当于定义了两次,必然编译时会出现错误,为了解决这个问题。在one.h里应该加入这么一段程序:
#ifndef ONE
#define ONE
//这里应是one.h里面本来应该有的代码程序
#endif
这样这个头文件在主程序处理时只会被处理一次。因为:当主程序首先碰到这句::#include“one.h,时,由于是第一次处理one头文件,ONE这个预处理器变量还没有定义呢,所以会执行#define ONE这个语句,ONE变量被定义了,头文件one中的代码也会被执行了。当主程序碰到这句:#include“two.h”,由于two头文件中,也有这么一句:#include“one.h”,然后程序就会再次进入到one这个头文件中执行,这是由于ONE这个变量在第一次执行one这个头文件时已经被定义了,所以#ifndef ONE判断失败,不会执行后续的代码了,也就不会在执行one头文件中实际有用的代码了。这样保证了头文件只会被处理一次。
所以作为好的编程习惯,我们应该在自己编写的每个头文件中都加上保护符,避免头文件被多次包含。
3)未定义行为是编译器经常报错的问题
未定义行为:语言没有规定其意义的用法。C++中常见的未定义问题有:
1、连接字符串字面值和宽字符串字面值。
2、使用在函数体内定义的未初始化的变量(非用作赋值操作符的左操作数)。
3、获取不存在的元素也是未定义行为。
当然这类问题很多,需要我们在平时积累并注意这种细节问题。
(2)表达式结合顺序问题
先把自己的错误给出来大家看看,这道题目是《C++ primer》第四版习题3.13的我的解答
int intval; vector<int> vectorval; while (cin>>intval) { vectorval.push_back(intval); } vector<int>::size_type length=vectorval.size(); if (length%2==0) { //如果是偶数 for (int i=0;i!=length-2;i++) { cout<<"plus:"<<vectorval[i]+vectorval[++i]<<endl; } } else { //如果是奇数 for (int i=0;i!=length-3;i++) { cout<<"plus:"<<vectorval[i]+vectorval[++i]<<endl; } cout<<"the last number is:"<<vectorval[length-1]<<endl; } getchar(); return 0;
(当然这里是省略了头文件引用)一个疏忽出现如下结果
按照自己想法应该得出的是 3,13,13;5。可是结果为什么会这样,原因就在于cout<<语句的执行顺序,是从右往左执行,这下明白了....