前言

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

似乎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;
}