C++ Primer笔记(四)表达式

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对象可以使用 != 运算符直接进行比较。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值