复习网址:http://www.runoob.com/cplusplus/cpp-tutorial.html
1,注释
//
/* */
块注释符(/…/)是不可以嵌套使用的。
此外,我们还可以使用 #if 0 … #endif 来实现注释,且可以实现嵌套,格式为:
#if 0
code
#endif
你可以把 #if 0 改成 #if 1 来执行 code 的代码。
这种形式对程序调试也可以帮助,测试时使用 #if 1 来执行测试代码,发布后使用 #if 0 来屏蔽测试代码。
#if 后可以是任意的条件语句
2,数据类型
#include<iostream>
#include<string>
#include <limits>
using namespace std;
int main()
{
cout << "type: \t\t" << "************size**************"<< endl;
cout << "bool: \t\t" << "所占字节数:" << sizeof(bool);
cout << "\t最大值:" << (numeric_limits<bool>::max)();
cout << "\t\t最小值:" << (numeric_limits<bool>::min)() << endl;
cout << "char: \t\t" << "所占字节数:" << sizeof(char);
cout << "\t最大值:" << (numeric_limits<char>::max)();
cout << "\t\t最小值:" << (numeric_limits<char>::min)() << endl;
cout << "signed char: \t" << "所占字节数:" << sizeof(signed char);
cout << "\t最大值:" << (numeric_limits<signed char>::max)();
cout << "\t\t最小值:" << (numeric_limits<signed char>::min)() << endl;
cout << "unsigned char: \t" << "所占字节数:" << sizeof(unsigned char);
cout << "\t最大值:" << (numeric_limits<unsigned char>::max)();
cout << "\t\t最小值:" << (numeric_limits<unsigned char>::min)() << endl;
cout << "wchar_t: \t" << "所占字节数:" << sizeof(wchar_t);
cout << "\t最大值:" << (numeric_limits<wchar_t>::max)();
cout << "\t\t最小值:" << (numeric_limits<wchar_t>::min)() << endl;
cout << "short: \t\t" << "所占字节数:" << sizeof(short);
cout << "\t最大值:" << (numeric_limits<short>::max)();
cout << "\t\t最小值:" << (numeric_limits<short>::min)() << endl;
cout << "int: \t\t" << "所占字节数:" << sizeof(int);
cout << "\t最大值:" << (numeric_limits<int>::max)();
cout << "\t最小值:" << (numeric_limits<int>::min)() << endl;
cout << "unsigned: \t" << "所占字节数:" << sizeof(unsigned);
cout << "\t最大值:" << (numeric_limits<unsigned>::max)();
cout << "\t最小值:" << (numeric_limits<unsigned>::min)() << endl;
cout << "long: \t\t" << "所占字节数:" << sizeof(long);
cout << "\t最大值:" << (numeric_limits<long>::max)();
cout << "\t最小值:" << (numeric_limits<long>::min)() << endl;
cout << "unsigned long: \t" << "所占字节数:" << sizeof(unsigned long);
cout << "\t最大值:" << (numeric_limits<unsigned long>::max)();
cout << "\t最小值:" << (numeric_limits<unsigned long>::min)() << endl;
cout << "double: \t" << "所占字节数:" << sizeof(double);
cout << "\t最大值:" << (numeric_limits<double>::max)();
cout << "\t最小值:" << (numeric_limits<double>::min)() << endl;
cout << "long double: \t" << "所占字节数:" << sizeof(long double);
cout << "\t最大值:" << (numeric_limits<long double>::max)();
cout << "\t最小值:" << (numeric_limits<long double>::min)() << endl;
cout << "float: \t\t" << "所占字节数:" << sizeof(float);
cout << "\t最大值:" << (numeric_limits<float>::max)();
cout << "\t最小值:" << (numeric_limits<float>::min)() << endl;
cout << "size_t: \t" << "所占字节数:" << sizeof(size_t);
cout << "\t最大值:" << (numeric_limits<size_t>::max)();
cout << "\t最小值:" << (numeric_limits<size_t>::min)() << endl;
cout << "string: \t" << "所占字节数:" << sizeof(string) << endl;
// << "\t最大值:" << (numeric_limits<string>::max)()
// << "\t最小值:" << (numeric_limits<string>::min)() << endl;
cout << "type: \t\t" << "************size**************"<< endl;
return 0;
}
type: ************size**************
bool: 所占字节数:1 最大值:1 最小值:0
char: 所占字节数:1 最大值: 最小值:€
signed char: 所占字节数:1 最大值: 最小值:€
unsigned char: 所占字节数:1 最大值: 最小值:
wchar_t: 所占字节数:2 最大值:65535 最小值:0
short: 所占字节数:2 最大值:32767 最小值:-32768
int: 所占字节数:4 最大值:2147483647 最小值:-2147483648
unsigned: 所占字节数:4 最大值:4294967295 最小值:0
long: 所占字节数:4 最大值:2147483647 最小值:-2147483648
unsigned long: 所占字节数:4 最大值:4294967295 最小值:0
double: 所占字节数:8 最大值:1.79769e+308 最小值:2.22507e-308
long double: 所占字节数:8 最大值:1.79769e+308 最小值:2.22507e-308
float: 所占字节数:4 最大值:3.40282e+038 最小值:1.17549e-038
size_t: 所占字节数:4 最大值:4294967295 最小值:0
string: 所占字节数:32
type: ************size**************
请按任意键继续. . .
3,枚举类型
为什么需要枚举类型?
枚举类型(enumeration)是C++中的一种派生数据类型,它是由用户定义
的若干枚举常量的集合
。
enum 枚举名{
标识符[=整型常数],
标识符[=整型常数],
...
标识符[=整型常数]
} 枚举变量;
// C风格
enum color { red, green, blue } c;
c = blue;
// C++风格
enum color { red, green=5, blue };
4,变量的声明、定义、初始化
extern int d = 3, f = 5; // d 和 f 的声明
int d = 3, f = 5; // 定义并初始化 d 和 f
byte z = 22; // 定义并初始化 z
char x = 'x'; // 变量 x 的值为 'x'
#include <iostream>
using namespace std;
// 变量声明
extern int a, b;
extern int c;
extern float f;
int main ()
{
// 变量定义
int a, b;
int c;
float f;
// 实际初始化
a = 10;
b = 20;
c = a + b;
cout << c << endl ;
f = 70.0/3.0;
cout << f << endl ;
return 0;
}
5,register 存储类
定义 ‘register’ 并不意味着变量将被存储在寄存器中,它意味着变量可能存储在寄存器中,这取决于硬件和实现的限制。
{
register int miles;
}
6,extern 存储类
extern 是用来在另一个文件中声明一个全局变量或函数
// 第一个文件
#include <iostream>
int count ;
extern void write_extern();
int main()
{
count = 5;
write_extern();
}
// 第二个文件
#include <iostream>
extern int count;
void write_extern(void)
{
std::cout << "Count is " << count << std::endl;
}
7,mutable 存储类
mutable 说明符仅适用于类的对象,它允许对象的成员替代常量。也就是说,mutable 成员可以通过 const 成员函数修改。
8,thread_local 存储类
使用 thread_local 说明符声明的变量仅可在它在其上创建的线程上访问。 变量在创建线程时创建,并在销毁线程时销毁。 每个线程都有其自己的变量副本。
thread_local 说明符可以与 static 或 extern 合并。
可以将 thread_local 仅应用于数据声明和定义,thread_local 不能用于函数声明或定义。
9,位运算符
A = 0011 1100
B = 0000 1101
-----------------
A&B = 0000 1100 // 两个都为1,才为1
A|B = 0011 1101 // 两个至少有一个1,才为1
A^B = 0011 0001 // 两个不同为1,相同为0
~A = 1100 0011 // 相反,0为1,1为0
10,explicit 与 volatile
关键字explicit
,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。声明为explicit的构造函数不能在隐式转换中使用。
关键字volatile
往往会用于多线程的修饰,以确保线程每次都重新从内存中读取用它声明的变量的值
11,Lambda 函数与表达式
C++11 匿名函数
- 有返回值:
[capture](parameters)->return-type{body}
例:[](int x, int y){ return x < y ; }
- 无返回值:
[capture](parameters){body}
例:[]{ ++global_x; }
[] // 沒有定义任何变量。使用未定义变量会引发错误。
[x, &y] // x以传值方式传入(默认),y以引用方式传入。
[&] // 任何被使用到的外部变量都隐式地以引用方式加以引用。
[=] // 任何被使用到的外部变量都隐式地以传值方式加以引用。
[&, x] // x显式地以传值方式加以引用。其余变量以引用方式加以引用。
[=, &z] // z显式地以引用方式加以引用。其余变量以传值方式加以引用。
12, 数学运算
1 double cos(double); //该函数返回弧度角(double 型)的余弦。
2 double sin(double); //该函数返回弧度角(double 型)的正弦。
3 double tan(double); //该函数返回弧度角(double 型)的正切。
4 double log(double); //该函数返回参数的自然对数。
5 double pow(double, double); //假设第一个参数为 x,第二个参数为 y,则该函数返回 x 的 y 次方。
6 double hypot(double, double);//该函数返回两个参数的平方总和的平方根,
//也就是说,参数为一个直角三角形的两个直角边,函数会返回斜边的长度。
7 double sqrt(double); //该函数返回参数的平方根。
8 int abs(int); //该函数返回整数的绝对值。
9 double fabs(double); //该函数返回任意一个十进制数的绝对值。
10 double floor(double); //该函数返回一个小于或等于传入参数的最大整数。
13,随机数
#include <ctime>
#include <cstdlib>
{
// 设置种子
srand( (unsigned)time( NULL ) );
int x = rand(); /*生成实际的随机数*/
int y = rand() % 100; /*产生100以内的随机整数 0-99 */
}
14,格式化输出
#include <iomanip>
using std::setw;
{
cout << "Element" << setw( 13 ) << "Value" << endl;
// 输出数组中每个元素的值
for ( int i = 0; i < 10; j++ )
{
cout << setw( 7 )<< i << setw( 13 ) << i*2 << endl;
}
}
在C++中,setw(int n)用来控制输出间隔,(n-1个空格)。
setw()默认填充的内容为空格,可以setfill()配合使用设置其他字符填充。
cout << setfill('*') << setw(5) << 'a' << endl;
则输出:
****a //4个*和字符a共占5个位置。
15,指向数组的指针
double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
double *p = balance; //使用数组名作为指针赋值, balance 等同 &balance[0]
使用指针的数组值
*(p + 0) : 1000
*(p + 1) : 2
*(p + 2) : 3.4
*(p + 3) : 17
*(p + 4) : 50
使用 balance 作为地址的数组值
*(balance + 0) : 1000
*(balance + 1) : 2
*(balance + 2) : 3.4
*(balance + 3) : 17
*(balance + 4) : 50
16,数组参数传递
void myFunction(int *param)
void myFunction(int param[10])
void myFunction(int param[])
double getAverage(int arr[], int size)
17,C风格字符串常用函数
1 strcpy(s1, s2); //复制字符串 s2 到字符串 s1。
2 strcat(s1, s2); //连接字符串 s2 到字符串 s1 的末尾。
3 strlen(s1); //返回字符串 s1 的长度。
4 strcmp(s1, s2); //如果 s1 和 s2 是相同的,则返回 0;
//如果 s1<s2 则返回值小于 0;如果 s1>s2 则返回值大于 0。
5 strchr(s1, ch); //返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
6 strstr(s1, s2); //返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。
18, C++ 中的 string 类
string str1 = "Hello";
string str2 = "World";
string str3 = str1; // 复制 str1 到 str3
str3 = str1 + str2; // 连接 str1 和 str2
int len = str3.size(); // str3 的总长度
1. append() -- 在字符串的末尾添加字符
2. find() -- 在字符串中查找字符串
4. insert() -- 插入字符
5. length() -- 返回字符串的长度
6. replace() -- 替换字符串
7. substr() -- 返回某个子字符串
8. find_first_of() -- 从头开始寻找字符的位置
9. find_last_of() -- 从尾开始寻找字符的位置
10. ...
问题:
1. C++ string 的 size 与 length 有什么区别? ——— 无
2. 字符串字面值 size 与 strlen 有什么区别?
cout<<strlen("123")<<endl; //返回 3
cout<<sizeof("123")<<endl; //返回 4 --------- 前都包含'\0',后都不包含
char str[20]="0123456789";
int a=strlen(str); // a=10; >>>> strlen 计算字符串的长度,以结束符 0x00 为字符串结束。
int b=sizeof(str); // 而 b=20; >>>> sizeof 计算的则是分配的数组 str[20] 所占的内存空间的大小,
// 不受里面存储的内容改变。
char* ss = "0123456789"; //sizeof(ss) 结果 4 ===》ss 是指向字符串常量的字符指针,
//sizeof 获得的是一个指针的之所占的空间,应该是长整型的,所以是 4。
sizeof(*ss) //结果 1 ===》*ss 是第一个字符 其实就是获得了字符串的第一位 '0' 所占的内存空间,
//是 char 类型的,占了 1 位
strlen(ss) // = 10 ===》 如果要获得这个字符串的长度,则一定要使用 strlen。
//strlen 用来求字符串的长度;而 sizeof 是用来求指定变量或者变量类型等所占内存大小。
C++ string 容器
vector<int>::const_iterator //不能改变指向的值,自身的值可以改变
const vector<int>::iterator //可以改变指向的值,自身的值不能改变
const vector<int>::const_iterator //自身的值和指向的值都是只读的
19,引用
注意:当返回一个引用时,要注意被引用的对象不能超出作用域。所以返回一个对局部变量的引用是不合法的,但是,可以返回一个对静态变量的引用。
int& func() {
int q;
//! return q; // 在编译时发生错误
static int x;
return x; // 安全,x 在函数作用域外依然是有效的
}
20,时间
<ctime> 头文件
clock_t、time_t、size_t 和 tm
// tm的结构详情
struct tm {
int tm_sec; // 秒,正常范围从 0 到 59,但允许至 61
int tm_min; // 分,范围从 0 到 59
int tm_hour; // 小时,范围从 0 到 23
int tm_mday; // 一月中的第几天,范围从 1 到 31
int tm_mon; // 月,范围从 0 到 11
int tm_year; // 自 1900 年起的年数
int tm_wday; // 一周中的第几天,范围从 0 到 6,从星期日算起
int tm_yday; // 一年中的第几天,范围从 0 到 365,从 1 月 1 日算起
int tm_isdst; // 夏令时
}
// 使用
#include <ctime>
{
time_t now = time(0); // 基于当前系统的当前日期/时间
// 获取本地时间
char* dt = ctime(&now); // 把 now 转换为字符串形式
cout << "本地日期和时间:" << dt << endl; // Wed May 30 15:01:09 2018
// 获取UTC时间
tm *gmtm = gmtime(&now);
dt = asctime(gmtm);
cout << "UTC 日期和时间:"<< dt << endl; // Wed May 30 07:01:09 2018
cout << "1970 到目前经过秒数:" << now << endl; //1970 到目前经过秒数:1527663824
tm *ltm = localtime(&now);
// 输出 tm 结构的各个组成部分
cout << "年: "<< 1900 + ltm->tm_year << endl; //年: 2018
cout << "月: "<< 1 + ltm->tm_mon<< endl; //月: 5
cout << "日: "<< ltm->tm_mday << endl; //日: 30
cout << "时间: "<< ltm->tm_hour << ":" << ltm->tm_min << ":" << ltm->tm_sec << endl;
// 时间: 15:3:44
}
// 获取一个自定义时间格式
#include <iostream>
#include <ctime>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
string Get_Current_Date();
int main( )
{
// 将当前日期以 20** - ** - ** 格式输出
cout << Get_Current_Date().c_str() << endl;
getchar();
return 0;
}
string Get_Current_Date()
{
time_t nowtime;
nowtime = time(NULL); //获取日历时间
char tmp[64];
strftime(tmp,sizeof(tmp),"%Y-%m-%d",localtime(&nowtime));
return tmp;
}
21,多继承
多继承(环状继承),A->D, B->D, C->(A,B),例如:
class D{......};
class B: public D{......};
class A: public D{......};
class C: public B, public A{.....};
这个继承会使D创建两个对象,要解决上面问题就要用虚拟继承格式
格式:class 类名: virtual 继承方式 父类名
class D{......};
class B: virtual public D{......};
class A: virtual public D{......};
class C: public B, public A{.....};
22,运算符重载
// 重载 + 运算符,用于把两个 Box 对象相加
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;
}
// 重载负运算符( - )
Distance operator- ()
{
feet = -feet;
inches = -inches;
return Distance(feet, inches);
}
A operator+(const A & obj);
A operator+(const int b);
friend A operator+(const int b, A obj);
A A::operator +(const A& obj)//重载+号用于 对象相加
{
return this->a+obj.a;
}
A A::operator+(const int b)//重载+号用于 对象与数相加
{
return A(a+b);
}
A operator+(const int b, A obj)
{
return obj+b;//友元函数调用第二个重载+的成员函数 相当于 obj.operator+(b);
}
{
a3=a1+a2;//可以交换顺序,相当月a3=a1.operator+(a2);
a4=a1+m;//因为加了个友元函数所以也可以交换顺序了。
a5=m+a1;
}
前++ 后++ 重载的区别
23,define
#include <iostream>
using namespace std;
#define MKSTR(x) #x
#define concat(a, b) a ## b
int main()
{
cout << MKSTR(HELLO C++) << endl;
cout << MKSTR("HELLO C++") << endl;
cout << MKSTR("HELLO C++" "wq") << endl;
cout << concat(10, 11) << endl;
cout << concat("aaa", "bbb") << endl;
return 0;
}
// 输出
HELLO C++
"HELLO C++"
"HELLO C++" "wq"
1011
aaabbb
请按任意键继续. . .
24,std::vector::resize
这个是重新分配容器的实质个数,但它也实际上改变了容器里的数值。