Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Apr 21, 2024. It is now read-only.

Commit 9442ce5

Browse files
committed
finish Chapter3
1 parent d4807cc commit 9442ce5

11 files changed

+298
-7
lines changed

‎README.md‎

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,113 @@
1-
# read_cpp_primer
1+
# CPP Primer Note
2+
3+
This README contains important/hard points while reading the book.
4+
5+
## Reference in C++
6+
7+
### 1. No rebinding
8+
#### From the book:
9+
> A reference defines an alternative name for an object.
10+
11+
> When we define a reference, instead of copying the initializer's value, we **bind** the reference to ins initializer. There is no way to rebind a reference to refer to a different object. Thus, references **must** be initialized.
12+
13+
#### From Tensorflow:
14+
15+
https://stackoverflow.com/a/728272
16+
> The reason that C++ does not allow you to rebind references is given in Stroustrup's "Design and Evolution of C++" :
17+
>> It is not possible to change what a reference refers to after initialization. That is, once a C++ reference is initialized it cannot be made to refer to a different object later; it cannot be re-bound. I had in the past been bitten by Algol68 references where r1=r2 can either assign through r1 to the object referred to or assign a new reference value to r1 (re-binding r1) depending on the type of r2. I wanted to avoid such problems in C++.
18+
19+
20+
https://stackoverflow.com/a/728249
21+
> In C++, it is often said that "the reference is the object". In one sense, it is true: though references are handled as pointers when the source code is compiled, **the reference is intended to signify an object that is not copied when a function is called.** Since references are not directly addressable (for example, references have no address, & returns the address of the object), it would not semantically make sense to reassign them. Moreover, C++ already has pointers, which handles the semantics of re-setting.
22+
23+
### 2. Reference is not an object
24+
#### From the book
25+
> A reference is not an object. Instead, a reference is just another name for an already existing object.
26+
27+
> When we assign to a reference, we are assigning to the object bound with the reference.
28+
> When we fetch the value of a reference, we are really fetching the value of the object bound with the reference.
29+
> Similarly, when we use a reference as an initializer, we are really using the object bound with the reference.
30+
31+
https://stackoverflow.com/a/728299
32+
> A reference is not a pointer, it may be implemented as a pointer in the background, but its core concept is not equivalent to a pointer. A reference should be looked at like it **IS** the object it is referring to.
33+
> A pointer is simply a variable that holds a memory address. **The pointer itself has a memory address of its own, and inside that memory address it holds another memory address that it is said to point to.** A reference is not the same, **it does not have an address of its own**, and hence it cannot be changed to "hold" another address.
34+
>> The reference itself isn't an object (it has no identity; taking the address of a reference gives you the address of the referent; remember: the reference is its referent).
35+
36+
37+
### 3. Reference type
38+
With two exceptions, the type of a reference and the object it binds with must match exactly. Moreover, a reference may be bound only to an object, not to a literal.
39+
40+
Two exceptions:
41+
1. We can initialize [ a reference to `const` ] from any expression that can be converted to the type of the reference. We can bind a reference to `const` to a non-`const` object or literal.
42+
```C++
43+
int i = 10;
44+
const int &r1 = i; // bound with non constant int object
45+
const int &r2 = 10; // bound with int literal
46+
```
47+
Reason:
48+
When binding to an object of a different type, a temporary object is created by the compiler. I.e,:
49+
```C++
50+
double d = 1.0;
51+
const int &ri = d;
52+
```
53+
becomes:
54+
```C++
55+
double d = 1.0;
56+
const int temp = d;
57+
const int &ri = temp;
58+
```
59+
In this case, the reference is bound to a **temporary** object. If `ri` is not constant, we can assign to `ri`, which is essentially assigning to the temporary object. However, the programmer would probably expect that assigning to `ri` would change `d`, as no one would want to change the value of a temporary object. So, C++ makes this illegal.
60+
61+
2. Covered much later.
62+
63+
64+
65+
## Default Initialization
66+
- For built-in type(int, double, char, etc.), initializaed to `0` if not defined within any function, otherwise initialized to `undefined`.
67+
- For non built-in type, initialized according to the class definition.
68+
69+
## Arrays and Pointers
70+
> In C++ pointesr and arrays are closely intertwined. In particular, when we use an array, the compiler ordinarily converts the array to an pointer. ... **in most places** when we use an array, the compiler automatically substitutes a pointer.
71+
72+
Examples:
73+
1. When using `auto`
74+
```C++
75+
int arr[] = {0, 1, 2};
76+
auto ip(arr); // arr is an int * pointing to the first element
77+
```
78+
79+
2. When using subscipt
80+
```C++
81+
int arr[] = {0, 1, 2};
82+
int i = arr[2]; // arr is converted to be a pointer
83+
// equivalent to: int i = *(arr + 2)
84+
```
85+
86+
3. Multi-dimensional array Range `for`
87+
```C++
88+
constexpr size_t rowCount = 3, colCount = 4;
89+
int arr[rowCount][colCount];
90+
91+
size_t count = 0;
92+
for (auto &row : arr){
93+
for (auto &col: row){
94+
col = count;
95+
count++;
96+
}
97+
}
98+
99+
for (auto &row : arr){ // & is required even for reading (*)
100+
for (auto col: row){
101+
cout << col << endl;
102+
}
103+
}
104+
```
105+
The `&` is required to avoid the normal array to pointer conversion by the compiler. If `&` is neglected, `row` would be converted to a pointer pointing to the first element of the 4-element array, `row` has type `int *`. Then the inner loop is illegal.
106+
107+
108+
109+
110+
111+
112+
113+

‎ch2/2_const_reference_pointer_first_exception.cpp‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@ int main() {
66

77
cout << "Reference Example: " << endl;
88
// 1.1 Normal reference usage
9-
int &intRef = i;
10-
cout << intRef << endl;
11-
const int &constIntRef = i;
12-
cout << constIntRef << endl;
13-
// double &doubleRef = i; // error: type mismatch
9+
int &intRef1 = i; // nonconst int ref can bind nonconst int
10+
cout << intRef1 << endl;
11+
const int &constIntRef1 = i; // const int can bind nonconst int
12+
cout << constIntRef1 << endl;
13+
// double &doubleRef = i; // error: type mismatch
14+
15+
const int ci = 20;
16+
// int &intRef2 = ci; // nonconst int ref CANNOT bind const int
17+
const int constIntRef2 = ci; // const int ref can bind const int
1418

1519
// 1.2 Reference first exception
1620
const double &constDoubleRef = i;

‎ch2/5_sales_data_example.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ int main() {
1414

1515
if (data1.bookNo == data2.bookNo) {
1616
int total_units_sold = data1.units_sold + data2.units_sold;
17-
if (total_units_sold > 0 ){
17+
if (total_units_sold > 0) {
1818
double avg_price = (data1.revenue + data2.revenue) / total_units_sold;
1919
cout << "Result: " << data1.bookNo << " " << total_units_sold << " " << avg_price << endl;
2020
} else {

‎ch3/1.read_str‎

49.4 KB
Binary file not shown.

‎ch3/1.read_str.cpp‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <iostream>
2+
#include <string>
3+
using std::cin;
4+
using std::cout;
5+
using std::endl;
6+
using std::string;
7+
8+
int main() {
9+
// string str;
10+
// while ( cin >> str ){
11+
// cout << str << " ";
12+
// }
13+
14+
string line;
15+
cout << "getline(cin, line) reads the stream up to the first newline character \'\\n\' (inclusive)." << endl;
16+
cout << "Then it stores what is read in to the string argument, EXCLUDING the \'\\n\' character." << endl;
17+
cout << "Thus we need to manually add a endl at the end of cout." << endl << endl;
18+
19+
cout << "Enter a whole new line and will print it out: " << endl;
20+
while (getline(cin, line)) {
21+
if ( !line.empty()){
22+
cout << line << " | Length: " << line.size() << endl;
23+
}
24+
}
25+
}

‎ch3/2_change_char_in_string.cpp‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <iostream>
2+
#include <string>
3+
using namespace std;
4+
5+
int main() {
6+
string str = "aaaaaaaa";
7+
cout << str << endl;
8+
cout << "Without referene: " << endl;
9+
for (char c : str) {
10+
c = toupper(c);
11+
}
12+
cout << str << endl;
13+
14+
cout << "With reference: " << endl;
15+
for (char &c : str) {
16+
c = toupper(c);
17+
}
18+
cout << str << endl;
19+
}

‎ch3/3.iterate_char_in_string‎

48.6 KB
Binary file not shown.

‎ch3/3.iterate_char_in_string.cpp‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include <iostream>
2+
#include <string>
3+
using namespace std;
4+
5+
int main() {
6+
string str = "kobe bryant";
7+
for (decltype(str.size()) i = 0; i < str.size() && !isspace(str[i]); i++){
8+
str[i] = toupper(str[i]);
9+
}
10+
cout << str << endl;
11+
12+
for (int i = 0; i < str.size(); i++){
13+
cout << str[i] << " ";
14+
}
15+
}

‎ch3/4_vector_initialization.cpp‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include <iostream>
2+
#include <string>
3+
#include <vector>
4+
using namespace std;
5+
6+
int main() {
7+
// case 1: int, could have confusion
8+
9+
// default initialization
10+
vector<int> v1;
11+
12+
// copy elements, approach 1
13+
vector<int> v2 = v1;
14+
// copy elements, approach 2
15+
vector<int> v3(v1);
16+
17+
// list initialization, approach 1
18+
vector<int> v4 = {1, 2, 3};
19+
// vector<int> v4 = (1, 2, 3); // error, cannot use ()
20+
// list initialization, approach 2
21+
vector<int> v5{1, 2, 3};
22+
23+
// value initialization, with explicit initializer
24+
vector<int> v6(10, 1);
25+
// value initialization, without explicit initialization
26+
vector<int> v7(10);
27+
28+
29+
// case 2: string, no confusion
30+
vector<string> v8{"hi"};
31+
// vector<string> v8("hi"); // error
32+
vector<string> v8{10}; // list initialization fail
33+
vector<string> v10(10, "hi");
34+
vector<string> v11{10, "hi"}; // list initialization fail
35+
}

‎ch3/5_array_decay.cpp‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include <iostream>
2+
using namespace std;
3+
4+
int main() {
5+
// In all but two cases, when a fixed array is used in an expression,
6+
// the fixed array will decay (be implicitly converted) into a pointer that points to the first element of the array.
7+
// Fixed arry: an array whose size is known at compile time.
8+
9+
int array[5] = {9, 7, 5, 3, 1};
10+
11+
// 1. Decay happens automatically:
12+
// print address of the array's first element
13+
cout << "Element 0 has address: " << &(array[0]) << '\n';
14+
15+
// print the value of the pointer the array decays to
16+
cout << "The array decays to a pointer holding address: " << array << '\n';
17+
18+
19+
// It’s a common fallacy in C++ to believe an array and a pointer to the 1st element in the array are identical.
20+
// They’re not. In the above case, array is of type "int[5]", and it’s "value" is the array elements themselves.
21+
// A pointer to the array would be of type "int *", and its value is the address of the first element of the array.
22+
23+
// All elements of the array can still be accessed through the pointer,
24+
// but information derived from the array’s type (such as how long the array is) can not be accessed from the pointer.
25+
int arr[] = {0, 1, 2};
26+
int i = arr[2]; // arr decays to a pointer, equivalent to: int i = *(arr + 2)
27+
28+
29+
cout << *array << endl;
30+
// We’re not dereferencing the array itself. The array (of type int[5]) decays into a pointer (of type int *),
31+
// and we dereference the pointer.
32+
33+
int *ptr = array; // Decay happens.
34+
cout << *ptr << endl;
35+
36+
37+
// 2. When decay does not happen
38+
39+
// 2.1 sizeof()
40+
cout << sizeof(array) << " " << sizeof(ptr) << endl;
41+
// For array, sizeof() returns the size for entire array (array length * element size);
42+
// For pointer, sizeof() returns the size of the memory address.
43+
// An array knows the number of elements itself contains(this is part of its type information),
44+
// but a pointer to the array (pointing to the first element) does not.
45+
46+
// 2.2
47+
// The second difference occurs when using the address-of operator (&).
48+
// Taking the address of a pointer yields the memory address of the pointer variable.
49+
// Taking the address of the array returns a pointer to the ENTIRE array.
50+
// This pointer also points to the first element of the array, but the type information is different
51+
// (in the above example, int(*)[5]).
52+
53+
// https://stackoverflow.com/a/4223652
54+
return 0;
55+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /