Skip to content

Commit

Permalink
book: fix a chunk of english typos
Browse files Browse the repository at this point in the history
  • Loading branch information
changkun committed Mar 15, 2020
1 parent 89060d4 commit a5d1563
Show file tree
Hide file tree
Showing 12 changed files with 34 additions and 32 deletions.
Binary file added assets/figures/pointers1_en.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion book/en-us/00-preface.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ order: 0
## Introduction

C++ user group is a fairly large. From the advent of C++98 to the official finalization of C++11, it has accumulated over a decade. C++14/17 is an important complement and optimization for C++11, and C++20 brings this language to the door of modernization. The extended features of all these new standards are given to the C++ language. Infused with new vitality.
C++ programmers, who are still using **traditional C++** (this book refers to C++98 and its previous C++ standards as traditional C++), may even amzed by the fact that they are not using the same language while reading modern C++ code.
C++ programmers, who are still using **traditional C++** (this book refers to C++98 and its previous C++ standards as traditional C++), may even amazed by the fact that they are not using the same language while reading modern C++ code.

**Modern C++** (this book refers to C++11/14/17/20) introduces a lot of features into traditional C++, which makes the whole C++ become language that modernized. Modern C++ not only enhances the usability of the C++ language itself, but the modification of the `auto` keyword semantics gives us more confidence in manipulating extremely complex template types. At the same time, a lot of enhancements have been made to the language runtime. The emergence of Lambda expressions has made C++ have the "closure" feature of "anonymous functions", which is almost in modern programming languages ​​(such as Python/Swift/.. It has become commonplace, and the emergence of rvalue references has solved the problem of temporary object efficiency that C++ has long been criticized.

Expand Down
4 changes: 3 additions & 1 deletion book/en-us/01-intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Before learning modern C++, let's take a look at the main features that have been deprecated since C++11:

> **Note**: Deprecation is not completely unusable, it is only intended to imply that programmers will disappear from future standards and should be avoided. However, the deprecated features are still part of the standard library, and most of the features are actually "permanently" reserved for compatibility reasons.
> **Note**: Deprecation is not completely unusable, it is only intended to imply that features will disappear from future standards and should be avoided. However, the deprecated features are still part of the standard library, and most of the features are actually "permanently" reserved for compatibility reasons.
- **The string literal constant is no longer allowed to be assigned to a `char *`. If you need to assign and initialize a `char *` with a string literal constant, you should use `const char *` or `auto`.**

```cpp
char *str = "hello world!"; // A deprecation warning will appear
```
Expand Down Expand Up @@ -115,6 +116,7 @@ LDFLAGS_COMMON = -std=c++2a
all:
$(C) -c $(SOURCE_C)
$(CXX) $(SOURCE_CXX) $(OBJECTS_C) $(LDFLAGS_COMMON) -o $(TARGET)

clean:
rm -rf *.o $(TARGET)
```
Expand Down
12 changes: 6 additions & 6 deletions book/en-us/02-usability.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ In the above example, `char arr_4[len_2]` may be confusing because `len_2` has b
Why is `char arr_4[len_2]` still illegal?
This is because the length of the array in the C++ standard must be a constant expression,
and for `len_2`, this is a `const` constant, not a constant expression,
so even if this behavior is in most compilers Both support, but) it is an illegal behavior,
so even if this behavior is supported by most compilers, but it is an illegal behavior,
we need to use the `constexpr` feature introduced in C++11, which will be introduced next,
to solve this problem; for `arr_5`, before C++98 The compiler cannot know that `len_foo()`
actually returns a constant at runtime, which causes illegal production.
Expand All @@ -155,7 +155,7 @@ actually returns a constant at runtime, which causes illegal production.
C++11 provides `constexpr` to let the user explicitly declare that the function or
object constructor will become a constant expression at compile time.
This keyword explicitly tells the compiler that it should verify that `len_foo`
should be a compile time. Constant expression.
should be a compile time constant expression. Constant expression.
In addition, the function of `constexpr` can use recursion:
Expand Down Expand Up @@ -222,8 +222,8 @@ int main() {
```

In the above code, we can see that the `itr` variable is defined in the scope of
the entire `main()`, which causes us to rename the other when we need to traverse
the entire `std::vectors` again. A variable. C++17 eliminates this limitation so that
the entire `main()`, which causes us to rename the other when a variable need to traverse
the entire `std::vectors` again. C++17 eliminates this limitation so that
we can do this in if(or switch):

```cpp
Expand Down Expand Up @@ -280,7 +280,7 @@ To solve this problem,
C++11 first binds the concept of the initialization list to the type
and calls it `std::initializer_list`,
allowing the constructor or other function to use the initialization list
like a parameter, which is The initialization of class objects provides
like a parameter, which is the initialization of class objects provides
a unified bridge between normal arrays and POD initialization methods,
such as:

Expand Down Expand Up @@ -961,7 +961,7 @@ public:
};
class Subclass : public Base {
public:
using Base::Base; // inhereit constructor
using Base::Base; // inheritance constructor
};
int main() {
Subclass s(3);
Expand Down
12 changes: 6 additions & 6 deletions book/en-us/03-runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ order: 3
## 3.1 Lambda Expression

Lambda expressions are one of the most important features in modern C++, and Lambda expressions actually provide a feature like anonymous functions.
Anonymous functions are used when a function is needed, but you don't want to use a function to name a function. There are actually many, many scenes like this.
Anonymous functions are used when a function is needed, but you dont want to use name to call a function. There are actually many, many scenes like this.
So anonymous functions are almost standard on modern programming languages.

### Basics
Expand All @@ -24,7 +24,7 @@ The basic syntax of a Lambda expression is as follows:
}
```

The above grammar rules are well understood except for the things in `[catch list]`,
The above grammar rules are well understood except for the things in `[capture list]`,
except that the function name of the general function is omitted.
The return value is in the form of a `->`
(we have already mentioned this in the tail return type earlier in the previous section).
Expand Down Expand Up @@ -143,7 +143,7 @@ void lambda_generic() {

## 3.2 Function Object Wrapper

Although this part of the standard library is part of the standard library,
Although the features are part of the standard library and not found in runtime,
it enhances the runtime capabilities of the C++ language.
This part of the content is also very important, so put it here for introduction.

Expand Down Expand Up @@ -262,7 +262,7 @@ are all pure rvalue values.
**xvalue, expiring value** is the concept proposed by C++11 to introduce
rvalue references (so in traditional C++, pure rvalue and rvalue are the same concept),
that is, A value that is destroyed but can be moved.
a value that is destroyed but can be moved.
It would be a little hard to understand the xvalue,
let's look at the code like this:
Expand Down Expand Up @@ -330,7 +330,7 @@ int main()

std::string&& rv2 = lv1 + lv2; // legal, rvalue ref extend lifecycle
rv2 += "string"; // legal, non-const reference can be modified
std::cout << rv2 << std::endl; // string,string,string,
std::cout << rv2 << std::endl; // string,string,string,string

reference(rv2); // output: lvalue

Expand Down Expand Up @@ -496,7 +496,7 @@ For `pass(1)`, although the value is the rvalue, since `v` is a reference, it is
Therefore `reference(v)` will call `reference(int&)` and output lvalue.
For `pass(l)`, `l` is an lvalue, why is it successfully passed to `pass(T&&)`?
This is based on the **reference contraction rule**: In traditional C++, we are not able to continue to reference a reference type.
This is based on the **reference collapsing rule**: In traditional C++, we are not able to continue to reference a reference type.
However,
C++ has relaxed this practice with the advent of rvalue references,
resulting in a reference collapse rule that allows us to reference references,
Expand Down
2 changes: 1 addition & 1 deletion book/en-us/04-containers.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ Key:[3] Value:[3]
## 4.3 Tuples

Programmers who have known Python should be aware of the concept of tuples. Looking at the containers in traditional C++, except for `std::pair`
There seems to be no ready-made structure to store different types of data (usually we will define the structure ourselves).
there seems to be no ready-made structure to store different types of data (usually we will define the structure ourselves).
But the flaw of `std::pair` is obvious, only two elements can be saved.

### Basic Operations
Expand Down
14 changes: 7 additions & 7 deletions book/en-us/05-pointers.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ These smart pointers include `std::shared_ptr`/`std::unique_ptr`/`std::weak_ptr`
## 5.2 `std::shared_ptr`

`std::shared_ptr` is a smart pointer that records how many `shared_ptr` points to an object, eliminating the display call `delete`, which automatically deletes the object when the reference count becomes zero.
`std::shared_ptr` is a smart pointer that records how many `shared_ptr` points to an object, eliminating to call `delete`, which automatically deletes the object when the reference count becomes zero.

But not enough, because using `std::shared_ptr` still needs to be called with `new`, which makes the code a certain degree of asymmetry.

Expand Down Expand Up @@ -133,12 +133,12 @@ int main() {
// p2 is empty, no prints
if(p2) p2->foo();
std::cout << "p2 was destroied" << std::endl;
std::cout << "p2 was destroyed" << std::endl;
}
// p1 is not empty, prints
if (p1) p1->foo();
// Foo instance will be destroied when leaving the scope
// Foo instance will be destroyed when leaving the scope
}
```
Expand All @@ -157,14 +157,14 @@ class A {
public:
std::shared_ptr<B> pointer;
~A() {
std::cout << "A was destroied" << std::endl;
std::cout << "A was destroyed" << std::endl;
}
};
class B {
public:
std::shared_ptr<A> pointer;
~B() {
std::cout << "B was destroied" << std::endl;
std::cout << "B was destroyed" << std::endl;
}
};
int main() {
Expand All @@ -177,9 +177,9 @@ int main() {
}
```
The result is that A and B will not be destroyed. This is because the pointer inside a, b also references `a, b`, which makes the reference count of `a, b` become 2, leaving the scope. When the `a, b` smart pointer is destructed, it can only cause the reference count of this area to be decremented by one. This causes the memory area reference count pointed to by the `a, b` object to be non-zero, but the external has no The way to find this area, it also caused a memory leak, as shown in Figure 5.1:
The result is that A and B will not be destroyed. This is because the pointer inside a, b also references `a, b`, which makes the reference count of `a, b` become 2, leaving the scope. When the `a, b` smart pointer is destructed, it can only cause the reference count of this area to be decremented by one. This causes the memory area reference count pointed to by the `a, b` object to be non-zero, but the external has no way to find this area, it also caused a memory leak, as shown in Figure 5.1:
![Figure 5.1](../../assets/figures/pointers1.png)
![Figure 5.1](../../assets/figures/pointers1_en.png)
The solution to this problem is to use the weak reference pointer `std::weak_ptr`, which is a weak reference (compared to `std::shared_ptr` is a strong reference). A weak reference does not cause an increase in the reference count. When a weak reference is used, the final release process is shown in Figure 5.2:
Expand Down
8 changes: 4 additions & 4 deletions book/en-us/07-thread.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ C++11 introduces a class related to `mutex`, with all related functions in the `
It can be locked by its member function `lock()`, and `unlock()` can be unlocked.
But in the process of actually writing the code, it is best not to directly call the member function,
Because calling member functions, you need to call `unlock()` at the exit of each critical section, and of course, exceptions.
At this time, C++11 also provides a template class `std::lock_gurad` for the RAII syntax for the mutex.
At this time, C++11 also provides a template class `std::lock_guard` for the RAII syntax for the mutex.

RAII guarantees the exceptional security of the code while losing the simplicity of the code.
RAII guarantees the exceptional security of the code while keeping the simplicity of the code.

```cpp
#include <iostream>
Expand Down Expand Up @@ -156,7 +156,7 @@ The condition variable `std::condition_variable` was born to solve the deadlock
For example, a thread may need to wait for a condition to be true to continue execution.
A dead wait loop can cause all other threads to fail to enter the critical section so that when the condition is true, a deadlock occurs.
Therefore, the `condition_variable` instance is created primarily to wake up the waiting thread and avoid deadlocks.
`notd_one()` of `std::condition_variable` is used to wake up a thread;
`notify_one()` of `std::condition_variable` is used to wake up a thread;
`notify_all()` is to notify all threads. Below is an example of a producer and consumer model:

```cpp
Expand Down Expand Up @@ -253,7 +253,7 @@ int main() {
}
```

Intuitively, ʻa = 5;` in `t2` seems to always execute before `flag = 1;`, and `while (flag != 1)` in `t1` seems to guarantee `std ::cout << "b = " << b << std::endl;` will not be executed before the mark is changed. Logically, it seems that the value of `b` should be equal to 5.
Intuitively, `a = 5;` seems in `t2` seems to always execute before `flag = 1;`, and `while (flag != 1)` in `t1` seems to guarantee `std ::cout << "b = " << b << std::endl;` will not be executed before the mark is changed. Logically, it seems that the value of `b` should be equal to 5.
But the actual situation is much more complicated than this, or the code itself is undefined behavior, because for `a` and `flag`, they are read and written in two parallel threads.
There has been competition. In addition, even if we ignore competing reading and writing, it is still possible to receive out-of-order execution of the CPU, and the impact of the compiler on the rearrangement of instructions.
Cause `a = 5` to occur after `flag = 1`. Thus `b` may output 0.
Expand Down
2 changes: 1 addition & 1 deletion book/zh-cn/07-thread.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ C++11 引入了 `mutex` 相关的类,其所有相关的函数都放在 `<mutex
而通过其成员函数 `lock()` 可以进行上锁,`unlock()` 可以进行解锁。
但是在在实际编写代码的过程中,最好不去直接调用成员函数,
因为调用成员函数就需要在每个临界区的出口处调用 `unlock()`,当然,还包括异常。
这时候 C++11 还为互斥量提供了一个 RAII 语法的模板类 `std::lock_gurad`
这时候 C++11 还为互斥量提供了一个 RAII 语法的模板类 `std::lock_guard`
RAII 在不失代码简洁性的同时,很好的保证了代码的异常安全性。

在 RAII 用法下,对于临界区的互斥量的创建只需要在作用域的开始部分,例如:
Expand Down
4 changes: 2 additions & 2 deletions code/5/5.2.unique.ptr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ int main() {

// p2 is empty, no prints
if(p2) p2->foo();
std::cout << "p2 was destroied" << std::endl;
std::cout << "p2 was destroyed" << std::endl;
}
// p1 is not empty, prints
if (p1) p1->foo();

// Foo instance will be destroied when leaving the scope
// Foo instance will be destroyed when leaving the scope
}
4 changes: 2 additions & 2 deletions code/5/5.3.weak.ptr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ class A {
public:
std::shared_ptr<B> pointer;
~A() {
std::cout << "A was destroied" << std::endl;
std::cout << "A was destroyed" << std::endl;
}
};
class B {
public:
std::shared_ptr<A> pointer;
~B() {
std::cout << "B was destroied" << std::endl;
std::cout << "B was destroyed" << std::endl;
}
};
int main() {
Expand Down
2 changes: 1 addition & 1 deletion exercises/7/7.1/thread_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ decltype(auto) ThreadPool::enqueue(F&& f, Args&&... args) {
{
std::unique_lock<std::mutex> lock(queue_mutex);

// avoid add new thread if theadpool is destroied
// avoid add new thread if theadpool is destroyed
if(stop)
throw std::runtime_error("enqueue on stopped ThreadPool");

Expand Down

0 comments on commit a5d1563

Please sign in to comment.