Skip to content

Commit

Permalink
Merge pull request pezy#34 from pezy/master
Browse files Browse the repository at this point in the history
fixed some bugs
  • Loading branch information
Mooophy committed Nov 11, 2014
2 parents cf68ffe + d2f7c13 commit f252a12
Show file tree
Hide file tree
Showing 28 changed files with 841 additions and 701 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
- [Chapter 3. Strings, Vectors, and Arrays](ch03/README.md)
- [Chapter 4. Expressions](ch04/README.md)
- [Chapter 5. Statements](ch05/README.md)
- [Chapter 6. Functions](ch06)
- [Chapter 6. Functions](ch06/README.md)
- [Chapter 7. Classes](ch07)
- [Chapter 8. The IO Library](ch08)
- Part II: The C++ Library
Expand Down
4 changes: 2 additions & 2 deletions ch01/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

int main()
{
std::cout << "Hello, World" << endl;
std::cout << "Hello, World" << std::endl;
return 0;
}
```
Expand Down Expand Up @@ -265,7 +265,7 @@ Watch out for "sum + value" in the `cout` line.

> What happens in the program presented in this section if the input values are all equal? What if there are no duplicated values?
If the input values are all equal, it will print nothing unless you enter `EOF`.
If the input values are all equal, it will print a line which shows the count of the number you input.

If there are no duplicated values, when different values input, a new line will be printed if you click `Enter`.

Expand Down
40 changes: 26 additions & 14 deletions ch02/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,21 +156,25 @@ int input_value = 0;
std::cin >> input_value;
```

(b): warning: implicit conversion from 'double' to 'int' changes value
from 3.14 to 3.
(b):---when you compile the code without the argument "-std=c++11", you will get the warning below:
warning: implicit conversion from 'double' to 'int' changes value from 3.14 to 3.
---when you compile the code using "-std=c+11", you will get a error below:
error: type 'double' cannot be narrowed to 'int' in initializer list
---conclusion: Obviously, list initialization becomes strict in c++11.
```cpp
float i = { 3.14 };
double i = { 3.14 };
```
(c): error: use of undeclared identifier 'wage'
(c): --if you declared 'wage' before, it's right. Otherwhise, you'll get a error:
error: use of undeclared identifier 'wage'
```cpp
double salary = 9999.99;
double wage = 9999.99;
double wage;
double salary = wage = 9999.99;
```

(d): ok: but value will be truncated.
```cpp
float i = 3.14;
double i = 3.14;
```

##Exercise 2.10
Expand All @@ -185,8 +189,12 @@ int main()
}
```

`global_str` and `local_str` are the empty string.
`global_int` and `local_int` are the zero.
`global_str` is global variable, so the value is empty string.
`global_int` is global variable, so the value is zero.
`local_int` is a local variable which is not uninitialized, so it has a undefined value.
`local_str` is also a local variable which is not uninitialized, but it has a value that is defined by the class. So it is empty string.
PS: please read P44 in the English version, P40 in Chinese version to get more.
The note: Uninitialized objects of built-in type defined inside a function body have a undifined value. Objects of class type that we do not explicitly inititalize have a value that is defined by class.

##Exercise 2.11
> Explain whether each of the following is a declaration or a
Expand Down Expand Up @@ -259,7 +267,7 @@ Yes.It is legal.Printed:

```
(a): valid. let d equal 3.14159.
(b): invalid. r1 must be a double object.
(b): valid. automatical convert will happen.
(c): valid. but value will be truncated.
(d): valid. but value will be truncated.
```
Expand Down Expand Up @@ -381,7 +389,7 @@ variables.

```
(a): ip is a pointer to int, i is an int, r is a reference to int i.
(b): ip is a valid, null pointer.
(b): ip is a valid, null pointer, and i is an int.
(c): ip is a pointer to int, and ip2 is an int.
```

Expand Down Expand Up @@ -444,6 +452,7 @@ const int *p2 = &v2, *const p3 = &i, &r2 = v2;

v2 is top-level const, p2 is low-level const.
p3: right-most const is top-level, left-most is low-level.
r2 is low-level const.

##Exercise 2.31
>Given the declarations in the previous exercise determine
Expand Down Expand Up @@ -500,9 +509,11 @@ const int i = 42;
auto j = i; const auto &k = i; auto *p = &i; const auto j2 = i, &k2 = i;
```

j and j2 are int.
k and k2 are &int.
p is a pointer to const int.
j is int.
k is const int&.
p is const int *.
j2 is const int.
k2 is const int&.

[Here](ex2_35.cpp) is the code.

Expand All @@ -529,6 +540,7 @@ decltype(a = b) d = a;
```

`c` is an int, `d` is a reference of int.
the value: a=3, b=4, c=3, d=3

##Exercise 2.38
>Describe the differences in type deduction between decltype and auto. Give an example of an expression where auto and decltype will deduce the same type and an example where they will deduce differing types.
Expand Down
233 changes: 232 additions & 1 deletion ch03/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,232 @@
##Exercise 3.1 : [part1](ex3_1a.cpp) | [part2](ex3_1b.cpp)##Exercise 3.2 : [part1](ex3_2a.cpp) | [part2](ex3_2b.cpp)##Exercise 3.3>Explain how whitespace characters are handled in the stringinput operator and in the getline function.The `getline` function takes an input stream and a string.This function reads the given stream up to and includingthe first newline and stores what it read—not includingthe newline—in its string argument.After getline sees a newline, even if it is the first character in the input,it stops reading and returns.If the first character in the input is a newline,then the resulting string is the empty string.`getline` function whitespace handling,do not ignore the beginning of the line blank characters read charactersuntil it encounters a line break,read to termination and discard newline(line breaks removed from the input stream but is not stored in the string object).[Read more](http://www.cplusplus.com/reference/string/string/getline/)##Exercise 3.4 : [part1](ex3_4a.cpp) | [part2](ex3_4b.cpp)##Exercise 3.5 : [part1](ex3_5a.cpp) | [part2](ex3_5b.cpp)##[Exercise 3.6](ex3_6.cpp)##Exercise 3.7>What would happen if you define the loop control variable in the previousexercise as type char? Predict the results and then change your programto use a char to see if you were right.No different. auto& c : strWe use `auto` to let the compiler determine the type of `c`.which in this case will be `char&`.##[Exercise 3.8](ex3_8.cpp)##Exercise 3.9>What does the following program do? Is it valid? If not, why not?```cppstring s;cout << s[0] << endl;```invalid in theory, but the compiler passes.`s` is empty, so `s[0]` is undefined. But the compiler always define `s[0]`with `\0`, so you can use `s[0]` in the `cout`.##[Exercise 3.10](ex3_10.cpp)##Exercise 3.11>Is the following range for legal? If so, what is the type of c?```cppconst string s = "Keep out!";for (auto &c : s){/*... */}```When you don't change `c`'s value, it's legal, else it's illegal.For example: cout << c; // legal. c = 'X'; // illegal.The type of `c` is `const char&`. read-only variable is not assignable.##Exercise 3.12>Which, if any, of the following vector definitions are in error?For those that are legal, explain what the definition does.For those that are not legal, explain why they are illegal.```cppvector<vector<int>> ivec; // legal(c++11), vectors.vector<string> svec = ivec; // illegal, different type.vector<string> svec(10, "null"); // legal, vector have 10 strings: "null".```##Exercise 3.13>How many elements are there in each of the followingvectors? What are the values of the elements?```cppvector<int> v1; // size:0, no values.vector<int> v2(10); // size:10, value:0vector<int> v3(10, 42); // size:10, value:42vector<int> v4{10}; // size:1, value:10vector<int> v5{10, 42}; // size:2, value:10, 42vector<string> v6{10}; // size:10, value:""vector<string> v7{10, "hi"}; // size:10, value:"hi"```##[Exercise 3.14](ex3_14.cpp)##[Exercise 3.15](ex3_15.cpp)##[Exercise 3.16](ex3_16.cpp)##[Exercise 3.17](ex3_17.cpp)##[Exercise 3.18](ex3_18.cpp)##[Exercise 3.19](ex3_19.cpp)##[Exercise 3.20](ex3_20.cpp)##[Exercise 3.21](ex3_21.cpp) ([Generics Version](ex3_21_generics_version))##[Exercise 3.22](ex3_22.cpp)##[Exercise 3.23](ex3_23.cpp)##[Exercise 3.24](ex3_24.cpp)##[Exercise 3.25](ex3_25.cpp)##Exercise 3.26>In the binary search program on page 112,why did we write `mid=beg+(end-beg)/2;` instead of `mid=(beg+end) /2;`?Because the iterator of vector don't define the `+` operator **between the two iterators**.`beg + end` is illegal.We can only use the subtraction between the two iterators.##Exercise 3.27>Assuming txt_size is a function that takes no argumentsand returns an int value, which of the following definitions are illegal?Explain why.```cppunsigned buf_size = 1024;int ia[buf_size]; // legalint ia[4 * 7 - 14]; // legalint ia[txt_size()]; // legalchar st[11] = "fundamental"; // illegal, the string's size is 12.```##Exercise 3.28>What are the values in the following arrays?```cppstring sa[10];int ia[10];int main() { string sa2[10]; int ia2[10];}```please see 2.2.1. Variable Definitions -> Default Initialization.`std::string` isn't a build-in type. The initializer will set it empty.`ia` and `ia2` are build-type. But `ia` isn't in the function body, so itwill be initalized to **zero**. `ia2` is in the function body. so it'svalue is **undefined**.You can also use gdb to debug the value when the code is running.##Exercise 3.29:>List some of the drawbacks of using an array instead of a vector.1. can't add elements to an array.2. can't use auto to deduce the type from a list of initalizers.3. no arrays of references.4. can't use template and iterator.5. vector have lots of useful methods and algorithms.##Exercise 3.30>Identify the indexing errors in the following code:```cppconstexpr size_t array_size = 10;int ia[array_size];for (size_t ix = 1; ix <= array_size; ++ix) ia[ix] = ix;```The size of ia is 10, so the index of value should less than 10.ix **cannot** equal the array_size.##[Exercise 3.31](ex3_31.cpp)##[Exercise 3.32](ex3_32.cpp)##Exercise 3.33>What would happen if we did not initialize the scores array in the programon page 116?If we did not initialize the scores array. the array is undefined. the valuewill be Unknown.Look like this:![result](https://db.tt/3T4TQoo8)##Exercise 3.34>Given that p1 and p2 point to elements in the same array, what does the following code do?Are there values of p1 or p2 that make this code illegal?```cppp1 += p2 - p1;```we assume p1 and p2 point to an array arr. so `p1 = &arr[0]`; and `p2 = &arr[0]`.p2 - p1 is the distance of arr[0] to arr[0], and must be zero.so `p1 += 0;` can not change the p1's point.`p1 += p2 - p1;` same as `p1 = p2;`. If p2 and p1 are legal, this code always legal.##[Exercise 3.35](ex3_35.cpp)##[Exercise 3.36](ex3_36.cpp)##Exercise 3.37>What does the following program do?```cppconst char ca[] = {'h', 'e', 'l', 'l', 'o'};const char *cp = ca;while (*cp) { cout << *cp << endl; ++cp;}```Print all the elements of the array.##Exercise 3.38>In this section, we noted that it was not only illegal but meaningless to try to add two pointers.Why would adding two pointers be meaningless?Because Subtracting two points gives a logically explainable result - the offsetin memory between two points. Similarly, you can subtract or add an integral number to/from a pointer,which means "move the pointer up or down". Adding a pointer to a pointer is something which is hard toexplain. The result is meaningless.----References:- [Why can't I add pointers](http://stackoverflow.com/questions/2935038/why-cant-i-add-pointers)##[Exercise 3.39](ex3_39.cpp)##[Exercise 3.40](ex3_40.cpp)##[Exercise 3.41](ex3_41.cpp)##[Exercise 3.42](ex3_42.cpp)##[Exercise 3.43](ex3_43.cpp)##[Exercise 3.44](ex3_44.cpp)##[Exercise 3.45](ex3_45.cpp)
##Exercise 3.1 : [part1](ex3_1a.cpp) | [part2](ex3_1b.cpp)
##Exercise 3.2 : [part1](ex3_2a.cpp) | [part2](ex3_2b.cpp)
##Exercise 3.3
>Explain how whitespace characters are handled in the string
input operator and in the getline function.

The `getline` function takes an input stream and a string.
This function reads the given stream up to and including
the first newline and stores what it read—not including
the newline—in its string argument.
After getline sees a newline, even if it is the first character in the input,
it stops reading and returns.
If the first character in the input is a newline,
then the resulting string is the empty string.

`getline` function whitespace handling,
do not ignore the beginning of the line blank characters read characters
until it encounters a line break,
read to termination and discard newline
(line breaks removed from the input stream
but is not stored in the string object).

[Read more](http://www.cplusplus.com/reference/string/string/getline/)

##Exercise 3.4 : [part1](ex3_4a.cpp) | [part2](ex3_4b.cpp)
##Exercise 3.5 : [part1](ex3_5a.cpp) | [part2](ex3_5b.cpp)
##[Exercise 3.6](ex3_6.cpp)
##Exercise 3.7
>What would happen if you define the loop control variable in the previous
exercise as type char? Predict the results and then change your program
to use a char to see if you were right.

No different.

auto& c : str

We use `auto` to let the compiler determine the type of `c`.
which in this case will be `char&`.

##[Exercise 3.8](ex3_8.cpp)
##Exercise 3.9
>What does the following program do? Is it valid? If not, why not?
```cpp
string s;
cout << s[0] << endl;
```

invalid in theory, but the compiler passes.

`s` is empty, so `s[0]` is undefined. But the compiler always define `s[0]`
with `\0`, so you can use `s[0]` in the `cout`.

##[Exercise 3.10](ex3_10.cpp)
##Exercise 3.11
>Is the following range for legal? If so, what is the type of c?
```cpp
const string s = "Keep out!";
for (auto &c : s){/*... */}
```
When you don't change `c`'s value, it's legal, else it's illegal.
For example:
cout << c; // legal.
c = 'X'; // illegal.
The type of `c` is `const char&`. read-only variable is not assignable.
##Exercise 3.12
>Which, if any, of the following vector definitions are in error?
For those that are legal, explain what the definition does.
For those that are not legal, explain why they are illegal.
```cpp
vector<vector<int>> ivec; // legal(c++11), vectors.
vector<string> svec = ivec; // illegal, different type.
vector<string> svec(10, "null"); // legal, vector have 10 strings: "null".
```

##Exercise 3.13
>How many elements are there in each of the following
vectors? What are the values of the elements?
```cpp
vector<int> v1; // size:0, no values.
vector<int> v2(10); // size:10, value:0
vector<int> v3(10, 42); // size:10, value:42
vector<int> v4{10}; // size:1, value:10
vector<int> v5{10, 42}; // size:2, value:10, 42
vector<string> v6{10}; // size:10, value:""
vector<string> v7{10, "hi"}; // size:10, value:"hi"
```
##[Exercise 3.14](ex3_14.cpp)
##[Exercise 3.15](ex3_15.cpp)
##[Exercise 3.16](ex3_16.cpp)
##[Exercise 3.17](ex3_17.cpp)
##[Exercise 3.18](ex3_18.cpp)
##[Exercise 3.19](ex3_19.cpp)
##[Exercise 3.20](ex3_20.cpp)
##[Exercise 3.21](ex3_21.cpp) ([Generics Version](ex3_21_generics_version))
##[Exercise 3.22](ex3_22.cpp)
##[Exercise 3.23](ex3_23.cpp)
##[Exercise 3.24](ex3_24.cpp)
##[Exercise 3.25](ex3_25.cpp)
##Exercise 3.26
>In the binary search program on page 112,
why did we write `mid=beg+(end-beg)/2;` instead of `mid=(beg+end) /2;`?
Because the iterator of vector don't define the `+` operator **between the two iterators**.
`beg + end` is illegal.
We can only use the subtraction between the two iterators.
##Exercise 3.27
>Assuming txt_size is a function that takes no arguments
and returns an int value, which of the following definitions are illegal?
Explain why.
```cpp
unsigned buf_size = 1024;
int ia[buf_size]; // illegal, The dimension value must be a constant expression.
int ia[4 * 7 - 14]; // legal
int ia[txt_size()]; // illegal, The dimension value must be a constant expression.
char st[11] = "fundamental"; // illegal, the string's size is 12.
```

##Exercise 3.28
>What are the values in the following arrays?
```cpp
string sa[10];
int ia[10];

int main() {
string sa2[10];
int ia2[10];
}
```

please see 2.2.1. Variable Definitions -> Default Initialization.

`std::string` isn't a build-in type. The initializer will set it empty.
`ia` and `ia2` are build-type. But `ia` isn't in the function body, so it
will be initalized to **zero**. `ia2` is in the function body. so it's
value is **undefined**.

You can also use gdb to debug the value when the code is running.

##Exercise 3.29:
>List some of the drawbacks of using an array instead of a vector.
1. can't add elements to an array.
2. can't use auto to deduce the type from a list of initalizers.
3. no arrays of references.
4. can't use template and iterator.
5. vector have lots of useful methods and algorithms.

##Exercise 3.30
>Identify the indexing errors in the following code:
```cpp
constexpr size_t array_size = 10;
int ia[array_size];
for (size_t ix = 1; ix <= array_size; ++ix)
ia[ix] = ix;
```

The size of ia is 10, so the index of value should less than 10.
ix **cannot** equal the array_size.

##[Exercise 3.31](ex3_31.cpp)
##[Exercise 3.32](ex3_32.cpp)
##Exercise 3.33
>What would happen if we did not initialize the scores array in the program
on page 116?

If we did not initialize the scores array. the array is undefined. the value
will be Unknown.

Look like this:

![result](https://db.tt/3T4TQoo8)

##Exercise 3.34
>Given that p1 and p2 point to elements in the same array, what does the following code do?
Are there values of p1 or p2 that make this code illegal?
```cpp
p1 += p2 - p1;
```

we assume p1 and p2 point to an array arr. so `p1 = &arr[0]`; and `p2 = &arr[0]`.
p2 - p1 is the distance of arr[0] to arr[0], and must be zero.
so `p1 += 0;` can not change the p1's point.

`p1 += p2 - p1;` same as `p1 = p2;`. If p2 and p1 are legal, this code always legal.

##[Exercise 3.35](ex3_35.cpp)
##[Exercise 3.36](ex3_36.cpp)
##Exercise 3.37
>What does the following program do?
```cpp
const char ca[] = {'h', 'e', 'l', 'l', 'o'};
const char *cp = ca;
while (*cp) {
cout << *cp << endl;
++cp;
}
```

Print all the elements of the array.

##Exercise 3.38
>In this section, we noted that it was not only illegal but meaningless to try to add two pointers.
Why would adding two pointers be meaningless?


Because Subtracting two points gives a logically explainable result - the offset
in memory between two points. Similarly, you can subtract or add an integral number to/from a pointer,
which means "move the pointer up or down". Adding a pointer to a pointer is something which is hard to
explain. The result is meaningless.

----
References:
- [Why can't I add pointers](http://stackoverflow.com/questions/2935038/why-cant-i-add-pointers)

##[Exercise 3.39](ex3_39.cpp)
##[Exercise 3.40](ex3_40.cpp)
##[Exercise 3.41](ex3_41.cpp)
##[Exercise 3.42](ex3_42.cpp)
##[Exercise 3.43](ex3_43.cpp)
##[Exercise 3.44](ex3_44.cpp)
##[Exercise 3.45](ex3_45.cpp)
Loading

0 comments on commit f252a12

Please sign in to comment.