参考网址: C++ 教程 (github.com)
C++ 教程 | 菜鸟教程 (runoob.com)
c++基础 const关键字 声明指定类型的常量,此类型不会发生变化.
比如常用的字符串const char* str
,例如
1 const char * str = "hello world!" ;
当然也会有常数,常指针等.只需要记住它修饰的是它后边的那个.例如
1 2 3 const char * str #值不能改char const *str #值不能改char * const str #修饰的是常数指针,该指针不能修改
static修饰 静态变量,在程序的生命周期内保持局部变量的存在,用于保存上一次运行数据,比如计数等
#define 预处理器,例如
extern储存类 extern 存储类用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的.例如
1 2 3 4 5 6 7 8 9 10 #include <iostream> int count ;extern void write_extern () ; int main () { count = 5 ; write_extern (); }
1 2 3 4 5 6 7 8 #include <iostream> extern int count; void write_extern (void ) { std::cout << "Count is " << count << std::endl; }
两个文件之间传递参数.
register 存储类 寄存器局部变量,用于快速访问.因此也意味着最大尺寸只有寄存器尺寸.
thread_local 存储类 量在创建线程时创建,并在销毁线程时销毁。可以将 thread_local 仅应用于数据声明和定义
,thread_local 不能用于函数声明或定义
。thread_local 说明符可以与 static 或 extern 合并。
1 2 3 4 5 6 7 8 9 10 11 thread_local int x; class X { static thread_local std::string s; }; static thread_local std::string X::s; void foo () { thread_local std::vector<int > v; }
成员运算符 1 2 3 4 struct Employee { char first_name[16 ]; int age; } emp;
(.)点运算符 下面的代码把值 “zara” 赋给对象 emp 的 first_name 成员
1 strcpy(emp.first_name, "zara");
(->)箭头运算符 如果 p_emp 是一个指针,指向类型为 Employee 的对象,则要把值 “zara” 赋给对象 emp 的 first_name 成员,需要编写如下代码:
1 strcpy (p_emp->first_name, "zara" );
条件运算符 ? : 1 2 3 4 5 if (y < 10 ){ var = 30 ; }else { var = 40 ; }
可写为:
1 var = (y < 10 ) ? 30 : 40 ;
sizeof 运算符 sizeof 运算符可用于获取类、结构、共用体和其他用户自定义数据类型的大小。
指针运算符(& 和 *) 取地址运算符 & 间接寻址运算符 * 顾名思义,挺形象的.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <iostream> using namespace std; int main () { int var; int *ptr; int val; var = 3000 ; ptr = &var; val = *ptr; cout << "Value of var :" << var << endl; cout << "Value of ptr :" << ptr << endl; cout << "Value of val :" << val << endl; return 0 ; }
传参三种方式 传值、传址、传引用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> #include <stdint.h> using namespace std;int fun1 (int a) return a*a ;void man (int &a) a =a*a;void cubeByReference (int *a) *a =*a * *a;void fun2 (uint8_t * *buffer) { uint8_t buf[10 ]={0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 }; *buffer = buf; } int main () { int a=5 ,b=5 ,number=5 ; cout<<fun1 (a)<<endl; man (b); cout<<b<<endl; cubeByReference (&number); cout<<number<<endl; return 0 ; }
Lambda 函数与表达式 1 [capture](parameters)->return-type{body}
例如:
1 [](int x, int y) -> int { int z = x + y; return z + x; }
1 2 3 4 5 6 [] [x, &y] [&] [=] [&, x] [=, &z]
值得注意的是this
指针
1 [this ]() { this ->someFunc (); }();
数学运算 #include <cmath 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <iostream> #include <cmath> using namespace std; int main () { short s = 10 ; int i = -1000 ; long l = 100000 ; float f = 230.47 ; double d = 200.374 ; cout << "sin(d) :" << sin (d) << endl; cout << "abs(i) :" << abs (i) << endl; cout << "floor(d) :" << floor (d) << endl; cout << "sqrt(f) :" << sqrt (f) << endl; cout << "pow( d, 2) :" << pow (d, 2 ) << endl; return 0 ; }
通过time实现的伪随机数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <iostream> #include <ctime> #include <cstdlib> using namespace std; int main () { int i,j; srand ( (unsigned )time ( NULL ) ); for ( i = 0 ; i < 10 ; i++ ) { j= rand (); cout <<"随机数: " << j << endl; } return 0 ; }
setw() 函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <iomanip> using std::setw;cout << setw ( 7 )<< j << setw ( 13 ) << n[ j ] << endl; # 结果 Element Value 0 100 1 101 2 102 3 103 4 104 5 105 6 106 7 107 8 108 9 109
字符串操作 #include <string 1 2 3 4 5 6 7 8 9 10 11 12 strcpy (s1, s2); strcat (s1, s2); strlen (s1); strcmp (s1, s2); strchr (s1, ch); strstr (s1, s2); str3 = str1; str3 = str1 + str2; len = str3.size ();
时间 #include <ctime 1 2 3 4 5 6 7 8 9 time_t time (time_t *time) ; char *ctime (const time_t *time) ; struct tm *localtime (const time_t *time) ; clock_t clock (void ) ; char * asctime ( const struct tm * time ) ; struct tm *gmtime (const time_t *time) ; time_t mktime (struct tm *time) ; double difftime ( time_t time2, time_t time1 ) ; size_t strftime () ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <iostream> #include <ctime> using namespace std;int main ( ) { time_t now = time (0 ); char * dt = ctime (&now); cout << "本地日期和时间:" << dt << endl; tm *gmtm = gmtime (&now); dt = asctime (gmtm); cout << "UTC 日期和时间:" << dt << endl; }
cin、cout、cerr 和 clog 标准输入输出1 2 3 4 cin :一个istream对象,用来从标准输入读取数据。 cout:一个ostream对象,经过缓冲区而直接输出. cerr:一个ostream对象,写到cerr数据是不缓冲 clog:一个ostream对象,被缓冲的
结构体 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 struct Books { char title[50 ]; char author[50 ]; char subject[100 ]; int book_id; }; typedef struct Books { char title[50 ]; char author[50 ]; char subject[100 ]; int book_id; }books; typedef long int pint32;pint32 x, y, z;
结构体指针
1 2 3 4 5 struct Books *struct_pointer ;struct_pointer = &Book1; struct_pointer->title;
面向对象 c++对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Line { public : double getLength ( void ) ; Line (); friend void printWidth ( Box box ) ; Line ( const Line &obj); ~Line (); private : double length; }; Line::Line (void ) { cout << "Object is being created" << endl; } Line::~Line (void ) { cout << "Object is being deleted" << endl; } Line::Line (const Line &obj) { cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl; ptr = new int ; *ptr = *obj.ptr; } double Line::getLength ( void ) { return length; } void printWidth ( Box box ) { cout << "Width of box : " << box.width <<endl; }
内联函数inline 引入内联函数的目的是为了解决程序中函数调用的效率问题,这么说吧,程序在编译器编译的时候,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体进行替换,而对于其他的函数,都是在运行时候才被替代。这其实就是个空间代价换时间的节省
。所以内联函数一般都是1-5行的小函数。在使用内联函数时要留神:
1.在内联函数内不允许使用循环语句和开关语句;
2.内联函数的定义必须出现在内联函数第一次调用之前;
3.类结构中所在的类说明内部定义的函数是内联函数。
结论: 一个较为合理的经验准则是, 不要内联超过 10 行的函数 . 谨慎对待析构函数 , 析构函数往往比其表面看起来要更长, 因为有隐含的成员和基类析构函数被调用!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> using namespace std;inline int Max (int x, int y) { return (x > y)? x : y; } int main ( ) { cout << "Max (20,10): " << Max (20 ,10 ) << endl; cout << "Max (0,200): " << Max (0 ,200 ) << endl; cout << "Max (100,1010): " << Max (100 ,1010 ) << endl; return 0 ; }
this指针 友元函数没有 this 指针,因为友元不是类的成员。只有成员函数才有 this 指针。
this 指针的类型可理解为 Box*
1 2 # 实际上就是指针引用结构体成员 this ->Volume ();
继承 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include <iostream> using namespace std; class Shape { public : void setWidth (int w) { width = w; } void setHeight (int h) { height = h; } protected : int width; int height; }; class Rectangle : public Shape{ public : int getArea () { return (width * height); } }; int main (void ) { Rectangle Rect; Rect.setWidth (5 ); Rect.setHeight (7 ); cout << "Total area: " << Rect.getArea () << endl; return 0 ; }
多继承 另外多继承(环状继承),A->D, B->D, C->(A,B),例如:
1 2 3 4 class D { ......};class B : public D{......};class A : public D{......};class C : public B, public A{.....};
重载运算符 类内重调用
1 2 3 4 5 6 7 8 Box operator +(const Box& b) { Box box; box.length = this ->length + b.length; box.breadth = this ->breadth + b.breadth; box.height = this ->height + b.height; return box; }
算术运算符
+ (加),-(减),*(乘),/(除),% (取模)
关系运算符
==(等于),!= (不等于),< (小于),> (大于),<=(小于等于),>=(大于等于)
逻辑运算符
||(逻辑或),&&(逻辑与),!(逻辑非)
单目运算符
+ (正),-(负),*(指针),&(取地址)
自增自减运算符
++(自增),–(自减)
位运算符
| (按位或),& (按位与),~(按位取反),^(按位异或),,<< (左移),>>(右移)
赋值运算符
=, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>=
空间申请与释放
new, delete, new[ ] , delete[]
其他运算符
() (函数调用),**->(成员访问), ,(逗号), []**(下标)
多态 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Shape { protected : int width, height; public : Shape ( int a=0 , int b=0 ) { width = a; height = b; } virtual int area () { cout << "Parent class area :" <<endl; return 0 ; } virtual int area1 () = 0 ; }; class Rectangle : public Shape{ public : Rectangle ( int a=0 , int b=0 ):Shape (a, b) { } int area () { cout << "Rectangle class area :" <<endl; return (width * height); } };
文件和流 头文件:iostream 和 fstream
读写文件模板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <fstream> #include <iostream> using namespace std; int main () { char data[100 ]; ofstream outfile; outfile.open ("afile.dat" ); cout << "Writing to the file" << endl; cout << "Enter your name: " ; cin.getline (data, 100 ); outfile << data << endl; cout << "Enter your age: " ; cin >> data; cin.ignore (); outfile << data << endl; outfile.close (); ifstream infile; infile.open ("afile.dat" ); cout << "Reading from the file" << endl; infile >> data; cout << data << endl; infile >> data; cout << data << endl; infile.close (); return 0 ; }
文件位置指针 1 2 3 4 5 6 fileObject.seekg ( n ); fileObject.seekg ( n, ios::cur ); fileObject.seekg ( n, ios::end );
异常处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> using namespace std;double division (int a, int b) { if ( b == 0 ) { throw "Division by zero condition!" ; } return (a/b); } int main () { int x = 50 ; int y = 0 ; double z = 0 ; try { z = division (x, y); cout << z << endl; }catch (const char * msg) { cerr << msg << endl; } return 0 ; }
动态内存 变量动态内存 1 2 3 double * pvalue = NULL ; pvalue = new double ; delete pvalue;
数组动态内存 1 2 3 4 5 6 7 char * pvalue = NULL ; pvalue = new char [20 ]; for (int i = 0 ; i < COL; i++) { delete [] pvalue[i]; } delete [] pvalue;
对象的动态内存分配 1 2 Box* myBoxArray = new Box[4 ]; delete [] myBoxArray;
模板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> using namespace std; int main () { double* pvalue = NULL; // 初始化为 null 的指针 pvalue = new double; // 为变量请求内存 *pvalue = 29494.99; // 在分配的地址存储值 cout << "Value of pvalue : " << *pvalue << endl; delete pvalue; // 释放内存 return 0; }
命名空间 1 2 3 4 5 namespace namespace_name { func (); } name::func ();
模板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <iostream> using namespace std;template <typename T1,typename T2>class Test {public : Test (T1 i,T2 j):a (i),b (j){cout<<"模板类" <<endl;} private : T1 a; T2 b; }; template <> class Test <int ,char >{public : Test (int i,char j):a (i),b (j){cout<<"全特化" <<endl;} private : int a; int b; }; template <typename T2> class Test <char ,T2>{public : Test (char i,T2 j):a (j),b (j){cout<<"个数偏特化" <<endl;} private : char a; T2 b; }; template <typename T1,typename T2> class Test < T1*,T2*>{public : Test (T1* i,T2* j):a (i),b (j){cout<<"指针偏特化" <<endl;} private : T1* a; T2* b; }; template <typename T1,typename T2>class Test < T1 const ,T2 const >{public : Test (T1 i,T2 j):a (i),b (j){cout<<"const偏特化" <<endl;} private : T1 a; T2 b; }; int main () { int a; Test<double ,double > t1 (0.1 ,0.2 ) ; Test<int ,char > t2 (1 ,'A' ) ; Test<char ,bool > t3 ('A' ,true ) ; Test<int *,int *> t4 (&a,&a) ; Test<const int ,const int > t5 (1 ,2 ) ; return 0 ; }
预处理器 1 2 #define PI 3.14159 #define MIN(a,b) (((a)<(b)) ? a : b)
条件编译 1 2 3 4 #define DEBUG #ifdef DEBUG cerr <<"Trace: Coming out of main function" << endl; #endif
# 和 ## 运算符 1 2 3 4 5 6 7 # 将x转换为字符串 #define MKSTR( x ) #x cout << MKSTR (HELLO C++) << endl; ## 将x,y连接 #define CONCAT( x, y ) x ## y int xy = 100 ;cout << concat (x, y);
预定义宏 1 2 3 4 cout << "Value of __LINE__ : " << __LINE__ << endl; cout << "Value of __FILE__ : " << __FILE__ << endl; cout << "Value of __DATE__ : " << __DATE__ << endl; cout << "Value of __TIME__ : " << __TIME__ << endl;
信号处理 信号类型 1 SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> #include <csignal> using namespace std;void signalHandler ( int signum ) { cout << "Interrupt signal (" << signum << ") received.\n" ; exit (signum); } int main () { int i = 0 ; signal (SIGINT, signalHandler); while (++i){ cout << "Going to sleep...." << endl; if ( i == 3 ){ raise ( SIGINT); } sleep (1 ); } return 0 ; }
多线程 1 2 3 4 5 #include <pthread.h> pthread_create (thread, attr, start_routine, arg) pthread_exit (NULL );
向线程传递参数 1 2 3 4 5 6 struct thread_data { int thread_id; char *message; }; struct thread_data td [NUM_THREADS ];rc = pthread_create (threadid, NULL ,PrintHello, (void *)&td[i]);
连接和分离线程 1 2 pthread_join (threadid, status) pthread_detach (threadid)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #include <iostream> #include <cstdlib> #include <pthread.h> #include <unistd.h> using namespace std;#define NUM_THREADS 5 void *wait (void *t) { int i; long tid; tid = (long )t; sleep (1 ); cout << "Sleeping in thread " << endl; cout << "Thread with id : " << tid << " ...exiting " << endl; pthread_exit (NULL ); } int main () { int rc; int i; pthread_t threads[NUM_THREADS]; pthread_attr_t attr; void *status; pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE); for ( i=0 ; i < NUM_THREADS; i++ ){ cout << "main() : creating thread, " << i << endl; rc = pthread_create (&threads[i], NULL , wait, (void *)i ); if (rc){ cout << "Error:unable to create thread," << rc << endl; exit (-1 ); } } pthread_attr_destroy (&attr); for ( i=0 ; i < NUM_THREADS; i++ ){ rc = pthread_join (threads[i], &status); if (rc){ cout << "Error:unable to join," << rc << endl; exit (-1 ); } cout << "Main: completed thread id :" << i ; cout << " exiting with status :" << status << endl; } cout << "Main: program exiting." << endl; pthread_exit (NULL ); }
vector与iterator 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <iostream> #include <vector> using namespace std; int main () { vector<int > vec; int i; cout << "vector size = " << vec.size () << endl; for (i = 0 ; i < 5 ; i++){ vec.push_back (i); } cout << "extended vector size = " << vec.size () << endl; for (i = 0 ; i < 5 ; i++){ cout << "value of vec [" << i << "] = " << vec[i] << endl; } vector<int >::iterator v = vec.begin (); while ( v != vec.end ()) { cout << "value of v = " << *v << endl; v++; } return 0 ; }