Exercise 4.1

1
2
// it's 105.

Exercise 4.2

1
2
3
// *vec.begin() equals to *(vec.begin())
// *vec.begin() + 1 equals to (*(vec.begin())) + 1

Exercise 4.3

1
2
// That is acceptable, it is too strict under an orded evaluation order, complier left it blank to allow users to diy, it's more flexible.

Exercise 4.4

1
2
3
4
5
6
int main()
{
  int i = 12 / 3 * 4 + 5 * 15 + 24 % 4 / 2; // 91
  std::cout << i << std::endl;
}

Exercise 4.5

1
2
3
4
5
6
7
8
9
int main()
{
  int i = -30 * 3 + 21 / 5;	// -86
  int j = -30 + 3 * 21 / 5;	// -18
  int k = 30 / 3 * 21 % 5;	// 0
  int x = -30 / 3 * 21 % 4;	// -2
  cout << i << " " << j << " " << k << " " << x << endl;
}

Exercise 4.6

1
2
3
4
5
6
7
8
9
int main()
{
  int i;
  cout << "Please enter an integer: " << endl;
  cin >> i;
  if(i % 2) cout << i << " is odd" << endl;
  else cout << i << " is even" << endl;
}

Exercise 4.7

1
2
3
4
5
6
7
8
9
// overflow means that one computed result is beyond the representation range of one certain type
int main()
{
  int i = 2147483648;
  unsigned j = 4294967296;
  char k = 256;
  std::cout << i << " " << j << " " << k << std::endl;
}

Exercise 4.8

1
2
3
4
// && operator: if the left operand is flase, there is no need to compute the right operand
// || operator: if the left operand is true, there is no need to compute the right operand
// == operator: there is no order

Exercise 4.9

1
2
3
4
5
6
int main()
{
  const char *cp = "Hello World";
  if(cp && *cp) return 0;	// check whether the pointer a nullptr, if not so, check whether the char object cp points to is an null char or not.
}

Exercise 4.10

1
2
3
4
5
6
7
8
int main()
{
  int i;
  cout << "Please enter integer number one by one succeded by enter: "
       << endl;
  while(cin >> i && i != 42) continue;
}

Exercise 4.11

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
int main()
{
  int a, b, c, d;
  cout << "Please enter four integer numbers in descending order: "
       << endl;
  cin >> a >> b >> c >> d;
  if(a > b && b > c && c > d) cout << "Good boy" << endl;
  else cout << "False" << endl;
}

Exercise 4.12

1
2
// i, j and k are integers, expression i != j < k means that check whether i equals to the result of expression j < k, whose value depends on whether j is smaller than k.

Exercise 4.13

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
int main()
{
  int i;
  double d;
  d = i = 3.5;			// d = 3.0, i = 3
  cout << d << " " << i << endl;
  i = d = 3.5;			// d = 3.5, i = 3
  cout << d << " " << i << endl;
}

Exercise 4.14

1
2
3
// if(42 = i) // ... illegal, 42 could not be a left operand, 42 as a literal type value could only be treated as right operand
// if(i = 42) // .. legal, this condition is always true.

Exercise 4.15

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
int main()
{
  double dval;
  int ival;
  int *pi;
  // dval = ival = pi = 0; illegal, type int* could not be converted to int;
  pi = 0;
  dval = ival = 0;
}

Exercise 4.16

1
2
3
// if(p = getPtr() != 0) the expression inside could be read as p = (getPtr() ! = 0); p's value is the value converted from a bool value computed from the right expression, which is unexpected. if((p = getPtr()) != 0) would be ok.
// if(i = 1024) the expression inside is an assignment, the return result of which is the left operand i, that is not illegal, but the initial purpose is to check if i equals to 1024 and make variable i unchanged, so if(i == 1024) is the right solution.

Exercise 4.17

1
2
3
// pre ++ operator increases the operand by 1 and then return the object as a left value
// rear ++ operator first keeps the copy of value of the operand, then increases the operand by 1, at last returns the original stored value as a right value.

Exercise 4.18

1
2
// if pre ++ operator applied, the program woould miss the first element in the vector, and in case that there is no negative value in the vector, it would run into the off-the-end element of this vector, which would cause an error.

Exercise 4.19

1
2
3
4
5
6
7
8
// ptr int*, vec vector<int>, ival int
// ptr != 0 && *ptr++ ptr is not a nullptr and the int value pointed by ptr is not zero
// ival++ && ival if ival's original value is not zero and ival's new value is not zero after increased it by 1
// vec[ival++] <= vec[ival] illegal due to the <= operator not implemented the order of operands evaluation, and the operand modify the value of variable ival, this behavior is undefined; could be changed like this:
// int i = vec[ival];
// int j = vec[++ival];
// vec[j] <= vec[i];

Exercise 4.20

1
2
3
4
5
6
7
8
// iter vector<string>::iterator
// *iter++, legal, increase iterator iter by 1, get the string element which is pointed by the original iter's content.
// (*iter)++, get the string which is pointed by iter, then increase this string by 1, return the original string value; illegal, string object does not support rear ++ operator
// *iter.empty(), illegal, that means *(iter.empty()), for that iterator does not have empty() as a member.
// iter->empty(), legal, that means (*iter).empty()
// ++*iter, illegal, the evaluation order is from right to left, while the string type object does not support pre ++ operator
// iter++->empty() legal, get the string object the original iterator iter points to, call it's member function empty(), increase iter by 1

Exercise 4.21

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
int main()
{
  vector<int> iv;
  int i;
  cout << "Please enter integer numbers: " << endl;
  while(cin >> i) iv.push_back(i);
  for(auto &i : iv) ((i % 2) ? (i *= 2) : i);
  for(auto &i : iv) cout << i << endl;
}

Exercise 4.22

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main()
{
  unsigned grade;
  cout << "Please enter a grade: " << endl;
  cin >> grade;
  string finalgrade;
  // that's simpler and better
  // finalgrade = (grade > 90) ? "high pass"
  //   : (grade > 60 && grade < 75) ? "low pass"
  //   : (grade < 60) ? "fail" : "pass";
  if(grade > 90) finalgrade = "high pass";
  else
    {
      if(grade > 60 && grade < 75) finalgrade = "low pass";
      else
      {
	if(grade < 60) finalgrade = "fail";
	else finalgrade = "pass";
      }
    }
  cout << finalgrade << endl;
}

Exercise 4.23

1
2
3
4
5
6
7
// string s = "world";
// string p1 = s + s[s.size() - 1] == 's' ? "" : "s";
// equals to (s + s[s.size() - 1]) == 's' ? "" : "s"
// which compares a string object with a char object
// which is illegal
// string p1 = s + (s[s.size() - 1] == 's' ? "" : "s");

Exercise 4.24

1
2
3
4
5
// if operands in ?: operator expression combined from left to right
// the epressions would be changed to
// finalgrade = ((grade > 90) ? "high pass" : (grade < 60)) ? "fail" : "pass";
// which would produce an unexpected behaviour, if grade > 90, the first condition's result would be "high pass", then the finalgrade would always be fail

Exercise 4.25

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 'q' 01110001
// ~'q' << 6
// 11111111111111111111111110001110 << 6
// 11111111111111111110001110000000
int main()
{
  char q = 'q';
  std::cout << (~q << 6) << std::endl;
}

Exercise 4.26

1
2
3
4
// on certain machine, int type object consumes 16 bits
// if so, quiz1 would just consume 16 bits, it could not be used to represent the results of tests of 30 students
// 1U << 27 would be an undefined behviour

Exercise 4.27

1
2
3
4
5
6
7
8
9
int main()
{
  unsigned long ul1 = 3, ul2 = 7;
  cout << (ul1 & ul2) << endl;	// 3
  cout << (ul1 | ul2) << endl;  // 7
  cout << (ul1 && ul2) << endl; // 1
  cout << (ul1 || ul2) << endl; // 1
}

Exercise 4.28

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
int main()
{
  cout << "bool " << sizeof(bool) << endl;
  cout << "char " << sizeof(char) << endl;
  cout << "wchar_t " << sizeof(wchar_t) << endl;
  cout << "char16_t " << sizeof(char16_t) << endl;
  cout << "char32_t " << sizeof(char32_t) << endl;
  cout << "short " << sizeof(short) << endl;
  cout << "int " << sizeof(int) << endl;
  cout << "long " << sizeof(long) << endl;
  cout << "long long " << sizeof(long) << endl;
  cout << "float " << sizeof(float) << endl;
  cout << "double " << sizeof(double) << endl;
  cout << "long double " << sizeof(long double) << endl;
}

Exercise 4.29

1
2
3
4
5
6
7
8
int main()
{
  int x[10];
  int *p = x;
  cout << sizeof(x)/sizeof(*x) << endl; // 10
  cout << sizeof(p)/sizeof(*p) << endl; // 2, but it depends on certain machine, as my pc is 64-bits arch, a pointer consumes 64 bits, which is 8 bytes, so this expression causes undefined behaviour.
}

Exercise 4.30

1
2
3
4
5
// sizeof x + y; (sizeof x) + y
// sizeof p->mem(); sizeof(p->mem())
// sizeof a < b; (sizeof a) < b
// sizeof f(); sizeof(f()), while 'f()' returns 'void' this is undefined.x

Exercise 4.31

1
2
3
4
// is there any difference between pre ++ operator and rear ++ operator applied int this program?
// no influence on the output
// use prefix ++ operator is a better habit, that's all.

Exercise 4.32

1
2
// use ix !- size and ptr != ia + size to go through all elements in array ia.

Exercise 4.33

1
2
3
4
5
// someValue ? ++x, ++y : --x, --y
// due to the mose lowesr precedence of the ',' operator
// (someValue ? ++x, ++y : --x), --y
// could be treated as: someValue ? (++x, y) : (--x, --y)

Exercise 4.34

1
2
3
4
// if (fval); float -> bool
// dval = fval + ival; int -> float, float -> double
// dval + ival * cval; char -> int, int -> double

Exercise 4.35

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
int main()
{
  char cval;
  int ival;
  unsigned int ui;
  float fval;
  double dval;
  cval = 'a' + 3;		// implicit conversion, char -> int, int -> char
  fval = ui - ival * 1.0;	// ~, int -> double, unsigned int -> double, double -> float
  dval = ui * fval;		// ~, unsigned int -> float, float -> double
  cval = ival + fval + dval;	// ~, int -> float, float -> double, double -> char
}

Exercise 4.36

1
2
3
4
5
6
7
int main()
{
  int i = 3;
  double d = 3.14;
  i *= static_cast<int>(d);
}

Exercise 4.37

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
int main()
{
  int i;
  double d;
  const string *ps;
  char *pc;
  void *pv;
  pv = static_cast<void*>(const_cast<string*>(ps));
  i =  static_cast<int>(*pc);
  pv = static_cast<void*>(&d);
  pc = static_cast<char*>(pv);
}

Exercise 4.38

1
2
3
// double slope = static_cast<double>(j/i);
// same as expression: double slope = j / i;