Description

Le langage C est un langage particulièrement important pour Unix car c'est en C que 99% de Unix et Linux sont écrits. Le compilateur C utilisé dans le département est gcc.

Séminaire INGI

Cours d'introduction au langage C

Archive avec les exercices

Exemples

Générer des nombres aléatoires

Lorsqu'on écrit des applications, on a souvent besoin de nombres aléatoires, voici un exemple simple permettant de générer de tels nombres:

 #include <stdlib.h>
 #include <sys/time.h>
 #define gen_random(max)   random()/(RAND_MAX + 1.0f)*max
 int main(int argc, const char **argv){
    /* initialisation du générateur */
    struct timeval trecv;
    gettimeofday(&trecv, NULL);
    srandom(trecv.tv_usec);         /* prendre les µs comme semance */
    /* obtenir un nombre aléatoire */
    printf("Le beau nombre aléatoire: %.4f\n", gen_random(666.0f));
 }

Il va de soi que l'initialisation ne doit se faire qu'une seule fois! On utilise les µs comme semance pour que la suite pseudo-aléatoire soit différente à chaque exécution du programme (attention aux propriétés de l'horloge). NOTE: pour avoir toutes les semances virtuellement différentes, on pourrait fusionner les µs avec le pid...

Liste de paramètres

L'exemple suivant illustre l'utilisation d'une liste de paramètres de taille inconnue (mot clé params en c#)

 #include <stdarg.h>
 #define SIZE    512
 char *  
 citation(const char *fmt, ...){
    va_list ap;               
    char buf[SIZE+1];                     
    va_start(ap, fmt);                        
    bzero(buf, sizeof(buf));
 #ifdef HAVE_VSNPRINTF
    vsnprintf(buf, SIZE, fmt, ap);   
 #else                                 
    vsprintf(buf, fmt, ap);               
 #endif                                    
    printf(""%s"\n",buf);                          
    va_end(ap);                                           
    return;                                     
 }
 int
 main(int argc, const char **argv){
    citation("%d, %d, %d %s %d, %d, %d %s", 1,2,3, "nous irons au bois", 4,5,6, "cueillir des cerises");
 }

Créer une librairie dynamique

Création de la librairie:

 /* fichier lib.c */
 void
 doubler(int value){
    printf("Le double de %d vaut %d\n", value, value * 2);
 }

Utilisation de la librairie:

 /* fichier use.c */
 #include <stdio.h>
 #include <stdlib.h>
 #include <dlfcn.h>
 int
 main(){
    const char *sh_lib = "lib.so" ;
    const char *fct = "doubler";
    void (*fp) (int);
    void *handle = dlopen( sh_lib , RTLD_LAZY);
    if(NULL == handle)
        exit(EXIT_FAILURE);
    else{
        fp  = (void (*)(int))dlsym(handle, fct);
        if(NULL != fp)
            fp(333);
        if (0 != dlclose(handle))
            exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
 }

Compilation:

 cc use.c -o use.bin -ldl
 cc -fPIC -c lib.c -o lib.o
 ld -shared lib.o -o lib.so

Ajouter le chemin d'accès de la librairie: En bash:

 export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/repertoire/ou/se/trouve/la/librairie/

Sinon:

 setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:/repertoire/ou/se/trouve/la/librairie/

Si vous utilisez FreeBSD, il n'est pas nécessaire d'ajouter le -ldl pour le linkage. Il faut toujours être très prudent lors de cette phase car le compilateur ne sait pas tester les choses aussi bien que sans librairies (ie: dans notre exemple on pourait ajouter un deuxième paramètre à fp, le compilateur ne dirait rien...).

Si maintenant, votre librairie doit changer, il suffira de la modifier et de la recompiler, pas besoin de recompiler use.c.

Dans notre exemple, la fonction est chargée de manière "lazy", un peu comme en Oz...

Informations complémentaires

Trucs et astuces

Lorsque vous développez des programmes en C, n'hésitez pas pas à utiliser le plus haut niveau de warnings. Avec gcc, utilisez chaque fois le paramètre -Wall

Pour utiliser les fonctions mathématiques telles que sqrt ou sqrtf, inclure math.h. Lors de la compilation, ajouter l'option -lm