main.c
#include <stdio.h>
#include "sum.h"
int main() {
int tab[] = {1, 2, 3, 4};
"sum: %d\n", sum(tab, 4));
printf(return 0;
}
Programmation séquentielle en C, 2020-2021
Orestis Malaspinas (A401), ISC, HEPIA
2020-09-30
struct
(1/5)Plusieurs variables qu’on aimerait regrouper dans un seul type: struct
.
Les champs sont accessible avec le sélecteur “.
”.
struct
(2/5)typedef
permet de définir un nouveau type.
L’initialisation peut aussi se faire avec
struct
(3/5)Comme pour tout type, on peut avoir des pointeurs vers un struct
.
Les champs sont accessible avec le sélecteur ->
struct
(4/5)Avec le passage par référence on peut modifier un struct en place.
Les champs sont accessible avec le sélecteur ->
struct
(5/5)On peut allouer un complexe, l’initialiser et le retourner.
La valeur retournée peut être copiée dans une nouvelle structure.
Les arguments d’une fonction sont toujours passés par copie.
Les arguments d’une fonction ne peuvent jamais être modifiés.
Que pourrait-on faire pour modifier x
?
Pour modifier une variable, il faut passer son adresse mémoire (sa référence) en argument.
L’adresse d’une variable, a
, est accédée par &a
.
Un pointeur vers une variable entière a
le type, int *
.
*a
sert à déréférencer le pointeur (accéder la mémoire pointée).
stdio.h
: printf()
, scanf()
, …Prototypes de fonctions nécessaires quand:
Un prototype indique au compilateur la signature d’une fonction.
On met les prototypes des fonctions publiques dans des fichiers headers, extension .h
.
Les implémentations des fonctions vont dans des fichier .c
.
Porte l’extension .h
Contient:
Utilisé pour décrire l’interface d’une librairie ou d’un module.
Un fichier C
(extension .c
) utilise un header en l’important avec la directive #include
:
gcc
appelle cpp
, le préprocesseur qui effectue de la substitution de texte (#define
, #include
, macros, …) et génère le code C
à compiler, portant l’extension .i
(prog.i
).gcc
compile le code C en code assembleur, portant l’extension .s
(prog.s
).gcc
appelle as
, l’assembleur, qui compile le code assembleur en code machine (code objet) portant l’extension .o
(prog.o
).gcc
appelle ld
, l’éditeur de liens, qui lie le code objet avec les librairies et d’autres codes objet pour produire l’exécutable final (prog
).Les différents codes intermédiaires sont effacés.
main.c
La compilation séparée se fait en plusieurs étapes.
.o
avec l’option -c
.-o
pour générer l’exécutable.Création des fichiers objets, main.o
et sum.o
Édition des liens
gcc
ou clang
.//
et /* ... */
).#
.define
Permet de définir un symbole:
Permet de définir une macro.
include
Permet d’inclure un fichier.
Le contenu du fichier est ajouté à l’endroit du #include
.
Inclusion de fichiers “globaux” ou “locaux”
Les inclusions multiples peuvent poser problème: définitions multiples. Les headers commencent par:
C
offre uniquement des tableaux statiques
[i]
où i
est l’index de l’élément.0
!float tab1[5]; // tableau de floats à 5 éléments
// ses valeurs sont indéfinies
int tab2[] = {1, 2, 3}; // tableau de 3 entiers,
// taille inférée
int val = tab2[1]; // val vaut 2 à présent
int w = tab1[5]; // index hors des limites du tableau
// comportement indéfini!
// pas d'erreur du compilateur
main()
.void main()
.int main()
.void main(int argc, char **argv)
.int main(int argc, char **argv)
.argc
est le nombre d’arguments passés à la ligne de commande: le premier est celui du programme lui-même.argv
est un tableau de chaînes de caractères passés sur la ligne de commande.Pour la fonction dans le programme prog
Pour l’exécution suivante on a
Les arguments sont toujours stockés comme des chaînes de caractère.
Peu pratique si on veut manipuler des valeurs numériques.
Fonctions pour faire des conversions:
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
int main(int argc, char **argv) {
if (argc != 3) {
char *progname = basename(argv[0]);
fprintf(stderr, "usage: %s name age\n", progname);
return EXIT_FAILURE;
}
char *name = argv[1];
int age = atoi(argv[2]);
printf("Hello %s, you are %d years old.\n", name, age);
return EXIT_SUCCESS;
}