zoukankan      html  css  js  c++  java
  • C++语法小技巧

    前言

    写的很乱,各种内容都有。仅仅是为了记录一下

    而且内容极其不严谨(没错,只有实践,没有理论)!请各位谨慎驾驶!

    强制内联

    #define Inline __inline__ __attribute__((always_inline))
    

    本地测试结果:

    • 开O2之后inline和Inline加不加没啥用

    • 不开O2时inline可能会有负优化,而Inline会让程序快很多

    当然也可以强制不inline

    直接在函数名前加

    __attribute__((noinline))
    

    利用位运算实现大小写转化

    可以这么写

    char ToUpper(char a) {return (a >= 'a' && a <= 'z') ? a ^ ' ' : a;}
    

    实测比c++内置的toupper快6倍。。

    enum类型

    这玩意儿叫“枚举”

    格式如下:

    enum [enumeration name] {enumerator1[=value1], enumerator2[=value2], ...};

    其中,第二个变量的取值默认是第一个变量取值+1,第一个默认是0,当然也可以自己设定

    一个简单的栗子

    enum NOIP {a, b, c, d = 22};
    cout << c << " " << d;
    

    将会输出2 22

    自定义输入输出流

    这部分有点硬核啊。。

    一个简单的栗子是这样的

    #include<bits/stdc++.h>
    using namespace std;
    class Pair {
    private: 
    	int id;
    	string s;
    public:
    	friend ostream& operator << (ostream& os, Pair& a) {
    		os << a.s << ":" << a.id << "
    ";
    		return os;		
    	}
    	friend istream& operator >> (istream& is, Pair& a) {
    		is >> a.s >> a.id;
    		return is;		
    	}
    };
    int main( ) {
    	Pair a;
    	cin >> a;
    	cout << a;
        return 0;
    }
    //input: abc 123
    //output : abc:123
    

    注意这里我们实际上还是在用cin / cout输入输出

    输入输出流在OI中常常应用于输入输出优化。

    struct InputOutputStream {
        enum { SIZE = 1000001 };
        char ibuf[SIZE], *s, *t, obuf[SIZE], *oh;
    
        InputOutputStream() : s(), t(), oh(obuf) {}
        ~InputOutputStream() { fwrite(obuf, 1, oh - obuf, stdout); }
    
        inline char read() {
            if (s == t) t = (s = ibuf) + fread(ibuf, 1, SIZE, stdin);
            return s == t ? -1 : *s++;
        }
    
        template <typename T>
        inline InputOutputStream &operator>>(T &x) {
            static char c;
            static bool iosig;
            for (c = read(), iosig = false; !isdigit(c); c = read()) {
                if (c == -1) return *this;
                iosig |= c == '-';
            }
            for (x = 0; isdigit(c); c = read()) x = x * 10 + (c ^ '0');
            if (iosig) x = -x;
            return *this;
        }
    
        inline void print(char c) {
            if (oh == obuf + SIZE) {
                fwrite(obuf, 1, SIZE, stdout);
                oh = obuf;
            }
            *oh++ = c;
        }
    
        template <typename T>
        inline void print(T x) {
            static int buf[23], cnt;
            if (x != 0) {
                if (x < 0) print('-'), x = -x;
                for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 | 48;
                while (cnt) print((char)buf[cnt--]);
            } else print('0');
        }
    
        template <typename T>
        inline InputOutputStream &operator<<(const T &x) {
            print(x);
            return *this;
        }
    } io;
    

    template

    template,中文名:模板

    分为两类,一种叫类模板,一种叫函数模板

    类模板我用的不多

    函数模板用的多一些

    下面是一个求最大值的模板,c++的标准库中也是这么实现的,因此同时存在的话会引起CE

    template <typename T>
    inline T const& max(T const &a, T const &b) {
    	return a > b ? a : b;
    }
    

    如果直接调用的话,当(a, b)的类型不同时会引起CE。

    这时可以直接强制类型转化

    	int a = 1e9;
    	long long b = 1e18;
    	long long c = max<int>(a, b);
    //the output is 1e9
    
    	int a = 1e9;
    	long long b = 1e18;
    	long long c = max<long long>(a, b);
    //the output is 1e18
    

    预编译黑科技

    第一条是强制开栈空间

    后面的并不清楚在干啥,貌似可以强制(O_2)

    #pragma comment(linker, "/STACK:102400000,102400000") 
    #pragma GCC diagnostic error "-std=c++11"
    #pragma GCC optimize("-fdelete-null-pointer-checks,inline-functions-called-once,-funsafe-loop-optimizations,-fexpensive-optimizations,-foptimize-sibling-calls,-ftree-switch-conversion,-finline-small-functions,inline-small-functions,-frerun-cse-after-loop,-fhoist-adjacent-loads,-findirect-inlining,-freorder-functions,no-stack-protector,-fpartial-inlining,-fsched-interblock,-fcse-follow-jumps,-fcse-skip-blocks,-falign-functions,-fstrict-overflow,-fstrict-aliasing,-fschedule-insns2,-ftree-tail-merge,inline-functions,-fschedule-insns,-freorder-blocks,-fwhole-program,-funroll-loops,-fthread-jumps,-fcrossjumping,-fcaller-saves,-fdevirtualize,-falign-labels,-falign-loops,-falign-jumps,unroll-loops,-fsched-spec,-ffast-math,Ofast,inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2",3)
    #pragma GCC target("avx","sse2")
    

    __builtin系列

    • __builtin_popcount(unsigned int n)

    计算(n)的二进制表示中有多少个1

    • __builtin_parity(unsigned int n)

    判断(n)的二进制表示中1的个数奇偶性(要你何用?)

    • __builtin_ffs(unsigned int n)

    判断(n)的二进制末尾最后一个1的位置,从1开始

    • __builtin_ctz(unsigned int n)

    判断(n)的二进制末尾(0)的个数

    • __builtin_clz(unsigned int n)

    判断(n)的二进制前导0的个数

    指针的骚操作

    通过指针实现负下标数组

    #include<bits/stdc++.h>
    using namespace std;
    int main() {
        int __a[21];
        for(int i = 0; i <= 20; i++) __a[i] = i;
        int *const a = &__a[10];
        printf("%d %d %d", a[7], a[0], a[-7]);
    }
    
  • 相关阅读:
    leetcode刷刷刷
    素数问题
    TCP/IP详解(整理)
    关于区块链应用方向与前景的一些思考
    设计模式
    面经中的各种问题汇总
    基于消逝时间量的共识机制(POET)
    c++语言知识点汇总
    二叉树前中后/层次遍历的递归与非递归形式(c++)
    layui表格搜索数据登录失效后的处理
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9795043.html
Copyright © 2011-2022 走看看