美文网首页
ARRAYSIZE宏讲解

ARRAYSIZE宏讲解

作者: 于天佐 | 来源:发表于2018-07-06 11:50 被阅读0次

ARRAYSIZE宏

    不同的C++实现有很多的库中都有一个计算数组长度的宏,名字大致都叫ARRAYSIZE,如VS中就定义了这个宏,它的使用很简单,len = ARRAYSIZE(a),只要传入的a是一个数组就能计算出这个数组的长度。实际上计算数组的常用套路是这样的

#define ARR_SIZE(A) (sizeof(A)/sizeof(A[0]))

    上面这个计算方法有很多问题,如果传入的A是指针那就不可能计算出来正确的数组长度了,而现实中数组退化成指针的情况非常多。所以综合考虑下结合C++的特性就出现了ARRAYSIZE这个新的C++下使用的全新宏。它克服了上面说的传统arraysize的问题,那么直接看一下它的实现:

template<typename T, unsigned int N>
char (&array_size_fake_func(T(&)[N]))[N];

#define MYARRAYSIZE(A) sizeof(array_size_fake_func(A))

    上面的语法极难看懂,因为平时几乎用不到,那么我们来分析一下这段简单的代码。它的核心实际上是上面的模板函数的一个声明,抛开模板,这个函数的参数和返回值都是T类型数组(数组长度N)的引用,很不常见吧,这里容易忽视的一个语法是c/c++是不支持函数返回数组的(java可以),所以这里返回数组的引用(或指针),而数组的引用语法本身很少用,并且写法比较怪。弄清楚了函数的结构,我们先看一下数组引用的使用

    //返回一个数组引用的函数,参数也是一个数组引用
    static int (&ret_arr_ref(int(&ref)[6]))[6]
    {
        return ref;
    }
    int a[6] = {0};
    int (&arf)[6] = a;
    arf[0] = 1;
    int (&arf2)[6] = ret_arr_ref(a);
    //arf 和 arf2 均是指向数组a的数组引用

    以上代码比较清晰的解释了数组引用如何用,那么回到刚才的模板函数,通过传入参数的推导(如果是一个数组类型变量),编译器就可以推导出T和N,这里我们更关心N的值,我们再通过拿到返回值char[N]的引用ref,求它的长度len = sizeof(ref),显然len就是N,通过上面的推导,就可以把N的值传递出来了。这里的好处是,如果传递给函数的参数不是数组,而是退化的指针,那么编译会报错,因为无法推导出N,这就有效的防止了数组退化成指针的问题,从编译层面彻底杜绝了这种情况的发生,从而保证计算数组长度的准确性。
    在看一下宏#define MYARRAYSIZE(A) sizeof(array_size_fake_func(A)),其中sizeof(array_size_fake_func(A)),sizeof是编译期行为,所以这里函数并不产生调用,只是产生函数返回值类型,这个函数甚至不需要调用就能推导出N,所以这个宏没有额外的运行期损耗,所以这就是它的优势,没有类型不明确造成的错误(数组退化指针),没有运行期效率损失。
    这个神奇的宏实现背后隐藏着很多故事,通过层层分析我们大致了解了它背后的实现原理和优势,以后碰到计算数组长度的场景尽量用这个宏吧,安全又快捷。

相关文章

  • ARRAYSIZE宏讲解

    ARRAYSIZE宏     不同的C++实现有很多的库中都有一个计算数组长度的宏,名字大致都叫ARRAYSIZE...

  • Java Day 3

    数组 声明数组: 创建数组: arrayRefVar = new dataType[arraySize]; 1、使...

  • cin.get() getline() cout fout用法总

    Cin 用于char数组: cin.get(arrayname, arraysize); 如果读入空行 cin为f...

  • [基础]数组(c,java,js,lua)

    未完待续 1. c语言 1.1 数组的定义格式 格式:type arrayName [ arraySize ]例:...

  • 2019年2月14 工作总结

    1、凯宏店员成套讲解的抽查,复习…新培训内容的布置,讲解口径的学习,下周培训要认证,下周作业,体验区口径讲解。 2...

  • 【DL】理论篇

    台大教授李宏毅的深度学习课程 2017(附中文视频讲解PPT)

  • 重读经典系列之《C++PrimerPlus》第4章

    第四章 复合类型 声明数组的通用格式如下:typeName arrayName[arraysize];表达式arr...

  • 可变长数组(Arrays of Variable Length)

    早期C语言中定义数组: 类型说明符 数组名 [常量表达式]; type arrayName [ arraySize...

  • Java 数组

    一.声明数组变量 二.创建数组 上面的语法做了两件事: 使用dataType[arraySize] 创建了一个数组...

  • 用例子来说明概念对比2

    这次,分析宏江老师的TF3-1概念对比实录。 首先,片段涉及了很多概念点,宏江老师想要讲解的概念是——积极主动。 ...

网友评论

      本文标题:ARRAYSIZE宏讲解

      本文链接:https://www.haomeiwen.com/subject/qxpvuftx.html