小人物学个大习(131-140)
C++ primer
多维数组,按照由内而外的顺序理解数组
int ia[3][4]; //大小为3的数组,每个元素是含有4个整数的数组
int (*p)[4] = ia; //p指向含有4个整数的数组
p = &ia[2]; //p指向ia的尾元素
根据3.5.1节(第103页)提出的策略,我们首先明确(*p)意味着p是一个指针。接着观察右边发现,指针p所指的是一个维度为4的数组:再观察左边知道,数组中的元素是整数。因此,p就是指向含有4个整数的数组的指针。一元运算符、二元运算符
C++的表达式要不然是右值(rvalue,读作“are-value”),要不然就是左值(lvalue, 读作“ell-value”)。这两个名词是从C语言继承过来的,原本是为了帮助记忆:左值可以位于赋值语句的左侧,右值则不能。
在C++语言中,二者的区别就没那么简单了。一个左值表达式的求值结果是一个对象或者一个函数,然而以常量对象为代表的某些左值实际上不能作为赋值语句的左侧运算对象。此外,虽然某些表达式的求值结果是对象,但它们是右值而非左值。可以做一个简单的归纳:当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。优先级与结合率
从左到右求值顺序、优先级、结合率
例如<<运算符是没有规定求值顺序的,
cout<< I<<“”<<++I<<endl;
这里的++i的顺序是未定义的
只有四种运算符明确了计算顺序,&& || ?: ,算数运算符
整数相除结果还是整数,也就是说,如果商含有小数部分,直接弃除:
int ivall = 2l/6;// ivall是3,结果进行了删节,余数被抛弃掉了
int ival2 = 21/7; //ival2是3,没有余数,结果是整数值
运算符%俗称“取余”或“取模”运算符,负责计算两个整数相除所得的余数,参与回取余运算的运算对象必须是整数类型:
int ival = 42;
double dval = 3.14;
ival % 12; //正确:结果是6
ival % dval; //错误:运算对象是浮点类型
在除法运算中,如果两个运算对象的符号相同则商为正(如果不为0的话),否则商为负。C++语言的早期版本允许结果为负值的商向上或向下取整,C++11新标准则规定商律向0取整(即直接切除小数部分)。
根据取余运算的定义,如果m和n是整数且n非0,则表达式(m/n)*n+m%n的求值结果与m相等。隐含的意思是,如果m%n不等于0,则它的符号和m相同。
C++语言的早期版本允许m%n的符号匹配n的符号,而且商向负无穷一侧取整,这一方式在新标准中已经被禁止使用了。除了-m导致溢出的特殊情况,其他时候(-m)/n和m/(-n)都等于-(m/n),m%(-n)等于m%n,(-m)%n等于-(m%n)。具体示例如下:
21%6; /结果是3/
21%7; /结果是0/
-21%-8; /结果是-5/
21%-5; /结果是1/
21 / 6; /结果是3/
21 / 7; /结果是3/
-21 /-8; /结果是2/
21 / -5; /结果是-4/关系运算符作用于算数类型或指针类型,逻辑运算符作用于任意能转换成布尔值的类型。
逻辑与,逻辑或采用短路求值策略
关系运算符采用左结合率,并且返回布尔值赋值运算符
赋值运算的结果是它的左侧运算对象,并且是一个左值。
int k = 0;
k = {3.14};错误,窄化转换
赋值运算满足右结合率
a = a op b
a += b递增和递减运算符
j = ++i;j得到递增之后的值
j = i++;j得到递增之前的值
除非必须,建议使用前置版本,这样更快,不用保留前值
p++,等同于(p++),推荐使用的简洁写法
*pbeg = toupper(*pbeg++);该行为未定义,这是由于运算顺序未定义造成的成员访问运算符,点运算符和箭头运算符
访问运算符的优先级高于解引用运算符条件运算符
cond?expr1:expr2;
每走一小步,都是一大步。
2023年08月06日