---
tags: language
---
C++ 11 Basic
===
* Learning Resource
* **Inportant: C++ Primer(5th) is the main reference**
* [Standard C++](https://isocpp.org/)
* [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html#C++_Version)
* [How to Learn the C and C++ Languages: The Ultimate List](https://www.toptal.com/c/the-ultimate-list-of-resources-to-learn-c-and-c-plus-plus)
* [Solve C++ Code Challenges](https://www.hackerrank.com/domains/cpp)
* [在 Linux 下開發 C/C++ 的新手指南](https://medium.com/fcamels-notes/%E5%9C%A8-linux-%E4%B8%8B%E9%96%8B%E7%99%BC-c-c-%E7%9A%84%E6%96%B0%E6%89%8B%E6%8C%87%E5%8D%97-735fcd960b0)
* [C++ application development ( Part 1 — Project structure )](https://medium.com/heuristics/c-application-development-part-1-project-structure-454b00f9eddc)
# C++ Development Common Sense
## 高階程式語言:
電腦可以了解的語言就是以0/1為主的機器語言,後續發展出配合簡單符號的組合語言(EX:ADD表示+, MOV代表資料傳送...等),後續再編譯成機器語言以降低編程複雜性,但無論是機器語言還是組合語言都是面向硬體操作的,需要比較深的電腦硬體知識才能編寫。最終,比較貼近人類語言,又不太依賴硬體的高階語言被發明出來,C++就是一種高階語言。只要配上相對應的**編譯**或**直譯**程式,其程式就可以在電腦正常運作。
## 編譯器:
* 高階語言的**編譯**,是指透過事先寫好一個稱為**編譯器**的程式語言,其作用是把來源程式**整個翻譯**成用機器語言表示的執行程式,這樣目的程式可以脫離原本語言環境獨立執行,效率較高,C++語言需要先經過編譯才能執行。
* 相對於編譯的就是**直譯**,可以比喻成同聲翻譯,其是原始程式碼是由對應的直譯器一邊轉成機器語言一邊執行,整體靈活性較佳,但執行時相對較沒效率,Python就是一種直譯語言。
## C++ History:
* C++ 是1979年 Bjarn Stroustrp想把 UINX分佈到由區域網連接起來的網路上時,需要將內核模組化卻沒有適合工具時,其在C語言添加類似Simula的類別機制,稱為 Cpre(可以執行預處理的 C)。持續發展到 1985年,第一個C++ Release E發布,後續持續發展編準如下:

* 目前 有五個正式的 C++ 版本,分別以 "C++" 開頭再加上被 ISO 採納為標準的年度:
* C++98
* C++03:與 C++98 只有技術細節的差異
* C++11
* C++14:是 C++11的母集合(superset)
* C++17
* C++ 是從C語言發展而來,其後續發展都最大程度兼容 C語言,很多 C語言不用特別修改就可以被C++ 編譯器編譯,算是 C語言的超集合。
* C++ 設計成直接的和廣泛的支援多種程式設計風格(**程序化程式設計**、**資料抽象化**、**物件導向程式設計**、**泛型程式設計**),且其給程式設計者更多的選擇(即使可能導致程式設計者選擇錯誤)讓C++ 的學習曲線較很多其他語言高。
## C++ Compile Process
C++ compilation process looks like this:
1. Peprocessing(預處理):(處理跟#開頭有關的東西)
The C++ preprocessor copies the contents of the included header files into the source code file, generates macro code, and replaces symbolic constants defined using #define with their values.
2. Cmpile(編譯): 把原始碼翻譯成系統對應的組合語言(assembly)
The expanded source code file produced by the C++ preprocessor is compiled into the assembly language for the platform.
3. Assemble: 把組合語言轉換成可執行的機器碼
The assembler code generated by the compiler is assembled into the object code for the platform.
4. Linking(連結): 將一個或多個由編譯器或組譯器生成的目標文件和外加函式庫連結為一個可執行文件
The object code file generated by the assembler is linked together with the object code files for any library functions used to produce an executable file.


Compile .cpp file in Linux by gcc:
```bash
# run whole process
$ g++ -Wall -std=c++11 -o OutputFile CppFile.cpp
# Stop after preprocessor step
$ g++ -Wall -std=c++11 -E CppFile.cpp
# stop after compile step
$ g++ -Wall -std=c++11 -S CppFile.cpp
# stop after assembly step
$ g++ -Wall -std=c++11 -c CppFile.cpp
# -Wall: show warning message
# -Wextra: show more error message
# -pedantic: show unstandard c syntax error
```
* [一个C/C++程序从编译到最终生成可执行文件的全过程分析](https://blog.csdn.net/weibo1230123/article/details/79970866)
* [C++的编译过程及原理](https://blog.csdn.net/qq_43133135/article/details/82865618)
## Why & What is linked with object code?
早期在記憶體昂貴且設備很慢的時代,把函式庫的程式碼包含進新開發的應用程式一起編譯的話,會花費非常久的時間,為了縮短編譯時間,程式設計師將函式庫的原始碼獨立出來並分別編譯好後,再將二進位制檔放到當時磁性原理下的已知記憶體位址(可以放一段時間),執行應用程式前會先載入二進位制函式庫後在載入應用程式。
因應函式庫特定記憶體位址的方式產生很多問題(程式和函式庫碎片化),因此發展出了**鏈結器(linking) 和 載入器(loader)**,功能如下:
* 鏈結(linking):將函式庫函式的外部參考,連結到某程式定義之函式庫函式的外部定義,其輸出是一個可重置位址的鏈結。
* 載入(loader):其可以將程式和函式庫載入時重新定址,。
以上在電腦設備緩慢的年代是分兩階段進行,在電腦運作快速的現代,單一鏈結載入器(linking loader) - 也就是載入時同時進行鏈結。
# Basic Knowledge Behind Data
* What is Bit:
* Inside the computer's world, there is only data. All data is stored as long sequences of bits. Bits are any kind of two-valued things, usually described as zeros and ones.
* Inside the computer, they take forms such as a high/low electrical charge, a strong/weak signal, or a shiny/dull spot on the surface of a CD.
* Any piece of discrete information can be reduced to a sequence of zeros and ones and thus represented in bits.
* Byte: Most computers deal with memory as chunks of bits of size that power of 2. The smallest chunk of addressable memory is referred to as a "byte" (8-bits)
## Numeral System
### Decimal for human
A decimal system involves counting in units of ten
Power is decimal system, so we can convert any numeral system to decimal by power:
* $1*10^4+ 2*10^3+ 3*10^2+ 4*10^1 + 5*10^0=12345$
* $(213)_4 = 2*4^2 + 1*4^1 + 3*4^0 = (39)_{10}$
* $(4301)_5 = 4*5^3+3*5^2+0*5^1+1*5^0 = (576)_{10}$
### Binary for computer
Binary is a base 2 number system invented by Gottfried Leibniz that is made up of only two numbers: 0 and 1.
In computer world,electronic structure can distinguish 0, 1 with ease.
* Binary => Decimal:
$(1110011)_2=1*2^6+1*2^5+1*2^4+0*2^3+0*2^2+1*2^1+1*2^0+=(115)_{10}$
* Decimal => Binary:
1. Devide the number by 2.
2. Get the integer quotient for the next iteration.
3. Get the remainder for the binary digit.
4. Repeat the steps until the quotient is equal to 0.
Convert $(13)_{10}$ to binary.
|Division by 2|Quotient|Remainder|
|----|----|----|
|13/2|6|1|
|6/2|3|0|
|3/2|1|1|
|1/2|0|1|
$(13)_{10} = (1101)_2$
* 白話說明 13 = 8+4+1:
* 除了3次2還餘1,有一個 8 ($2^3$)
* 除了2次2還餘1,有一個 4 ($2^3$)
* ...
### Compression Binary: Octal & Hexadecimal
Large number representation by binary is too long. The Octal and Hexadecimal is usage for short representation because multiple of two is convenient to convert to binary.
|binary|110|111|010|110|
|----|----|----|----|----|
|Octal|6|7|2|6|
|binary|1101|1110|0010|0011|
|----|----|----|----|----|
|Hexa.|D|E|2|3|
[Reference: Numeral system converted by c++](https://www.geeksforgeeks.org/program-decimal-hexadecimal-conversion/)
[My C++ code](https://github.com/EricYangsw/cpp_learning_note/blob/master/numeral_system.cpp)
```cpp
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
/*
void quick_tobinary(int n){
string r;
while(n!=0) {r=(n%2==0 ?"0":"1")+r; n/=2;}
cout << "quick_tobinary:" << r << endl;
}
*/
void numeral_convert(int decimal, const int convert){
string r;
int i = 0;
int remainder;
while (decimal != 0){
remainder = decimal % convert;
if (remainder < 10)
r = to_string(remainder) + r;
else{
char c = remainder + 55;
r = string(1, c) + r;
}
i++;
decimal = decimal / convert;
}
cout << "ANS: " << r << endl;
}
int main(){
int decimal = 0;
int c = 0;
cout << "input a integer number: ___ (decimal)" << endl;
cin >> decimal;
cout << "Choice a numeral system to converted: __" << "\n"
<< " -Input 2 : Binary !" << "\n"
<< " -Input 8 : Octal !" << "\n"
<< " -Input 16 : Hexadecimal!" << endl;
cin >> c;
numeral_convert(decimal, c);
//quick_tobinary(decimal);
return 0;
}
```
## Bitwise Operation
* a Bit in computer is a 0/1 of binary sequence.
* a Byte include 8 Bit.
* 1KB = 1024Byte; 1MB=1024KB; 1GB=1024MB
In c++ there are 6 basic bit operator:
|Operator|Mean|
|---|---|
|&|and(bitwise)|
|||or (bitwise)|
|^|xor (bitwise)|
|~|opposite|
|<<|move left|
|>>|move right|
For example:
```cpp
# include<iostream>
# include<bitset>
# include<stdio.h>
using namespace std;
// and operation
void int_and_op(int a, int b){
int ans = a&b;
bitset<8> a_bit(a);
bitset<8> b_bit(b);
bitset<8> ans_bit(ans);
cout << a_bit << '\n'
<< b_bit << '\n'
<< ans_bit << endl;
}
// and operation: judge odd integer number
void is_odd(int n){
const int one = 1;
cout << (n & one ? 'Y', 'N')
}
// exange the value of int a, b by XOR
void exange(int *a, int *b){
*a = *a^*b;
*b = *b^*a;
*a = *a^*b;
}
bool is_opposite_signs(long long int_a, long long int_b){
return ((int_a ^ int_b) < 0);
}
int addOne(int x){
int m = 1;
while (x & m){
bitset<8> bit_x = x;
bitset<8> bit_m = m;
x = x ^ m;
m = m << 1;
bitset<8> bit_xor_xm = x;
cout << bit_x << "\n"
<< bit_m << "\n"
<< bit_xor_xm << "\n\n" << endl;
}
x = x ^ m;
return x;
}
int multiplyWith3Point5(int x){
return (x<<1) + x + (x>>1);
}
```
```cpp
//Swap bits in a given number & position
#include<iostream>
#include<bitset>
using namespace std;
void show_bitset(int x){
bitset<8>output(x);
cout << output << endl;
}
int swap_bit(unsigned x, unsigned p1, unsigned p2, unsigned n){
/* set1 = take n bit from p1
* set2 = take n bit from p2
* using xor operation to swap value
* EX: c = a ^ b, then b = c ^ a
* a = c ^ b
*/
// Move set1 to rightmost side, then & with 1 at same position
unsigned int set1 = (x >> p1) & ((1U << n) - 1);
// Move set2 to rightmost side, then & with 1 at same position
unsigned int set2 = (x >> p2) & ((1U << n) - 1);
// first xor
unsigned int Xor = (set1 ^ set2);
// let two set back original position(or with 0 can keep original value)
unsigned int Xor = (Xor << p1) | (Xor << p2);
// second xor
unsigned int result = x ^ Xor;
return result;
}
int main(){
int a = swap_bit(12, 1, 3, 2);
return 0;
}
```
Bitwise operation usage scenarios:
* Bit fields (flags)
They're the most efficient way of representing something whose state is defined by several "yes or no" properties. ACLs are a good example; if you have let's say 4 discrete permissions (read, write, execute, change policy), it's better to store this in 1 byte rather than waste 4. These can be mapped to enumeration types in many languages for added convenience.
* Communication over ports/sockets
Always involves checksums, parity, stop bits, flow control algorithms, and so on, which usually depend on the logic values of individual bytes as opposed to numeric values, since the medium may only be capable of transmitting one bit at a time.
* Compression, Encryption
Both of these are heavily dependent on bitwise algorithms. Look at the deflate algorithm for an example - everything is in bits, not bytes.
* Finite State Machines
I'm speaking primarily of the kind embedded in some piece of hardware, although they can be found in software too. These are combinatorial in nature - they might literally be getting "compiled" down to a bunch of logic gates, so they have to be expressed as AND, OR, NOT, etc.
* Graphics
There's hardly enough space here to get into every area where these operators are used in graphics programming. XOR (or ^) is particularly interesting here because applying the same input a second time will undo the first. Older GUIs used to rely on this for selection highlighting and other overlays, in order to eliminate the need for costly redraws. They're still useful in slow graphics protocols (i.e. remote desktop).
More: [Bitwise Algorithms](https://www.geeksforgeeks.org/bitwise-algorithms/)
# Variable & Baic Types
* Types are fundamental to any program: They tell us what our data mean and what operations we can perform on those data.
* Except several primitive types, C++ provides mechanisms that let us define our own data types.
* The library uses these mechanisms to define more complicated types such as vectors, variable-length character string, and so on.
## Primitive Built-in Types
* C++ defines a set of primitive types that include the:
* **arithmetic** types (such as characters, integers, boolean, floating-point)
* a special type named **void**. Void type is most commonly as the return type for function that do not reutrn a value.
### Arithmetic Types:
* The arithmetic types are divided into two categories:
* integral: include character, integers, boolean
* floating-point: single-, double-, extended-precision values
* The types list with minimum sizes:

* character:
* there are several character types because of supporting internationalization
* basic char hold a numeric values corresponging to the characters with the same of byte(8 bits)
* wchar_t: guarateed to be large enough to hold character in the machine's largest extended character set
* char16_t / char32_t are intended for Unicode characters
* float-point:
* typically, floats are represented in one word(32 bits)
* float usually does not have enough precision
* double: two words(64 bits)
* on some machines, double-precision operations are faster than single
* long double: 3~4 words
* note: word是處理器指令集存取 memory 的單位,某些架構中,一個word 表示4個 bytes (32 bits)
* Signed and Unsigned Types of Integral:
* Signed: represent negative or positive numbers
* int, short, long, long long are all signed
* Unsigned: represent only values greater than or equal to zero
* add ```unsigned``` key word in front of above signed types
### Type Conversions:
* automatically conversions:
* when?: using a object of type where an object of another type is expected
* example:
```cpp
bool b = 42; // b in true
int i = b; // i has value 1
i = 3.14; // i has value 3
double pi = i; // pi has value 3.0
unsigned char c = -1; // assuming 8-bits char, c has value 255
signed char c3 = 256; // assuming 8-bits char, the values of c2 is undefined
```
* assign an **out-of-range** value to **unsigned**: result is remainder of target unsigned type can hold
* assign an **out-of-range** value to **signed** type: result is **undefined**
* compiler is not required to detect the undefined behavior result
* there is no guarantee that all compilers have same result of an same program with undefined behavior
### Literals:
* a value, such as **42**, is known as a **literal** because its value self-evident
* every literal has a type
* integer literal:
* ```29 ```: decimal, default is signed
* ```024```: octal
* ```0x14```: hexadecimal
* floating-point literal:default is double
* ```3.14159```
* ```3.14159E0```
* ```0.```
* ```0e0```
* ```.01```
* character & character String literal:
* ```'a'```: character literal
* ```"Hello"```: string literal
* string literal is an array of constant chars
* compiler appends a null character ```'/0'``` to every string literal
* ```std::string string_a ="a";``` => ```char array_a = {'a', '\n'};```
* escape sequences:

* numerical value of the character:
* ```\x``` + hexadecimal digis
* ```\``` + one, two, three octal digits
## Variables
* a variable provides us with named storage that our programs can manipulate
* each variable in c++ has a type that determines
* the size of memory
* layout of the memory
* the range of values that can be stored
* a set of operations
### Variable Definitions
* C++ programmers tend to refer to variables as “variables” or “objects” interchangeably.
* Most generally, an object is a region of memory that can contain data and has a type.
* simple variable definition:
* ```type_specifier var_name1, var_name2=init_value,...;```
* Initializers:
* different way to initialize:
* ```int units_sold = 0;```
* ```int units_sold = {0}; //list initialization```
* ```int units_sold{0}; //list initialization```
* ```int units_sold(0); //list initialization```
* initialization in C++ is a surprisingly complicated topic
* Initialization and assignment(```var = value;```) are different operation in C++. But the distinction often doesn't matter.
* When used with variables of built-in type. The compiler will not let us use **list initialize** if the initializer might lead to the imformation lose.
```
long double ld = 3.141596;
int a{pi}; //error
```
* We recommend initializing every object of built-in type.
### Variable Declarations and Definitions
* C++ supports what is commonly known as **separate compilaion** and it let us can split our programs into several files taht can be compiled independently.
* To support separate compilation, C++ distinguishes between **declarations** and **definitions**. The distinction is important in the variable usage in more than one file.
* declaration: makes a name known to the program
* specifies the type and name of variable
* in multiple files, one file define and other files of using variable must declare variable (no define).
* definition: create the associated entity
* declaration + allocates storage and may provide an initial value.
* in multiple files, variable define in one-and only one-file.
### Identifiers:

* There are a number of generally accepted conventions for naming variables:
* An identifier should give some indication of its meaning.
* Variable names normally are lowercase
* classes define usually begin with an uppercase letter
* identifiers with multiple words should visually distinguish each word
### Scope of a Name:
* At any particular point in a program, each name that is in use refers to a specific entity(a variable, function, type, and so on).
* However, a given name can be reused to refer to different entities at diffetent points in the program.
* **Scope**: a part of the program in which a name has a particular meaning.
* Most scopes in C++ are delimited by curly braces **{}**.
* An example:
```cpp
#include <iostream>
int main()
{
int in_main = 0;
for (int in_for =0; in_for<10; in_for++)
in_main += in_for;
std::cout << in_main << std::endl;
}
```
* ```main```:
* be defined outside any curly braces
* global scope
* ```in_main```:
* be defined within the scope of the block that is the body of the main function
* accessible from its point of declaration throughout the rest of the main funciton
* ```in_for```:
* be defined in the scope of for statement
* cannot be accessible out of for statement
* ```cout``` , ```endl```:
* uses a namespace names ```std```
* along with ```cout```&```endl``` from this namespce
* Nested Scpoe:
* Scopes can contain other scopes
* the contained scpoe is **inner scpoe**
* the containing scpoe is **outer scope**
* Once a name has been declared in a scope, that name can be used or redefined in inner scope
* Example:
```cpp
#include <iostream>
int reused = 42; // reused has global scope
int main()
{
int unique = 0; // unique has block scope
// output 1: uses global reused; prints 42 0
std::cout << reused << " " << unique << std::endl;
int reused = 0; // new, local object named reused hides global reused
// output 2: uses local reused; prints 0 0
std::cout << reused << " " << unique << std::endl;
// output 3: explicitly requests the global reused; prints 42 0
std::cout << ::reused << " " << unique << std::endl;
return 0;
}
```
* Output 3: uses the scope operator to override the default scoping rules. And the global scope has no name.
* Hence, when the scope operator has an empty left-hand side, it is a request to fetch the name on the right-hand side from the global scope.
* Thus, this expression uses the global reused and prints 42 0.
### Compound Types:
* 前導:
* 程式的指令和資料都是存在記憶體中,編譯器的工作流程就是將程式中的變數和操作,翻譯成針對記憶體位址進行操作的機器語言。
* 記憶體管理:記憶體被劃分成很多小單元,然後會被給予一個編號 (Ex: 0x0019F878)
* 變數名稱算是記憶體儲存單元一個"臨時別名",**位址**才是儲存單元的永久真名(無法更改與重複)
* A compound type is a type that is defined in terms of another type.
* **reference**
* A reference defines an alternative name for an object.
* A reference is not an object. It's just another name for an already existing.
* defined by "&" symbol:
```cpp
int i = 100, i2=200;
int &r = i, &r2 = i2, &r3 = i2;
```
* 因為只是別名,所以無法指向空值的 reference, 因此效率較高
* 使用 reference 無須測試其合法性,因為不可能為空
* 不能建立 reference of array, 因為陣列是某種資料類型的集合,而陣列名稱只是表示其第一個位址
* When we use the term **reference**, we mean **lvalue reference**. **rvalue reference** is difference
* **pointers**
* pointer is used to "points to" another type
* unlike a reference, pointer is an object and it hold a address of another object
* a pointer with a sizeof 8 (bits)
* unlike a reference, pointer need not be initialized at the time it is difined.
* define pointer by **/*** symbol:
```cpp
int *p1, *p2;
int a = 10;
p1 = &a; //p1 hold the address of a
```
* The value (address) stored in a pointer can be in one of four states:
* it can point to an object
* It can point to the location just immediately past the end of an object.
* It can be a null pointer, indicating that it is not bound to any object.
* It can be invalid; values other than the preceding three are invalid.
* when a pointer point a object, the deference operator (*) can be used to access that object:
```cpp
int a = 10;
int *p = &a;
std::cout << p << "\n" // 0x0000141412
<< *p << std::endl; // 10
*p = 20; // change the value of a
```
* void *p
* void* is a special pointer type that can hold the address of any object.
* we use a void* pointer to deal with memory as memory
* compare it to another pointer
* pass it to or return from a function
* assign it to another void* pointr
* We cannot use a void* to operate on the object it address
* pointer to pointer:
```cpp
int ival = 1024;
int *pi = &ival; //pi have a address, it just hold another address
int **ppi = π
```

* null point:
```cpp
int *p1 = nullptr; // most direct approach
int *p2 = 0;
int *p3 =NULL;
```
* other compound type:
* pointers to data members
* array
* function
* class
* enumeration
* **&** 以及 **/*** 當成運算子時:
* 這兩個運算子是 C 語言
* **&** 運算子:可以看成是用來返回一個變數或運算式所佔據的記憶體位址
* **\*** 運算子:是用來返回一個變數或運算式對應位址所儲存的數值
### const Qualifier:
* Basic:
* Sometimes we want to define a variable whose value we know connot be changed.
* make a variable unchangeable by defining the variable's type as ```const```
* example:
```cpp
const int bufSize = 512;
```
* any attempt to assign to bufSize is an error
* const object must be initialied
```cpp
const int i = get_size(); //initialized at run time
const int j = 42; //initialized at compile time
const int k; //erroe
```
* restriction of operations on const type is that we may use only operations that connot change an object
* References to **const**:
* bind a reference to an object of a const type
* we connot assign directly to ci, we also should not be able to use a reference to change ci
```cpp
int i = 42;
const int ci = 42;
const int &r1 = ci; // ok
const int &r2 = i; // ok
const int &r3 = r2 * 2; // ok
r1 = 42; //error
int &r2 = ci; //error
```
* Pointers and **const** :
* example:
```cpp
const double pi = 3.14;
double *ptr = π
const double *cptr = π
```
* const Pointers:
* pointers are object (unlike reference)
* we can have pointer is itself const
```cpp
int errNumb = 0;
int *const curErr = &errNumb; // always point to errNumb
const double pi = 3.14;
const double *const pip = π //pip is a const pointer to a const object
```
* Top-Level const:
* we use the term **top-level const** to indicate that the pointer itself is a const
* more generally, top-level const indicates that an object itself is const
* top-level const can appear in any object type
* low-level const:
* when a pointer can point to a const object, we refer to that const as a **low-level const**
* low-level const appears in the base type of compound types such as pointer or reference
* pointer types can have both top-level and low-level const independently
* **constexpr** Variavles:
* ...
### Dealing with Types:
* **type alias** :
* a type alias is a name that is a synonym(同義字) for another type
* purpose :
* simplify complicated type definition
* emphasize the purpose for which a type is used
* use a **typedef** to define a type alias:
```cpp
typedef double wages; // wages is a synonym for double
typedef wages base, *p; // base is a synonym for double, p for double*
```
* second way to define a type alias, **using**:
```cpp
using wages = double;
```
* **auto** type specifier:
* when we write a program, it can be surprisingly diffcult - and sometimes even impossible to determine the type of an expression
* C++11 有三組推導型別規則,一是 **template**, 一是**auto** 使用, 一是 **decltype** 使用,C++14又接著擴展後面兩者的使用情境
* **auto** let the compiler figure out the type for us
```cpp
#include<iostream>
int main(int argc, char *argv[]){
unsigned long v1{100}, v2{200};
auto vv = v1+ v2;
std::cout << vv << std::endl;
auto i = 0, j = 0; // of, i & j is same tyep
auto ii = 0, jj = 0.1; // error
return 0;
}
```
* auto with compound types and const:
* the type that compiler infers for auto is not always exactly the same as the initializer's type
* instead, the compiler adjusts the type to conform to normal initialization rules
* ex: reference
```cpp
int i =0, &r = i;
auto a = r; // a is an int
```
* ex: auto ordinarily ignores top-level consts, but low-level const is kept
```cpp
int i = 0;
const int ci = i, &cr = ci;
auto b = ci; // b is an int (drop const)
auto c = cr; // c is an int (cr is a alias of ci whose type is int)
auto d = &ci; // d is const int*
```
* directly define const type:
``` const auto e = ci;```
* **decltype** type specifier:
* Sometimes we want to define a variable with a type that compiler deduces from an expression but do not want use the initalize the variable.
* **decltype** return the type of its operand
* ```decltype(f()) sum = x;``` sum has whatever type f returns
```cpp
const int ci = 0, &cj = ci;
decltype(ci) x = 0; // x has type const int
decltype(cj) y = x; // y has type const int& and is bound to x
decltype(cj) z; // error, reference must be initialized
```
### defining our own data structure:
* at the most basic level, a data structure is a way to group together related data elements and a strategy for using those data
* in C++, we define our own data tyeps by defining a class
* **struct**:
* the library types **string, istream, ostream** are all defined as classes
* defining a class that does not support any operations can use **struct** :
```cpp
struct Sales_data {
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
```
* the class body is surrounded by curly braces and forms a new scope
* the semicolon followed body is needed because we can define variabel after the call body:
```cpp
struct Sales_data{...} a, b, c;
// equivalent, but better way to define object
struct Sales_data{...};
Sales_data a, b, c;
```
* in above example, we only have data **members**
* each object have its own copy of the class data members
* using class:
```cpp
#include <iostream>
#include <string>
#include "Sales_data.h"
int main(int argc, char *argv[]){
Sales_data data1;
double price = 0;
std::cin >> data1.bookNo >> data1.units_sold >> price;
data1.revenue = data1.units_sold * prince;
}
```
* writing our own **header files**:
* if we use a class in several different files, classes are usually defined in **header files**
* typically, classes are stored in headers whose name derives from the name of the class
* ``` class_name.h ```
* headers (usually) contain entities (such as class definitions and const and constexpr variables) that can be defined only once in any given file
* include header file multi times :
* In above case, the **string** must be included in one header file. If another file need using string, they need include twice.
* write our headers in a way that is safe even if the header is included multiple times : it is **preprocessor**
* **preprocessor**
* it is inherits from C
* it is a program that runs before the compiler and changes the source text of our programs
* our program already rely on one preprocessor facility, **#include**
* when the preprocessor sees a **#include**, it replaces the **#include** with the contents of the specified header
* **header guards**:
* rely on preprocessor variables
* preprocessor variables have one or two possible states: defined or not defined
* **#define** directive takes a neme and defines that name as a preprocessor variable
* **#ifdef** is true if the variable has been defined
* **#ifndef** is ture if the variable has not been deined
* **#endif**
* example:
```cpp
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <string>
struct Sales_data {
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
#endif
```
* The first time Sales_data.h is included, the ```#ifndef``` test will succeed. The preprocessor will process the lines following ```#ifndef``` up to the ```#endif```. As a result, the preprocessor variable SALES_DATA_H will be defined and the contents of Sales_data.h will be copied into our program.
* If we include Sales_data.h later on in the same file, the ```#ifndef``` directive will be false. The lines between it and the #endif directive will be ignored.
# Strings, Vectors and Arrays
* Basic build-in types:
* such as int, float... are defined direcly by the C++ language.
* These types represent facilities present in most computer hardware, such as numbers or characters...
* array:
* Higher-level types:
* string:supports variable-length character strings
* vector:variable-size collections
* iterators:be used to access the characters in a string or the elements in a vector...
* ...
## Namespace "using" Declarations
* scope operator (::):
* the complier should look in the scope of the left-hand operand for the name of right-hand operand
* ```std::cin``` is mean that using the name **cin** from the namespce **std**
* **using** declaration:
* let us use a name from a namespace without qualifying the name with **namespace_name::** prefix
* fome1: ```using namespace::std;```
* fome2: ```using std::cin;```
* Headers should **not** include ```using``` declaration
## Library String Type
* string is a variable-length sequence of characters
* how to use:
```cpp
#include <string>
std::string s1 = "some characters";
std::string s2(10, 'c');
std::string s3 = s1;
stdllstring s4("some_characters");
```
* initializing by assign ```=``` called **copy initialization**
* it is asking the compiler to copy the initilizer on the right-hand side into the object being created
* when we omit the ```=```, we use direct initialization
* Operations on strings:
* whole function:

* try function:
```cpp
#include <iostream>
#include <string>
int main(){
std::string s1("This is a string!");
std::string s2(10, 'g');
std::string s3 = s1 + s2;
s1.size();
s2.empty();
char c1 = s2[10]; // get char
bool b = (s1==s2); // >, >=, <, <=, !=
return 0;
}
```
* **getline()**: Reading an Entire Line of strings
```cpp
int main(){
std::string line;
while (getline(std::cin, line))
if (!line.empty())
std::cout << line << std::endl;
return 0;
/* just read a string:
std::string words;
std::cin >> words;
* /
}
```
* empty()
* a member function of string
* it returns a bool indicating whether the string is empty
* size()
* as member function of string
* return the length of string
* return a ```string::size_type``` value
* it is a companion types of string
* using scop operator to say that the name ```size_type``` is defined in the string class
* it's an **unsigned** type and **big enough** to hold the size of any string
* ```auto``` or ```decltype``` are work
```cpp
std::string line("hello");
auto len = line.size();
```
* Comparing strings:
* ```==``` & ```!=``` test whether two strings are equal(same lenght & characters) or unequal
* ```>, <, ```
* Dealing with the Characters in a string

* Use Range-Base ```for```
* Basic
```cpp
std::string s1("The is a string!");
char h;
for (auto c : s1){
h = toupper(c);
std::cout << c << " : "
<< h << std::endl;
}
```
* Reference
```cpp
std::string s("Hello!!");
for (auto &c : s)
c = toupper(c);
std::cout << s << std::endl; // HELLO!!
```
* covert to hexadecimal:
```cpp
#include <iostream>
#include <string>
int main(int argc, char *argv[]){
std::string hex = "0123456789ABCDEF";
std::string result;
std::string::size_type n;
for (int i=0; i<5; i++){
std::cin >> n;
if (n < hex.size())
result += hex[n];
}
std::cout << result << std::endl;
return 0;
}
```
## Library vector Type
* Basic Introduction:
* A **vector** is a collection of objects, all of which have the same type.
* every object has an index
* a **vector** is often referred to as a **container** because it "contains" other object
* a **vector** is a **class template**
* C++ has both class and function templates.
* Template can be thought of as instructions to the compiler for generating class or function
* the process is called **instantiation**
* For a class template, we specify which class to instantiate by supplying additional information in a pair of angle brackets
* reference is not object, therefore we cannot have a vector of references
* How to use?
```cpp
#include <vector>
std::vector<int> my_int_vector;
std::vector<std::vector<std::string>> file;
```
* most common ways to define vectors:

* vectors operations

* Some example:
```cpp
#include <iostream>
#include <string>
#include <vector>
int main(int argc, char *argv[]){
// initialize vector
std::vector<int> empty_int_vec;
std::vector<float> flo_vec(10.);
std::vector<char> char_vec(10, 's');
std::vector<std::string> str_vec{"aa", "bb", "cc"};
std::vector<std::string> str_vec2 = {"aa", "bb", "cc"};
// copy elements from another vector
std::vector<int> int_vec(100);
std::vector<int> new_int_vec = int_vec;
std::vector<int> new_int_vec2(int_vec);
std::vector<int> int_list;
for (int i=0; i<100; i++)
int_list.push_back(i);
for (auto &i : int_list)
i *= i;
for (auto i : int_list)
std::cout << i << std::endl;
for (decltype(int_list.size()) xi; xi<20; xi++)
std::cout << int_list[xi] << std::endl;
return 0;
}
```
## Introducing Iterators
* Describe:
* we can use **iterators** to access the elements of **container**
* in addition to vector, the library defines several other kinds of **container**
* all of library containers have iterators type to support the action of an (conceptual) iterator
* like **pointers**, iterators give us indirect access to an object
* using iterators
* begin() and end() operations:
```cpp
std::vector<int> v{1,2,3,4,5};
const std::vector<int> cv{5,4,3,2,1};
auto it1 = v.begin(); // it1 has type vector<int>::iterator
auto it2 = cv.begin(); // it2 has type vector<int::const_iterator
atuo it3 = v.cbegin(); // vector<int::const_iterator
```
* iterators use the increment (++) operator to move fom one element to the next
```cpp
std::string s("some_test!");
for ( auto it=s.begin(); it != s.end(); ++it)
*it = toupper(*it);
std::cout << s << std::endl;
```
* When we dereference an iterator, we get the object that iterator denotes.
* if that object has a class type, we can access a member of object by
```cpp
(*it).member();
(*it)->member();
```
* exemple:
```cpp
std::vector<std::string> str_vec{"a", "bb", "ccc"};
for (auto it2=str_vec.begin();
it2 != str_vec.end();
it2++){
std::cout << *it2 << "\t"
<< (*it2).size() << "\t"
<< it2->empty() << "!"
<< std::endl;
```
* Iterator Arithmetic
* All the library containers have iterators that support increment that moves the iterator one element at a time.
* we can use ```==``` ```!=``` to compare two valid iterators into any of the library containers types.
* Iterators for string & vactor support additional operations that can move an iterator multiple elements at a time.

* example1:
```cpp
std::vector<std::string> str_vec{"a", "bb", "ccc"};
auto mid = str_vec.begin() + (str_vec.size()/2);
std::cout << *mid << std::endl; // print: "bb"
```
* example2:
```cpp
int fine_int(std::vector<int> list, int sought){
auto beg = list.begin();
auto end = list.end();
auto mid = beg + (list.size()/2);
while (mid != end && *mid != sought){
if (sought < *mid)
end = mid;
else
beg = mid + 1;
mid = beg + (end-beg)/2;
}
return *mid;
}
```
## Array
* Basic concept:
* An array is a data structure that is similar to the library vector type but offers a different trade-off between performance and flexibility.
* same: array is a container of unnamed object of a single type that we access by position
* array can hold objects of most any type
* different:
* array is fixed size
* connot add elements to an array
* note: if you don't know exactly how many elements you need, use a vectoe
* array is a compound type
* declarator array: ```type array_name[dim];```
* dimension must be known at compile time; which means that the dimension must be a constant expression
* initialize an array:
```cpp
const unsigned sz = 3;
int ia1[sz] = {0,1,2};
int a2[] = {0,1,2}; //dim. 3
int a3[5] = {0,1,2}; // {0,1,2,0,0}
string a4[3] = {"hi", "go"}; //{"hi", "go", ""}
int a5[2] = {0,1,2}; //error
//char
char ar1[] = {'c', '+', '+'}; // dim. 3
char ar2[] = {'c', '+', '+', '\0'}; // dim. 4
char ar3[] = "c++"; //dim. 4
const char ar4[6]="daniel"; // error, no null
int a5[] = a2; //error, connot initialize one array with another
a2 = ia1; // error, connot assign one error to another
```
* Complicated array declarations
* array of pointer or point to an array (no reference of array, because reference is not an object)
```cpp
int *ptrs[10]; // array hold a ten pointer
int &refs[] = /* ? */; //error
int (*parray)[10] = &arr; //parray points to an array of ten ints
int (&arrRef)[10] = arr; //arrRef refers to an array of ten ints
```
* tips: type modifiers bind right to letf
* Accessing the elements fo an Array
* **size_t** type:is a machine-specific unsigned type that is guaranteed to be large enough to hold the size of any object in memory
* example:
```cpp
unsigned scores[11] = {}; // 11 buckets, all value intialized to 0
unsigned grade;
while (cin >> grade){
if (grade <= 100)
++scores[grade/10]; // increment the counter for the current cluster
}
```
```cpp
for (auto i : scores)
std::cout << i << " ";
std::cout << endl;
```
* Pointers and arrays
* in C++ pointers and arrays are closely inertwined
* when we use an array, the compile ordinary converts the array to a pointer
* normally, we obtain a pointer to an object by using the address-of operator
* example:
```cpp
string nums[] = {"one", "two", "three"};
string *p = &nums[0];
string *p2 = &nums;
// p & p2 all point to nums[0]
```
```cpp
int ia[] = {0,1,2,3,4,5};
auto ia2(ia); //ia2 ia an int* that point to the first elemnet of ia
decltype(ia) ia3 = {0,1,2,3,4,5}; // ia3 ia an array of ten ints
```
* pointers are iterators
```cpp
int arr[] = {0,1,2};
int *p = & arr;
++p; // p point to arr[1]
int *e = &arr[4]; // pointer just past the last element in arr
for (int *b=arr; b!=e; ++b)
std::cout << *b << std::endl;
```
* Library begin() and end() functions
```cpp
int ia[] = {0,1,2,3};
int *beg = begin(ia); // begin() returns a pointer to the first
int *last = end(ia); // end() returns a pointer to the last
while (beg != last)
++beg;
```
* Pointer Arithmetic
```cpp
constexpr size_t sz = 5;
int arr[sz] = {0,1,2,3,4};
int *ip = arr; // => int *ip = &arr[0]
int ip2 = ip + 4; // points to arr[4]
auto n = end(arr) - begin(arr); // n is 5
```
* C-Style Character Strings
...
## Multidimensional Arrays
* Strictly speaking, there are no multidimensional arrays in C++
* it actually is arrays of arrays
* example:
```cpp
int ia[3][4]; //array of dim. 3; each element is array of dim.4
int arr[10][20][30] ={0};
int ia2[3][4] ={
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
int ia3[3][4] ={{0}, {1}, {2}}
```
# Expressions
* This chapter focuses on the operators as defined in the language and applied to operands of built-in type.
* An **expression** is composed of one or more operands and yield a result when it is evaluated.
* the simplest form of an expression is a single literal or variable.
* the result of such an expression is the value of the variable or literal
## Fundamentals
* Basic Concepts
* unary & binary operators:
* unary operators: act on one operand, such as ```&```, ```*```
* binary operators: act on two operands, such as ```==```, ```/```
* Grouping Operators and Operands
* two main concept need to understand : **precedence** & **associativity**
* Operand Conversions
* operands are often converted from one type to another
* Overloaded Operators
* language defines what the operators mean when applied to build-in and compound types. But we can also define what most operators mean when applied to class types.
* such definitions give an alternative meaning to an existing operator symbol
* Lvalues & Rvalues
* every expression in C++ is either an **rvalue** or an **lvalue**
* lvalues could stand on the left-hand side of an assignment whereas rvalues could not
* roughly speaking,
* when we use an object as an rvalue, we use the object's value (its content).
* when we use an object as an lvalue, we use the object's identify (its location in memory)
* operators differ as to whether they require lvalue or rvalue operands and as to whether they return lvalues or rvalues.
* Precedence & Associatively
* an expression with two or more operators is a **compound expression**
* evaluating a compound expression involves grouping the operands to the operators
* precedence, associatively & parenthesizing determine how the operands are grouped
* operands of operators with higher precedence group more tightly than lower precedence
* Associativity determines how to group operands with the same precedence
* Parentheses override precedence and associativity
* when precedence and associativity matter
```cpp
int main(int argc, char *argv[]){
int ai[]={0,2,4,6,8};
std::cout << *(ai+4) << "\n" // ai[4] = 8
<< *ai+4 << std::endl; // ai[0] + 4 = 4
return 0;
}
```
* Order of evaluation
* ```int i = f1() + f2()```
* in above statement, we have no idea about which function be called first
* for operators that do not specify evaluation order, it is an error for an expression to refer to and change the same object and it is call undefined behavior
* there are four operators that do guarantee the order in which operands are evaluated
* **AND** ```&&```
* **OR** ```||```
* conditional ```? :```
* comma```,```
## Arithmetic Operators
* Arithmatic Operators

* the unary arithmetic operators have higher precedence than : multiplication, division, binary addition & subtraction operators
* operators are left associative, meaning that they group left to right when the precedence levels are the same
* ...
## Logical and Relational Operators
* operators list :

* these operators all return values of type bool
* relational operators:
* take operands of arithmetic or pointer type
* ```<, <=, >, >=```
* have their ordinary meaning and return bool values
* it is left associative
* ```if (i < j < k) // if (True or False < k)
* ```if (i<j && j<k) // is ok```
* ```if (val) //true if val nonzero value```
* ```if (!val) //true if val is zeor```
* logical operators
* take operands of any type that can be converted to bool
* **short-circuit evaluation** :``
* the right side of an ```&&``` is evaluated if and only if the left side is true
* the right side of an ```||``` is evaluated if and only if the left side is false
* the logical **NOT** operator ```!``` returns the inverse of the truth value fo its operand
* ``` if (!vec.empty()){...} ```
## Assignment Operators
* the left-hand operator of an assignment operator must be a modifiable lvalue
```cpp
int i =0, j = 0, k = 0; // initializations, not assignment
const int ci = i; // initialization, not assignment
// some error example
1024 = k; //error
i + j = k; //error
ci = k; //error
```
* the result of an assignment is its left-hand operand, which is an lvalue
* if the type of the left and right operands differ, the right-hand operand is converted to the type of left
```cpp
int k{0};
k = 3.1415; // int k = 3
k = {3.14}; // error: narrowing conversion
vector<int> vi; // initially empty
vi = {0,1,2,3,4,5};
```
* vector template defines its own version of an assignment operator that can take an initializer list
* Assignment is Right Associative
* unlike the other binary operators, assignment is right associative
```cpp
int ival, jval;
ival = jval = 0; // ok: each assigned 0
```
* Assignment has low precedence
* parenthesize the assignment for the condition to work properly
```cpp
int i;
while ((i = get_value()) != 42){
// ...
}
```
* Equality and Assignment operators
```cpp
if (i = j){...} // be true if the result of assignment is nonzero
if (i == j){...} // test whether i equal to j
```
* Compound Assignment Operators

## Increment and Decrement Operators
* the increment ```++``` and decrement ```--``` operators provide a convenient notational shorthand for adding or subtracting 1 from an object
* prefix: yields the changed vlaue
* postfix: yields the unchangec value
```cpp
int j=0, j;
j = ++i; // j = 1, i = 1
j = i++; // j = 1, i = 2
```
* these operators require lvalue operands
* note: postfix have mort work to store original value than prefix
* combining Dereference and Increment in a single expression
```cpp
auto pbeg = v.begin();
while (pbeg != v.end() && *pbeg >= 0)
std::cout << *pbeg++ endl;
```
* the precedence of postfix increment is higher than dereference operator
* ```*pbeg++``` is equivalent to ```*(pbeg++)```
* Remember That Operands Can Be Evaluated in Any Order
* one undefine example:
```cpp
// ok version
for (auto it=s.begin(); it != s.end() && !isspace(*it); ++it)
*it = toupper(*it);
// undefine version
while (beg != s.end() && !isspace(*beg))
*beg = toupper(*beg++); //error: assignmen is undefined
```
* there two possible
```*beg = toupper(*beg); //if left-hand side is evaluated first```
```*(beg + 1) = toupper(*beg); //if right-hand side is evaluated first```
## The Member Access Operators
* the **dot** ```.``` and **arrow** ```->``` operators provide for member access
* dot ```.``` : fatches a member from an object of an object of class type
* arrow ```->```: is defined so that ```ptr->mem``` is a synonym for ```(*ptr).mem```
```cpp
std::string str{"abcde!"};
std::string *p_str = &str;
std::cout << str.size() << "\n"
<< (*p_str).size()
<< std::endl;
```
* note: dereference has a lower precedence than dot, we must parenthesize the dereference subexpression
## The Conditional Operators
* the conditional operators ```:``` & ```?``` let us embed simple if-else logic inside an expression
* the form: ```cond ? expr1 : expr2;```
* **cond** is an ecpression that is used as a condition and expr1 & expr2 expressions of the same type
* cond is true: expr1 is evaluated
* cond is false: expr2 is evaluated
* an example:
```cpp
int grade{0};
std::cin >> grade;
std::string finalgrade = (grade < 60) ? "fail" : "pass";
std::cout << finalgrade << std::endl;
```
* Nesting Conditional Operations
```cpp
finalgrade = (grade > 90) ? "A!!"
: (grade < 60) ? "fail" : "pass"
```
* Using a Conditional Operator in an Output Expression
* the conditional operators has fairly low precedence
* when we embed a conditional expression in a larger expression, we usually must parenthesize the conditional subexpression
```cpp
std::cout ((grade < 60) ? "fail" : "pass");
```
## The Bitwise Operators
* the bitwise operators take operands of integral type as a collection of bits
* we can also use these operators on a library type nemed ```bitset``` that represents a flexibly sized collection of bits
* operators table

## The sizeof Operators
* the ```sizeof``` operator reutrn the size, in bytes, of an expression or a type name
* ```sizeof``` is right associative
* ```sizeof``` return a constant expression of type size_t
* form
* ```sizeof(type)```
* ```sizeof expr```
## Comma Operator
...
## Type Conversion
...
## Operator Precedence Table


# Statements
## Simple statement
* introduction
* most statement in c++ end with a semicolon ```;```
* an expression becomes an **expression statement** when it is followed by a semicolon
```cpp
ival+5; // rather useless expression statement
std::cout << ival; //useful expression statement
```
* Null Statement
* the simplest statement is the empty statement, also known as a **null statement**:
* ```; //null statement```
* a null statement is useful where the language requires a statement but the program's logic does not
```cpp
while (std::cin >> s && s != sought)
; //null statement
```
* best practices: null statement should be commented
* Beware of Missing or Extraneous Semicolons
* null statement is legel anywhere
* a unnecessary null statement is often harmless
``` ival = v1 + v2;```
* some can drastically alter the programmer's intent
```cpp
while (iter != svec.end()) ; // while body is the empty statement
++iter; // increment is not part of the loop
```
* Compound Statements (Blocks)
* a compound statement, usually referred to as a **block**, is a sequence of statements and declarations surrounded by a pair of curly braces ```{}```
```cpp
while (cin >> s && s != sought)
{}
while (val <= 10) {
sum += val;
++val;
}
```
* compound statement are used when the **language requires a single statement** but the **logic of our program needs more than one**
* a block is a scope; names introduced inside a block are accessible only in that block and in blocks nested inside that block
* names are visible from where they are defined until the end of the (immediately) enclosing block
## Statement Scope
* we can define variables inside the control structure of the **if, switch, while, and for** statement
* variable defined in the control structure are visible only within that statement
```cpp
while (int i = get_num()){
std::cout << i << std::endl;
}
i = 0; //error, out of scope
```
## Conditional Statements
* c++ provides two statements that allow for conditional execution: ```if``` & ```switch```
* **if statement**
* if statement conditionally executes another statement based on whether a specified condition is true
```cpp
if (condition)
statement
else if (condition2)
statement2
else
statement3
```
* condition must be enclosed in parentheses
* condition can be an expression or an initialzed variable declaration
* the expression or variable must have a type that is **convertible to bool**
* **switch statement**
* switch statement provides a convenitent way of selecting among a number of fixed alternatives
```cpp
unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0;
char ch;
while (std::cin >> ch){
switch (ch) {
case 'a':
++aCnt;
break;
case 'e':
++eCnt;
break;
case 'i':
++iCnt;
break;
case 'o':
++oCnt;
break;
}
}
```
* a switch statement executes by evaluating the parenthesized expression that follows the keyword ```switch```
* if the expression matches the value of a ```case``` label, execution begins with the first statement following that label
* after a case label is matched, execution starts at that label and continues across all the remaining cases or until the program explicitly interrupts it (ex: break;)
* there are situations where the default ```switch``` behavior is exactly what is needed
```cpp
unsigned vowelCnt = 0;
switch (ch)
{
case 'a':
case 'e':
case 'i':
case 'o':
++vowelCnt;
break;
}
```
* ```default``` Label
```cpp
switch (ch) {
case 'a':
case 'b':
++vowelCnt;
break;
default:
/* default statement */
break;
}
```
## Iterative Statemnts
* iterative statements include:
* while, traditional for loop, range for loop, do while
* The **while** Statement
```cpp
vector<int> v;
int i;
while (std::cin >> i)
v.push_back(i);
auto beg = v.begin();
while (beg != v.end() && *beg >= 0)
++beg;
```
* Traditional for loop:
```cpp
for (initializer; condition; expression)
statement
```
* Range for Statement
* the new standard introducted a simpler ```for``` statement that can be used to iterate through the elements of a container or other sequence
```cpp
for (declaration : expression)
statement
std::vector<int> v = {0,1,2,3,4,5,6};
for (auto &r : v)
r *= 2;
```
* do while statement
* a **do while** statement is like a while but the condition is testd after the statement body completes
```cpp
do
statement
while (condition);
```
## Jump Statement
* ```break```, ```continue```, ```goto```
## try Blocks and Exception Handling
* Basic introduction:
* **Exceptions** are run-time anomalies-such as losing a database connection or encountering unexpected input-that exist outside the normal functioning of a program
* **Exception handling**
* is generally used when one part of a program detects a problem that it cannot resolve and the problem is such that the detecting part of program cannot continue
* the detecting part needs a way to signal that something happened and that it connot continue
* In C++, exception handing involves:
* **throw** expressions: which the detecting part uses to indicate that it encountered something it can't handle; we say that a throw **raises** an exception
* **try** blocks: which the handling part uses to deal with an exception; a try block starts with try keyword try and ends with one or more **catch** clauses
* a set of **exception classes** that are used to pass information about what happened between a throw and an associated catch
## A throw Exception
* the detecting part of a program uses a throw expression to raise an exception
```cpp
int main(int argc, char *argv[]){
int saving_amount;
std::cout << "input how much you want to saved: ";
while (true){
std::cin >> saving_amount;
if (saving_amount < 0)
throw std::runtime_error("Must ");
}
return 0;
}
```
## The try Block
* the general form of a try block is:
```cpp
try{
statements
} catch (exception-declaration) {
handler-statements
} catch (exception-declaration) {
handler-statements
} //...
```
```cpp
try{
throw 20;
} catch (int e) {
std::cout << "An exception occurred. Exception Nr. " << e << '\n';
}
```
```cpp
#include <iostream>
#include <exception>
class MyException : public std::exception {
virtual const char* what() const throw()
{
return "My exception happened";
}
};
int main(int argc, char *argv[]){
MyException myex;
try
{
throw myex;
}
catch (std::exception& e)
{
std::cout << e.what() << "\n";
}
return 0;
}
```
## Standard Exceptions

# Function
## Function Basic
* 高階語言提供的函式從真正意義上展現了**封裝(Encapsulation)**的思想,其透過函式名稱(function name)、參數(parameters)、返回直(return values)與外界進行交流,以下幾個基本重點。
1. 函式結構(function structure):
* 反還數值 (return value): "void" is special type meaning no return.
* 函式名稱(function name): the identify.
* 形式參數列表 (parameters): a specified in a comma-separated list enclosed in parentheses ().
* 函式主體(function body):
2. 呼叫與執行: call by funciton name, executed through the call operator - a pair of parentheses **()**. Inside the parentheses is a comma-separated list of arguments. The arguments are used to initialize the function's parameters.
```cpp
// function structure
return_type func_name(type1 para1, type2 para2){
func_body;
return value;
}
// Example:
int fact(int val)
{
int ret = 1;
while (val >1)
ret *= val--;
return ret;
}
```
3. 呼叫函式時會初始化函式的參數(parameters)以及將控制移轉給被呼叫的函式,直到 遇到 return statement 控制權才會回到原函式。
## 參數傳遞方式
* 函數的 parameters 藉由呼叫方給予的 arguments 來初始化,其初始化行為就跟變數給予直的過程一樣( type var = values;),其參數傳遞方式如下:
1. 按值:拷貝參數,函式內參數(區域變數)值的改變不影響函式外參數數值,因為其被儲存在不同空間中,其中,也可以傳遞自己定義的物件進入函式,以下範例:
```cpp
#include <iostream>
#include <cstdlib>
#include <string>
#include <cassert>
using namespace std;
class Student{
string name;
int age;
public:
Student() : name("stud"), age(15){}
void set_age(int age){this->age=age;}
int get_age() {return age;}
void set_name(string name){this->name=name;}
string get_name() {return name;}
};
void increment_age(Student s){
s.set_age(s.get_age() + 1);
cout << "Newage: " << s.get_age() << endl;
}
int main(){
Student s;
s.set_name("Eric");
s.set_age(18);
cout << "student name: " << s.get_name() << "\n"
<< "student age: " << s.get_age()
<< endl;
increment_age(s);
return 0;
}
```
2. 指標(pointer):函式參數為指標變數,可將所傳參數的指標傳遞到函式內部,其值可以直接在函式內部被更動。
```cpp
return_type func_name(type* pointer){
func_body;
return value;
}
int main(){
func_name(¶meter); //直接傳遞參數位址給函式
return 0;
}
```
* 舉例:array 無法傳遞所有直,只能傳遞指標,所以函式內變更 array 參數直的話,外部 argument 也會被改變。
```cpp
#include <iostream>
using namespace std;
double average (int array[], int size){
int total = 0;
double avg;
for (int i=0; i<size; i++)
{
total += array[i];
}
avg = total / size;
array[5]=100;
return avg;
}
int main(){
int array[6] = {1,2,3,4,5,6};
double avg;
cout << " Original array[5]:" << array[5] << endl;
avg = average(array, 6);
cout << "Average: " << avg << endl << endl;
cout << " After function array[5]:" << array[5] << endl;
return 0;
}
```
* 提到 array 的傳遞,順便講一下如何藉由 command-line 來傳遞參數給 main() 函式,如下:
``` int main(int argc, char *argv[]){...}```
* argc 是個整數,紀錄了總共幾個參數,
* argv 是個 array,其存的是指向 char 的 pointer, 實際內容就是傳入的參數,而且argv[0]預設是執行的檔名,由於陣列的變數本身就是指標,因此 argv 可改寫成:
``` int main(int argc, char **argv){}```
* 顯示 argv is a pointer & point to a char pointer, 最後一個例子如下:
**main_para.cpp**
```cpp
#include<iostream>
#include<stdio.h>
using namespace std;
int main(int argc, char **argv){
for (int i=0; i<argc; i++)
{
printf("argv[%d] = %s , \n", i, argv[i]);
}
int i = 10 + atoi(argv[3]);
printf("%d \n", i);
return 0;
}
```
```
$ g++ main_para.cpp -Wall -std=c++11 -o main_para.out
$ ./main_para.out 1 2 3 4
```

3. 參照(reference):參照傳遞提供另一種非拷貝傳遞方式,函式在此直接收到一個參照,參照指向要給函式的真實參數。
```cpp
return_type func_name(type& pointer){
func_body;
return value;
}
int main(){
func_name(parameter); //直接傳參數
return 0;
}
```
* 如果有預期 argument 直在函式內會被改變,那麼傳一般參照;
* 只是要省去複製的時間,但不希望原 argument 直被改變,則可以增加 const 宣告來預防,以下範例:
```cpp
#include <iostream>
using namespace std;
/* para. r1: int reference;
* para. r2: const int reference;
* */
void fun(int& r1, const int& r2){
cout << "\tr1= " << r1 << "\n"
<< "\tr2= " << r2 << endl;
r1++;
cout << "\tr1= " << r1 << "\n"
<< "\tr2= " << r2 << endl;
}
int main(int argc, int* argv[]){
int x1 = 0;
int x2 = 0;
cout << "x1 = " << x1 << "\n"
<< "x2 = " << x2 << endl;
fun(x1, x2);
cout << "x1 = " << x1 << "\n"
<< "x2 = " << x2 << endl;
return 0;
}
```
* variting parameter:
如果傳遞的參數數量不固定,可以用 **initializer_list** type 來協助:
```cpp
#include<iostream>
#include<iomanip>
#include<initializer_list>
using namespace std;
void error_msg(initializer_list<string> es){
for (auto beg=es.begin(); beg!=es.end(); ++beg)
cout << *beg << " ";
cout << endl;
}
int main(int argc, char **argv){
error_msg({"this", "is", "error", "message!"});
return 0;
}
```
## Function Declaration & Separate Compilation
* Function declarations are know as the function prototype. Just describe the function's interface as follow:
```cpp
type fun_name(type1, type2, ...);
```
* Functions should be declared in header files and defined in source files.
* As our programs get more complicated, we'll wnat to store various parts of the programs in sepatate files, just like head and source files. C++ suports what is commonly known as separate compilation. Separate compilation lets us split our programs into several files, each of which can be compiled independently.
## Return Value
* Function will terminate after "return" statement, and it can return something with type that we pre-declare.
* And function can return a reference!
```cpp
#include<iostream>
#include<string>
using namespace std;
void print_longer_str(string &a, string &b){
if (a.size() == b.size())
return; //function just terminate
else if(a.size() > b.size())
cout << a << endl;
else
cout << b << endl;
}
// function return a reference
string &give_short_str(string &a, string &b){
if (a.size() < b.size())
return a;
else
return b;
}
int main(int argc, char *argv[]){
string a = "asdf asdf";
string b = "asdf ads fasdf";
print_longer_str(a, b);
//function return a or b, so we can assign value!
give_short_str(a, b) = "i change the string!!";
cout << a << endl;
return 0;
}
```
### Function return a pointer to an array
* First, let's take look the different of some variable declared:
```cpp
int arr[10]; //arr is a array of ten ints
int *p1[10]; //p1 is a array of ten pointers
int (*p2)[10]=&arr; //p2 points to an array of ten ints
```
* The variable with right array dim. [10] have priority to combine, except meet parentheses.
* There is same situation in a function that returns a pointer to an array. And just remember **func_name(para.) => the return value**.
* The syntax show as follow:
```cpp
// Function that returns a pointer to an array.
Type (*function(parameter_list))[dimension]
```
* We can re-understand the syntax by:
```cpp
Type (*return_value)[dimension]
```
* Compare to above p2, it's same mean.
* a not very good example taht just for try **return a pointer that point to array**:
```cpp
#include<iostream>
int (*re_point_to_a_array(int (*arr)[10]))[10]{
*arr[9]=100;
return arr;
}
int main(){
int arr[10] = {0};
int (*point_arr)[10];
point_arr = re_point_to_a_array(&arr);
std::cout << "*point_arr[0]= " << *point_arr[0] << std::endl;
std::cout << "*point_arr[9]= " << *point_arr[9] << std::endl;
return 0;
}
```
## Overloaded function
* [說明:重載函式(Overloaded function)](https://openhome.cc/Gossip/CppGossip/OverloadedFunction.html)
* What is overload function:
* Function that have the same name but different parameter lists and that appear **in the same scope**. But name do **not** overload across scopes.
* For example:
```cpp
void print(const char *cp);
void print(const int *beg, const *end);
vodi print(const int ia[], size_t size);
```
* When we call these functions, the compile can deduce which function we want based on the argument type we pass.
## Features for Specialized Uses
### Default Arguments:
* Some function have parameters that are given a particular value in most, but not all. In such cases, We can declare that common value as a default argument for the function.
```cpp
typedef string::size_type sz;
string screen(sz=24, sz win=80, char backrnd=' ');
```
## pointers to function
* 前導知識-指令:
我們都知道資料是透過0/1形式存在記憶體裡,然而,比較少提到程式碼被編譯完後變成可以被CPU執行的指令是放在哪裡,其實對電腦來說,資料和指令的本質都是一樣的二進位位元,即將被執行的指令可以被臨時放在 CPU的電路裡,其他一樣都放在記憶體中,因此當然也可以有**對應的指標去指向存放指令的記憶體空間**。
* 指向函式的指標:
現在我們知道程式碼也是有位址,在 C 語言中指標變數也可以指向一個函式,一個函式在編譯時會被分配一個入口位址,其就是該函式中第一條指令的位址,也是該函式的指標,一般定義形式如下:
**函式指標:**
```cpp
// 函式類型 (*指標變數名稱)();
//EX: 宣告p是函式指標,所指函式反還直是 double type
double (*p)(double, double);
//宣告完畢後再將p指向一個函式
p = function;
```
* **比較:去掉括號表示函數返回直型別是一個指標**
```cpp
//函式類型 * 函式名稱();
double* p(double, double);
//函式 p返回直是一個指向 double的指標。
```
* **Function pointer parameter**:
* A function can has a parameter of pointer to function.
* We can write a parameter that look like a function type, but it will be treated as a pointer.
```cpp
// the third parameter is function type and it automatically treated as a pointer to function
void useBigger(const string &s1, const string &s2,
bool pf(const string &, const string &));
//
void useBigger(const string &s1, const string &s2,
bool (*pf)(const string &, const string &));
```
* **以下來一個簡單x*x積分函數例子**
```cpp
#include <stdio.h>
#include <math.h>
using namespace std;
double integer_func(double a, double b){
double sum = 0.0;
double const length = 0.000001;
double x = a;
while(x < b){
sum += x*x*length;
x += length;
}
return sum;
}
int main(){
double result = 0.0;
double (*func_pointer)(double, double);
func_pointer = integer_func;
result = (*func_pointer)(0.0, 1.0);
printf("%g\n", result);
}
```
* 當函式指標作為參數給其他函式使用,並且每次函式所呼叫的其他函式無法固定時,其函式指標的功能就顯得很有用處,範例如下:
```cpp
#include "stdio.h"
#include "math.h"
// Given 3 ingeteral of math function, and can be call by a integral function
// function1: intergal x*x
double func1(double a, double b){
double sum = 0.0;
double const length = 0.000001;
double x = a;
while(x < b){
sum += x*x*length;
x += length;
}
return sum;
}
// function2: intergal sin(x)
double func2(double a, double b){
double sum = 0.0;
double const length = 0.000001;
double x = a;
while(x < b){
sum += sin(x)*length;
x += length;
}
return sum;
}
// function3: intergal e^(x^-2)
double func3(double a, double b){
double sum = 0.0;
double const length = 0.000001;
double x = a;
while(x < b){
sum += exp(sqrt(x))*length;
x += length;
}
return sum;
}
// Intergal function
void intergal(double a, double b, double (*func)(double, double)){
double result = 0.0;
result = (*func)(a, b);
printf("%g\n", result);
}
int main(){
intergal(0.0, 1.0, func1);
intergal(0.0, 3.141593, func2);
intergal(0.0, 1.0, func3);
}
```
Function pointer also can points to overloaded function:
```cpp
void ff(int*);
void ff(unsigned int);
void (*pf1)(unsigned int)=ff;
// the function pointer pf1 will points to ff(undigned)
```
# Classes
* in C++ we use classes to define our own data types
* the fundamental ideas behined classes are **data abstraction** and **encapsulation**
* **Data abstraction**:
* a programming technique that relies on the separation of **interface** and **implementation**
* the interface of class consists of the operations that users of the class can execute
* the implementation includes the class' data members, the bodies of the functions that constitute the interface, and any function needed to define the class that are not intended for general use
* **Encapsulation**:
* enforces the separation of a class' interface and implementation
* a class that is encapsulated hides its implementation-users of the class can use the interface but have no access to the implementation
* **abstract data type**:
* a class that uses data abstraction and encapsulation defines an **abstract data type**
* class designer worries about how the calss is implemented
* programmers who use the class need not know how the works; they can instead think abstractly about waht the type does
## Basic Concept
* although every member must be declared inside its class, we can define a member function's body either inside ot outside of the class body
* **this**:
* member functions access the object on which they were called through an extra, implicit parameter named **this**
* when we call a member function, this is initialized with the address of object on which the function was invoked
* for example:
* when we call: ```obj.member()``` the compiler passes the address of **obj** to the implicit **this** parameter in member
* just like ```Class_name::member(&obj)```
* ```this->member()```
* const:
* ```std::string isbn() const {return this->bookNo;}```
* **this** parameter is defined for us implicitly
* because **this** is intended to always refer to "this" object, this is a const pointer
* the key word **const** that follows the parameter list is to modity the type of the implicit htis pointr
* class Scope
* recall that a class is itself a scope
* the definitions of the member functions of a class are nested inside the scope of the class itself
* member functions
* compiler processes classes in two steps-
* the member declarations are compiled first
* the member function bodies are processed
* Defining a Member Function outside the Class
* when we define a member function outside the class body, the member function must match its declaration
* retrun type
* parameter list
* name
* defining a function to return "This" Object
* the combine function is intended to act like the compound assign
* Constructors
* each class defines how object of its type can be initialized
* classes control object initialization by defining one or more special member function known as **constructors**
* the obj of a constructor is to initialize data members of a class object
* constructor form:
* constructors have the smae name as the class
* have no return type
* have a (possibly empty) parameter list and a (possibly empty) function body
* a class can have multiple constructors; like any other overloaded function, the constructors must differ from each other in the number or types of their parameters
## Class 基本語法快速瀏覽
* 先快速將基本語法跑過一遍,先不著墨太多細節,內容是參閱 C++Primer, 5th和 [本連結內容 C++ Class(I)](http://www.cplusplus.com/doc/tutorial/classes/):
### class 關鍵字語法
C++ 是用 class 來定義自己的資料型式(In C++ we use classes to define our own data types.)可以當作是 **struct** 的擴展應用,
類是用關鍵字 class 來實現,以下為語法:
```cpp
class Class_Name{
access_specifier_1:
member_1;
access_specifier_2:
member_2;
} Object_Name; //object name is optional
```
* Class_Name: 是該類別的唯一識別名稱
* Object_Name: 是透過 class 所產生的物件變數名稱,當然可以另外定義其他各種物件名稱。
* access_specifier: 是定義出對本類成員有訪問權限的對象,主要是以下3個關鍵字:
* public: 最寬鬆,任何對象都有訪問權限
* protected:同類和其繼承關係的子類的其他成員都有訪問權限
* private: 最嚴格,只有類別自己成員有訪問權限
以下一個範例:
```cpp
// class example
#include <iostream>
using namespace std;
class Rectangle{
int width, height;
public:
void set_values(int, int);
int area(){return width*height;};
};
void Rectangle::set_values(int x, int y){
width = x;
height = y;
}
int main(){
Rectangle rect_a, rect_b;
rect_a.set_values(10, 20);
rect_b.set_values(10, 20);
cout << rect_a.area() << endl;
cout << rect_b.area() << endl;
//Rectangle::width = 10;
}
```
特別說明:
* width, height 因為沒特別聲明訪問權限,所以預設是 private:, 如果要用物件對該資料做訪問```cout << rect.area();```會遇到錯誤說明如下圖:

* Scope Operator (**::**) 是當我們要在 class 區塊以外定義其成員函式實作內容時需要用到。
* 依靠宣告後的物件來呼叫成員時,只須用一個點 **.** 來表示```obj_var.dunc()```。
* class is a type, 所以我們可以宣告好幾個物件,就像```ina a, b, c```。
### Constructors 初始化函數
上述 Rectangle class 範例有個缺點,如果我們在進行 set_values() 函式前就先呼叫 ares() 會發生無法確定的結果(undetermined result),如下圖出現奇怪的數值。

為了避免以上狀況, Class 有個與 Class_Name 同名的特別函式叫做 Constructors function,其允許 class 初始化成員變數(initialize member variables)或是分配儲存空間(allocate storage), 範例可以改成以下:
```cpp
// class example
#include <iostream>
using namespace std;
class Rectangle{
int width, height;
public:
Rectangle(int, int); // Constructor
int area(){return width*height;};
};
Rectangle::Rectangle(int x, int y){
width = x;
height = y;
}
int main(){
Rectangle rect_a(10, 20);// Initialize & give values
Rectangle rect_b(20, 30); // Initialize & give values
cout << rect_a.area() << endl;
cout << rect_b.area() << endl;
}
```
以上用 constructor function 取代掉了 set_values() 函式,並且避免了無法確定結果的狀況。
### Overloaded Condtructor
C++支援函式「重載」(Overload),這種機制為類似功能的函式提供了統一的名稱,但是根據參數列個數或型態的不同,而自動呼叫對應的函式,函式 過載的功能使得程式設計人員能較少苦惱於函式名稱的設計,以統一的名稱來呼叫相同功能但實際提供的資料不同的函式,例如依參數列個數的不同來重載,而 constructor function 也適用,以下改寫:
```cpp
// class example
#include <iostream>
using namespace std;
class Rectangle{
int width, height;
public:
// Two constructor func.
Rectangle();
Rectangle(int, int);
int area(){return width*height;};
};
Rectangle::Rectangle(){
width = 0;
height = 0;
}
Rectangle::Rectangle(int x, int y){
width = x;
height = y;
}
int main(){
Rectangle rect_a(10, 20);// Initialize & give values
Rectangle rect_b; // Initialize & give values
cout << rect_a.area() << endl;
cout << rect_b.area() << endl;
}
```
### Uniform initialization
除了函數寫法的初始化,也可以用大括號 **{}** 來初始化成員變數,並稱作 uniform initialization,語法為```class_name object_name { value, value, ... } ```。
以下範例:
```cpp
#include <iostream>
using namespace std;
class Circle{
double radius;
double const pi = 3.14159265;
public:
Circle(double r) {radius=r;}
double circum() {return 2*radius*pi;}
};
int main(){
Circle a(10.); // functional form
Circle b = 20.; // assignment init, only for one parameter
Circle c {30.}; // uniform inti
Circle d = {40.}; // POD-like
cout << a.circum() << endl;
cout << b.circum() << endl;
cout << c.circum() << endl;
cout << d.circum() << endl;
}
```
備註:[什么是 POD 数据类型?](https://zhuanlan.zhihu.com/p/45545035)
### Member initialization in constructors
當 construstor 被用來建構其他成員時,其他成員可以一起被初始化,並藉由 **:** 的運算子來達到:
* 原本方法:```Rectangle::Rectangle(int x, int y){width=x, height=y}```
* 改寫:```Rectangle::Rectangle(int x, int y) : width(x), height(y) {}```
有點像是把原寫法的函式裡面東西拿出來並用 **:** 來區隔,以下範例:
```cpp
// member initialization
#include <iostream>
using namespace std;
class Circle {
double radius;
public:
Circle(double r) : radius(r) { }
double area() {return radius*radius*3.14159265;}
};
class Cylinder {
Circle base;
double height;
public:
Cylinder(double r, double h) : base (r), height(h) {}
double volume() {return base.area() * height;}
};
int main () {
Cylinder foo (10,20);
cout << "foo's volume: " << foo.volume() << '\n';
return 0;
}
```
### Pointers to classes
Objects can also be pointed to by pointers: Once declared, a class becomes a valid type, so it can be used as the type pointed to by a pointer. For example:
```Rectangle * prect;```
```cpp
// pointer to classes example
#include <iostream>
using namespace std;
class Rectangle {
int width, height;
public:
Rectangle(int x, int y) : width(x), height(y) {}
int area(void) { return width * height; }
};
int main() {
Rectangle obj (3, 4);
Rectangle * foo, * bar, * baz;
foo = &obj;
bar = new Rectangle (5, 6);
baz = new Rectangle[2] { {2,5}, {3,6} };
cout << "obj's area: " << obj.area() << '\n';
cout << "*foo's area: " << foo->area() << '\n';
cout << "*bar's area: " << bar->area() << '\n';
cout << "baz[0]'s area:" << baz[0].area() << '\n';
cout << "baz[1]'s area:" << baz[1].area() << '\n';
delete bar;
delete[] baz;
return 0;
}
```
### 最後一個練習實例
```cpp
#include <iostream>
#include <random>
#include <algorithm>
#include <vector>
using namespace std;
class Two_Sum{
public:
int target;
vector<int> nums;
Two_Sum(int input_tar, vector<int> input_vec):target(input_tar), nums(input_vec){};
vector<int> twosum();
};
vector<int> Two_Sum::twosum(){
vector<int> result;
for(int i=0; i<nums.size()-1; i++)
{
for(int j= i+1; j<nums.size();j++)
{
if(nums[i]+nums[j]==target)
{
result.push_back(i);
result.push_back(j);
}
}
}
return result;
}
int main(){
vector<int> input;
random_device random;
mt19937 gen(random());
uniform_int_distribution<> dis(1, 10);
int length, target;
cout << " Input Vector Length: " << endl;
cin >> length;
cout << " Input target(the sum of two numbers): " << endl;
cin >> target;
for (int n=0; n <length; n++)
input.push_back(dis(gen));
Two_Sum obj(target, input);
vector<int> ans;
ans = obj.twosum();
// delete repeat element
sort(ans.begin(), ans.end());
ans.erase(unique(ans.begin(), ans.end()), ans.end());
// unique()将重复元素放到尾部,後返回指向第一个重复元素的迭代器,再用erase()刪除此元素之後的所有元素
for (int n = 0;n<obj.nums.size()-1;n++)
cout << input[n] << ", ";
cout << "\nAns: "<< endl;
for (int n = 0;n<ans.size()-1;n++)
cout << ans[n] << ", ";
return 0;
}
```
[c++11 Advanced](https://hackmd.io/@L_VGP_ZqS2WG30NvJnde1g/BksjfG8Er)
---