• C++类型转换与函数


    前置:C语言


    1.1 IO

    1.1.1 cout 输出流

    操作符描述
    ws提取空白符
    endl插入换行符并刷新流
    ends插入空字符
    setw(int)设置域宽
    setprecision(int)设置浮点数小数位数(包含小数点)
    cout << setw(5) << setprecision(3) << 3.1415 << endl;
    //设置域宽为5,小数点后保留两位有效小数
    
    • 1
    • 2

    setw() 函数会用当前的填充字符控制对齐位置,默认的填充字符是空格

    可以通过 setfill 来设置填充字符

    #include 
    #include 
    
    using namespace std;
    
    int main(void) {
        cout << setfill('0') << setw(10) << 45698 << endl;//0000045698
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    CPU所执行的指令并不对操作数的类型加以区分,对各个操作数都执行相同的操作,编译器根据变量的数据类型选择合适的指令

    • 符号扩展:有符号数据类型,用符号位扩展

    • 0扩展:无符号数据类型,用0填充

    1.1.2 I/O格式化输出

    coutSTL 库提供的一个 iostream 实例,拥有 ios_base 基类的全部函数和成员数据

    进行格式化定义可以使用 setfunsetf 函数和 flag 函数

    cout 维护一个当前的格式状态

    setfunsetf 是在当前的格式状态上追加或删除指定的格式

    flag 则是将当前格式状态全部替换成指定的格式

    操作符名含义
    ios::dec数值类型采用十进制表示
    ios::hex数值类型采用十六进制表示
    ios::oct数值类型采用八进制表示
    ios::showbase为整数添加一个表示其进制的前缀
    ios::internal在符号位和数值中间按需插入字符,使两端对齐
    ios::left在串的末尾插入填充字符使串左对齐
    ios::right在串的末尾插入填充字符使串右对齐
    ios::boolalphabool 类型的值以 truefalse 表示
    ios::fixed将浮点数按照普通定点格式处理(非科学计数法)
    ios::scientific将浮点数按科学计数法处理(带指数域)
    ios::showpoint在浮点数表示的小数中强制插入小数点(默认情况下浮点数表示的整数不显示小数点)
    ios::showpos强制在正数前添加 +
    ios::skipws忽略前导空格,主要用于 cin
    ios::unitbuf在每次输出后清空缓存
    ios::uppercase强制大写字母

    以上每种格式都独立占用一bit,可以用 | 运算符组合使用,调用 setf/unsetf 设置输出格式一般用法

    setf 可接受一个或两个参数

    • cout.setf(指定格式);
    • cout.setf(指定格式,删除的格式);
    cout.setf(ios::right | ios::hex);//设置十六进制右对齐
    cout.setf(ios::right ,ios::adjustfield);//取消其他对对齐,设置为右对齐
    
    • 1
    • 2

    以预定义的bit组合位

    • ios::adjustifield 对齐格式的bit组合位
    • ios::basefield 进制的bit组合位
    • ios::floatfield 浮点表示方式的bit组合位

    设置格式后,之后所有的 cout 都会按照指定的格式状态执行

    如果在一次输出过程中需要混在多种格式,使用 cout 的成员函数来处理就很不方便了,STL 提供了一套 库可以满足这种使用方式

    库中将每一种格式的设置和删除都进行了函数级的同名封装,比如 fixed ,就可以将一个ostream的对象作为参数,在内部调用 setf(ios::fixed) 后再返回原对象。此外 还提供了setiosflags、setbase、setfill、setw、setprecision等方便的格式控制函数。大多数示例代码都会使用到,因此默认包含的头文件均为:

    #include 
    #include 
    
    • 1
    • 2
    缩进

    将输出内容按指定的宽度对齐

    #include 
    #include 
    
    using namespace std;
    
    int main(void) {
        cout.flags(ios::left); //左对齐
        cout << setw(10) << -456.98 << "The End" << endl;
        cout.flags(ios::internal); //两端对齐
        cout << setw(10) << -456.98 << "The End" << endl;
        cout.flags(ios::right); //右对齐
        cout << setw(10) << -456.98 << "The End" << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    #include 
    #include 
    
    using namespace std;
    
    int main(void) {
        cout << left << setw(10) << -456.98 << "The End" << endl; //左对齐
        cout << internal << setw(10) << -456.98 << "The End" << endl; //两端对齐
        cout << right << setw(10) << -456.98 << "The End" << endl; //右对齐
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    整数
    #include 
    #include 
    
    using namespace std;
    
    int main(void) {
        cout.setf(ios::showpos | ios::uppercase);
        cout << showbase << hex << setw(4) << 12 << setw(12) << -12 << endl;
        cout << showbase << dec << setw(4) << 12 << setw(12) << -12 << endl;
        cout << showbase << oct << setw(4) << 12 << setw(12) << -12 << endl;
            
        cout.unsetf(ios::showpos | ios::uppercase);
        cout << noshowbase << hex << setw(4) << 12 << setw(12) << -12 << endl;
        cout << noshowbase << dec << setw(4) << 12 << setw(12) << -12 << endl;
        cout << noshowbase << oct << setw(4) << 12 << setw(12) << -12 << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述


    由于 setbase() 函数设置整数进制反而比上述方法还复杂,所以除非特殊的代码规范要求,一般不建议使用

    小数

    分为两种:

    • 定点表示 ios::fixed ,不带指数域
    • 科学计数法表示 ios::scientific 带指数域

    setprecision 配合使用,可以指定小数点后保留位数

    #include 
    #include 
    
    using namespace std;
    
    int main(void) {
        cout.setf(ios::fixed);
        cout << setprecision(0) << 12.05 << endl;
        cout << setprecision(1) << 12.05 << endl;
        cout << setprecision(2) << 12.05 << endl;
        cout << setprecision(3) << 12.05 << endl;
    
        cout.setf(ios::scientific, ios::floatfield);
        cout << setprecision(0) << 12.05 << endl;
        cout << setprecision(1) << 12.05 << endl;
        cout << setprecision(2) << 12.05 << endl;
        cout << setprecision(3) << 12.05 << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

    有时因为机器表示浮点数的舍入误差,需要手动修正

    #include 
    #include 
    
    using namespace std;
    
    int main(void) {
        cout << fixed << setprecision(1) << 2.05 << endl;//2.0
        cout << fixed << setprecision(1) << 2.05 + 1e-8 << endl;//2.1
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    字符串

    字符串的输出处理主要是对齐,

    字符串的输入方法

    getline() 会读取屏幕上输入的字符,直至遇到换行符 \n 位置

    • getline(指定输入流,指定一个string对象)
    • getline(指定输入流,指定一个string对象,指定的结束字符)

    getline 不会读入结束符号,读取指针会跳转至下一个非结束字符处

    #include 
    #include 
    #include 
    
    using namespace std;
    
    int main(void) {
        string str1, str2;
        getline(cin, str1);
    
        cin >> str2;
        cout << str1 << endl << str2 << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    输入:

    abc
    abc

    结果:

    abc
    abc

    缓冲区

    由于调用系统函数在屏幕上逐个显示字符是很慢的,因此cin/cout为了加快速度使用缓冲区技术,粗略的讲就是暂时不输出指定的字符,而是存放在缓冲区中,在合适的时机一次性输出到屏幕上

    如果要和C标准库的stdio库函数混合使用就必须要小心的处理缓冲区了

    如果要与scanf和printf联合使用,务必在调用cout前加上cout.sync_with_stdio(),设置与stdio同步,否则输出的数据顺序会发生混乱。

    flush和endl都会将当前缓冲区中的内容立即写入到屏幕上,而unitbuf/nounitbuf可以禁止或启用缓冲区。

    #include 
    #include 
    
    using namespace std;
    
    int main(void) {
        cout << 123 << flush << 456 << endl;
        cout << unitbuf << 123 << nounitbuf << 456 << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    1.2 函数

    C++完全兼容了 C语言结构化程序设计

    • 自顶向下:针对可能存在二义性的问题描述,转化为流程化、有限确定的算法描述,进而用无二义性的程序进行实现
    • 按功能划分模块
    • 每一模块都由顺序,选择,循环三种基本结构组成
    • 模块化实现的具体方法为子程序

    1.2.1 基本结构

    /*求x的n次方*/
    # include
    
    using namespace std;
    
    double mypower(int x,int n){
        double val = 1.0;
        
        while(n--)
    		val *= x;
        return val;
    }
    
    int main(){
        int x,n;
        
        cin >> x >> n;
        cout << x << "的" << n << "次幂是:" << mypower(x,n) << endl;
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    /*二进制转十进制*/
    # include
    
    using namespace std;
    
    /*x的n次幂*/
    double power(int x,int n){
        double val = 1.0;
        
        while(n--)
            val *= x;
        
        return val;
    }
    
    int main(){
    	int val = 0;
        char ch;
        
        /*每8位为一组*/
        for(int i = 8;i >= 0;--i){
            cin >> ch;
            if('1' == ch)
                val += static_cast<int>(power(2,i));
        }
        
        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
    • 28
    随机数
    /*随机数的获取*/
    # include
    # include
    
    using namespace std;
    
    enum GameStatus{WIN,LOSE,PLAYING};
    
    /*产生结果*/
    int rollDice(){
        int die1 = 1 + rand()%6;
        int die2 = 1 + rand()%6;
        
        cout << "payer rolled" << die1 << "+" << die2 << "=" << die1 + die2 << endl;
        
        return die1 + die2;
    }
    
    int main(){
        int sum,myPoint;
        GameStatus status;
        
        unsigned seed;
        cin >> seed;//输入随机数种子,即为随机数序列设置初值,不同初值,产生的随机数序列不同
        srand(seed);//产生随机数序列
        
        sum = rollDice();
        switch(sum){
            case 7:
            case 11:
                status = WIN;
                break;
            case 2:
            case 3:
            case 12:
                status = LOSE;
                break;
            default:
            	status = PLAYING;
            	myPoint = sum;
                cout << "point is" << sum << endl;
        }
        
        while(PLAYING == status){
    		sum = rollDice();
            if(sum == myPoint)
                status == WIN;
            else if(7 == sum)
                status == LOSE;
        }
        
        if(WIN == status)
            cout << "You win" << endl;
        else
            cout << "You lose" << 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
    • 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
    • 55
    • 56
    • 57
    • 58
    • 59
    数学函数

    s i n ( x ) = x + x 3 3 ! + x 5 5 ! + . . . + x 2 n − 1 ( 2 n − 1 ) !

    sin(x)=x+x33!+x55!+...+x2n1(2n1)!" role="presentation" style="position: relative;">sin(x)=x+x33!+x55!+...+x2n1(2n1)!
    sin(x)=x+3!x3+5!x5+...+(2n1)!x2n1

    # include
    # include
    
    using namespace std;
    
    const double TINY_VALUE = 1e-10;
    
    double tsin(double x){
        double g = 0;
        double t = x;
        int n = 1;
        
        do{
            g += t;
            n++;
            t = -t*x*x/(2*n-1)/(2*n-1);
        }while(fabs(t) >= TINY_VALUE);//涉及精确度,添加精度变量
        
        return g;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    1.2.2 递归

    # include
    
    using namespacce std;
    
    int c(int n,int k){
        if(k > n)
            return 0;
        else if(n == k || k == 0)
            return 1;
        else
            return c(n-1,k)+c(n-1,k-1);
    }
    
    int main(){
        int n,k;
        
        cin >> n >> k;
        cout << "C(n,k)" << c(n,k) << endl;
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    1.2.3 引用形参

    一个变量的别名,指向同一块内存空间

    声明引用时,必须对他初始化,使他指向已存在的对象

    • 只能初始化,不能修改

    在作为函数参数时:执行主调函数中的 调用 时才会为变量分配内存,同时用实参来初始化形参

    1.2.4 内联函数

    内联函数不在调用时发生控制转移,只是将代码嵌入到调用处

    适用于功能简单,规模小,经常使用的函数

    inline 数据类型 函数名(形参列表){
        /*函数体*/
    }
    
    • 1
    • 2
    • 3

    1.2.5 带默认形参的函数

    在函数声明时,声明默认值

    带默认形参值的形参必须在参数列表的最后

    不允许对同于函数的形参多次定义,默认形参只能声明一次,声明时初始化,定义是不需要再次初始化的

    1.2.6 函数重载

    两个以上的函数,具有相同的函数名,但是形参个数或数据类型不同,编译器根据不同的参数列表调用最佳匹配函数

    • 构造函数可以重载,析构函数不能重载

    在C标准中

    • 求整数的绝对值 abs()labs() 应该包含 stdlib.h

    • 求浮点数的绝对值 fabs() 应该包含 math.h

    在C++标准中

    • stdlib.h:

      int abs(int n);

      long int abs(long int n);

    • math.h:

      double abs(int n);

      float abs(float x);

      long double abs(long double x);

  • 相关阅读:
    elasticsearch-analysis-dynamic-synonym同义词插件实现热更
    过滤器Filter
    并发-生产者消费者、线上问题定位、性能测试、异步任务池
    常说的I2C协议是干啥的(电子硬件)
    如何高性能、高效率地实现3D Web轻量化?
    Chrome插件 — ReRes
    python的opencv操作记录(八)——小波变换
    微信小程序插件--wxml-to-canvas(生成图片)
    Survey on Cooperative Perception in an Automotive Context 论文阅读
    adb Error: failed to write; /data/local/tmp/??.apk (No such file or directory)
  • 原文地址:https://blog.csdn.net/qq_40479037/article/details/126807125