宏使用汇总

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

原文地址:https://www.cnblogs.com/faithlocus/p/13433635.html