Reset C int array to zero : the fastest way?

前端 未结 7 1295
感情败类
感情败类 2020-12-22 18:34

Assuming that we have a T myarray[100] with T = int, unsigned int, long long int or unsigned long long int, what is the fastest way to reset all its content to

相关标签:
7条回答
  • 2020-12-22 18:50

    You can use memset, but only because our selection of types is restricted to integral types.

    In general case in C it makes sense to implement a macro

    #define ZERO_ANY(T, a, n) do{\
       T *a_ = (a);\
       size_t n_ = (n);\
       for (; n_ > 0; --n_, ++a_)\
         *a_ = (T) { 0 };\
    } while (0)
    

    This will give you C++-like functionality that will let you to "reset to zeros" an array of objects of any type without having to resort to hacks like memset. Basically, this is a C analog of C++ function template, except that you have to specify the type argument explicitly.

    On top of that you can build a "template" for non-decayed arrays

    #define ARRAY_SIZE(a) (sizeof (a) / sizeof *(a))
    #define ZERO_ANY_A(T, a) ZERO_ANY(T, (a), ARRAY_SIZE(a))
    

    In your example it would be applied as

    int a[100];
    
    ZERO_ANY(int, a, 100);
    // or
    ZERO_ANY_A(int, a);
    

    It is also worth noting that specifically for objects of scalar types one can implement a type-independent macro

    #define ZERO(a, n) do{\
       size_t i_ = 0, n_ = (n);\
       for (; i_ < n_; ++i_)\
         (a)[i_] = 0;\
    } while (0)
    

    and

    #define ZERO_A(a) ZERO((a), ARRAY_SIZE(a))
    

    turning the above example into

     int a[100];
    
     ZERO(a, 100);
     // or
     ZERO_A(a);
    
    0 讨论(0)
  • 2020-12-22 18:51

    memset (from <string.h>) is probably the fastest standard way, since it's usually a routine written directly in assembly and optimized by hand.

    memset(myarray, 0, sizeof(myarray)); // for automatically-allocated arrays
    memset(myarray, 0, N*sizeof(*myarray)); // for heap-allocated arrays, where N is the number of elements
    

    By the way, in C++ the idiomatic way would be to use std::fill (from <algorithm>):

    std::fill(myarray, myarray+N, 0);
    

    which may be optimized automatically into a memset; I'm quite sure that it will work as fast as memset for ints, while it may perform slightly worse for smaller types if the optimizer isn't smart enough. Still, when in doubt, profile.

    0 讨论(0)
  • 2020-12-22 18:54

    zero(myarray); is all you need in C++.

    Just add this to a header:

    template<typename T, size_t SIZE> inline void zero(T(&arr)[SIZE]){
        memset(arr, 0, SIZE*sizeof(T));
    }
    
    0 讨论(0)
  • 2020-12-22 19:04

    From memset():

    memset(myarray, 0, sizeof(myarray));
    

    You can use sizeof(myarray) if the size of myarray is known at compile-time. Otherwise, if you are using a dynamically-sized array, such as obtained via malloc or new, you will need to keep track of the length.

    0 讨论(0)
  • 2020-12-22 19:09

    For static declaration I think you could use:

    T myarray[100] = {0};
    

    For dynamic declaration I suggest the same way: memset

    0 讨论(0)
  • 2020-12-22 19:11

    Here's the function I use:

    template<typename T>
    static void setValue(T arr[], size_t length, const T& val)
    {
        std::fill(arr, arr + length, val);
    }
    
    template<typename T, size_t N>
    static void setValue(T (&arr)[N], const T& val)
    {
        std::fill(arr, arr + N, val);
    }
    

    You can call it like this:

    //fixed arrays
    int a[10];
    setValue(a, 0);
    
    //dynamic arrays
    int *d = new int[length];
    setValue(d, length, 0);
    

    Above is more C++11 way than using memset. Also you get compile time error if you use dynamic array with specifying the size.

    0 讨论(0)
提交回复
热议问题