1、C++支持操作符重载。
2、表达式由一个或多个操作数通过操作符组合成,每个表达式都会产生一个结果。表达式的结果是右值,可以读取该结果值,但不允许对它进行赋值。
要理解操作符的优先级、结合性和操作数的求值顺序。
3、对于两个数的除法和求模,若均为正,则结果均为正。若均为负,除法结果为正,取模的结果为负。若一正一负,则结果依赖于具体编译器。
4、不能串联使用关系操作符。因为关系操作符具有左结合特性。如if(i<j<k);
i<j首先比较,比较的结果为0或1,然后在与k进行比较,只要k>=1,结果恒为真。
5、对于判断与bool值相等与否,一般都是判断非假,if(val!=false),或是写成if(val)。
因为val可能是int或是相关类型,如果使用if(val==true),此时只有当val==1时才成立,而对于int类型来说非零即为真,0为假。
6、前置自增自减运算符效率较后置自增自减运算符较高。因为前置运算符只需加一或减一后返回结果,而后置运算符必须先保存原来的值,再加一或减一。
7、对于cout<<*iter++,它等同于*(iter++)。
因为自增运算符优先级高于解引用操作,且它们都是从右向左结合。此句也相当于cout<<*iter; iter++; 因为iter++自增后,返回原值的副本,然后在解引用此值。
8、条件操作符的优先级相当低,应该注意使用括号。如cout<<(i<j?i:j);
如果写成cout<<i<j?i:j; 它将i和j的值相比较后的值视为cout的操作数,输出0或1,<<操作符返回cout值,然后将返回结果作为条件操作符的判断条件。
9、使用sizeof的结果部分地依赖所涉及的类型:
1)对char类型或值为char类型的表达式做sizeof操作保证得1。
2)对引用类型做sizeof操作将返回存放此引用类型对象所需的内存空间大小。
3)对指针做sizeof操作将返回存放指针所需的内存大小。注意,如果要获取该指针所指向对象的大小,则必须对该指针进行解引用。
4)对数组做sizeof操作等效于将对其元素类型做sizeo操作的结果乘上数组元素的个数。
10、对于内置的类型,动态申请空间如int*p=new int; 与int*p=new int( ); 有显著的差别。
第一种情况int变量没有被初始化,第二种被初始化为0。对于类类型,第一种写法与第二种写法没有显著差别,类的默认构造函数都会被调用。
11、堆空间可能会被耗尽,因此动态申请内存可能会失败。动态内存交换并不能保证堆空间随用随有。
delete动态申请的空间之后要将指针置为NULL,否则将变成野指针,有可能被误用。
两次对同一块堆空间调用delete可能会导致堆空间被破坏。
12、const_cast用于去掉表达式const性质。
如const char *ptr; char *p=const_cast<char*>(ptr); 去除了ptr的const属性。
13、static_cast,编译器隐式执行的任何类型转换都可以由static_cast显式完成。
用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。
这种转换的安全性也要开发人员来保证。把空指针转换成目标类型的空指针。把任何类型的表达式转换成void类型。
14、旧式的强制转换符号有两种形式,如int(ptr)或(int) ptr;
但这是c语言的强制类型转换,虽然C++支持,但是推荐使用C++中的强转操作符。
15、一个带下标的数组名是一个左值。数组名const指针。数组无边界检查,而vector有at函数可以进行。
声明数组:类型 数组名 [数组大小];
然后编译器保留恰当容量的内存。数组大小必须是一个大于0的常数常量。
初始化数组:int n[10]; for(int i=0; i<10; i++) n[i]=0; //数组元素全初始化为0
16、int n[10] = { 0 };
//initialize elements of array n to 0 此方法只能用于数组的声明。
17、常量变量必须在声明时用一个常量表达式来初始化,而且之后不能修改。
如const arraysize = 10; int s [arraysize];
只能使用常量声明自动数组和静态数组的大小,如果不这样做,会导致编译错误。但gcc允许变量作为数组的大小。
18、for(int i=0; i<arraysize; i++) total += a[i];计算有10个元素的整数数组a所包含的值之和。
19、可以把数组元素当作计数器使用。应该使用const限定符实施最小特权原则。
可以直接比较两个vector, 可以把一个vector赋给另一个vector。
20、可以将static应用于局部数组声明,这样数组就不会在每次程序调用该函数时都进行创建和初始化,也不会在程序中每次该函数结束时被销毁,特别是在使用大型数组时。
21、当第一次遇到static局部数组时,程序就初始化它们。如果一个static数组没有被程序员进行显式的初始化,那么在创建这个数组时,编译器会把它的每个元素初始化为0。这一点要注意,因为C++对自动变量是不执行这种默认初始化的。
22、静态变量在函数内显式地初始化时仅第一次有用,再次调用时不再初始化。
23、将数组传递给函数——int hourly[24]; modifyArray(hourly, 24);
c++以按引用传递的方式将数组传递到函数中,但是单个数组元素是按值传递的。 数组大小通常也要传递。因此当被调用的函数在它的函数体中修改数组元素时,实际上是在数组原始的内存位置上修改它们的值。
24、若一个函数要通过函数调用接收一个数组,这个函数的参数列表必须指明该函数期望接收一个数组。
void modifyArray( int b [ ],int arraysize );
表示modifyArray期望在参数b中接收一个整数数组的地址,在参数arraysize中接收数组元素的个数。
25、使用const可以防止在函数体内对数组元素无意识的修改。这样数组的元素在函数体内就变成了常量。如 void tryToModify( const int b[ ])。
26、当创建包含static数据成员的类的对象时,该类的所有对象共享该类的static数据成员的一个副本。
static const int students = 10; //not public data 类的静态数据成员不是真正的类的成员,它存储在全局区域。
只有静态常量整型数据成员才能在类中初始化。
27、static数据成员可以在类定义和成员函数定义中被访问,即使没有该类的对象存在,使用:: 和数据成员名的类名,public static数据成员也可以在类之外被访问。
28、采用线性查找法查找数组。采用插值排序法排序数组。
29、多维数组:在第0行的所有元素名的第一个下标都是0。
int [ ] [6]; 第一维大小不需要有,但所有后面的维的大小是必须的,否则会报错。
30、将长的vector对象赋值给短的对象,短对象的长度自动增长到与长的对象相等。由于开辟了新的空间,其起始地址发生了改变,由短赋长不变。好像vector的空间增长是成双倍的,这在C++ primer上有介绍。
vector对象可以使用 != 运算符直接进行比较。