数组的大小

两种方法

1. chromium中得到数组的大小使用如下宏【1】---- 使用数组的引用[下面解释]

template <typename T, size_t N>
char (&ArraySizeHelper(T (&array)[N]))[N];

#define arraysize(array) (sizeof(ArraySizeHelper(array)))


2.stdlib.h中_countof()宏【2】---- 使用数组的指针

template <typename _CountofType, size_t _SizeOfArray>
char (*__countof_helper(UNALIGNED _CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];
#define _countof(_Array) sizeof(*__countof_helper(_Array))


原理:

1> 对数组引用或数组指针取sizeof 可以得到数组的大小

     char a[5];

     char (&r_a)[5] = a; // 数组的引用

     char (*p_a)[5]] = &a; // 数组的指针

     sizeof(a);    sizeof(r_a);    sizeof(*p_a)都能得到数组大小(由于是char类型,所以也是数组中元素的个数 3>中用到)

2> 模板自动推导在编译期完成

    1>中可以看出,定义数组引用和数组指针时,需要数组的维度,所以还需要模板来完成这个任务。

       template< typename T, size_t N>
  void Fun( T (&)[N] );

  这个模板里既有类型T,又有数值N;模板推导时,是根据Fun的实参来推导得到的。比如:
  int a[5];
  Fun(a); // 编译器经过推导就知道,T=int,N=5。注意这里的N能得到5,是因为Fun的参数声明决定的。这里Fun的参数是:数组引用

      通过a,已经得到N了,但是怎么返回呢?

3> sizeof在编译器完成,与运行无关

    sizeof是C/C++语言中的keyword,不是函数。对其参数里的表达式是不会在执行期去执行的,而只是在编译期去推算整个表达式的最后的类型信息,所以

    char fun();

    sizeof(fun()); // 就是对fun的返回类型求sizeof

    如果返回数组的引用,再取sizeof就能得到数组的大小了。所以构造fun函数如下:

    char (&fun)[N], N通过2>得到,所以就得到

    template< typename T, size_t N>
    char(&fun(T (&)[N]))[N];

    所以sizeof(fun(a))就能得到数组的大小(数组中元素的个数)

http://www.cnblogs.com/bigbigtree/p/3580585.html——对sizeof讲的非常详细

注:

红色部分为一体,即数组的引用,表示fun是一个函数,函数参数为T (&)[N],返回值为char &[],即返回数组的引用。

如果写成: char ((&fun)(T (&)[N]))[N];则表示定义了一个函数的引用,该函数参数为T (&)[N],返回值为char [],但是c/c++中是不能返回数组的。


   

   用宏wrap一下就得到方法1,如果用数组的指针取代数组的引用就能得到方法2

数组的引用:

     int a[10] = {0};

     int (&ra)[10] = a;  // 这是数组的引用

     int &b[10];// 这是错误的,没有引用的数组,即数组里面不可能有引用。简单推测一下就知道,如果有引用的数组,那么数组必须初始化(因为引用必须初始化),但是数组是可以不初始化的,所以假设不成立。


c/c++中不能返回数组,但是可以返回数组的引用/指针

数组引用:首先是引用,只是引用的是数组。 int (&r_arr)[N]; // r_arr是一个引用,引用的是int[]

数组指针:首先是指针,只是指向的是数组。 int (*p_arr)[N]; // p_arr是一个指针,指向的是int[]

函数不可返回数组,但是可以返回指针和引用,那返回数组指针和数组引用的函数如何写呢?

将r_arr和p_arr换成函数不就可以了吗

int (& fun())[N]; // 这里的函数没有参数。如果加上参数,再用上模板,不就是ArraySizeHelper了吗

int (* fun())[N]

返回数组指针和数组引用的函数,平时基本用不到,原因很简单,定义函数前必须知道N值,但运用到模板后,N值就容易得到了。所以以后可以多用一下。

简单例子:

template <typename T, size_t N>
char (&fun(T (&array)[N]))[N]

{

    printf("sizeof(T)=%lu\n", sizeof(T));
    printf("N=%lu\n", N); // N即为传入数组的个数

}


int a[10];

fun(a); // 舍弃返回值不用

运行结果为

sizeof(T)=1
N=10


再简单一些

template <size_t N>
void fun(char (&array)[N])

{

    printf("N=%lu\n", N); // N即为传入数组的个数

}

通过使用模板,一次性地把数组长度传了进来,而不是在使用
void fun(char *array, size_t len);




【1】http://www.cnblogs.com/tekkaman/archive/2013/08/19/3268518.html

【2】http://blog.csdn.net/yuanmanzheng/article/details/5472967

【3】http://blogs.msdn.com/b/the1/archive/2004/05/07/128242.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值