C++primer-learning-notes-chapter4,5

239 阅读3分钟

表达式基础

  • 左值和右值:左值可以在表达式左边,右值不能。当一个对象被用作右值的时候,用的是对象的值(内容); 被用做左值时,用的是对象的身份(在内存中的位置)。
  • 逻辑与,逻辑或运算符的短路求值问题:逻辑与运算符和逻辑或运算符都是先求左侧运算对象的值再求右侧运算对象的值,当且仅当左侧运算对象无法确定表达式的结果时才会计算右侧运算对象的值。
  • if(i<j<k)是拿i<j的布尔值和k比较,应该用if(i<j && j<k){}

赋值运算符

  • 如果赋值运算的左右侧运算对象类型不同,则右侧运算对象将转换成左侧运算对象的类型。
  • 赋值运算符满足右结合律,这点和其他二元运算符不一样。 ival = jval = 0;等价于ival = (jval = 0);
  • 赋值运算优先级比较低。

递增递减运算符

  • 两种运算符必须作用域左值运算对象,前置版本将对象本身作为左值返回,后置版本则将对象原始值的副本作为右值返回。
  • 除非必须,否则不用递增递减运算符的后置版本。
  • 后置递增运算符返回初始的未加1的值。
cout<<*iter++<<endl; //等价于*(iter++),把iter的值加1,然后返回iter的初始值的副本作为求值结果

cout<<*iter<<endl;
++iter;
while(beg!=s.end() && !isspace(*beg))
    *beg = toupper(*beg++); //错误,该赋值语句未定义。左右两端都用到了beg,右侧还改变了其值。

条件运算符

string finalgrade = (grade<60) ? "fail" : "pass";
finalgrade = (grade>90) ? "high pass" : (grade<60)? "fail" : "pass";
  • 在cout中使用条件运算符注意括号。

位运算符

sizeof运算符

  • 返回一条表达式或一个类型名字所占的字节数。返回的类型是 size_t。
  • 两种形式: sizeof (type)和 sizeof expr

类型转换


隐式类型转换

  • 比 int类型小的整数值先提升为较大的整数类型。
  • 条件中,非布尔转换成布尔。
  • 初始化中,初始值转换成变量的类型。
  • 算术运算或者关系运算的运算对象有多种类型,要转换成同一种类型。
  • 函数调用时。

显式类型转换(尽量避免)

  • static_cast:任何明确定义的类型转换,只要不包含底层const,都可以使用。 double slope = static_cast(j);
void* p = &d;
double *dp = static_cast<double*>(p);
  • const_cast:只能改变运算对象的底层const,一般可用于去除const性质。
const char *pc;
char *p = const_cast<char*>(pc); //对象本身是常量,用const_cast执行写操作会产生未定义的后果。
const char *cp;
char *q = static_cast<char*>(cp); //错误,static_cast不能转换掉const性质
static_cast<string>(cp);  //正确:字符串字面值转换成string类型
const_cast<string>(cp); //错误:const_cast只改变常量属性
  • reinterpret_cast:通常为运算对象的位模式提供低层次上的重新解释.

语句

迭代语句

  • for循环和范围for语句