Skip to content

Latest commit

 

History

History
370 lines (349 loc) · 14.4 KB

cs207.md

File metadata and controls

370 lines (349 loc) · 14.4 KB

CS207

GNU General Public License v3.0 licensed. Source available on github.com/zifeo/EPFL.

Spring 2015: Programmation Orientée Système

[TOC]

Sous le capôt

  • mémoire virtuelle
    • pile : variables locales, vers le bas (0xFFFFFFFF)
    • tas : allocation dynamique, vers le haut
    • données : variables statiques et globales
    • texte : code du programme et constantes (0x00000000)

Types

  • types élémentaires : int, double, char
  • valeurs littérales : 1, 1.23, 12.3e4
  • caractère
    • échapper ' et \ par \
    • retour de ligne : \n
    • nul : \0
  • non modifiable (différent de constant) : const (associativité à gauche)
  • modificateurs
    • long
    • short
    • unsigned (long/short/)
    • signed
    • extern : déclaré ailleurs
    • static : limite la portée ou rend la variable commune
    • register : suggère le registre
    • restrict : 1 seul pointeur sur cette zone
    • volatile : pas d'optimisation
  • taille : char < short int < int < long int < double < long double
  • minimum/maxium : limits.h
    • SCHAR_MIN/SCHAR_MAX
    • SHRT_MIN/SHRT_MAX
    • 0/ULONG_MAX
    • DBL_MIN/DBL_MAX/DBL_ESPILON (précision)
  • énumeration : enum Type { v1, v2 }
    • comme des entiers (conversion est possible)
  • tableau : type nom[taille] = { v1, v2 }
    • size_t pour id
    • taille connu à la compilation (excepté VLA)
      • #define SIZE 4
      • size_t const size = 2
    • pas de notion de taille hors celle définie à la déclaration
    • argument de fonction : comme un pointeur f(double nom[taille]) (taille faculative et à passer par un autre argument)
    • pas en retour de fonction
    • plusieurs dimensions : seul la première taille peut être ignoré dans une fonction
    • pas manipulable globalement : pas de =
  • alias : typedef type alias (typedef double nom[2])
  • structure : struct nom { type id1; type id2; }
    • initialisation : struct nom id = { v1, v2 }
    • type : struct nom
    • typedef : typedef struct {} nom
    • acces : id.champ
    • affectation : s1 = s2 (copie profonde)
  • union : union intOrDouble { int i; double d; } (même zone mémoire)
  • bit field : specification bit à bit de zone (typedef struct { unsigned int sign: 1; unsigned int exp: 15; unsigned int mant: 32; } FN)
  • pointeur : type* nom (stdlib.h)
    • NULL : pointe sur rien
    • &nom : adresse
    • *pointeur : déréference
    • allocation dynamique
      • sizeof(type) : taille d'un type en mémoire
        • sizeof(tab)/sizeof(tab[0]) si déclaré juste avant
      • void* malloc(size_t taille)
      • calloc(nombre, taille)
      • realloc(taille)
      • valeur NULL si allocation échouée
      • free(pointeur) : libère l'allocation (suivi d'une assignation à NULL)
      • bus error : noyau n'a pas detecté l'erreur (sinon segmentation fault)
      • attention overflow : allocated > SIZE_MAX / sizeof(type)
      • SIZE_MAX : stdint.h et #ifndef SIZE_MAX #define SIZE_MAX (~(size_t) 0) #endif
  • chaine de caractères : tableaux de char
    • constante littérale : char const s[] = "Yop"
    • tableau : char s[23]
    • allocation : char* s
    • allouer n + 1 caractères pour la fin de chaine (\0)
    • attention à la constance : char* s = "b" faux
    • strncpy(s, "bonjour", TAILLE) (char s[TAILLE+1] et s[TAILLE] = '\0')
    • sur fonction : double (*g)(int i)
    • sur pointeur : int** n'est pas int[][] (non continu, non alloué, ligne pas forcément le même nombre d'élément)
    • arithmetic
      • accès : p[id] (symmetrique 3[p])
      • suivant : +1
      • précédent : -1
      • soustraction : ptrdiff_t = p2 - p1 (stddef.h)

Opérations

  • modulo : signe du premier opérande
  • division entière (sauf si 1.)
  • associativité à gauche
  • expression logique : évaluation paresseuse
    • faux : valeur nulle, 0
    • vrai : sinon
  • opérateur binaire , : évalue les opérands et vaut la valeur de celle de droite
  • priorité : () [] -> . · ! ++ -- · * / % · + - · < <= > >= · == != · && · || · = += -= etc. · ,
  • bit : ~ (inversion), |, &, <<, >>
  • qsort : void qsort(void* base, size_t nb_el, size_t size, int(*compar)(const void*, const void*))
    • base : zone à trier
    • nb_el : nombre d'élément
    • size : taille d'un élément
    • compar : fonction de compairson
    • qsort(tab, NB, sizeof(int), compare_int)
    • int compare_int(void const* arg1, void const* arg2) { int const* const i = arg1; int const* const j = arg2; return ((*i == *j) ? 0 : ((*i < *j) ? -1 : 1)); }
  • casting : (type)
  • digraph : <:, :>, <%, %>, %:, %:%

Structures & fonctions

  • bloc : variables redéfinissables et portée limitée
  • prototypages : nom de variable facultatif
  • function sans argument : void sinon c'est un pré-prototype
  • passage des arguments
    • valeur : copie
    • référence : non
    • pointeur : type const* si uniquement lecture
    • pas de valeur par défaut (excepté vararg)
  • pas de surcharge de fonction
  • tertiaire : ? :
  • main : int main(int argc, char* argv[])
    • nom du programme : 1er argument
    • retourne code d'erreur (0 si succès, shell $?)

IO

  • flots (stdio.h)
    • stdin
    • stdout
    • stderr
  • format d'affichage : %|option|spécification
    • options
      • ajustement à gauche : -
      • affiche le signe : +
      • remplace le signe par un espace :
      • indication de format (0 devant les octaux, un point pour les double) : #
      • compléter par des zéros non significatifs : 0
      • taille minimum : nombre
      • taille donnée par une variable supplémentaire : *
      • précision : .nombre
      • indicateur de taille
        • short : h
        • long : l
        • long double : L
    • spécification
      • int entier : d/i
      • int non signé : u
      • int hexadécimal : x/X
      • int octal : o
      • char : c
      • chaine : s
      • décimal : f
      • scientifique : e/E
      • décimal automatique : g/G
      • caractère % : %
  • buffering : fflush(stdout)
  • lecture de ligne : fgets(phrase_a_lire, taille, stdin) mieux (garanti \0 à taille)
  • format de lecture : scanf
    • lettre majuscule : %[A-Z]
    • ne doit pas contenir de retour à la ligne : %[^\n]
    • controle de taille : %19s
  • control du tampon : jamais utiliser scanf mais caractère par caractère (getc)
    • scanf retourne le nombre de champ correctement saisi
    • si erreur : while (!feof(stdin) && !ferror(stdin) && getc(stdin) != '\n')
  • utilisation de fichier (stdio.h)
    • ouverture : FILE* fopen(const char* nom, const char* mode) (renvoie NULL en cas d'erreur)
    • mode
      • lecture : r
      • écriture : w (écrasement)
      • écriture : a (ajout)
      • binaire : b (à la fin)
      • lecture et écriture : w+ ou a+b
    • numéro d'erreur : errno
    • message d'erreur : strerror(errno)
    • parcourt de fichier
      • fin : feof(FILE*)
      • erreur : fint ferror(FILE* fichier)
      • remet à zéro les erreurs : void clearerr(FILE* fichier)
      • change la position de la lecture : int fseek(FILE* fichier, long offset, int depart)
        • début de fichier : depart = SEEK_SET
        • position courante : depart = SEEK_CUR
        • fin du fichier : depart = SEEK_END
      • position actuelle : long ftell(FILE* fichier)
      • recommence : void rewind(FILE* fichier)
      • écriture binaire : size_t fwrite(const void* ptr, size_t taille_el, size_t nb_el, FILE* fichier)
      • lecture binaire : size_t fread(void* ptr, size_t taille_el, size_t nb_el, FILE* fichier)
    • fermeture : fclose(FILE*)
  • flots dans chaine
    • sprintf(chaine, FORMAT, variables...)

Librairies

  • fonction de string.h

    • copier : char* strncpy(char* dest, char const* src, size_t n) (ajoute pas forcément le nul de fin)
    • joindre : char* strncat(char* dest, char const* src, size_t n)
    • comparer : int strcmp(char const* s1, char const* s2)
    • comparer : int strncmp(char const* s1, char const* s2, size_t n)
    • taille : size_t strlen(char const * s)
    • rechercher : char* strchr(char const* s, char c)
    • rechercher : char* strrchr(char const* s, char c) (arrière)
    • rechercher : char* strstr(char const* s1, char const* s2) (chaine)
  • fonction de stdio.h

    • prinft("%s", "dsf")
    • puts("yop") (ajoute retour de ligne)
    • put('y')
    • fputs(s, stdout)
    • scanf("%s", s)
    • fgets(s, taille, stdin)
  • standard

    • <assert.h> tests d’assertions pendant l’exécution (désactivés par #define NDEBUG)
    • <ctype.h> divers tests/traitements sur les caractères
      • isalpha, isupper, isspace
    • <errno.h> code d’erreurs retournés dans la bibliothèque standard
    • <float.h> diverses informations sur la représentation des réels
    • <iso646.h> (C95) écriture texte des opérateurs logiques (and, or, ...), digraphes et trigraphes
    • <limits.h> divers tests sur les entiers
    • <locale.h> adaptation à diverses langues
      • char* setlocale(int category, const char* locale)
      • category = LC_ALL, LC_TIME, LC_COLLATE (caractères composés)
      • locale = C, en, french
    • <math.h> divers définitions mathématiques
      • acos, floor, log, sin, pow
      • en cas d'erreur de domaine : errno = EDOM
      • en cas d'overflow : errno = ERANGE et HUGE_VAL est retournée
      • en cas d'underflow : errno = ERANGE (pas toujours le cas) et 0.0 est retourné
    • <setjmp.h> branchement non locaux
    • <signal.h> contrôle des signaux (processus)
    • <stdarg.h> nombre variables d’arguments
      • void f(int nb_args, ...)
      • type : va_list
      • défini ou ça commence : va_start(va_list, nom) (où nom = fonction)
      • termine le traitement : va_end(va_list)
      • argument : type va_arg(va_list, type) renvoit la valeur de l'argument
    void f(int nb_args, ...) {
    	va_list arguments;
    	int j;
    	va_start(arguments, nb_args);
    	for (j = 0; j < nb_args; ++j)
    		printf(" %f\n", va_arg(arguments, double));
    	va_end(arguments);
    }
    • <stddef.h> diverses définitions (types et macros)
    • <stdio.h> entrées sorties de base
    • <stdlib.h> diverses opérations de base utiles
      • malloc, etc.
      • nombres aléatoires
        • int rand() : entre 0 et RAND_MAX
        • graine : void srand(unsigned int seed) (souvent time(NULL) avec time.h)
        • mieux : random entiers ou drand48 (réel [0,1[)
      • conversion de chains
      • math : labs, abs, atoi, atof
      • qsort
    • <string.h> manipulation des chaînes de caractères à la C
    • <time.h> diverses conversions de date et heures
    • <wchar.h> (C95) caractères étendus (« wide chars »), genre UTF-8 (et leurs chaînes)
    • <complex.h> (C99) nombres complexes
    • <fenv.h> (C99) outils pour tester/manipuler les états des nombres à virgule flottante
    • <inttypes.h> (C99) macros pour les stdint
    • <stdbool.h> (C99) booléens
    • <stdint.h> (C99) entiers de tailles définies (int8_t, etc.)
    • <tgmath.h> (C99) « type generic » macro wrapper pour math.h et complex.h
    • <stdalign.h> (C11) macro pour alignement mémoire de struct
    • <stdatomic.h> (C11) types atomiques (multi-threading)
    • <stdnoreturn.h> (C11) noreturn macro pour fonctions
    • <threads.h> (C11) multi-threading
    • <uchar.h> (C11) UTF-16 & UTF-32

Compilation

  • macro : #define alias ( arguments ) séquence_à_récrire
    • toujours mettre en parenthèse
    • peut prendre des arguments
    • prédéfinies
      • __LINE__
      • __FILE__
      • __DATE__ : compilation
      • __TIME__ : compilation
      • __STDC__ : 1 si conforme avec le standard
  • compilation conditionnelle : #if expression #ifdef identificateur #ifndef identificateur #elif #else #endif
  • modularité
    • déclaration (.h) : compilation de source à objet
    • définition (.c) : édition des liens
    • en toute rigueur les prototypes devraient être externe : #ifndef QCM_C extern #endif
    • éviter la redondance et dépendence entre les modules
    • compatiblité C++ : #ifdef __cplusplus extern "C" { #endif
  • code objet : code partiel et tables d'adressage
    • table d'exportation : objets globaux (variables et fonctions)
    • table d'importation : objets référencés (mais adresse inconnue)
    • table des tâches : liste des endroits dans le code où se trouvent les adresses à résoudre
  • chargeur (OS) : résoud les derniers liens et ambiguïtés liées au placement effectif en mémoire du programme
  • précompilation (gcc -E)
    • substituer les macros
    • choisir les lignes de compilation conditionnelle
    • inclure les fichiers demandés
  • compilation (gcc -S) : en code assembleur
  • assemblage (gcc -c) : en code objet
  • édition de liens (ld): entre les différents codes objets
  • makefile
    • make but
    • commentaire : # comm
    • règle : but: dépendances <TAB> commande
    • variables prédéfinies
      • but : $@
      • dépendances plus à jour : $?
      • dépendances par défaut : $<
      • liste des dépendances (GNU make) : $^
      • nom du compilateur : $(CC)
      • options de compilation : $(CFLAGS)
      • options du linker : $(LDFLAGS)
      • librairies à ajouter : $(LDLIBS)
    • compilation par défaut : $(CC) -c $(CPPFLAGS) $(CFLAGS) $< (.c -> .o)
    • liens par défaut : $(CC) -o $@ $(LDFLAGS) $ˆ $(LDLIBS)
CC = gcc
CFLAGS = -ansi -g -Wall
LDFLAGS =
LDLIBS = -lm
RM = /bin/rm -f
TARGETS = bidulemachin
OBJS = *.o
RUBS = $(OBJS) *~ core \#*\#
all: $(TARGETS)
	@echo All done.
clean:
	-@$(RM) $(RUBS)
	@echo Cleaned.
new: clean
	-@$(RM) $(TARGETS)
	$(MAKE) all
  • debugging
    • erreurs de syntax
    • erreurs de conceptions
    • erreurs d'implémentation
    • erreurs d'algorithms
    • déverminage pour les 2 derniers
    • compiler avec l'option -g et lancer ddd monprogram
  • optimisation
    • affection : $\log(n)$
    • aditions : $\log(n)$
    • multiplications : $\log(n)\log^2(n)\log^3(n)$
    • décalages : $\log(n)$
  • profiling : compiler avec l'option -pg et lancer gprof monprogram

Normes

  • C89 : gcc -ansi
    • variable déclarée en tête de bloc
    • ne supporte pas %lf
  • C99 : gcc -std=c99
    • long long int
    • double complex, double imaginary (complex.h)
    • bool (stdbool.h)
    • float (float.h)
    • int8_t, uint16_t (stdint.h)
    • VLA : variable length array (taille non connu à la compilation)
    • litérale de tableau/structure : (double[2]){ 1.2, 2.4 }
  • C11 : gcc -std=c11