• C++杂文(1)


    1、不能使用int x,y=0;方式来定义x和y都为0的情况。(这种定义只是给y赋值为0,而x是随机数。)
    #include <iostream>
    #include<stdio.h>
    using namespace std;
    int main()
    {
        int x,y=0;
        cout<<x<<" "<<y<<endl;
        //result: 4354304 0  //因此定义x,y同时为0不能那么定义
        return 0;
    }
    
    2、print()函数的压栈处理:
    //printf()函数:
    #include<stdio.h>
    main(){
        int i=9;
        int j=3;
        printf("%d
    ",j,i,++j);  //函数printf从右到左压栈,然后将先读取放到栈底,最后读取的放在栈顶,处理时候是从栈顶开始的,所以我们看见的结果是,从右边开始处理的。
        printf("%d
    ",i,--i);
    }
    
    3、父类容器是可以容纳子类对象的,只不过定义vector< A >(父类)时,只调用父类的函数,即只保留父类(基类)函数的作用
    //父类容器是可以容纳子类对象的,只不过定义vector<A>(父类)时,只调用父类的函数,即只保留父类(基类)函数的作用
    #include <iostream>
    #include<vector>
    using namespace std;
    class A{
    protected:
        int a;
        int b;
    public:
        A(){};
        A(int a,int b):a(a),b(b){}
        void get(){
            cout<<a<<" "<<b<<endl;
        }
    };
    class B:public A{
        int c;
    public:
        B(){};
        B(int a,int b,int c){
            //构造函数内赋值应该用this->
            this->a=a;
            this->b=b;
            this->c=c;
        }
        //定义vector<A>时,只调用父类的get()函数,即该函数不会被调用
        void get(){
            cout<<a<<" "<<b<<" "<<c<<endl;
        }
    };
    
    int main(){
        vector<A>obj;
        A a(1,2);
        B b(2,3,4);
        obj.push_back(a);
        obj.push_back(b);
        for(int i=0;i<obj.size();i++)
        {
            //此处只调用父类的get()函数
            obj[i].get();
        }
    }
    
    

    result:在这里插入图片描述

    4、分别定义bool,char类型的变量各一个,并依次输出它们的存储空间大小(单位:字节)。实践表明都为1个字节。
    //分别定义bool,char类型的变量各一个,并依次输出它们的存储空间大小(单位:字节)。
    #include<stdio.h>
    main()
    {
        bool a;
        char b;
        printf("%d %d",sizeof(a),sizeof(b));
    }
    
    5、输入n个数,计算最大值与最小值之差(while(scanf("%d",&x)!=EOF))
    //输入n个数,计算最大值与最小值之差
    #include <stdio.h>
    int main()
    {
    	int n,i,x,min,max;
    	//scanf("%d",&n);
    	scanf("%d",&x);
    	min=x;
    	max=x;
    	//for(i=1;i<=n-1;i++)
    	while(scanf("%d",&x)!=EOF)  //scanf("%d",&x)!=EOF 按^Z停止
    	{
    		//scanf("%d",&x);
    		if(max<x)max=x;
    		if(min>x)min=x;
    	}
    	printf("%d
    ",max-min);
    	return 0;
     }
    
    
    6、输出1-500以内的所有完数(纯C语言)

    注意内容:
    在重新赋值时若令s=1; 则输出2^n,原因是正好符合等比公式求和公式,详见解释。

    cout<< (-3)%1<< endl; //输出值为0(对于任意整数,对1取余均为0)。
    //输出1-500以内的所有完数(纯C语言)
    
    //完数(Perfect number),又称完美数或完备数,是一些特殊的自然数。
    //它所有的真因子(即除了自身以外的约数)(故1不是完数)的和(即因子函数),恰好等于它本身。如果一个数恰好等于它的因子之和,则称该数为“完数”。
    
    #include <stdio.h>
    //注释掉C++写法:
    //#include<iostream>
    //using namespace std;
    int main()
    {
        int a,i,s=0;
        for(i=2; i<=500; i++)
        {
            for(a=1; a<i; a++)
            {
                if(i%a==0)  //找出真因子
                    s=s+a;
            }
            if(i==s)
                printf("%d
    ",i);
            //cout<<i<<endl;
            s=0;
            //s=1;  //当s=1;时输出2^n 解释:
            /*
                因为对于每一个2^n来说,2^n的真因子(不包含其自身)就是2^1...到2^(n-1)次,而2^1...到2^(n-1)次求和+1正好等于2^n次(可以由等比公式求和公式推出)
                对于等比公式求和公式Sn,将a1=1,q=2代入Sn+1得Sn+1=q^n(仅在a1=1,q=2情况下成立)
                故有此结果2^n
                等比公式资料来自百度百科:https://baike.baidu.com/item/%E7%AD%89%E6%AF%94%E6%95%B0%E5%88%97
            */
        }
        //cout<<(-3)%1<<endl;  //对于任意整数,对1取余均为0
        return 0;
    }
    
    7、& 按位与, | 按位或, ^ 按位异或, ~按位取反, <<左移运算符, >>右移运算符等
    //https://blog.csdn.net/weixin_42837024/article/details/98736834
    #include <iostream>
    int main()
    {
        //& 按位与 | 按位或 ^ 按位异或 ~按位取反 <<左移运算符 >>右移运算符等
        auto a = 1, b = 2;
        auto i1 = 10;		//2进制:1010 , 10进制:10
        auto i2 = 20;		//2进制:10100 , 10进制:20
        auto i3 = 11;
        auto i = 11;		//2进制: 1011 ,10进制:11
    
        //& 按位与:
        std::cout << (i1 & i2)<<std::endl; //2进制00000 10进制:0
    
        /*				步骤: 当两个都为1时,才为1
        							1 0 1 0
        						  1 0 1 0 0
        						  ---------
        						  0	0 0 0 0
        */
    
        std::cout << (i1 & i3);			  //2进制:1010 10进制:10
    
        /*				步骤: 当两个都为1时,才为1
        							1 0 1 0
        							1 0 1 1
        						  ---------
        						  	1 0 1 0
        */
    
        system("pause");
    
        //| 按位或:
        std::cout << (i1 | i2) << std::endl; //2进制11110 10进制:30
    
        /*				步骤: 当有一个为1时,就为1
        							1 0 1 0
        						  1 0 1 0 0
        						  ---------
        						  1	1 1 1 0
        */
    
        std::cout << (i1 | i3)<< std::endl;			  //2进制:1011 10进制:11
    
        /*				步骤: 当有一个为1时,就为1
        							1 0 1 0
        							1 0 1 1
        						  ---------
        							1 0 1 1
        */
    
        system("pause");
    
        //^按位异或:
        std::cout << (i1 ^ i2) << std::endl; //2进制11110 10进制:30
    
        /*				步骤: 当前位的两个二进制表示不同则为1相同则为0
        							1 0 1 0
        						  1 0 1 0 0
        						  ---------
        						  1	1 1 1 0
        */
    
        std::cout << (i1 ^ i3)<<std::endl;			  //2进制:1011 10进制:1
    
        /*				步骤: 当前位的两个二进制表示不同则为1相同则为0
        							1 0 1 0
        							1 0 1 1
        						  ---------
        							0 0 0 1
        */
    
    
        //按位取反~
        //这里涉及到补码与原码的转换问题:https://zhidao.baidu.com/question/181720031.html
        //https://www.cnblogs.com/zhgyki/p/9452637.html
        auto x = 9;  //二进制表示为0 1001,按位取反为1 0110,即符号位为负数,
        //在计算机内部存储形式都是以补码形式存储,补码等于原码取反+1(符号位不变),即1 1001+1 即1 1010,即十进制表示为-10
        std::cout<<(~x);
    
        system("pause");
    
        //<<左移运算符 >>右移运算符:
        i = i << 1;		//左移1位
        std::cout << i << std::endl;	//2进制: 10110 ,10进制:22
        i = i << 1;		//继续左移1位
        std::cout << i << std::endl;	//2进制: 101100 ,10进制:44
    
        i3 = i3 >> 1;		//右移
        std::cout << i3 << std::endl;	//2进制: 101 ,10进制:5
        i3 = i3 >> 1;		//继续右移一位
        std::cout << i3 << std::endl;	//2进制: 10 , 10进制:2
    
    }
    
    

    在这里插入图片描述

    8、对于cin与scanf以及输入缓冲区的简要比较:

    关于这一部分内容可参考以下博客:
    C语言scanf输入时缓冲区问题
    ios_base sync_with_stdio(false)引发的一些思考
    关于ios::sync_with_stdio(false);和 cin.tie(0)加速c++输入输出流
    scanf 与 cin 的区别

    C语言isspace()函数:判断字符是否为空白字符

    例:
    头文件:#include <ctype.h>
    定义函数:int isspace(int c);
    函数说明:检查参数c是否为空格字符,也就是判断是否为空格(’ ‘)、定位字符(’ ‘)、CR(’ ‘)、换行(’ ‘)、垂直定位字符(’ v ‘)或翻页(’ f ')的情况。
    返回值:若参数c 为空白字符,则返回非 0,否则返回 0。

    #include <ctype.h>
    #include<stdio.h>
    main(){
        char str[] = "123c @# FD	sP[e?
    ";
        int i;
        for(i = 0; str[i] != 0; i++)
            if(isspace(str[i]))
                printf("str[%d] is a white-space character:%d
    ", i, str[i]);  //这里对字符型的输出用%d格式,即将字符转换为ASCII码格式进行输出
    }
    

    reslut:
    在这里插入图片描述
    简要说明:

    ios::sync_with_stdio(false);

    c中的标准输入输出流sacanf ,printf,与c++中的cin ,cout有所不同。
    cin、cout是输入输出流效率稍低但是书写方便,cin、cout输入输出效率比较低的原因是它们都需要先将内容存入缓存区,
    用std::ios::sync_with_stdio(fasle)可以取消与stdio同步,不再存入缓存区,提高输入输出效率

    若不加 ios_base::sync_with_stdio 则默认为true。
    true的时候,iostream 和 stdio 共享缓冲区。
    false的时候,iostream 和 stdio 分别有独立的缓冲区。

    cin的问题主要是对每一个变量都要调用一次操作符函数,而scanf不用。
    但是scanf要解析格式串,但是解析复杂度是线性的。
    如果你只有一个变量 比如 cin>>a[i] // scanf("%d", a+i) 这种应该是cin比较快吧,从这个角度。
    如果你有很多东西 比如要scanf("%u-%u-%u-%u", &a, &b, &c, &d); 这种,应该是scanf快吧。

    在100000的情况下,关闭同步的cin比scanf慢0.5s左右。

    一、scanf输入缓冲区测试:
    #include <cstdio>
    #include <cstdlib>
    #include <cctype>
    int main()
    {
        int ival1 = 0, ival2 = 0;
        char ch = 't';
        char ch_tmp;
        scanf("%d", &ival1);
        scanf("%c", &ch_tmp);
        if (isspace(ch_tmp))
        {
            printf("%d is a whitespace right ? %d is the newline character!
    ", ch_tmp, ch_tmp);
        }
        if (scanf("%d", &ival2) != 1)
        {
            printf("Damn it! ival2 cannot read input!
    ");
        }
        for(int i=0;i<5;i++)
            scanf("%c", &ch);
        printf("ival1:%d ival2:%d ch:%c
    ", ival1, ival2, ch);
        system("pause");
        return 0;
    }
    

    不加for循环进行一次输入时的测试:
    在这里插入图片描述
    加入for循环进行循环输入以便观察缓冲区内读取数据的变化:
    在这里插入图片描述

    二、cin输入缓冲区测试:
    #include <iostream>
    #include <cctype>
    using namespace std;
    int main()
    {
        int ival1 = 0, ival2 = 0;
        char ch = 't';
        char ch_tmp;
        streambuf* sb;
        sb = cin.rdbuf();
        cout << "sb->in_avail()---first	" << sb->in_avail() << endl;// will print 0
        cin >> ival1;// 读取并忽略有效字符之前所有的空白字符,然后读取字符直至再次遇到空白字符,读取终止,该空白字符仍留在输入流中
        cout << "sb->in_avail()---second	" << sb->in_avail() << endl;// will print 1 证明空白字符'/n' 确实留在输入缓冲区中
        cin >> ch_tmp;// 注意:这里与scanf的区别,此处将空白字符忽略,而不是作为有效字符
        if (isspace(ch_tmp))
        {
            cout << ch_tmp << " is a whitespace right ?" << ch_tmp << " is the newline character!" << endl;
        }
        cin >> ival2;
        if (! cin)
        {
            cout << "Damn it! ival2 cannot read input!" << endl;
        }
        cin >> ch;
        cout << ival1 << " " << ival2 << " " << ch<<endl;
        system("pause");
        return 0;
    }
    

    在这里插入图片描述在这里插入图片描述
    加入for循环后进行测试:
    在这里插入图片描述

    三、可以得出结论:

    scanf输入缓冲区内读取数据时如果格式不匹配,不一致的话下次scanf读取依然会从该位置进行读取,直到遇到格式匹配时进行赋值(读取输出),不会终止读取。但是cin缓冲区内如果格式不匹配则终止读取,结束缓冲区,不再从缓冲区内读取任何内容,可认为缓冲区失效了。

    加入ios::sync_with_stdio(false);语句后再次进行测试:
    未加入ios::sync_with_stdio(false);语句时,此时scanf缓冲区与cin缓冲区同步,cin缓冲区输入导致错误,则scanf输入输出也受到影响,故障。
    加入ios::sync_with_stdio(false);语句使得scanf与cin有独立的缓冲区,则cin缓冲区故障后scanf缓冲区仍然可以输入和读取。

    #include <iostream>
    #include <cctype>
    using namespace std;
    int main()
    {
        ios::sync_with_stdio(false);
        int ival1 = 0, ival2 = 0;
        char ch = 't';
        char ch_tmp;
        streambuf* sb;
        sb = cin.rdbuf();
        cout << "sb->in_avail()---first	" << sb->in_avail() << endl;// will print 0
        cin >> ival1;// 读取并忽略有效字符之前所有的空白字符,然后读取字符直至再次遇到空白字符,读取终止,该空白字符仍留在输入流中
        cout << "sb->in_avail()---second	" << sb->in_avail() << endl;// will print 1 证明空白字符'/n' 确实留在输入缓冲区中
        cin >> ch_tmp;// 注意:这里与scanf的区别,此处将空白字符忽略,而不是作为有效字符
        if (isspace(ch_tmp))
        {
            cout << ch_tmp << " is a whitespace right ?" << ch_tmp << " is the newline character!" << endl;
        }
        cin >> ival2;
        if (! cin)
        {
            cout << "Damn it! ival2 cannot read input!" << endl;
        }
        for(int i=0;i<5;i++)
            cin >> ch;
        cout << ival1 << " " << ival2 << " " << ch<<endl;
        int a=3;
        scanf("%d",&a);
        for(int i=0;i<5;i++)
            cout<<i<<endl;
        cout<<"a: "<<a<<endl;
        system("pause");
        return 0;
    }
    

    在这里插入图片描述在这里插入图片描述

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。
  • 相关阅读:
    python_变量前加*或者**
    python 获取上级(上上级目录..)
    pip install git+
    《手把手教你》系列技巧篇(十八)-java+ selenium自动化测试-元素定位大法之By css中卷(详细教程)
    《手把手教你》系列技巧篇(十七)-java+ selenium自动化测试-元素定位大法之By css上卷(详细教程)
    《手把手教你》系列技巧篇(十六)-java+ selenium自动化测试-元素定位大法之By xpath下卷(详细教程)
    《手把手教你》系列技巧篇(十五)-java+ selenium自动化测试-元素定位大法之By xpath中卷(详细教程)
    《手把手教你》系列技巧篇(十四)-java+ selenium自动化测试-元素定位大法之By xpath上卷(详细教程)
    《手把手教你》系列技巧篇(十三)-java+ selenium自动化测试-元素定位大法之By partial link text(详细教程)
    《手把手教你》系列技巧篇(十二)-java+ selenium自动化测试-元素定位大法之By link text(详细教程)
  • 原文地址:https://www.cnblogs.com/study-hard-forever/p/14387288.html
Copyright © 2020-2023  润新知