-
Notifications
You must be signed in to change notification settings - Fork 246
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 6.
- Loading branch information
Jaege
committed
Jan 15, 2016
1 parent
baf2b49
commit caf2897
Showing
59 changed files
with
771 additions
and
10 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
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 **parameter** is the variable in the parentheses after the function name when we defining the function and used inside a function. | ||
|
||
An **argument** is the variable in the parentheses after the function name when we calling the function, and it is used to initialize the parameter of the function. |
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> | ||
|
||
void swapInt(int *a, int *b) { | ||
int tmp = *a; | ||
*a = *b; | ||
*b = tmp; | ||
} | ||
|
||
int main() { | ||
int a, b; | ||
std::cin >> a >> b; | ||
swapInt(&a, &b); | ||
std::cout << a << " " << b << 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,15 @@ | ||
#include <iostream> | ||
|
||
void resetInt(int &i) { | ||
i = 0; | ||
} | ||
|
||
int main() { | ||
int a; | ||
std::cin >> a; | ||
std::cout << "before reset: " << a << std::endl; | ||
resetInt(a); | ||
std::cout << "after reset: " << a << 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,19 @@ | ||
#include <iostream> | ||
|
||
void swapInt(int &a, int &b) { | ||
int tmp = a; | ||
a = b; | ||
b = tmp; | ||
} | ||
|
||
int main() { | ||
int a, b; | ||
std::cin >> a >> b; | ||
swapInt(a, b); | ||
std::cout << a << " " << b << std::endl; | ||
|
||
// The reference version looks like easier to use, but the user must know | ||
// from other source that the function will change the value of the argument. | ||
|
||
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 @@ | ||
`void f(T)` will pass the argument by value, which means in the function `f`, a copy of `T` will be made. | ||
|
||
`void f(T&)` will pass the argument by reference, which means in the function `f`, the same variable defined in the caller is used. |
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,21 @@ | ||
Reference parameters | ||
- Functions must use reference parameters to operate on objects of a type that cannot be copied. | ||
- Functions prefer to use reference parameters to operate on objects of large class types or large containers. | ||
- Functions should use reference parameters to return additional information via the reference parameters. | ||
|
||
void printStr(std::ostream &os, const std::string &str, bool &stat) { | ||
if (os << str) | ||
stat = true; | ||
else | ||
stat = false; | ||
} | ||
|
||
Nonreference parameters | ||
- Functions should use nonreference parameters when the value of the parameters may changed but should not affect the objects passed to the function. | ||
|
||
int sum(int n) { | ||
int sum = 0; | ||
while (n > 0) | ||
sum += n--; | ||
return sum; | ||
} |
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 @@ | ||
The function prototype is | ||
|
||
string::size_type find_char(const string &s, | ||
char c, | ||
string::size_type &occurs) | ||
|
||
`s` and `occurs` are both referecnes to avoid copy. | ||
|
||
`s` is `const` because it isn't changed inside function and a string literal can be used here. `occurs` is plain reference beacuse it is used to pass information (changed inside function). | ||
|
||
`c` is nonreference because copy a `char` is very cheap. It's fine to make it a `const` reference but not plain reference, because we don't want to accidentally change `c` inside function, and we may want to pass a `char` literal to the function. | ||
|
||
If `occurs` is made a reference to `const`, then we cannot get how many times the character `c` occurred in string `s`. |
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 parameter of the function should be `const string &s`. So that we can pass string literals or const strings to the function. |
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,29 @@ | ||
#include <string> | ||
#include <iostream> | ||
|
||
bool hasCapital(const std::string &s) { // Only ASCII | ||
for (auto &c : s) // `c` would be `const char &` since `s` is `const` | ||
if (c >= 'A' && c <= 'Z') | ||
return true; | ||
return false; | ||
} | ||
|
||
void toLowerStr(std::string &s) { // Only ASCII | ||
for (auto &c : s) | ||
if (c >= 'A' && c <= 'Z') | ||
c -= 'A' - 'a'; | ||
} | ||
|
||
// The parameters have different type, because in `hasCapital`, we don't need | ||
// to change the string, but in `toLowerStr`, we need to change the string. | ||
|
||
int main() { | ||
std::string str("Hello World!"); | ||
std::cout << hasCapital("Abc") << " " << hasCapital("abc") << " " | ||
<< hasCapital(str) << std::endl; | ||
std::cout << str << std::endl; | ||
toLowerStr(str); | ||
std::cout << str << 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,8 @@ | ||
(a) | ||
|
||
bool compare(const matrix &, const matrix &); | ||
|
||
(b) | ||
|
||
vector<int>::iterator &change_val(int, vector<int>::iterator &); | ||
|
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) Illegal. Only one parameter is needed for the function. | ||
(b) Legal. | ||
(c) Legal. | ||
(d) Legal. |
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,25 @@ | ||
(a) | ||
|
||
//int f() { // Return type doesn't match | ||
string f() { | ||
string s; | ||
// ... | ||
return s; | ||
} | ||
|
||
(b) | ||
|
||
//f2(int i) { /* ... */ } // Must have a return type | ||
void f2(int i) { /* ... */ } | ||
|
||
(c) | ||
|
||
//int calc(int v1, int v1) /* ... */ } // Forget begin brace `{` | ||
int calc(int v1, int v1) { /* ... */ } | ||
|
||
(d) | ||
|
||
//double square(double x) return x * x; // The function body should be a block. | ||
double square(double x) { return x * x; } | ||
|
||
|
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 @@ | ||
If the reference parameters will not be changed inside function, then they should be reference to `const`. | ||
|
||
If we make a parameter a plain reference, then we can not pass | ||
- a `const` object, | ||
- or a literal, | ||
- or an object that requires conversion | ||
to a plain reference parameter. |
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 @@ | ||
int largerInt(int a, int *pb) { | ||
return a > *pb ? a : *pb; | ||
} |
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,28 @@ | ||
#include <iostream> | ||
|
||
void swapIntPtr(int **pa, int **pb) { | ||
int *tmp = *pa; | ||
*pa = *pb; | ||
*pb = tmp; | ||
} | ||
|
||
void swapIntPtr(int *&pa, int *&pb) { | ||
int *tmp = pa; | ||
pa = pb; | ||
pb = tmp; | ||
} | ||
|
||
int main() { | ||
int i = 1, j = 2; | ||
int *pi = &i, *pj = &j; | ||
std::cout << "pi = " << pi << " *pi = " << *pi << std::endl; | ||
std::cout << "pj = " << pj << " *pj = " << *pj << std::endl; | ||
swapIntPtr(&pi, &pj); | ||
std::cout << "pi = " << pi << " *pi = " << *pi << std::endl; | ||
std::cout << "pj = " << pj << " *pj = " << *pj << std::endl; | ||
swapIntPtr(pi, pj); | ||
std::cout << "pi = " << pi << " *pi = " << *pi << std::endl; | ||
std::cout << "pj = " << pj << " *pj = " << *pj << 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,43 @@ | ||
#include <iostream> | ||
#include <iterator> | ||
|
||
//void print(const int arr[]) { | ||
// std::cout << "void print(const int arr[])" << std::endl; | ||
// // Cannot get the size of arr, unless by a marker in the array | ||
//} | ||
|
||
void print(int i) { | ||
std::cout << "void print(int i)" << std::endl; | ||
std::cout << i << std::endl; | ||
} | ||
|
||
void print(const int *bg, const int *ed) { | ||
std::cout << "void print(const int *bg, const int *ed)" << std::endl; | ||
while (bg != ed) | ||
std::cout << *bg++ << std::endl; | ||
} | ||
|
||
void print(const int arr[], size_t sz) { | ||
std::cout << "void print(const int arr[], size_t sz)" << std::endl; | ||
for (size_t i = 0; i != sz; ++i) | ||
std::cout << arr[i] << std::endl; | ||
} | ||
|
||
void print(const int (&arr)[2]) { | ||
std::cout << "void print(const int (&arr)[2])" << std::endl; | ||
for (auto & e : arr) | ||
std::cout << e << std::endl; | ||
} | ||
|
||
int main() { | ||
int i = 0, j[2] = {0, 1}; | ||
std::cout << "i:" << std::endl; | ||
print(i); | ||
print(10); | ||
std::cout << "j:" << std::endl; | ||
print(std::begin(j), std::end(j)); | ||
print(j, std::end(j) - std::begin(j)); | ||
print(j); | ||
|
||
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,4 @@ | ||
The function prototype is the same as `void print(const int *ia)`, which means we can pass any pointer to int to the function, not only an array of ten `int`s. This will lead to an error. We can change the parameter to a reference to array: | ||
|
||
void print(const int (&ia)[10]) { /* ... */ } | ||
|
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 <string> | ||
|
||
int main(int argc, char *argv[]) { | ||
std::cout << "All " << argc << " argument" | ||
<< (argc > 1 ? "s are:" : " is:") << std::endl; | ||
for (int i = 0; i < argc; ++i) | ||
std::cout << i << "\t" << argv[i] << std::endl; | ||
if (argc < 3) // programname argument1 argument2 0 | ||
return -1; | ||
std::string args(argv[1]); | ||
args += argv[2]; | ||
std::cout << args << 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,11 @@ | ||
#include <iostream> | ||
#include <string> | ||
|
||
int main(int argc, char *argv[]) { | ||
std::cout << "All " << argc << " argument" | ||
<< (argc > 1 ? "s are:" : " is:") << std::endl; | ||
for (int i = 0; i < argc; ++i) | ||
std::cout << i << "\t" << argv[i] << 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,16 @@ | ||
#include <initializer_list> | ||
#include <iostream> | ||
|
||
int sumIntList(std::initializer_list<int> il) { | ||
int sum = 0; | ||
// `il.begin()` or `il.end()` will return `const int *` | ||
for (auto &e : il) // `e` is `const int &`, since element in `il` are `const int` | ||
sum += e; | ||
return sum; | ||
} | ||
|
||
int main() { | ||
std::cout << sumIntList({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) << 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 @@ | ||
The type of `elem` is `const string &`. |
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 @@ | ||
Yes, I would use a reference as the loop control variable. So that we don't need to copy the value from the `initializer_list`. |
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 fact(int n) { // Ignore overflow | ||
if (n < 1) return n; | ||
int k = n; | ||
while (--n) | ||
k *= n; | ||
return k; | ||
} | ||
|
||
int main() { | ||
int n; | ||
std::cin >> n; | ||
std::cout << n << "! = " << fact(n) << 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,24 @@ | ||
#include <iostream> | ||
#include <string> | ||
using std::string; | ||
|
||
bool str_subrange(const string &str1, const string &str2) { | ||
if (str1.size() == str2.size()) | ||
return str1 == str2; | ||
auto size = (str1.size() < str2.size()) ? str1.size() : str2.size(); | ||
for (decltype(size) i = 0; i != size; ++i) { | ||
if (str1[i] != str2[i]) | ||
//return; // Error: need a return value | ||
return false; | ||
} | ||
// Error: need a return statement | ||
return true; | ||
} | ||
|
||
int main() { | ||
string s1, s2; | ||
std::cin >> s1 >> s2; | ||
std::cout << str_subrange(s1, s2) << 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,3 @@ | ||
When the object is not a local object, then that's fine to return a reference to it. | ||
|
||
When we don't want the reference returned from a function to be an lvalue, we should use a reference to `const` as the return type instead. |
Oops, something went wrong.