Acwing C++语法基础

1、bool  char 有1byte,等于8bit。1字节就是8位,可以表示

      int 和float 有4byte,有32位,可以表示正负2的32次方。float有效位数6-7位

      double  和long long 有8byte,有64位,可以表示正负2的64次方。double有效位数15-16位

2、取模运算,正负值取决于前面的值

        例如:5%2=1   -5%2=-1   5%-2=1

3、隐形类型转换,精度低自动转向精度高的类型,高精类型转向低精度类型需要强制类型转换            结果会向零取整。

一、小知识点
1、头文件问题

    #define x first   //宏定义
    #define y second
    typedef pair<int, int> PII;  //二维组习惯用pair存,typedef可以数据类型重定义
    typedef long long LL;  // typedef可以数据类型重定义
    const int N = 500010;  //定义常量,比#define安全

    若只用到scanf()和printf()可以只写 cstdio,不写 namespace

    iostream 中有<string>头文件,有abs()绝对值函数
    因为c++标准一直在更新,一些在cmath里的函数在iostream里直接被包含了
    cmath  中有sqrt()
    c++里max和min函数被<algorithm>和<iostream>同时包含了

    <string.h>、<cstring>、<string>三者关系
        1、c++的<cstring>兼容c的<string.h>,而<string>是c++标准模板库(STL)中的内容,可以定义string 对象,
            如string str="acwing",使用string相关函数。<cstring>和<string>不同。
        2、string.h,是C风格字符串操作的一个函数库,strlen,strcpy,strcat,strcmp,puts……都在这里面了。
        3、string,是C++定义的std::string所使用的文件,是string类的头文件,属于STL范畴,
            包含substr(),length(),size(),insert(),find(),replace(),erase()等函数。

    const可以写在函数内部

2、变量相关
    bool            false/true                                      1 byte
    char            'a'、'c'                                        1 byte
    int             -2147483648~+2147483647                        4 byte      int的最大值是个以二开头的十位数
    long long [int] -9223372036854775808 ~+9223372036854775807     8 byte      long long的最大值是一个以9开头的十九位的数
    float           1.23 2.63                                       4 byte      6-7位有效数字
    double          3.123456789123                                  8 byte      15-16位有效数字
    long double                                                     12byte      18-19位有效数,很少用到

    写算法99%的情况会用double不用float,因为float精度6-7位,double精度15-16位,位数有300多位,有些LL相乘,也可以用double。

    c++中 double也可 自增,如1.2 自增 变为2.2

3、输入输出相关

    scanf("%*d%d%d", &n, &m); //忽略第一个整数的读入方法
    scanf("A = %d, B = %d",&a, &b); // f代表格式化输入输出
    scanf("%d\n%c") //读入跨行的数字和字符

    scanf() 不能一次读入一个整数数组,只能一个一个读
    string 只能用cin 来读,不能用scanf

    scanf("%d%d %c",&a,&b,&c);  //%d 后加个空格,防止把空格当字符读入
    cin >> a >> b >> c;         //cin会自动过滤空格

    关于整行读入问题

        gets()函数在新版C++中被移除了,因为不安全。

        //第1个函数:fgets(),只能读入到字符数组中

        //fgets不会删除行末的回车字符,也就是说
        //你输完一行    点击回车时,  会把回车读进来,用cout输出str字符数组时,光标会停在 下一行;
        //你输完一行  不点击回车时,不会把回车读进来,用cout输出str字符数组时,光标会停在 本行末尾;
        fgets(str字符数组,读入个数size, stdin); //注意最多读入size-1个到字符数组str中

        //第二个函数:getline()
        //读入到字符数组和string字符串中, getline写法不同。读入整行到string中,只能用getline
        string s; 
        getline(cin,s);
        char  c[100];
        cin.getline(c,101); //注意最多读入100个到字符数组或string中


    cin >> str;             // 输入字符串时,遇到空格或者回车就会停止
    cout << str << endl;    // 输出字符串时,遇到空格或者回车不会停止,遇到'\0'停止

    while (cin >> x && x) //while (cin >> x, x)  //在条件表达式中,逗号表达式的值等于最后的值
    不告诉个数时,统计输入数据的个数时,循环判断条件可写为 while(scanf(“%d”,x)  !=  -1) cnt++;
                                                    //或者 while(scanf(“%d”,x)  !=  -1) cnt++;
    c++中EOF 为-1

    对应的占位符
        int         : %d
        float       : %f
        double      : %lf
        char        : %c
        long long   : %lld

    C++中取模结果正负只与%前面的数的正负有关系
        cout << 5%2 << endl;   输出  1
        cout << 5%-2 << endl;  输出  1
        cout << -5%2 << endl;  输出 -1
        cout << -5%-2 << endl; 输出 -1

    C++中除法是向0取整
        cout << 5/2 << endl;    输出  2
        cout << -5/2 << endl;   输出 -2

    C++中强制类型转换是向0取整 
        cout << (int)2.5 << endl;  输出  2
        cout << (int)-2.5 << endl; 输出 -2


    printf("%-5d",23); //%-5d向左对齐,%5d向右对齐
    printf("%8.3f",23.44); //%8.3f 表示这个浮点数最小宽度为8,保留三位小数,宽度不足时前面补0.
    printf("%.0lf  ", 0.15 * 100);   //保留0位小数,输出15
    printf(%s,str_arr);//str_arr为存有字符串的数组,则输出字符串结束标记'\0'前的内容.同cout
    %%输出%,比较特殊的转义

    不能用printf直接输出string,需要写成:printf(“%s”, str.c_str());或者puts(str.c_str()); 
    cout可以输出带有空格的字符数组、字符串和string,puts能输出char类型字符数组或字符串,不能输出string类型

4、数组初始化

    int c[5] = {0, 1, 2};   // 函数里未被初始化的部分为0. 等价于c[] = {0, 1, 2, 0, 0} ,
    int a[5] = {0};         // 全部为0

    char a1[] = {'C', '+', '+'};           // 列表初始化,没有空字符
    char a2[] = {'C', '+', '+', '\0'};       // 列表初始化,含有显示的空字符
    char a3[] = "C++";               // 自动添加表示字符串结尾的空字符
    char a4[6] = "Daniel";            // 错误:没有空间可以存放空字符
    char str[5]={'s','s','d'}; //还是一个字符串

5、函数相关

    函数声明可写在main中。如 int fun(int);
    strcpy这个函数只能给char数组赋值,string直接用+=即可
    fabs() 是浮点数求绝对值,abs()是整数求绝对值 
    sort()函数是插入排序和快排的结合,数据个数小时用插入排序,大时用快排
    swap函数,在<algorithm>中,可以交换任意类型
    str.substr(string串开始下标,[长度]);//返回string字符串
    strlen 等函数只能用于 字符数组或字符串,不能比较string。

    //为什么编译器会报错
    //min 比较的时候得是两个相同的类型,string的size,的返回值类型是size_type,强转一下int就可以了
    int len=0;
    string str="adsd";
    len = min(len, str.size());//报错


    有返回值的函数可以不写return, 会返回随机值;
    函数内的static静态变量相当于在函数内部开了一个只有该函数能用的全局变量,有默认值,如0,储存在堆中,这样
    可以避免一定的重名问题;
    多维数组传参时,只有第一维的长度可省略不写,这个和数组内部实现方式有关,且后边的维数的长度需和形参大小相同;
    数组不能给数组赋值,可以使用<cstring>中的memcpy(要填充的数组b,被复制的数组a, 元素个数* 4);
    inline 函数,在被调用的地方,换成函数体内的代码,对递归函数在时间效率上不明显。

    void swaps(int &a,int &b);//函数声明要和函数定义的第一行保持一致,包括引用符号

6、算法相关

    判断闰年方法
        闰年分为普通闰年和世纪闰年,其判断方法为
        公历年份是4的倍数,但不是100的倍数,为普通闰年;
        公历年份是整百数,且必须是400的倍数,为世纪闰年。
        归结起来就是:四年一闰;百年不闰;四百年在闰。
        if(year%400==0||year%4==0&&year%100!=0)
            cout<<"yes"<<endl;
        else 
            cout<<"no"<<endl;

    秦九韶算法 求p^0+p^1+...+p^n ,时间复杂度O(N)
    LL calc(string n, LL r)// 秦九韶算法求r进制转换为十进制(递推思想)
    {
        LL res = 0;
        for (auto c : n)
        {
            res = res * r + get(c);
        }
        return res;
    }
    int get(char c) //获取36进制下字符c代表的数字
    {
        if (c <= '9') return c - '0';
        return c - 'a' + 10;
    }

    //打印100以内所有质数
    #include <iostream>
    using namespace std;
    int main()
    {
        for (int i = 2; i <= 100; i ++ )
        {
            bool is_prime = true;
            for (int j = 2; j < i; j ++ )
            {
                if (i % j == 0)
                {
                    is_prime = false;
                    break;
                }
            }
            if (is_prime) cout << i << endl;
        }
        return 0;
    }

    //判断一个数是不是质数
    bool is_prime(int n)
    {
        if (n == 1) return false;

        for (int i = 2; i * i <= n; i ++ )
            if (n % i == 0)
                return false;
        return true;
    }
    曼哈顿距离:|x1-x2|+|y1-y2|,可用于打印菱形或者方格相关问题
    欧几里得距离:sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))    

    //第一类双指针算法
    //如统计字符串中最长的连续的相同字符
        string str;
        cin >> str;
        int cnt = 0;
        char c;
        for (int i = 0; i < str.size(); i ++ )
        {
            int j = i;
            while (j < str.size() && str[j] == str[i]) j ++ ;
            if (j - i > cnt) cnt = j - i, c = str[i];
            i = j - 1;
        }
        cout << c << ' ' << cnt << endl;

7、技巧相关

    ~i 表示 对i二进制取反,i=-1的时候,取反刚好是0
    string 可以做的char a[]不一定能做,80%用string

8、课外知识

    外存和内存进制不一样,外存是10的3次方,如硬盘,内存是2的10次方
    网线带宽 8Mb=1MB(实际上)
    99%的评测器会自动过滤掉程序最后的一个回车和每一行末尾的多余空格,但是PAT不是

9、结构体---
    结构体排序方法参见我的《结构体排序的四种方法【推荐】》这篇分享
    //结构体类型定义:固定大小空间的内存块
    struct teacher
    {
        char name[62];//64
        int age;//4
    };

    void main()
    {
        //结构体变量的定义及初始化
        //在c编译环境下和.cpp环境下变量定义方法有所区别
        //struct teacher t1;//C语言需要加上struct关键字
        //teacher t2;//C++中则不必
        struct teacher t1={"daiwen",22};
        //结构体变量作为函数的参数时,若需要修改 结构体变量,则函数的形参要加上指针或引用
        //结构体数组作为函数的参数时,若需要修改 结构体数组,则函数的形参写成
        //struct Teacher *tarray 或struct Teacher tarray[]来接收 结构体数组即可
    }

语法基础课 比较难点的或有技巧的题
    655 天数转换    //技巧
    656 钞票和硬币  //技巧  小数没有取余运算,本题先把小数变为整数
    725 完全数
    726 质数
    727 菱形          //技巧
    753 平方矩阵I   //找规律
    754 平方矩阵II  //找规律
    756 蛇形矩阵    //技巧
    760 字符串长度  //注意:fgets函数会把回车也读进来,getline不会
    763 循环相克令  //技巧
    773字符串插入
    766 去掉多余的空格
    770 单词替换
    823 排列      //难


二、STL 总结

ASCII 表
常用ASCII值:'A'- 'Z'是65 ~ 90,'a' - 'z'是97 - 122,0 - 9是 48 - 57。



链接:https://www.acwing.com/blog/content/24751/

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aimigas

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值