• 宏使用汇总


    1. 简单应用

    1.1 定义变量一改全改,使代码更易于维护

    #define MY_ARRAY_LEN 3
    
    int* arr_int = new int[MY_ARRAY_LEN]{};
    char* arr_char = new char[MY_ARRAY_LEN]{};
    A* arr_A = new A[MY_ARRAY_LEN]{};
    

    某天因业务需求,需要将3变更为3w,此时代码变更为

    #define MY_ARRAY_LEN 30000
    
    int* arr_int = new int[MY_ARRAY_LEN]{};
    char* arr_char = new char[MY_ARRAY_LEN]{};
    A* arr_A = new A[MY_ARRAY_LEN]{};
    

    1.2 定义函数,提高执行效率

    #define MAX(a, b) 
        if (a >= b) 
            return a; 
        else 
            return b;
    
    template<typename T>
    T max(const T& a, const T& b)
    {
        if (a >= b)
            return a;
        else
            return b;
    }
    /* 
    宏定义与函数定义实现了相同的功能,但是宏调用比函数调用效率要高,因为函数调用需要保留函数现场,以便子函数完成后恢复现场,这是存在资源开销的,(宏定义没有这个问题,在编译期间宏定义已经被展开,运行期间直接执行即可),区别虽然不大,但是如果在并发急剧升高后,区别就明显了,所以调用频率搞得功能优先封装为宏定义,复杂模块优先封装为函数调用,维护成本低。
    */
    

    2. 精简代码

    2.1 define中特殊符号

    // ## 拼接字符
    #define COMBIN(a, b) a##b
    COMBIN(123,456)     // 123456
    
    // #@ 字符化,容易溢出,慎用
    #define CS(a)   #@a
    CS(1)                // '1'
    CS(12)               // error
    
    // #字符串化
    #define CSS(a)  #a
    CSS(1)              // "a"
    CSS(123)            // "123"
    
    //  告诉编译器,下面和此行是一行, 宏不应该存在换行
    #define MAX(a, b) 
        if (a >= b) 
            return a; 
        else 
            return b;
    
    

    2.2 系统使用的宏

    _LINE_ /*(两个下划线),对应%d*/
    _FILE_ /*对应%s*/
    _DATE_ /*对应%s*/
    _TIME_ /*对应%s*/
    

    2.3 常用宏

    • 防止一个头文件被重复包含
    #ifndef BODYDEF_H 
    #define BODYDEF_H 
     //头文件内容 
    #endif
    
    • 得到指定地址上的一个字节或字
    #define MEM_B( x ) ( *( (byte *) (x) ) ) 
    #define MEM_W( x ) ( *( (word *) (x) ) )
    // 用法如下:
    #include <iostream>
    #include <windows.h>
    #define MEM_B(x) (*((byte*)(x)))
    #define MEM_W(x) (*((WORD*)(x)))
    int main()
    {
       int bTest = 0x123456;
       byte m = MEM_B((&bTest));/*m=0x56*/
       int n = MEM_W((&bTest));/*n=0x3456*/
       return 0;
    }
    
    • 得到一个field在结构体(struct)中的偏移量
    #define OFFSETOF( type, field ) ( (size_t) &(( type *) 0)-> field )
    // 得到一个field在结构体(struct type)中的偏移量。
    
    • 得到一个结构体中field所占用的字节数
    #define FSIZ( type, field ) sizeof( ((type *) 0)->field )
    
    • 得到一个变量的地址(word宽度)
    #define B_PTR( var ) ( (byte *) (void *) &(var) ) 
    #define W_PTR( var ) ( (word *) (void *) &(var) )
    
    • 将一个字母转换为大写
    #define UPCASE( c ) ( ((c) >= ''a'' && (c) <= ''z'') ? ((c) - 0x20) : (c) )
    
    • 判断字符是不是10进值的数字
    #define DECCHK( c ) ((c) >= ''0'' && (c) <= ''9'')
    
    • 判断字符是不是16进值的数字
    #define HEXCHK( c ) ( ((c) >= ''0'' && (c) <= ''9'') || 
                        ((c) >= ''A'' && (c) <= ''F'') || 
                        ((c) >= ''a'' && (c) <= ''f'') )
    
    • 防止溢出的一个方法
    #define INC_SAT( val ) (val = ((val)+1 > (val)) ? (val)+1 : (val))
    
    • 返回数组元素的个数
    #define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )
    
    • 使用一些宏跟踪调试

    3. 条件编译

    3.1 #ifdef #else #endif

    • bool分支判断时使用此方法
    #ifdef _DEBUG
    #   define MY_ARRAY_LEN     3
    #else
    #   define MY_ARRAY_LEN     30000      
    #endif
    

    3.2 #if defined(A) #elif define(B) #else #endif

    • int分支判断时使用此方法
    #if defined(AUTO_LOGIN)
    #   if defined(A) || defined(B)
    #       define MY_ARRAY_LEN     3
    #   elif (defined(C) && defined(D))
    #       define MY_ARRAY_LEN     30000
    #   elif (defined(E) || defined(F))
    #       define MY_ARRAY_LEN     300000000
    #   elif (!defined(G))
    #       define MY_ARRAY_LEN     3000
    #   else
    #       define MY_ARRAY_LEN     300
    #else
    #   define MY_ARRAY_LEN         30
    #endif
    

    3.3 示例代码

    • qsystemdetection.h(qt的源代码)
    /****************************************************************************
    **
    ** Copyright (C) 2016 The Qt Company Ltd.
    ** Contact: https://www.qt.io/licensing/
    **
    ** This file is part of the QtCore module of the Qt Toolkit.
    **
    ** $QT_BEGIN_LICENSE:LGPL$
    ** Commercial License Usage
    ** Licensees holding valid commercial Qt licenses may use this file in
    ** accordance with the commercial license agreement provided with the
    ** Software or, alternatively, in accordance with the terms contained in
    ** a written agreement between you and The Qt Company. For licensing terms
    ** and conditions see https://www.qt.io/terms-conditions. For further
    ** information use the contact form at https://www.qt.io/contact-us.
    **
    ** GNU Lesser General Public License Usage
    ** Alternatively, this file may be used under the terms of the GNU Lesser
    ** General Public License version 3 as published by the Free Software
    ** Foundation and appearing in the file LICENSE.LGPL3 included in the
    ** packaging of this file. Please review the following information to
    ** ensure the GNU Lesser General Public License version 3 requirements
    ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
    **
    ** GNU General Public License Usage
    ** Alternatively, this file may be used under the terms of the GNU
    ** General Public License version 2.0 or (at your option) the GNU General
    ** Public license version 3 or any later version approved by the KDE Free
    ** Qt Foundation. The licenses are as published by the Free Software
    ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
    ** included in the packaging of this file. Please review the following
    ** information to ensure the GNU General Public License requirements will
    ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
    ** https://www.gnu.org/licenses/gpl-3.0.html.
    **
    ** $QT_END_LICENSE$
    **
    ****************************************************************************/
    
    #ifndef QGLOBAL_H
    # include <QtCore/qglobal.h>
    #endif
    
    #ifndef QSYSTEMDETECTION_H
    #define QSYSTEMDETECTION_H
    
    /*
       The operating system, must be one of: (Q_OS_x)
    
         DARWIN   - Any Darwin system (macOS, iOS, watchOS, tvOS)
         MACOS    - macOS
         IOS      - iOS
         WATCHOS  - watchOS
         TVOS     - tvOS
         WIN32    - Win32 (Windows 2000/XP/Vista/7 and Windows Server 2003/2008)
         WINRT    - WinRT (Windows Runtime)
         CYGWIN   - Cygwin
         SOLARIS  - Sun Solaris
         HPUX     - HP-UX
         LINUX    - Linux [has variants]
         FREEBSD  - FreeBSD [has variants]
         NETBSD   - NetBSD
         OPENBSD  - OpenBSD
         INTERIX  - Interix
         AIX      - AIX
         HURD     - GNU Hurd
         QNX      - QNX [has variants]
         QNX6     - QNX RTP 6.1
         LYNX     - LynxOS
         BSD4     - Any BSD 4.4 system
         UNIX     - Any UNIX BSD/SYSV system
         ANDROID  - Android platform
         HAIKU    - Haiku
    
       The following operating systems have variants:
         LINUX    - both Q_OS_LINUX and Q_OS_ANDROID are defined when building for Android
                  - only Q_OS_LINUX is defined if building for other Linux systems
         FREEBSD  - Q_OS_FREEBSD is defined only when building for FreeBSD with a BSD userland
                  - Q_OS_FREEBSD_KERNEL is always defined on FreeBSD, even if the userland is from GNU
    */
    
    #if defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__))
    #  include <TargetConditionals.h>
    #  if defined(TARGET_OS_MAC) && TARGET_OS_MAC
    #    define Q_OS_DARWIN
    #    define Q_OS_BSD4
    #    ifdef __LP64__
    #      define Q_OS_DARWIN64
    #    else
    #      define Q_OS_DARWIN32
    #    endif
    #    if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
    #      define QT_PLATFORM_UIKIT
    #      if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH
    #        define Q_OS_WATCHOS
    #      elif defined(TARGET_OS_TV) && TARGET_OS_TV
    #        define Q_OS_TVOS
    #      else
    #        // TARGET_OS_IOS is only available in newer SDKs,
    #        // so assume any other iOS-based platform is iOS for now
    #        define Q_OS_IOS
    #      endif
    #    else
    #      // TARGET_OS_OSX is only available in newer SDKs,
    #      // so assume any non iOS-based platform is macOS for now
    #      define Q_OS_MACOS
    #    endif
    #  else
    #    error "Qt has not been ported to this Apple platform - see http://www.qt.io/developers"
    #  endif
    #elif defined(__ANDROID__) || defined(ANDROID)
    #  define Q_OS_ANDROID
    #  define Q_OS_LINUX
    #elif defined(__CYGWIN__)
    #  define Q_OS_CYGWIN
    #elif !defined(SAG_COM) && (!defined(WINAPI_FAMILY) || WINAPI_FAMILY==WINAPI_FAMILY_DESKTOP_APP) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__))
    #  define Q_OS_WIN32
    #  define Q_OS_WIN64
    #elif !defined(SAG_COM) && (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
    #  if defined(WINAPI_FAMILY)
    #    ifndef WINAPI_FAMILY_PC_APP
    #      define WINAPI_FAMILY_PC_APP WINAPI_FAMILY_APP
    #    endif
    #    if defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
    #      define Q_OS_WINRT
    #    elif WINAPI_FAMILY==WINAPI_FAMILY_PC_APP
    #      define Q_OS_WINRT
    #    else
    #      define Q_OS_WIN32
    #    endif
    #  else
    #    define Q_OS_WIN32
    #  endif
    #elif defined(__sun) || defined(sun)
    #  define Q_OS_SOLARIS
    #elif defined(hpux) || defined(__hpux)
    #  define Q_OS_HPUX
    #elif defined(__native_client__)
    #  define Q_OS_NACL
    #elif defined(__linux__) || defined(__linux)
    #  define Q_OS_LINUX
    #elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
    #  ifndef __FreeBSD_kernel__
    #    define Q_OS_FREEBSD
    #  endif
    #  define Q_OS_FREEBSD_KERNEL
    #  define Q_OS_BSD4
    #elif defined(__NetBSD__)
    #  define Q_OS_NETBSD
    #  define Q_OS_BSD4
    #elif defined(__OpenBSD__)
    #  define Q_OS_OPENBSD
    #  define Q_OS_BSD4
    #elif defined(__INTERIX)
    #  define Q_OS_INTERIX
    #  define Q_OS_BSD4
    #elif defined(_AIX)
    #  define Q_OS_AIX
    #elif defined(__Lynx__)
    #  define Q_OS_LYNX
    #elif defined(__GNU__)
    #  define Q_OS_HURD
    #elif defined(__QNXNTO__)
    #  define Q_OS_QNX
    #elif defined(__INTEGRITY)
    #  define Q_OS_INTEGRITY
    #elif defined(VXWORKS) /* there is no "real" VxWorks define - this has to be set in the mkspec! */
    #  define Q_OS_VXWORKS
    #elif defined(__HAIKU__)
    #  define Q_OS_HAIKU
    #elif defined(__MAKEDEPEND__)
    #else
    #  error "Qt has not been ported to this OS - see http://www.qt-project.org/"
    #endif
    
    #if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINRT)
    #  define Q_OS_WIN
    #endif
    
    #if defined(Q_OS_WIN)
    #  undef Q_OS_UNIX
    #elif !defined(Q_OS_UNIX)
    #  define Q_OS_UNIX
    #endif
    
    // Compatibility synonyms
    #ifdef Q_OS_DARWIN
    #define Q_OS_MAC
    #endif
    #ifdef Q_OS_DARWIN32
    #define Q_OS_MAC32
    #endif
    #ifdef Q_OS_DARWIN64
    #define Q_OS_MAC64
    #endif
    #ifdef Q_OS_MACOS
    #define Q_OS_MACX
    #define Q_OS_OSX
    #endif
    
    #ifdef Q_OS_DARWIN
    #  include <Availability.h>
    #  include <AvailabilityMacros.h>
    #
    #  ifdef Q_OS_MACOS
    #    if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_6
    #       undef __MAC_OS_X_VERSION_MIN_REQUIRED
    #       define __MAC_OS_X_VERSION_MIN_REQUIRED __MAC_10_6
    #    endif
    #    if !defined(MAC_OS_X_VERSION_MIN_REQUIRED) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
    #       undef MAC_OS_X_VERSION_MIN_REQUIRED
    #       define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_6
    #    endif
    #  endif
    #
    #  // Numerical checks are preferred to named checks, but to be safe
    #  // we define the missing version names in case Qt uses them.
    #
    #  if !defined(__MAC_10_11)
    #       define __MAC_10_11 101100
    #  endif
    #  if !defined(__MAC_10_12)
    #       define __MAC_10_12 101200
    #  endif
    #  if !defined(__MAC_10_13)
    #       define __MAC_10_13 101300
    #  endif
    #  if !defined(__MAC_10_14)
    #       define __MAC_10_14 101400
    #  endif
    #  if !defined(MAC_OS_X_VERSION_10_11)
    #       define MAC_OS_X_VERSION_10_11 101100
    #  endif
    #  if !defined(MAC_OS_X_VERSION_10_12)
    #       define MAC_OS_X_VERSION_10_12 101200
    #  endif
    #  if !defined(MAC_OS_X_VERSION_10_13)
    #       define MAC_OS_X_VERSION_10_13 101300
    #  endif
    #  if !defined(MAC_OS_X_VERSION_10_14)
    #       define MAC_OS_X_VERSION_10_14 101400
    #  endif
    #
    #  if !defined(__IPHONE_10_0)
    #       define __IPHONE_10_0 100000
    #  endif
    #  if !defined(__IPHONE_10_1)
    #       define __IPHONE_10_1 100100
    #  endif
    #  if !defined(__IPHONE_10_2)
    #       define __IPHONE_10_2 100200
    #  endif
    #  if !defined(__IPHONE_10_3)
    #       define __IPHONE_10_3 100300
    #  endif
    #  if !defined(__IPHONE_11_0)
    #       define __IPHONE_11_0 110000
    #  endif
    #  if !defined(__IPHONE_12_0)
    #       define __IPHONE_12_0 120000
    #  endif
    #endif
    
    #ifdef __LSB_VERSION__
    #  if __LSB_VERSION__ < 40
    #    error "This version of the Linux Standard Base is unsupported"
    #  endif
    #ifndef QT_LINUXBASE
    #  define QT_LINUXBASE
    #endif
    #endif
    
    #endif // QSYSTEMDETECTION_H
    
    

    本文来自博客园,作者:flxx,转载请注明原文链接:https://www.cnblogs.com/faithlocus/p/13433635.html

  • 相关阅读:
    cast() 函数进行类型转换
    '+' 拼接字符串引起的小事故
    shell统计ip访问情况并分析访问日志
    Windows 环境上域名配置
    WebApi中Route的作用
    Postman测试WebApi使用总结
    C# VS2017新建WepApi
    C# 反射总结
    winform--同一个项目窗体复制
    winform TextBox设置透明
  • 原文地址:https://www.cnblogs.com/faithlocus/p/13433635.html
Copyright © 2020-2023  润新知