- Expliquer comment faire pour avoir un paramètre en entrée/sortie d’une fonction en C.
Il faut que le paramètre soit de type pointeur :
// multiplie par 2 le nombre passé en paramètre
int fonction(int* paramES)
{
*paramES = 2 * *paramES;
}
- Expliquer la différence d’usage entre ces deux
types de déclaration :
char * machaine
etchar machaine[20]
char * machaine
déclare une variable appeléemachaine
de typechar*
(pointeur vers caractère)char machaine[20]
déclare un tableau dechar
appelémachaine
ayant une taille de20
- Expliquer pourquoi ces lignes lignes de code vont provoquer une erreur à la compilation :
// struct doit être en minuscule
Struct personne {
char nom[10];
char prenom[20];
} // manque le point-virgule
int main()
{
personne p; // manque le "struct" devant le nom du type
strcpy(p.nom,"dupond");
strcpy(p.prenom,"paul");
printf("%s %s", p.nom, p.prenom);
}
Le code correct est :
struct personne {
char nom[10];
char prenom[20];
};
int main()
{
struct personne p;
strcpy(p.nom,"dupond");
strcpy(p.prenom,"paul");
printf("%s %s", p.nom, p.prenom);
}
Si on veut être pédant, on pourrait dire qu'il manque le return 0;
dans main()
mais ce n'est pas une erreur mais seulement un warning.
- Expliquer en quelques lignes, l’intérêt de la compilation séparée
Cela permet de modifier le code et l'implémentation des fonctions sans que ceux qui utilisent notre code (par le biais des headers) n'aient à changer quoi que ce soit.
- Les nombres de Pell (Pn) et de Pell-Lucas
(Qn) sont définis par la récurrence linéaire suivante : [...]
Écrire une seule fonction permettant de calculer l’une ou l’autre des suites et retournant
la valeur au rang n dont le protype est définit comme suit :
typedef enum {pell,pelllucas} typeSuite; long suitePell(int rang, typeSuite suite)
Correction :
typedef enum {pell,pelllucas} typeSuite;
long suitePell(int rang, typeSuite suite)
{
if (suite == pell)
{
if (rang == 0) return 0;
if (rang == 1) return 1;
}
else if (suite == pelllucas)
{
if (rang <= 1) return 2;
}
return 2 * suitePell(rang - 1, suite) + suitePell(rang - 2, suite);
}
- Écrire une fonction qui permette de trouver le nombre max d’occurrence > 1 dans un
tableau d’entier positif trié ainsi que la valeur de cette occurrence (la taille du tableau
est donnée par la constante
MAX_TAB
)
#define MAX_TAB 11
void fonc(int tab[MAX_TAB], int* maxOcc, int* maxVal)
{
*maxOcc = 0;
*maxVal = -1;
int actOcc = 0;
int actVal = -1;
for (int i = 0; i <= MAX_TAB; i++)
{
if (i == MAX_TAB || tab[i] != actVal)
{
if (actOcc > 1 && actOcc > *maxOcc)
{
*maxOcc = actOcc;
*maxVal = actVal;
}
actVal = tab[i];
actOcc = 0;
}
actOcc++;
}
}
int main()
{
int T[MAX_TAB] = { 5, 6, 6, 6, 7, 8, 21, 21, 21, 25, 25 };
int occ, val;
fonc(T, &occ, &val);
printf("occ=%d, val=%d\n", occ, val);
return 0;
}
- Définir le type énuméré permettant de définir les mois d’une année standard puis
définir les structures (
date
,temps
,trace
) et les nouveaux types permettant de gérer une trace d’accès (trace
) et les traces d’accès bâtiments (tracebat
)
typedef enum
{
JAN = 1, FEV, MAR, AVR, MAI, JUN, JUL, AOU, SEP, OCT, NOV, DEC
} mois;
typedef struct
{
unsigned char jour;
mois mois;
unsigned short annee;
} date;
typedef struct
{
unsigned char heure;
unsigned char minute;
unsigned char seconde;
} temps;
typedef struct
{
char badge[15];
date date;
temps temps;
} trace;
typedef struct
{
trace traces[50];
unsigned char nombre;
} tracebat;
- Écrire les fonctions suivantes :
void ajouteTrace(trace t, tracebat * b) void afficheTrace(tracebat b) void videTrace(tracebat * b)
Corrigé :
void ajouteTrace(trace t, tracebat* b)
{
b->traces[b->nombre++] = t;
}
void afficheTrace(tracebat b)
{
trace* t = b.traces;
for (unsigned char i = 0; i < b.nombre; i++, t++)
{
printf("badge %.15s - %02d/%02d/%04d %02dh%02dm%02ds\n",
t->badge,
t->date.jour, t->date.mois, t->date.annee,
t->temps.heure, t->temps.minute, t->temps.seconde);
}
}
void videTrace(tracebat* b)
{
b->nombre = 0;
}
- Écrire le programme principal (main) permettant de tester l’ajout de deux traces (badge 123456 le 2 mars 2018 à 14:20:18 et badge 123456 le 2 mars 2018 à 14:45:18) , leur affichage et leur suppression
int main()
{
tracebat tb;
ajouteTrace((trace){ "123456", { 02, MAR, 2018}, { 14, 20, 18} }, &tb);
ajouteTrace((trace){ "123456", { 02, MAR, 2018}, { 14, 45, 18} }, &tb);
afficheTrace(tb);
videTrace(&tb);
return 0;
}
- Écrire une fonction (sans utiliser
string.h
) qui permet de concaténer deux chaînes dans la première et qui retourne la taille total de la nouvelle chaîne. On suppose que la fin de chaîne, passée en paramètre, est correctement formatée et que la taille de la première est suffisamment grande pour contenir la seconde
int concat(char dest[], char src[])
{
int pos_dest = 0;
// on cherche la fin de la chaîne destination
while (dest[pos_dest] != '\0')
pos_dest++;
int pos_src = 0;
// on copie la chaîne source
while (src[pos_src] != '\0')
dest[pos_dest++] = src[pos_src++];
return pos_dest;
}
- Écrire les fonctions suivantes :
int estVide(ListeCirculaire * liste) → retourne vrai si la liste est vide, faux sinon void afficheListe(ListeCirculaire * liste) → affiche la liste
Corrigé :
int estVide(ListeCirculaire* liste)
{
return liste->nbelt == 0;
}
void afficheListe(ListeCirculaire* liste)
{
Element* elem = liste->tete;
for (int i = 0; i < liste->nbelt; i++, elem = elem->suiv)
{
printf("Élément %d : %d\n", i, elem->valeur);
}
}
- On souhaite maintenant pourvoir insérer un élément (qui aura été précédemment alloué) en fin de liste
void insereEnFin(ListeCirculaire* liste, Element* elt)
{
liste->tete->prev->suiv = elt;
elt->prev = liste->tete->prev;
liste->tete->prev = elt;
elt->suiv = liste->tete;
}
- On souhaite maintenant pourvoir insérer un élément (qui aura été précédemment alloué) en tête de liste
void insereEnTete(ListeCirculaire* liste, Element* elt)
{
insereEnFin(liste, elt);
liste->tete = elt;
}
- En utilisant les fonctions précédentes (
insereEnFin()
,insereEnTete()
) créer une fonction d’ajout permettant d’ajouter de façon triée une valeur dans la liste
void ajouteListe(ListeCirculaire* liste, int valeur)
{
Element* elem = malloc(sizeof(Element));
elem->valeur = valeur;
Element* tete = liste->tete;
while (liste->tete->valeur < elem->valeur)
liste->tete = liste->tete->suiv;
insereEnFin(liste, elem);
}
TODO