forked from jaege/Cpp-Primer-5th-Exercises
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add solutions to all exercises in chapter 4.
- Loading branch information
Jaege
committed
Jan 12, 2016
1 parent
6f6b6f3
commit bdf9a9d
Showing
38 changed files
with
409 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#include <iostream> | ||
|
||
int main() { | ||
std::cout << (5 + 10 * 20 / 2) << std::endl; // 105 | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#include <iostream> | ||
|
||
int main() { | ||
int i; | ||
while (std::cin >> i && i != 42) { /* do something */ } | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#include <iostream> | ||
|
||
int main() { | ||
int a, b, c, d; | ||
std::cin >> a >> b >> c >> d; | ||
if (a > b && b > c && c > d) { /* do something */ } | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
The expression `i != j < k` is the same with `i != (j < k)`. | ||
|
||
First, `j < k` is evaluated and the result is a `bool`(either `true` or `false`). | ||
|
||
Second, `i != true` or `i != false` is evaluated. Since `i` is an `int`, the `bool` will be converted to `int`, which means `i != 1` or `i != 0` is evaluated. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#include <iostream> | ||
|
||
int main() { | ||
int i; | ||
double d; | ||
d = i = 3.5; | ||
std::cout << d << ' ' << i << std::endl; // 3 3 | ||
i = d = 3.5; | ||
std::cout << d << ' ' << i << std::endl; // 3.5 3 | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
`if (42 = i) // ...` is an error. | ||
|
||
`if (i = 42) // ...` will first assign 42 to `i` and yield the value of `i` as the condition expression of `if` statement. And because 42 is nonzero, the condition will be `true`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
int main() { | ||
double dval; | ||
int ival; | ||
int *pi; | ||
//dval = ival = pi = 0; | ||
// the type of `pi` is `int *` which cannot be converted to `int` | ||
dval = ival = 0; | ||
pi = 0; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
`if (p = getPtr() != 0)` is the same with `if (p = (getPtr() != 0))` and should be `if ((p = getPtr()) != 0)`. | ||
|
||
`if (i = 1024)` may be `if (i == 1024)`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
The prefix increment operator increases the operand and return the operand itself as an lvalue. | ||
|
||
The postfix increment operator increases the operand and return a copy of the operand's original value as an rvalue. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
The loop will print all elements except the first one in the vector, and also try to dereference to one past the last element, which is an error. Also, if there is no negative value in the vector, the loop will continue to dereference whatever in memeory until a negative value is found, which is a disaster. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
(a) | ||
ptr != 0 && *ptr++ | ||
|
||
The expression means if `ptr` is not null pointer, then point to whatever next in memory and return a copy of the value of the original `int` variable. Since we don't know what next in memory is, it will be an error if we dereference `ptr` after the expression. The expression may be: | ||
ptr != 0 && (*ptr)++ | ||
|
||
(b) | ||
ival++ && ival | ||
|
||
The expression first increases the value of `ival` and return a copy of the original value, then if the original value is nonzero, the right hand operand `ival`(the incremented one) is evaluated, if it is also nonzero, the expression is `true`, else it is `false. | ||
|
||
(c) | ||
vec[ival++] <= vec[ival] | ||
|
||
The order of evaluation of `<=` operator's operands is undefined. The expression should be: | ||
++ival, vec[ival] <= vec[ival + 1] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
(a) | ||
* vec.begin() ==> * ((vec.begin)()) | ||
|
||
The order is: member selector, function call, dereference. | ||
|
||
(b) | ||
* vec.begin() + 1 ==> ( * ((vec.begin)())) + 1 | ||
|
||
The order is: member selector, function call, dereference, add. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
(a) `*iter++;` is legal. The expression moves `iter` to point to the next element and returns the value of the original element. | ||
|
||
(b) `(*iter)++` is not legal. The expression means increasing value of the element, but the value is a `string` and `string` does not have `++` operator. | ||
|
||
(c) `*iter.empty()` is not legal. Because `iter` is an iterator and has no member named `empty`. | ||
|
||
(d) `iter->empty()` is legal. The expression means check if the string pointed by `iter` is empty. | ||
|
||
(e) `++*iter` is not legal. The expression means increasing value of the element, but the value is a `string` and `string` does not have `++` operator. | ||
|
||
(f) `iter++->empty()` is legal. The expression means move `iter` to point to the next element and check if that `string` is empty. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#include <iostream> | ||
#include <vector> | ||
|
||
int main() { | ||
std::vector<int> iv; | ||
int i; | ||
while (std::cin >> i) | ||
iv.push_back(i); | ||
for (auto &elem : iv) | ||
elem = elem % 2 ? elem + elem : elem; | ||
for (const auto &elem : iv) | ||
std::cout << elem << ' '; | ||
std::cout << std::endl; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#include <iostream> | ||
|
||
int main() { | ||
int grade; | ||
std::cin >> grade; | ||
|
||
std::cout << ( | ||
grade > 90 ? "high pass" | ||
: grade > 75 ? "pass" | ||
: grade >= 60 ? "low pass" | ||
: "fail" | ||
) << std::endl; | ||
|
||
// Note that the conditional operator is right associative, meaning that the | ||
// operands are grouped from right to left. | ||
|
||
if (grade > 90) | ||
std::cout << "high pass" << std::endl; | ||
else if (grade > 75) | ||
std::cout << "pass" << std::endl; | ||
else if (grade >= 60) | ||
std::cout << "low pass" << std::endl; | ||
else | ||
std::cout << "fail" << std::endl; | ||
|
||
// The `if` statements are relatively easy to understand when the conditions | ||
// do not have much braches. | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#include <string> | ||
using std::string; | ||
|
||
int main() { | ||
string s = "word"; | ||
//string pl = s + s[s.size() - 1] == 's' ? "" : "s"; | ||
string pl = s + (s[s.size() - 1] == 's' ? "" : "s"); | ||
|
||
// The precedence of the conditional operator is lower than arithmetic operator. | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
If the operator were left associative, then the expression | ||
|
||
grade > 90 ? "high pass" | ||
: grade < 60 ? "fail" : "pass"; | ||
|
||
would be evaluated as: | ||
|
||
(grade > 90 ? "high pass" : grade < 60) ? "fail" : "pass"; | ||
|
||
which means: | ||
|
||
- if the grade is greater than 90, then return "high pass", which is not empty string and evaluate to `true`, then return "fail"; | ||
- else evaluates `grade < 60` and takes the result as the condition for the second conditional operator, which means if the grade is less than 60, return "fail", else return "pass". |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
`~'q' << 6` is the same as `(~'q') << 6`. | ||
|
||
1. The operand of `~` operator is a "small integer"(`char` here), thus its value is first promoted to a larger integral type(`int` here). | ||
|
||
'q' = 01110001 promoted to | ||
00000000 00000000 00000000 01110001 | ||
|
||
2. After the `~` operator evaluated, | ||
|
||
~'q' 11111111 11111111 11111111 10001110 | ||
|
||
3. Left shift, | ||
|
||
~'q' << 6 11111111 11111111 11100011 10000000 | ||
|
||
4. The result is -7296. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
The standard guarantees the minimum size of `int` is 16 bits, and the minimum size of `long` is 32 bits. Since the teacher has 30 students in a class, which needs at least 30 bits, `int` would be not enough to hold all the results. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#include <iostream> | ||
|
||
int main() { | ||
unsigned long ul1 = 3, ul2 = 7; | ||
|
||
std::cout << (ul1 & ul2) << std::endl; // 3 | ||
std::cout << (ul1 | ul2) << std::endl; // 7 | ||
std::cout << (ul1 && ul2) << std::endl; // 1, means true | ||
std::cout << (ul1 || ul2) << std::endl; // 1, means true | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#include <iostream> | ||
|
||
int main() { | ||
std::cout << "char " << sizeof(char) << std::endl; | ||
std::cout << "wchar_t " << sizeof(wchar_t) << std::endl; | ||
std::cout << "char16_t " << sizeof(char16_t) << std::endl; | ||
std::cout << "char32_t " << sizeof(char32_t) << std::endl; | ||
std::cout << "short " << sizeof(short) << std::endl; | ||
std::cout << "int " << sizeof(int) << std::endl; | ||
std::cout << "long " << sizeof(long) << std::endl; | ||
std::cout << "long long " << sizeof(long long) << std::endl; | ||
std::cout << "float " << sizeof(float) << std::endl; | ||
std::cout << "double " << sizeof(double) << std::endl; | ||
std::cout << "long double " << sizeof(long double) << std::endl; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#include <iostream> | ||
|
||
int main() { | ||
int x[10]; | ||
int *p = x; | ||
std::cout << sizeof(x) / sizeof(*x) << std::endl; // 10 | ||
std::cout << sizeof(p) / sizeof(*p) << std::endl; // the size of a pointer / the size of an int | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
I think that is an acceptable trade-off. When an expression refers to and change the same object, we can always seperate that expression into several expressions to avoid the situation except where: | ||
- The operator involved is one of _and `&&`, or `||`, conditional `?:`, comma `,`_ operator, | ||
- The subexpression that change the operand is itself the operand of another subexpression. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
(a) `sizeof(x) + y` | ||
(b) `sizeof(p->mem[i])` | ||
(c) `sizeof(a) < b` | ||
(d) `sizeof(f())` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#include <iostream> | ||
#include <vector> | ||
|
||
int main() { | ||
std::vector<int> ivec(10); | ||
std::vector<int>::size_type cnt = ivec.size(); | ||
for (std::vector<int>::size_type ix = 0; ix != ivec.size(); ++ix, --cnt) | ||
ivec[ix] = cnt; | ||
for (const auto &e : ivec) | ||
std::cout << e << " "; | ||
std::cout << std::endl; | ||
|
||
// Because we don't need the value returned by postfix operator, and making a | ||
// copy of an object may be a heavy operation, so prefix operator is prefered | ||
// here. | ||
|
||
cnt = ivec.size(); | ||
for (std::vector<int>::size_type ix = 0; ix != ivec.size(); ix++, cnt--) | ||
ivec[ix] = cnt; | ||
for (const auto &e : ivec) | ||
std::cout << e << " "; | ||
std::cout << std::endl; | ||
|
||
// The results are same. | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
int main() { | ||
constexpr int size = 5; | ||
int ia[size] = {1, 2, 3, 4, 5}; | ||
for (int *ptr = ia, ix = 0; ix != size && ptr != ia + size; ++ix, ++ptr) { | ||
/* some code */ | ||
} | ||
|
||
// First, the loop created a pointer `ptr` point to the first element of the | ||
// array `ia` and an index `ix`. | ||
// | ||
// Then the loop will check if the index is at one past the last of the array | ||
// and if the pointer point to the element at one past the last of the array, | ||
// if these are not true, the loop continues. | ||
// | ||
// Every time, the index will increase 1 and the pointe will move to point | ||
// the next element. | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
The expression | ||
|
||
sameValue ? ++x, ++y : --x, --y | ||
|
||
is the same as | ||
|
||
(sameValue ? (++x, ++y) : --x), --y | ||
|
||
Then it will be easy to notice that whatever `sameValue` evaluated, `--y` will always be evaluated. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
(a) `fval` is converted to `bool`. | ||
(b) `ival` is converted to `float`, then added to `fval`, finally the result is converted to `double`. | ||
(c) `cval` is promoted to `int`, then multiplied by `ival`, then the result is converted to `double`, then added to `dval`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
int main() { | ||
char cval = 0; | ||
int ival = 0; | ||
unsigned int ui = 0; | ||
float fval = 0; | ||
double dval = 0; | ||
|
||
cval = 'a' + 3; | ||
// 'a' is promoted to `int`, then added to `3`, then converted to `char`. | ||
|
||
fval = ui - ival * 1.0; | ||
// `ival` is converted to double, then multiplied by `1.0`. The result is | ||
// converted to `unsigned int`, then subtracted by `ui`. The result is | ||
// converted to `float`, then assigned to `fval`. | ||
|
||
dval = ui * fval; | ||
// Since `float` usually has more bits then `unsigned int`, `ui` is converted | ||
// to `float`, then multiplied by `fval`. The result is converted to | ||
// `double`, then assigned to `dval`. | ||
|
||
cval = ival + fval + dval; | ||
// `ival` is converted to `float`, then added to `fval`. The result is | ||
// converted to `double`, then added to `dval`. The result is converted to | ||
// `char`, then assigned to `cval`. | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
int main() { | ||
int i = 0; | ||
double d = 0; | ||
i *= static_cast<int>(d); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#include <string> | ||
|
||
int main() { | ||
int i = 0; | ||
double d = 0; | ||
std::string str("some string"); | ||
const std::string *ps = &str; | ||
char c = 'c'; | ||
char *pc = &c; | ||
void *pv; | ||
|
||
//pv = (void*)ps; | ||
pv = static_cast<void *>(const_cast<std::string *>(ps)); | ||
//pv = const_cast<std::string *>(ps); // Also work. | ||
|
||
//i = int(*pc); | ||
i = static_cast<int>(*pc); | ||
|
||
//pv = &d; | ||
pv = static_cast<void *>(&d); | ||
|
||
//pc = (char*) pv; | ||
pc = static_cast<char *>(pv); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
The expression first did integral division `j / i`, then converted the result to `double` and assigned it to `slope`. The result is the same as `double slope = j / i;`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#include <iostream> | ||
|
||
int main() { | ||
// (((12 / 3) * 4) + (5 * 15)) + ((24 % 4) / 2) = 91 | ||
std::cout << 12 / 3 * 4 + 5 * 15 + 24 % 4 / 2 << std::endl; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#include <iostream> | ||
|
||
int main() { | ||
std::cout << -30 * 3 + 21 / 5 << std::endl; // -86 | ||
std::cout << -30 + 3 * 21 / 5 << std::endl; // -18 | ||
std::cout << 30 / 3 * 21 % 5 << std::endl; // 0 | ||
std::cout << -30 / 3 * 21 % 4 << std::endl; // -2 | ||
|
||
return 0; | ||
} |
Oops, something went wrong.