111 votes

Réinitialiser C int tableau à zéro : le moyen le plus rapide?

En supposant que nous avons un T myarray[100] T = int, unsigned int, long int ou unsigned long long int, quel est le moyen le plus rapide pour réinitialiser l'ensemble de son contenu à zéro (pas seulement pour l'initialisation, mais pour réinitialiser le contenu plusieurs fois dans mon programme)? Peut-être avec memset?

Même question pour un tableau dynamique comme T *myarray = new T[100].

193voto

Matteo Italia Points 53117

memset est probablement la manière la plus rapide façon standard, car, en général, une routine écrite directement dans l'assemblage et optimisé à la main.

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

---edit---

Par ailleurs, en C++ le idiomatiques moyen serait d'utiliser std::fill:

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

qui peut être optimisé automatiquement en memset; je suis tout à fait sûr que cela fonctionnera aussi vite qu' memset pour ints, alors qu'il peut effectuer légèrement pire pour les plus petits types, si l'optimiseur n'est pas assez intelligent. Toujours, dans le doute, de profil.

12voto

Alex Reynolds Points 45039

D' memset():

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

Vous pouvez utiliser sizeof(myarray) si la taille de l' myarray est connu à la compilation. Sinon, si vous utilisez dynamiquement un tableau de taille, comme obtenu par l'intermédiaire d' malloc ou new, vous aurez besoin de garder une trace de la longueur.

6voto

AndreyT Points 139512

Vous pouvez utiliser memset, mais seulement parce que notre sélection de types est limitée aux types intégraux.

Dans le cas général, en C, il est donc logique d'appliquer une 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)

Cela vous donnera le C++fonctionnalité qui vous permet de "remise à zéro" un tableau d'objets de tout type, sans avoir à recourir à des hacks comme memset. En gros, c'est un C analogique de C++ modèle de fonction, sauf que vous devez spécifier le type de l'argument explicitement.

En plus de cela, vous pouvez construire un "modèle" pour les non-pourri des tableaux

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

Dans votre exemple, il serait appliquée que

int a[100];

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

Il est également intéressant de noter que spécifiquement pour les objets de types scalaires, on peut mettre en œuvre un type indépendant de la macro

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

et

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

en tournant l'exemple ci-dessus en

 int a[100];

 ZERO(a, 100);
 // or
 ZERO_A(a);

3voto

Bruno Soares Points 122

Pour statique de la déclaration, je pense que vous pouvez utiliser:

T myarray[100] = {0};

Pour la déclaration dynamique je vous propose la même façon: memset

2voto

Navin Points 935

zero(myarray); est tout ce que vous devez en C++.

Il suffit d'ajouter ce fichier dans un autre:

template<typename T, size_t SIZE> inline void zero(T(&arr)[SIZE]){
    memset(arr, 0, SIZE);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X