前言

在研究数组排序的过程中,发现了个很基础的问题–如何获取数组长度(成员数)。

似乎C++并没有提供获取数组长度的方法,网上搜索得知sizeof可以计算变量大小,可以通过获取数组大小/成员大小的办法得到数组长度。

当我将这个计算数组长度的方法封装起来时,发现事情并不简单。

int array_length(int ai[]) {   return sizeof ai / sizeof ai[0];}int is[] = {2, 4, 1, 3, 6, 5};cout << sizeof is / sizeof is[0] << endl;  // 输出: 6,right.cout << array_length(is) << endl;  // 输出: 2,emmmm???

引用类型

编译时说明了原因所在。

warning: sizeof on array function parameter will return size of 'int *' instead of 'int []' [-Wsizeof-array-argument]

个人理解大概意思就是把数组传入函数,会变成引用类型(指针),即sizeof取得的是指针的size。

详情参考:点击查看

那就操蛋了,程序不封装好,每次想获取长度都tm要写一次sizeof的话,那就太傻逼了。

网上搜索了一下资料,似乎没有办法(不含复制)直接取出指针指向的数组。

模版类型

在做数组排序时,需要交换变量,搜索资料的时候发现了一种操作。

template <typename T>T minn(T a,T b){    return (a<b)? a:b;}

于是乎,尝试抄袭一下,正确获取到了数组长度。

template<typename T>int array_length(T &at) {    return sizeof at / sizeof at[0];}

原来只打算做int型数组排序的,结果,套用了这个template之后,全类型数值排序都实现了。

参考资料:点击查看

后话

如果想要简单获取length,也许该用vector

以下为本文实现的排序代码。

//// Created by HsOjo on 2018/10/31.//#include <iostream>using namespace std;template<typename T>void array_swap(T &at, int ia, int ib) {    int t = at[ia];    at[ia] = at[ib];    at[ib] = t;}template<typename T>int array_length(T &at) {    return sizeof at / sizeof at[0];}template<typename T>void array_sort(T &at, bool up) {    int c, l;    l = array_length(at);    do {        c = 0;        if (up) {            for (int i = 0; i < l - 1; i++) {                if (at[i] > at[i + 1]) {                    array_swap(at, i, i + 1);                    c++;                }            }        } else {            for (int i = l - 1; i > 0; i--) {                if (at[i] > at[i - 1]) {                    array_swap(at, i, i - 1);                    c++;                }            }        }    } while (c > 0);}int main() {    int is[] = {2, 4, 1, 3, 6, 5};    double ds[] = {2.5, 4.1, 1.2, 3.6, 6.123, 5.43, 4.32};    array_sort(is, true);    array_sort(ds, false);    for (int i: is) {        cout << i << ' ';    }    cout << endl;    for (double d: ds) {        cout << d << ' ';    }    cout << endl;    return 0;}