欣乐

The eagles are coming!

导航

第五章 表达式

 

code:

 

 

 

// 第五章 表达式



// 1、算术操作符 ---------------------------------------------------


// 溢出
#include <iostream>
#include <string>
using namespace std;
int main()
{
  // max value if shorts are 8 bits
  short short_value = 32767;
  short ival = 1;
  // this calculation overflows
  short_value += ival;
  cout << "short_value: " << short_value << endl;
  return 0;
}


#include <iostream>
#include <string>
using namespace std;
int main()
{
  int ival1 = 21 / 6; //  integral result obtained by truncating the remainder
  int ival2 = 21 / 7; //  no remainder, result is an integral value
  cout << ival1 << ' ' << ival2 << endl;
  
  int ival = 42;
  double dval = 3.14;
  ival % 12; //  ok: returns 6
  // ival % dval; //  error: floating point operand

  21 % 6; //  ok: result is 3
  21 % 7; //  ok: result is 0
   - 21 %  - 8; //  ok: result is -5
  21 / 6; //  ok: result is 3
  21 / 7; //  ok: result is 3
   - 21 /  - 8; //  ok: result is 2

  int i = 21 %  - 5; //  machine-dependent: result is 1 or -4 //1
  int j = 21 /  - 5; //  machine-dependent: result -4 or -5 //-4
  cout << i << ' ' << j << endl;

  return 0;
}



// 2、关系操作符和逻辑操作符 --------------------------------------------------------


// mytest:short-circuit evaluation

#include <iostream>
#include <string>
using namespace std;
int main()
{
  if( 1>2 && 2/0<0 )
    cout << "haha" << endl;
  else cout << "test short-circuit evaluation" << endl;

  return 0;
}


// 短路求值应用
#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s("Expressions in C++ are composed...");
  string::iterator it = s.begin();
  // convert first word in s to uppercase
  while(it != s.end() && !isspace(*it)) // 越界检查,要写在&&前面(左边)
  {
    *it = toupper(*it); // toupper covered in section 3.2.4 (p. 88)
    ++it;
  }
  return 0;
}


// !
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
  vector<int>v(2,3);
  int x=0;
  if(!v.empty()) {
    x=*v.begin();
    cout << x;
  }
  
  return 0;
}


// 如果把多个关系操作符串接起来使用,结果往往出乎预料

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
  int i=3,j=1,k=2;
  cout << (i<j<k) << endl; //不应该串接使用关系操作符。但是有返回值
  cout << (i<j && j<k) << endl;
  
  return 0;
}


// 在Cpp中,true,false用得不多。因为在C中,非0即true。在Cpp中,true值为1
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
  int val=2;
  if(val==true) // 要避免这样写
    cout << "en,yes" << endl;
  if(val) // 要这样写
    cout << "right!" << endl;
  
  return 0;
}



// 3、位操作符 --------------------------------------------------------------

#include <iostream>
#include <string>
#include <vector>
#include <bitset>
using namespace std;

void print(unsigned char n)
{
  bitset<8> b(n);
  cout << b << endl;
}

int main()
{
  unsigned char bits=0227; //8进制
  print(bits);
  bits=~bits;
  print(bits);
  bits <<= 1; // left shift
  print(bits);
  bits <<= 2;
  print(bits);
  bits >>= 3; // right shift
  print(bits);
  
  return 0;
}


// and,or..
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
using namespace std;

void print(unsigned char n)
{
  bitset<8> b(n);
  cout << b << endl;
}

int main()
{
  unsigned char b1=0145;
  unsigned char b2=0257;
  unsigned char result=b1 & b2; // and
  print(b1);
  print(b2);
  print(result);
  cout<<endl;
  
  result=b1 | b2; // or
  print(result);
  cout<<endl;
  
  result=b1 ^ b2; // xor
  print(result);
  
  return 0;
}


// 比较
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
using namespace std;
const unsigned long n=30;

void print(unsigned long i)
{
  bitset<n> b(i);
  cout << b << endl;
}

int main()
{
  bitset<n> bits;
  unsigned long inttest=0;
  print(inttest);
  
  bits.set(27);
  inttest |= 1UL<<27;
  print(inttest);
  
  bits.reset(27);
  inttest &= ~(1UL<<27);
  print(inttest);
  
  bool status1,status2;
  status1=bits[27];
  status2=inttest & (1UL<<27);
  
  cout << bits << endl;
  
  return 0;
}



// 左结合

#include <iostream>
#include <string>
#include <vector>
#include <bitset>
using namespace std;

int main()
{
  cout << "hi" << " there" << endl;
  ( (cout << "hi") << " there" ) << endl;
  
  return 0;
}


// 优先级
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
using namespace std;

int main()
{
  cout << 42 + 10;   // ok, + has higher precedence, so the sum is printed
  cout << (10 < 42); // ok: parentheses force intended grouping; prints 1
  // cout << 10 < 42;   // error: attempt to compare cout to 42!
  
  return 0;
}



// 4、赋值操作符 -----------------------------------------------------------------------


#include <iostream>
#include <string>
#include <vector>
#include <bitset>
using namespace std;
int main()
{
  int ia[10];
  ia[0] = 0; // ok: subscript is an lvalue
  *ia = 0; // ok: dereference also is an lvalue
  int ival = 0; // result: type int value 0
  ival = 3.14159; // result: type int value 3 会有个警告
  cout << ival << endl;
  return 0;
}



// 赋值操作的右结合性
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
using namespace std;
int main()
{
  int ival, jval;
  ival = jval = 0; // ok: each assigned 0
  int *pval;
  // ival = pval = 0; // error: cannot assign the value of a pointer to an int
  string s1, s2;
  s1 = s2 = "OK"; // ok: "OK" converted to string
  return 0;
}


// 书中的 get_value() 应该是自定义函数
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
using namespace std;

int get_value()
{
  int t;
  cin>>t;
  return t;
}

int main()
{
  int i;
  while((i=get_value()) != 42 ) {
    cout << i << endl;
  }
  
  return 0;
}


// 谨防混淆相等操作符和赋值操作符
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
using namespace std;

int get_value()
{
  int t;
  cin>>t;
  return t;
}

int main()
{
  int i;
  //while((i=get_value())==6 ) // 仅当输入6时输出
  //while((i=get_value())=6 ) // 如果少写一个=,成了死循环
  while( 6 == (i=get_value()) ) // 把6写前面,是绝招
  {
    cout << i << endl;
  }
  
  return 0;
}


// 复合赋值操作符
/*
+=   -=   *=   /=   %=   // arithmetic operators
<<= >>=   &=   ^=   |=   // bitwise operators
*/



// 5、自增和自减操作符 ------------------------------------------------------------------------


// 养成使用前置操作这个好习惯,就不必操心性能差异的问题
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
using namespace std;

int main()
{
  int i = 0, j;
  j = ++i; // j = 1, i = 1: prefix yields incremented value
  j = i++; // j = 1, i = 2: postfix yields unincremented value
  int k = 3, t = 3;
  cout << ++k << endl;
  cout << t++ << endl;
  cout << endl;
  cout << k << endl;
  cout << t << endl;  
  
  return 0;
}



//后置操作符返回未加1的值
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
using namespace std;

int main()
{
  vector<int> v;
  int n=10;
  while(n>0)
    v.push_back(n--); // 先用,再减一 

  vector<int>::iterator iter=v.begin();
  while(iter != v.end())
    cout << *iter++ << endl; // 相当于 *(iter++) ,所以不会:(*iter)++
  
  return 0;
}



// 6、箭头操作符 ------------------------------------------------------------------------

// my test
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
using namespace std;

struct st {
  int i,j;
} s;

int main()
{
  st *p=&s;
  p->i=0;
  p->j=1;
  cout << s.i << ' ' << s.j << endl;
  
  return 0;
}



// 7、条件操作符 ------------------------------------------------------------------------------------


#include <iostream>
#include <string>
#include <vector>
#include <bitset>
using namespace std;

int main()
{
  int i=1,j=2,k=3,t;
  cout << ( i>j?i:j ) << endl; // 输出两者中较大值
  
  t=i>j?i:j;
  t=t>k?t:k;
  cout << t << endl; // 这样逻辑还比较清楚,求出三者中的最大值
  
  int max=i>j?i>k?i:k:j>k?j:k; // 不鼓励这样写,坑爹
  cout << max << endl;
  
  return 0;
}



// 8、sizeof操作符 ----------------------------------------------------------------------------------

// my test
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
#include "Sales_item.h"
using namespace std;

struct st {
  int i,j;
} s;

int ar[10];
char a[3][4];

int main()
{
  Sales_item item, *ps;
  st *pt=&s;
  
  cout << sizeof(Sales_item) << endl;
  cout << sizeof item << endl;  
  cout << sizeof *ps << endl;
  cout << sizeof ps << endl;
  cout << "//" << endl;
  
  cout << sizeof(st) << endl;
  cout << sizeof(s) << endl;
  cout << sizeof(*pt) << endl;
  cout << sizeof pt << endl;
  cout << sizeof pt->j << endl;
  cout << "//" << endl;
  
  cout << sizeof ar << endl;
  cout << sizeof *ar << endl;
  cout << "//" << endl;
  
  cout << sizeof a << endl;
  cout << sizeof *a << endl; //对两维数组a,*a得到的是一行
  cout << sizeof **a << endl; // 一行中的第一个元素
  cout << "//" << endl;
  
  char (*p)[18];
  cout << sizeof p << endl; // 一个指针,4个字节
  cout << sizeof *p << endl; // 指针指向的内存块,18个字节
  cout << sizeof **p << endl; // 内存块中的第一个元素,1个字节
  cout << "//" << endl;
  
  char (*pp)[4];
  pp=a;
  cout << sizeof a << endl; // 重大发现:数组名就是数组名,虽然从中可以得到头一个元素的指针
  cout << sizeof pp << endl; // 4:指针4个字节
  cout << sizeof *pp << endl; // 4:一行有4个字符,占4个字节
  
  return 0;
}



// 9、逗号操作符 --------------------------------------------------------------------

// 这种用法不太常用。一般逗号用于for循环控制
#include <iostream>
using namespace std;

int main()
{
  int i,j,k;
  k = ( i=1,j=2,i+j );
  cout << k << endl;
  
  return 0;
}



// 10、复合表达式的求值 ------------------------------------------------------------------

#include <iostream>
using namespace std;
int main()
{
  int temp = 3 * 4; // 12
  int temp2 = temp / 2; // 6
  int temp3 = temp2 + 6; // 12
  int result = temp3 + 2; // 14
  cout << result << endl;
  // parentheses on this expression match default precedence/associativity
  cout << ((6+((3 *4) / 2)) + 2) << endl; // prints 14
  // parentheses result in alternative groupings
  cout << (6+3)*(4 / 2+2) << endl; // prints 36
  cout << ((6+3) *4) / 2+2 << endl; // prints 20
  cout << 6+3 * 4 / (2+2) << endl; // prints 9
  return 0;
}


/*
1. 如果有怀疑,则在表达式上按程序逻辑要求使用圆括号强制操作数的组合。
2. 如果要修改操作数的值,则不要在同一个语句的其他地方使用该操作数。如果必须使用改变的值,则把该表达式分割成两个独立语句:在一个语句中改变该操作数的值,再在下一个语句使用它。
*/



// 11、new和delete表达式 --------------------------------------------------------------------------

#include <iostream>
using namespace std;
int main()
{
  int i(1024);              // value of i is 1024
  int *pi = new int(1024);  // object to which pi points is 1024
  string s(10, '9');        // value of s is "9999999999"
  string *ps = new string(10, '9');  // *ps is "9999999999"

  return 0;
}


#include <iostream>
using namespace std;
int main()
{
  //对于类类型的对象,用该类的默认构造函数初始化;而内置类型的对象则无初始化。
  string *ps = new string; // initialized to empty string
  int *pi = new int;       // pi points to an uninitialized int
  cout << *ps << endl;
  cout << *pi << endl;

  return 0;
}


// 总要初始化。。
#include <iostream>
using namespace std;
int main()
{
  string *ps = new string();  // initialized to empty string
  int *pi = new int();  // pi points to an int value-initialized to 0
  //cls *pc = new cls();  // pc points to a value-initialized object of type cls

  cout << *ps << endl;
  cout << *pi << endl;
  
  delete ps;
  delete pi;
  
  return 0;
}


//零值指针的删除
#include <iostream>
using namespace std;
int main()
{
  int *ip = 0;
  delete ip; // ok: always ok to delete a pointer that is equal to 0
  
  return 0;
}



#include <iostream>
using namespace std;
int main()
{
  //与其他常量一样,动态创建的 const 对象必须在创建时初始化,并且一经初始化,其值就不能再修改。
  // allocate and initialize a const object
  const int *pci = new const int(1024);
  // allocate default initialized const empty string
  const string *pcs = new const string;
  cout << *pci << endl;
  
  delete pci;
  pci=0;
  delete pcs;
  pcs=0;
  
  return 0;
}



// 12、类型转换 ----------------------------------------------------------------------------------------


#include <iostream>
using namespace std;
int main()
{
  int ival = 0;
  ival = 3.541 + 3; // typically compiles with a warning 隐式类型转换
  cout << ival << endl;
  return 0;
}


// 何时发生隐式类型转换

#include <iostream>
using namespace std;
int main()
{
  int ival(3);
  double dval(3.14);
  ival >= dval;  // ival converted to double

  if(ival) ;  // ival converted to bool
  while(cin>>ival) break; // cin converted to bool
    
  int i = 3.14; // 3.14 converted to int
  int *ip;
  ip = 0; // the int 0 converted to a null pointer of type int *

  return 0;
}



#include <iostream>
using namespace std;
int main()
{
  bool flag;
  char cval;
  short sval;
  unsigned short usval;
  int ival;
  unsigned int uival;
  long lval;
  unsigned long ulval;
  float fval;
  double dval;
  3.14159L + 'a'; // promote 'a' to int, then convert to long double
  dval + ival; // ival converted to double
  dval + fval; // fval converted to double
  ival = dval; // dval converted (by truncation) to int
  flag = dval; // if dval is 0, then flag is false, otherwise true
  cval + fval; // cval promoted to int, that int converted to float
  sval + cval; // sval and cval promoted to int
  cval + lval; // cval converted to long
  ival + ulval; // ival converted to unsigned long
  usval + ival; // promotion depends on size of unsigned short and int
  uival + lval; // conversion depends on size of unsigned int and long
  return 0;
}



#include <iostream>
using namespace std;
int main()
{
  //大多数情况下数组都会自动转换为指向第一个元素的指针
  int ia[10];    // array of 10 ints
  int *ip = ia;  // convert ia to pointer to first element
  
  int a[3][4];
  int (*pa)[4] = a;
  int *pb = *a;
  cout << sizeof(*pa) << endl; // pa指向4个整数的一个块
  cout << sizeof(*pb) << endl; // pb指向第一个元素,即一个整数
  return 0;
}


// bool 还是数。。
#include <iostream>
using namespace std;
int main()
{
  bool b = true;
  int ival = b; // ival == 1
  cout << ival << endl;
  
  double pi = 3.14;
  bool b2 = pi; // b2 is true
  cout << b2 << endl;
  pi = false; // pi == 0
  cout << pi << endl;

  return 0;
}



#include <iostream>
using namespace std;
int main()
{
  int i(8);
  const int ci = 0;
  const int &j = i;   // ok: convert non-const to reference to const int
  const int *p = &ci; // ok: convert address of non-const to address of a const
  cout << i << ' ' << j << endl; // 上面这句,常量地址?不理解
  // j=0; // error:相当于变量i变常量j,
  return 0;
}



#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s;
  while( cin >> s ) // cin总有返回值,直到读不成功,返回0
    cout << s << endl;
    
  return 0;
}


// 强制类型转换(cast)
#include <iostream>
#include <string>
using namespace std;
int main()
{
  double dval(1.23);
  int ival(1);
  ival *= dval; // ival = ival * dval
  cout << ival << endl;
  ival *= static_cast<int>(dval); // converts dval to int
  cout << ival << endl;
    
  return 0;
}


// 当需要将一个较大的算术类型赋值给较小的类型时,使用强制转换非常有用。
#include <iostream>
#include <string>
using namespace std;

int main()
{
  double d = 98.9;
  // cast specified to indicate that the conversion is intentional
  char ch = static_cast<char>(d);
  cout << ch << endl;
  return 0;
}


// 强烈建议程序员避免使用强制类型转换,不依赖强制类型转换也能写出很好的 C++ 程序。

 

 

 

 

TOP

 

posted on 2014-11-10 20:52  欣乐  阅读(173)  评论(0编辑  收藏  举报