C++复习总结1

C++复习总结,仅供笔者复习使用,参考教材:

  • 《零基础C++——从入门到精通》
  • 《C++ Primer Plus》

本文主要内容为:C++ 基本语法、输入输出、流程控制、字符串和数组。
C++ 指针、函数和STL容器部分 见 C++复习总结2
C++ 结构体、面向对象和泛型编程部分 见 C++复习总结3.

一. 基本语法

1. 基本数据类型

以下为 gnu++14 标准下的数据类型:

类型说明字节数表示范围占位符
bool布尔型10 / 1%d
char字符型1-27 ~ 27-1%c: 字符
%d: ASCII码
wchar_t宽字符型20 ~ 216-1
short短整型2-215 ~ 215-1
int整型4-231 ~ 231-1%d
unsigned int无符号整型40 ~ 232-1
long long长整型8-263 ~ 263-1%Ld
unsigned long long长整型80 ~ 264-1
float单精度浮点型(10-6)4-2128 ~ 2128%.f
double双精度浮点型(10-15)8-21024 ~ 21024%.lf
long double扩展精度浮点型16%.Lf
string字符串8————“%s”, s.c_str()

可以用 typeid(var).name() 返回数据类型,用 sizeof(type) 返回类型存储空间大小(字节数)。

2. 变量与常量

  • char 元素可以用整数定义和输出:char c = 99; cout<<int(c)<<endl
  • int 元素可以用二进制数 int bin=0b1001、八进制数 int oct=0213 和十六进制数 int hex=0x4b 定义;
  • int 元素相除不会得到浮点数,需要提前作类型转换
  • float 元素可以用科学计数法定义:float f=31415926e-7f
  • 变量名必须用字母或下划线开头,不能使用数字
  • const 常量不能修改:const int a=5
  • typedef 可以定义变量的别名:typedef int age; age myAge=20.

3. 操作符

  • 算术操作符:+、-、*、/、%
  • 关系操作符:==、!=、>、<、>=、<=
  • 逻辑操作符:&&、||、!
  • 位操作符&、|、^、~、<<、>>
  • 三目运算符:condition ? expression1 : expression2

4. 转义符

转义符说明
\"字符串内部打印 "
\’字符串内部打印 ’
\n换行符
\t制表符(占8格整齐输出)

5. 一些数据处理

  • 生成 [a, a+b] 的随机整数:
#include <iostream>
#include <algorithm>

int main{
	int a=3;
	int b=5;
	int ran=rand()%(b+1)+a;

	return 0;
}
  • 求 a 和 b 的最大公因数:
#include <iostream>
#include <algorithm>

int main{
	int a=3;
	int b=5;
	int c=__gcd(a,b);

	return 0;
}
  • 取绝对值:
#include <iostream>
#include <math.h>

int main{
	int n=3;
	int f=5.2;
	int abs_n=abs(n);
	float abs_f=fabs(f)

	return 0;
}
  • 取整:ceil() 函数向上取整,floor() 函数向下取整:
#include <iostream>
#include <cmath>

int main() {
    double num = 3.14;
    double result = ceil(num); 	// 向上取整
    double result = floor(num); // 向下取整
    
    return 0;
}

  • 浮点数四舍五入到指定位数:利用 round() 函数,其原理为:(int)(x+0.5)
#include <iostream>
#include <math.h>
using namespace std;

int main(){
    double f0=3.1415926;
    double f1=round(f0);            //3
    double f2=round(f0*10)/10;      //3.1
    double f3=round(f0*10000)/10000;//3.146

    return 0;
}
  • 输出浮点数四舍五入到指定位数:
#include <iostream>
#include <iomanip>
using namespace std;

int main(){
    int n=5;
    float f=3.1415926;
    printf("%.0f\n",f);		//3
    printf("%.3f\n",f);		//3.142
    printf("%.*f\n",n,f);	//3.14159
    cout<<fixed<<setprecision(n)<<f<<endl;	//需要调 iomanip 包

    return 0;
}
  • 输出整数指定位数(当前位数小于指定位数时用前导零补齐):
#include <iostream>
using namespace std;

int main(){
    int n=10;
    int num=1234567;
    printf("%03d\n",num);   //1234567
    printf("%08d\n",num);   //01234567
    printf("%0*d\n",n,num); //0001234567

    return 0;
}
  • 计算运行时间:使用 clock_t 变量获取程序运行前后的时间 clock() 并作差得到程序的运行时间 (s);
#include<iostream>
#include<algorithm>
#include<time.h>
using namespace std;

int main() {
	clock_t start,end;
	start=clock();

	int a[100000];
	for(int i=0;i<100000;i++)	a[i]=rand()%200;
	sort(a,a+100000);

	end=clock();
	cout<<double(end-start)/CLOCKS_PER_SEC<<endl;
    return 0;
}

二. 流程控制语句

  • if...else if...else 语句;
  • switch 语句:别忘了 break 和 default、多个 case 情况可以合并;
  • while 语句;
  • do...while 语句;
  • for 语句;
  • break 语句;
  • continue 语句;
  • goto 语句;

三. 输入输出

1. cin

cin 接收输入遇到空格或回车键就停止,可用来接收 int、char、不含空格的 string 或 char 数组:

#include <iostream>
using namespace std;

int main(){
    char a[20];
    cin>>a;		//hello world
    cout<<a;	//hello

    return 0;
}

2. scanf

scanf 是除 cin 外的另一种输入方法,不仅可以节约时间,还可以 在题目要求的格式下 接收输入:

#include <iostream>
using namespace std;

int main(){
    int n;
    char c;
    scanf("The number is %d, the char is %c.", &n, &c);
    char s[20];
    scanf("%s",s);

    return 0;
}

注意:

  • scanf 语句通过 %+变量类型 将接收到的 字符 转换成指定的变量类型并赋值给 变量的地址。因此,在接收 int、char、bool 型变量时需要加取址符 &,接收 char 型数组时则不用取址;
  • scanf 语句接收 char 数组时也不能包含空格;
  • 缓冲区太长时需要释放:fflush(stdin)
  • 可以用 while(scanf("%d%c", &n, &c) != EOF) 来接收数量未知的输入元素,并用 CtrlZ+Enter 结束输入(若输入无格式要求,也可以直接采用 while(cin >> a));

3. getline

getline(cin,s) 主要用于接收 string 类型元素的输入,可以接收空格,遇到回车键结束。一般与 getchar() 配合使用以吞掉换行符

#include <iostream>
#include <string>
using namespace std;

int main(){
    int N;
    cin>>N;
    getchar();                      	//吸收回车
    for(int i=0;i<N;i++){
        string s;                   	//若无getchar,则第一个getline的是N
        getline(cin,s);             	//s中包含空格,不能直接cin
    }

    return 0;
}

4. gets/puts

gets(a) / puts(a) 一般用于对 字符数组 的整体输入输出。

四. 字符、字符串与数组

1. 字符

char 类型除了前面提到的一些基础用法,还有一些自己的方法:

  • isalnum(c):判断字符是否是字母或数字;
  • toupper(c) / tolower(c):将字符串换成大/小写;
  • isupper(c) / islower(c):判断字符是否是大/小写;
  • isdigit(c) / isalpha(c) / iscntrl(c) / ispunct(c) / isspace(c):判断字符是否是数字/字母/控制字符/标点空白符;
  • getchar():接收单个字符输入;
  • putchar():输出字符;

2. 字符串

C++ 中提供了 string 库,有一些自带的方法:

  • s.empty():判断字符串是否为空并返回结果;
  • s.length():返回字符串长度;
  • s+=s_new:字符串拼接;
  • s.push_back(c):尾部添加一个新字符不同于上面的拼接字符串);
  • s.pop_back():尾部移除一个字符;
  • s.insert(i, s_new):在 i 处插入字符或字符串;
  • s.replace(start, num, s_new):从 start 开始后面的 num 个元素替换成 s_new;
  • s.substr(start, len):从 start 处截取长度为 len 的子字符串并返回;
  • s.find(s2, start):返回从 start 处向后查找 s 中第一次出现 s2 的位置,没有则返回 -1;
  • stoi(s) / stod(s):字符串转 int 型 / double 型并返回【C++11】,遇到非数字就停止;
  • string(1,c):将 char 型转换成字符串并返回;
  • to_string(i) / to_string(f) / to_string(d):将 int 型 / float 型 / double 型转换成字符串并返回【C++11】;

string 还可以通过 stringstream 和其他数据类型相互转换:

//string <-> int
#include <iostream>
#include <sstream>
using namespace std;

int main(){
    stringstream ss;

    string s1="10086";
    int n1;
    ss<<s1;
    ss>>n1;
    ss.clear();     //连续使用需要清除流

    int n2=12345;
    string s2;
    ss<<n2;
    ss>>s2;
    cout<<n1<<endl<<s2<<endl;

    return 0;
}
//string <-> char
#include <iostream>
#include <sstream>
using namespace std;

int main(){
    stringstream ss;

    char c1='a';
    string s1;
    ss<<c1;
    ss>>s1;
    
    ss.clear();
    
    string s2=string(1,c1);		//char->string可以直接转换

    char c2;
    string s3="f";
    ss<<s3;
    ss>>c2;
    
    cout<<s1<<" "<<s2<<endl<<c2<<endl;

    return 0;
}

3. 静态数组

静态数组在 C 中就有了,是一种完全静态的数据结构,在初始化的时候就需要指定大小,并且不能修改数组长度。它存放在 中,内存分配与释放完全由系统自动完成,效率最高。

静态数组创建时可以只对部分赋值,则其余都会保留默认值:

#include <iostream>
using namespace std;

int main(){
    int arr1[5];            //默认值未知
    int arr2[5]={};         //默认值为0
    int arr3[5]={1};        //0号元素为1,其余为默认值0
    int arr4[5]={1,3,2};    //0~2号元素被赋值,其余为默认值0
    int arr5[]={0,1,2,3,4}; //根据数组元素数量自动补齐大小

    return 0;
}

4. 动态数组

动态数组是程序员通过 new 关键字创建的,存放在 中,需要程序员在使用完通过 delete 关键字释放内存,否则会出现 内存泄漏

#include <iostream>
using namespace std;

int main(){
    int n=5;
    int *arr=new int[n];
    int *tmp=arr;
    for(int i=0;i<n;i++){
        *tmp=i;
        cout<<*tmp++<<" ";
    }
    delete [] arr;
    delete tmp;
    
    return 0;
}

5. vector

C++ 标准库引入了动态的数据结构 ---- vector,存放在 中,由STL库负责内存分配与释放,使用起来相当方便。同时并提供了一些方法:

  • 初始化:vector 初始化可以通过 指定初始值、其他vector复制 或 数组复制:
#include <iostream>
#include <vector>
using namespace std;

int main(){
    int arr[5]={1,5,3,6,7};
    vector<int> v1(10);         //大小为10,初值为0
    vector<int> v2(10,1);       //大小为10,初值为1
    vector<int> v3(arr,arr+4);  //用arr[0]~arr[3]初始化v3
    vector<int> v4(v2);         //用v2初始化
    vector<int> v5(v2.begin(),v2.begin()+4);    //用v2部分初始化

    return 0;
}
  • v.assign(b.begin(), b.begin()+3) / v.assign(n,0):对 vector 重新赋值;
  • v.erase(v.begin()+1, v.begin()+3):删除 vector 部分元素;
  • v.resize(10,2):调整 vector 大小并指定默认值;
  • v.front() / v.back():返回 vector 首/尾元素;
  • v.clear():清空数组;
  • v.empty():返回数组是否为空;
  • v.push_back(a) / v.pop_back():末尾添加/弹出元素;
  • v.insert(v.begin()+2, 3, 5):在 vector 中插入元素;
  • merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v.begin()):将 v1 和 v2 合并成到 v;
  • find(v.begin(), v.end(), 3):在 vector 中查找元素;

resize() 函数常用来创建二维数组:

vector<vector<bool> > dp;
vector<bool> tmp(n);
dp.resize(m,tmp);

但嵌套的二维数组 vector<vector<int> > 必须保证每行元素个数相同,否则会被中断!如果想要每行元素随意的二维数组,可以采用元素类型为 vector 的静态数组:

vector<int> node[10001];

6. 一些通用函数

  • sort():对数组排序,支持自定义判断方法:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool cmp(int a,int b){  //自定义排序方法
    return a>b;
}

int main(){
    int arr[5]={1,5,3,6,7};
    vector<int> v(arr,arr+5);
    sort(arr,arr+5);
    sort(v.begin(),v.end(),cmp);
    for(int i=0;i<5;i++)    cout<<"arr["<<i<<"]:"<<arr[i]<<endl;
    for(int i=0;i<v.size();i++)    cout<<"v["<<i<<"]:"<<v[i]<<endl;

    return 0;
}
  • reverse():对 vector 或 字符串 逆置:
reverse(str.begin(),str.end());
reverse(v.begin(),v.end());
  • lower_bound() / upper_bound():在 有序 数组中查找第一次 / 最后一次出现的大于等于 / 大于 / 小于等于 / 小于 a 的地址,解引用后即为相应的值:
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
	/* lower_bound/upper_bound 函数返回地址,解引用后得到值 */

	int arr[10]={1,1,3,5,5,8,8,8,9,10};			//非降序数组 
	//第一次出现大于等于5的位置与值 
	cout<<lower_bound(arr,arr+10,5)-arr<<" ";
	cout<<*lower_bound(arr,arr+10,5)<<endl;			//3 5
	//第一次出现大于5的位置与值 
	cout<<upper_bound(arr,arr+10,5)-arr<<" ";
	cout<<*upper_bound(arr,arr+10,5)<<endl;			//5 8 
	//最后一次出现小于5的位置与值 
	cout<<prev(lower_bound(arr,arr+10,5))-arr<<" ";
	cout<<*prev(lower_bound(arr,arr+10,5))<<endl;	//2 3
	//最后一次出现小于等于5的位置与值 
	cout<<prev(upper_bound(arr,arr+10,5))-arr<<" ";
	cout<<*prev(upper_bound(arr,arr+10,5))<<endl;	//4 5

	return 0;
}

其中 std::prev(it) 表示将迭代器退回一个位置,从而变换得到小于(等于)的位置。需要注意的是,在使用 std::prev 之前,要 确保迭代器不指向数组开头,以避免越界。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值