C++Builder logo
Using standard algorithms with C arrays Utilisation des algorithmes de la STL avec des arrays de type C
 
Didn't you ever think that it could be interesting if you could use the standard algorithms with C arrays? Well, it can be done! Standards algorithms are designed to be used with standard containers and use iterators but containers are no more than some sort of "intelligent" arrays and iterators are no more than some kind of pointers.
For example, the sort algorithm is declared as:
Ne vous êtes-vous jamais demandé s'il était possible d'utiliser les algorithmes de la STL avec des arrays de type C? Et bien, c'est tout-à-fait possible! Les algorithmes ont été créés pour être utilisés avec les containers de la STL et utilisent des itérateurs mais, un container n'est jamais qu'une sorte d'array évolué et les itérateurs ne sont que des sortes de pointeurs.
Par example, l'algorithme sort est déclaré comme ceci:

void sort (RandomAccessIterator first,RandomAccessIterator last);

   
So, you may be tempted to use it like this: Vous pourriez être tenté de l'utiliser comme ceci:

int array[10];
std::sort(&array[0],&array[10]);


The issue here is that &array[10] yields to undefined behavior since array[10] is out of bounds. But, using pointer arithmetic is valid. You can have a pointer that points to one past the end of the array. So use it this way: Le problème ici est que &array[10] est indéfini parce que array[10] est hors des limites de l'array. Par contre, rien ne vous empêche d'utiliser un pointeur pointant vers un élément au delà de l'array. Donc, il faut l'utiliser de cette façon:
   

int array[10];
std::sort(array,array+10);


Here is a working sample which uses a simple array of integers and shows how to use some of the algoritms. Take a look at your favourite help resource to get a list of all of them. Voici un example complet montrant comment utiliser les algorithmes. Il est basé sur un simple array d'entiers et je vous invite à regarder dans votre fichier d'aide préféré pour avoir une liste complète de tous les algorithmes utilisables.

#include <iostream>
#include <algorithm>

// Simple global function used with the for_each algorithm.
// See below.
void Power(int value)
{
  std::cout<<value*value<<",";
}

int main()
{
  int array[10]={0,1,2,3,4,5,6,7,8,9};
  
  for(int i=0;i<10;++i)std::cout<<array[i]<<",";
  std::cout<<std::endl;
  
  // randomize mix up the values contained in the array.
  std::cout<<"randomize"<<std::endl;
  std::random_shuffle(array,array+10);
  for(int i=0;i<10;++i)std::cout<<array[i]<<",";
  std::cout<<std::endl;
  
  // find returns an iterator (in this case a pointer) to the item
  // if found and end() (in this case one past the last item in the
  // array) if not found.
  std::cout<<"find"<<std::endl;
  int* ptr=std::find(array,array+10,4);
  if(ptr==array+10)std::cout<<"not found"<<std::endl;
  else std::cout<<*ptr<<" found"<<std::endl;
  
  // reverse the order of the values in the array
  std::cout<<"reverse"<<std::endl;
  std::reverse(array,array+10);
  for(int i=0;i<10;++i)std::cout<<array[i]<<",";
  std::cout<<std::endl;
  
  // sort 
  std::cout<<"sort"<<std::endl;
  std::sort(array,array+10);
  for(int i=0;i<10;++i)std::cout<<array[i]<<",";
  std::cout<<std::endl;
  
  // copy copies one array to another.
  std::cout<<"copy"<<std::endl;
  int another_array[10];
  std::copy(array,array+10,another_array);
  for(int i=0;i<10;++i)std::cout<<array[i]<<",";
  std::cout<<std::endl;
  for(int i=0;i<10;++i)std::cout<<another_array[i]<<",";
  std::cout<<std::endl;
  
  // equality returns true if the two arrays have the same length
  // and the same elements at the same place.
  std::cout<<"equality"<<std::endl;
  if(std::equal(array,array+10,another_array))
      std::cout<<"the 2 arrays are equal"<<std::endl;  
  
  // fill fills the array with a given value.
  std::cout<<"fill"<<std::endl;
  std::fill(array,array+10,22);
  for(int i=0;i<10;++i)std::cout<<array[i]<<",";
  std::cout<<std::endl;
  
  // swap exchanges the items of one array with the ones of another.
  std::cout<<"swap"<<std::endl;
  std::swap_ranges(array,array+10,another_array);
  for(int i=0;i<10;++i)std::cout<<array[i]<<",";
  std::cout<<std::endl;
  for(int i=0;i<10;++i)std::cout<<another_array[i]<<",";
  std::cout<<std::endl;
  
  // count returns the number of times a given value is 
  // found in the array.
  std::cout<<"count"<<std::endl;
  int count=std::count(another_array,another_array+10,22);
  std::cout<<"there is "
           <<count
           <<" elements in new_array with value 22"
           <<std::endl;
  
  //for_each is non-mutating, this means that for_each
  //doesn't modify the array. The return value of the 
  //function is ignored.
  std::cout<<"for_each"<<std::endl;  
  std::for_each(array,array+10,Power);
  
  return 0;
}


The example above uses a simple array of integers. But what about arrays of user defined type?
The algorithms use the operators <, ==, ... to compare two items of the array, to evaluate them... so, all you need is to define the needed operators for your own types.
Below, I create a struct containing 2 char arrays and I define an operator < to be used with the std::sort algorithm. 
Dans l'example ci-dessus, je n'utilise qu'un array d'entiers. Comment faire si je veux que mon array contienne un type que j'ai défini moi-même?
Ce n'est pas vraiment compliqué. Il faut savoir que les algorithmes utilisent les opérateurs <, ==, ... lorsqu'ils comparent deux éléments de l'array. Il suffit donc de définir l'opérateur adéquat pour le type que l'on veut utiliser.
L'example ci-dessous crée une structure contenant deux char arrays et définit l'opérateur < utilisé par l'algorithme std::sort.
 

#include <iostream.h>
#include <algorithm>

struct MasterOfCpp
{
  char FirstName[16];
  char LastName[16];
};

// The sort algorithm uses the operator <.
// To make it work with our array, just overload operator <
// for our struct this way :
bool operator<(const MasterOfCpp& lhs,const MasterOfCpp& rhs)
{
  return (strcmp(lhs.LastName,rhs.LastName)<0)
      || ((strcmp(lhs.LastName,rhs.LastName)==0)
          && (strcmp(lhs.FirstName,rhs.FirstName)<0));
}

int main()
{
  MasterOfCpp moc[6];
  strcpy(moc[0].LastName,"Stroustrup");
  strcpy(moc[0].FirstName,"Bjarne");
  strcpy(moc[1].LastName,"Austern");
  strcpy(moc[1].FirstName,"Matt");
  strcpy(moc[2].LastName,"Meyers");
  strcpy(moc[2].FirstName,"Scott");
  strcpy(moc[3].LastName,"Josuttis");
  strcpy(moc[3].FirstName,"Nicolai");
  strcpy(moc[4].LastName,"Sutter");
  strcpy(moc[4].FirstName,"Herb");
  strcpy(moc[5].LastName,"Alexandrescu");
  strcpy(moc[5].FirstName,"Andrei");

  std::cout<<"array not sorted :"<<std::endl;
  for (int i=0;i<6;++i)
      std::cout<<moc[i].LastName
               <<" "<<moc[i].FirstName
               <<std::endl;
               
  std::cout<<std::endl;
  
  std::cout<<"array sorted :"<<std::endl;
  std::sort(moc,moc+6);
  for (int i=0;i<6;++i)
      std::cout<<moc[i].LastName
               <<" "<<moc[i].FirstName
               <<std::endl;
  
  return 0;
}