C++ Language
Install
# MacOS
xcode-select --install
Hello World
#include <iostream>
int main()
{
std::cout << "Hello world!" << std::endl;
return 0;
}
编译与运行
g++ main.cpp -o main.out
./main.out
输入输出
iosteam
#include <iostream>
int main()
{
int v1 = 0, v2 = 0;
std::cin >> v1 >> v2;
std::cout << "The sum of " << v1 << " and " << v2 << " is " << v1+v2 << std::endl;
return 0;
}
不知道有多少个输入时
int main()
{
string word;
while (cin >> word)
cout << word << endl;
return 0;
}
读取整行
int main()
{
string line;
while (getline(cin, line))
cout << line << endl;
return 0;
}
fstream
#include <fstream>
// open file
ofstream outfile("file.txt");
// append file
ofstream outfile("file.txt", ios_base::app);
// write data to file
if (! outfile)
cerr << "failed to open file.\n";
else
outfile << "content" << endl;
// read data from file
ifstream infile("file.txt");
if (! infile)
cerr << "failed to open file.\n";
else {
while (infile >> word) {
cout << word << endl;
}
}
注释
/*
* multi-line
* comment
*/
int main()
{
// single line comment
return 0;
}
流程控制
while
#include <iostream>
int main()
{
int i = 0;
while (i < 10) {
std::cout << i << std::endl;
++i;
}
}
for
#include <iostream>
int main()
{
for (int i = 0; i < 10; ++i) {
std::cout << i << std::endl;
}
}
if
#include <iostream>
int main()
{
int i = 0, j = 1;
std::cin << i;
if (i > j) {
std::cout << "i > j" << std::endl;
} else if (i < j) {
std::cout << "i < j" << std::endl;
} else {
std::cout << "i = j" << std::endl;
}
}
switch
char ch;
int aCnt = 0, bCnt = 0, cCnt = 0;
std::cin >> ch;
switch (ch) {
case 'a':
++aCnt;
break;
case 'b':
++bCnt;
break;
case 'c':
++cCnt;
break;
}
Null statement
;
{}
类型
基础类型
Type | Meaning | Minumum Size |
---|---|---|
bool | boolean | NA |
char | character | 8 bits |
wchar_t | wide character | 16 bits |
char16_t | Unicode character | 16 bits |
char32_t | Unicode character | 32 bits |
short | short integer | 16 bits |
integer | integer | 16 bits |
long | long integer | 32 bits |
long | long long integer | 64 bits |
float | single-precision floating-point | 6 significant digits |
double | double-precision floating-point | 10 significant digits |
long double | extended-precision floating-point | 10 significant digits |
- signed short: [-32768, 32767]
- unsigned short: [0, 65535]
- signed int: [-2^15, 2^15-1]
- unsigned int: [0, 2^16-1]
Conversion
int i = 3.14;
bool b = i;
signed char = 256; // undefined
Literals
int i = 20; // demical
int i = 024; // octal
int i = 0x14; // hexadecimal
long i = 1024L; // long
long long i = 1024LL; long long
unsigned int i = 20u; unsigned
float f = 3.14;
float f = 3.14E0;
long double f = 3.14L; // long double
char c = 'a'; // character literal
char16_t c = u'a'; // Unicode 16 character literal
char32_t c = U'a'; // Unicode 32 character literal
string s = "Hello"; // string literal
string s = "Hello "
"world!"; // multiline string literal
string s = u8"Hello"; // utf-8 string literal
类型别名
typedef double wages; // wages is a synonym for double
using SI = Sales_item; // SI is a synonym for Sales_item
类型推断
auto i = 0, *p = &i; // 自动推断类型
decltype(f()) sum = x; // 获取表达式的类型
指针、引用、常量
int &r
:&
在declaration中,表示referenceint *p
:*
在declaration中,表示pointer&i
:&
在expression中,表示address-of operator*p
:*
在expression中,表示dereference operator
int x = 1024;
int &ref = x; // ref是x的引用,引用不可被修改(rebind),必需初始化
int * p1 = &x; // 指针可以被修改,值也可以被修改
const int * p2 = &x; // 指针可以被修改,值不可以被修改(const int)
int * const p3 = &x; // 指针不可以被修改(* const),值可以被修改
const int * const p4 = &x; // 指针不可以被修改,值也不可以被修改
void *p = &obj; // 可以指向任意类型对象的地址
int *p = nullptr; // 空指针
int **pp = &p; // 指向指针的指针
int *&ref = p; // 指针的引用
- top-level const: a pointer itself is a const
- low-level const: a pointer points to a const
指针函数与函数指针
// addition是指针函数,一个返回类型是指针的函数
int* addition(int a, int b) {
int* sum = new int(a + b);
return sum;
}
int subtraction(int a, int b) {
return a - b;
}
int operation(int x, int y, int (*func)(int, int)) {
return (*func)(x,y);
}
// minus是函数指针,指向函数的指针
int (*minus)(int, int) = subtraction;
int* m = addition(1, 2);
int n = operation(3, *m, minus);
Operators
Operators Category | Operators | Operand | Result |
---|---|---|---|
Arithmetic | + ,- ,* ,/ ,% |
rvalue | rvalue |
Logical and Relational | ! ,< ,<= ,> ,>= ,== ,!= ,&& ,` |
` | |
Assignment | = |
left-hand operand must be a modifiable lvalue | left-hand operand lvalue |
Increment/Decrement | ++ ,-- |
lvalue | prefix: changed lvalue; postfix: unchanged lvalue |
Member Access | . |
lvalue or rvalue | lvalue if the operand is lvalue |
Member Access | -> |
pointer | lvalue |
Conditional | cond ? expr1 : expr2 |
lvalue if both expr are lvalues | |
Bitwise | ~ ,<< ,>> ,& ,^ ,` |
` | |
sizeof | size_t |
||
Comma | , |
right-hand expression, left-hand expression discard |
lvalue
and rvalue
- lvalue: the object’s identity (its location in memory)
- rvalue: the object’s value (its contencts)
Function
should be declared in header, defined in source file, and the source file should include the header.
// void return
void func() {
return;
}
// return value
int func() { return 1; }
// return vector
vector<string> func() { return {"a", "b", "c"};}
// pass by value
// 调用时复制值
void func(int x, int y){;}
// pass by reference
// 用于修改对象
void func(int &i) {
i = 0; // change the value of the object
}
// const reference
// 函数中用到但是不修改的对象
void func(const string &s){;}
// local static object
void func() {
static int cnt=0; // value will persist across calls
}
// 不定长参数
#include <initializer_list>
void error_msg(initializer_list<string> il){
for (auto beg = il.begin(); beg != il.end(); ++beg)
cout << *beg << " ";
cout << endl;
}
// declaration
void print(vector<int>::const_iterator beg, vector<int>::const_iterator end);
bool lengthCompare(const string &, const string &); // parameter names not required but nice to have
Pointer of function
// definition
bool (*pf)(const string &, const string &); // pf is a pointer to function whose return is bool and parameter list is const string and const string
// assignment
pf = lengthCompare; // points to the function
pf = &lengthCompare; // equivalent to above
// call
pf("hello", "world"); // call the function
(*pf)("hello", "world"); // equivalent call
Lambda expression
[capture list](parameter list) -> return type {function body}
[=]
: implicit by value capture list[&]:
implicit by reference capture list
auto f = [] { return 42; }; // empty parameter list
[](const string &a, const string &b) { return a.size < b.size; }; // with parameters
[sz](const string &a) { return a.size() > sz; }; // with capture list
[=](const string &a) { return a.size() > sz; }; // auto infer capture list
[](int i) -> int {if (i<0) return -i; else return i;}; // specify return type
Binding arguments
#include <functional>
auto newCallable = bind(callable, arg_list);
// example
using namespace std::placeholders;
auto check6 = bind(check_size, _1, 6); // binding other arguments except the first argument, 6 is the binded argument
// f has 5 arguments, g has 2, the first, second arguments of g is the last, the 3rd of f
auto g = bind(f, a, b, _2, c, _1);
Struct
struct Sales_data {
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
// semicolon is needed at the end
Sequential Containers
Generic
Iterator
string s = "hello";
// using `for` for iteratrion
for (auto it = s.begin(); it != s.end(); ++it)
*it = toupper(*it);
// using `while` for iteratrion
auto it = s.begin();
while (it != s.end()){
*it = toupper(*it);
++it;
}
// iterator type
string s;
string::iterator it = s.begin();
vector<int> ivec;
vector<int>::iterator it = ivec.begin();
// const iterator, read but do not write to an object
vector<int> ivec;
auto it1 = ivec.cbegin(), it2 = ivec.cend();
// member access
(*it).empty();
it->empty();
// arithmetic operations
auto mid = vec.begin() + vec.size() / 2;
// or
auto beg = vec.begin(), end = vec.end();
auto mid = beg + (end - beg) / 2;
assign
vector<int> ivec1={1,2,3}, ivec2={};
ivec2.assign(ivec1);
ivec2.assign(ivec1.begin(), ivec1.end());
ivec2.assign(1, 3); // {1,1,1}
swap
swap(ivec1, ivec2);
accessing
// access return references
c.back(); // return last element
c.front(); // return first element
c[n]; // return the n-th element
c.at(n); // safe access, throws error if out of range
operations
list<int> ilist;
// add element at the end
ilist.push_back(10);
// add element on the front.
ilist.push_front(1);
// add element at a specified position
ilist.insert(ilist.begin(), 5); // insert 5 at the beginning
ilist.insert(ilist.end(), 3, 1); // append {1,1,1} at the end
list<int> ilist2 = {1,2,3};
ilist.insert(ilist.end(), ilist2.begin(), ilist2.end()); // add elements from another list
ilist.insert(ilist.end(), {1,2,3});
// emplace construct an object by providing parameters
Object p = Object(arg1, arg2);
vector<Object> vec;
vec.emplace_back(arg1, arg2);
vec.emplace_front(arg1, arg2);
vec.emplace(vec.begin(), arg1, arg2);
// remove elements
ilist.pop_back(); // remove the last element
ilist.pop_front(); // remove the first element
ilist.erase(iter); // remove the element at iter
ilist.erase(ilist.begin()+1, ilist.begin()+2); //remove elements in the range
ilist.clear(); // remove all elements
// the return of insert and erase is an iterator points the inserting position
auto iter = ilist.begin() + 1;
iter = ilist.insert(iter, 0);
iter = ilist.erase(iter);
resize
vec.resize(10);
String
Defining and initializing
string s1; // empty string
string s2 = s1;
string s2(s1);
string s4("hello"); // direct initialization
string s3 = "hello"; //copy initialization
string s5(5, 'c'); // "ccccc"
string s6(s1.begin(), s1.end()); // copy of range defined by iterators
Operations
// size
bool b = s.empty();
auto len = s.size(); // return string::size_type
// adding
string s = s1 + s2;
s1 += s2;
s1 = s1 + '\n';
// equality
bool b = s1 == s2;
bool b = s1 != s2;
//characters in string
char c = s[n];
for (auto c: s)
cout << c << endl;
for (decltype(s.size()) i = 0; i != s.size(); ++i)
s[i] = toupper(s[i]);
// substr
string sub = s.substr(0,5);
// append
s.append("5th");
// replace
s.replace(11, 3, "abcd"); // replace the substr starts from 11 ends at 11+3
// search
s.find("anna"); // find the first occurrence
s.rfind("anna"); // find the last occurrence
s.find_first_of("abc"); // find the first occurrence of any characters
s.find_last_of("abc"); // find the last occurrence of any characters
s.find_first_not_of("abc");
s.find_last_not_of("abc");
// compare
s1.compare(s2);
Numeric conversions
int i = 42;
string s = to_string(i);
int j = stoi(s);
double d = stod(s);
Vector
Defining and initializing
// initially empty
vector<int> ivec;
vector<Sales_item> Sales_vec;
vector<vector<string>> file;
// initialize by copy
vector<int> ivec2(ivec);
vector<int> ivec3 = ivec;
vector<int> ivec4(ivec.begin(), ivec.end()); // copy of range defined by iterators
// list initializing
vector<string> svec = {"a", "an", "the"};
vector<string> svec{"a", "an", "the"};
// initializing by size
vector<int> ivec(10); // ten elements, each initialized to 0
vector<string> svec(10); // ten elements, each initialized to empty string
vector<int> ivec(5, 1); // {1,1,1,1,1}
Operations
v.empty();
v.size();
v.push_back(t);
v[n];
v1 = {a, b, c};
v1 == v2;
v1 != v2;
Built-in Array
Defining and initializing
int arr[10];
constexpr unsigned sz = 3;
int arr[sz]; // the dimension must be a constant expression
int arr[3] = {1,2,3};
int arr[3] = {1,2}; // equals {1,2,0}
int arr[] = {1,2,3};
// no copy or assignment for array
int *ptrs[10]; // ptrs is an array of ten poiters to int
int (*Parray)[10] = &arr; // Parray is a pointer points to an array of ten ints
int (&arrRef)[10] = arr; // arrRef refers to an array of ten ints
int * (&arry)[10] = ptrs; // reference to an array of ten pointers
Operations
// size
constexpr size_t sz = sizeof(arr) / sizeof(*arr)
// subdcript
arr[2] = 1;
// traverse
for (auto i : arr)
cout << i << endl;
Pointers and arrays
int[] arr = {1,2,3};
int * p = arr; // p points to the first element of arr
int * p = &arr[0]; // equivalent to `int *p = arr`
p + 1 // points to the subsequent element
p[1] // points to the (p + 1) element
int *beg = begin(arr); // points to the first element of arr
int *end = end(arr); // points to the end of arr, pasting the last element
Library Array
array<int, 3> arr; // size is part of the type
array<int, 3> arr = {0, 1, 2};
array<int, 3> arr = {1}; // {1, 0, 0}
array<int, 3> arr1 = arr; // unlike built-in array, can assign and copy as long as the type is the same
Deque
List
Forward_list
Adaptors
- stack
- queue
- Priority_queue
Generic Algorithms
#include <algorithm>
// find
int val = 42;
auto result = find(vec.cbegin(), vec.cend(), val);
// find if
auto wc = find_if(words.begin(), words.end(),
[sz](const string &a) {return a.size >= sz; });
// accumulate
#include <numeric>
vector<int> vec = {1,2,3};
int sum = accumulate(vec.cbegin(), vec.cend(), 0);
vector<string> vec = {"a","b","c"};
string sum = accumulate(vec.cbegin(), vec.cend(), string(""));
// equal
equal(roster1.cbegin(), roster1.cend(), roster2.cbegin());
// fill
fill(vec.begin(), vec.end(), 0); // set each element to 0
fill_n(vec.begin(), vec.size(), 0);
fill_n(back_inserter(vec), 10, 0); // append 10 elements to vec
// copy
auto ret = copy(vec.begin(), vec.end(), vec2.begin());
// replace
replace(vec.begin(), vec.end(), 0, 42); // replace the fisrt value with the second
// sort
sort(vec.begin(), vec.end());
// using lambda expression as predicate
sort(vec.begin(), vec.end(), [] (const string &a, const string &b) { return a.size() < b.size()});
// for each
for_each(words.begin(), words.end(),
[](const string &s){cout << s << " ";});
// transform
transform(vec.begin(), vec.end(), vec.begin(),
[](int i) -> int {return i < 0 ? -i : i});
其他
extern
extern int x; // to obtain a declaration that is not a definition
// const objects are local to file by default, to share const objects across multiple files, we add extern to its definition and declaration.
extern const int bufSize = 512; // file_1.cpp
extern const int bufSize; // file_1.h
constexpr
an expression whose value cannot change and that can be evaluated at compile time.
constexpr int mf = 20;
constexpr int limit = mf + 1;
using
#include <iostream>
using std::cin; using std::cout; using std::endl;
#include <string>
using std::string;
// using namespace
using namespace std;
C library
name.h
in C is calledcname
in C++- inside the
std
namespace incname
headers
#include <cctype>
int main() {
string s = "HeLlo";
for (auto *p : s) {
if (islower(*p))
*p = toupper(*p);
}
cout << s << endl;
}
Type conversion
static_cast
dynamic_cast
const_cast
reinterpret_cast