Skip to content

Latest commit

 

History

History
133 lines (85 loc) · 5.29 KB

语法问题.md

File metadata and controls

133 lines (85 loc) · 5.29 KB

Table of Contents generated with DocToc

数组定义和值初始化的语法形式混淆

int *ip = new int(12);  ip指向的是单个的一个整数。 int *ip = new int[12];  正确的内存申请方法。

最好的内存申请形式就是根本不去申请,直接用标准库的组件:Vector或者其他。

捉摸不定的评估求值顺序

函数参数的求值没有固定的顺序,必须手动消除这样的副作用。

子表达式的求值次序也不一样,运算符的优先级和结合性对求值次序没有影响。

new会比类型的构造函数先调用,先为对象拿到存储,再在这个存储上初始化它。

逗号,三目运算符有求值顺序的。

逻辑运算符&&和||有短路特性,也算是有顺序么?YEP。

运算符的优先级问题

C++中,没有非结合的运算符。

a>b>c,合法,但可能词不达意。

取大优先解析原则带来的问题

词法分析引入取大优先解析原则:尽可能取长的字符序列作为词法单位。

a+++++b是非法的,它被解析为a++ ++ +b。

list<vector> lovos也是错的,list<vector 空格> lovos。

声明修饰符次序的小聪明

先写连接修饰词,再写量化修饰词,再写类型。 extern const int size = 1024

指向常量的指针有两种声明形式:

  1. const int *pc;
  2. int const *pc;

“函数还是对象”的多义性

对象的默认初始化语句不应该写成一个空的初始化参数列表的形式,因为它会被解释成一个函数声明。如String x()。

该多义性在new表达式中并不发作:String *p = new String(),可以。

效果漂移的类型量化饰词

内建数组不可能有const或volatile,所以修饰它的类型量化饰词(const或volatile)的效果实际上会漂移,转而应用到其持有物的某个适当位置,

量化饰词的实际效果会转移到数组的元素上去了。

自反初始化

int var = 1;
{
	double var = var; //编译通过,但行为未定义,右边用到的var正是刚刚声明的
}
const int var = 1;
{
enum{var = var};
}

这是可以的,枚举的声明位置,与变量不同,是在它的初始化对象(枚举的定义)之后的。后面一个var是外层作用域中的常量。

静态连接类型和外部连接类型

根本没有本条款名称所说的这种东西。

连接类型饰词总是绑定到对象或函数,而不是类型。

static class R
{} r; //静态的
R r2;//非静态的

匿名名字空间

namespace{
R r2;
R r;
}

这样,r和r2就有了外部连接类型,能有比用static修饰用在更多的地方,而且就像静态对象一样,它们在当前编译单元以外的地方不可访问。

运算符函数名字查找的反常行为

当我们记不住中序记法时,函数调用更清晰。

a = b; a.operator = (b)

中序和函数调用的名字查找顺序不一样。

晦涩难懂的operator->

内建的operator->是二元的,重载版本的operator->是一元的。对于重载的operator->的调用,必须返回一个可以用(内建的)operator->访问其成员的。

operator->的调用序列的触发总是由包含operator->之定义的对象静态决定的,而且该调用顺序总是终结于返回指向class对象的内建指针的调用。

导航

目录

上一章:1. 基础问题.md

下一章:3. 预处理器问题