Pour comprendre la récursion, reproduit la à la main, ligne par ligne, et essaie d'en voir le systèmatisme.
Un peu comme une suite Un = f(Un-1). Il faut un porte de sortie (convergence de la suite) sinon, ça tourne indéfiniment.
Dans ton cas la récursion est produite par l'appel
combinaisons(ens,combinaison,n,p,i+1,k);
qui augmente i, et la sortie de la récursion se fait sur afficher() quand i>=p
Soit alors :
if (i<p) {
...
combinaisons(ens,combinaison,n,p,i+1,k);
...
}
else {
afficher(combinaison,p);
}
Après afficher(), le programme revient après l'appel à combinaisons().
Maintenant, regarde la boucle :
k=0
cmb[0]=ens[0];
combinaison(ens,cmb,n,p,1,0);
rappel :
cmb[1]=ens[0];
combinaison(ens,cmb,n,p,2,0);
etc... jusqu'à p-1 : afficher().
cmb[p-1]=ens[0];
combinaison(ens,cmb,n,p,p,0);// provoque afficher()
A ce moment, tous les cmb[] contiennent ens[0].
et première sortie de combinaison() : i = p-1 et on passe à k=k+1 (donc 1)
cmb[p-1]=ens[1];
combinaison(ens,cmb,n,p,p,0);
tous les cmb[] contiennent ens[0], sauf le dernier qui contient ens[1].
etc...
Ta dernière question est différente. Je ne sais pas s'il y en a déjà, alors il faut la faire ou la trouver (google !)