dianceh te réponds partiellement, mais avec une erreur malheureusement assez répandue.
Lorsque tu utilises #include <machin.h> ou "machin.h" tu ne demande pas au compilateur d'aller chercher une librairie, tu lui demande d'insérer,
avant la compilation, un fichier source nommé machin.h en remplacement de la ligne #include ... .
La différence entre " " et <> est assez subtile, mais en première analyse, on peut dire que si tu utilises <...>, le compilateur va rechercher le fichier dans ses répertoires de travail, puis ensuite, éventuellement dans ton espace de travail (répertoire courant par defaut, mais tu peux spécifier d'autres répertoires par paramètre du compilateur). Si tu utilises "..." il va chercher uniquement dans ton espace de travail, mais les choses sont un peu plus compliquée et tu peux jouer très finement avec les paramètres du compilateur.
Mais ceci ne te donne en aucun cas accès à une librairie. Cet accès se fait au moment de l'édition des liens (link-edit), je sais la mauvaise habitude qui est prise d'enseigner la programmation avec des environnements intégrés fait que les gens n'ont pratiquement plus idée de ce qu'est le link-edit. Pour faire simple, c'est une phase qui se fait après la traduction en langage machine et qui consiste à mettre ensemble différents bouts de programme en langage machine relogeable (dont certaines adresses ne sont pas encore fixées, le bout de programme peuvent encore être déplacé en mémoire).
En résumé, une compilation C, d'un programme ttt.c sous Linux se fait avec une série de programmes (gcc n'est qu'un script qui regroupe ces phases):
1) Le pré-processeur
Lit le programme écrit par le programmeur et résoud toute les instructions pré-processeurs (celles commençant par un # en colonne 1), donc, dans ton cas le #include. Il produit un fichier appelé ttt.i qui ne contient que du langage C, débarassé des instructions pré-processeurs. Par paramètre, on peut arrêter la compilation à ce stade, par exemple pour "debugger" des instructions pré-processeur un peu rêtives, comme des macros ou des compilations conditionnels un peu torchées.
2) Le compilateur
Lit le fichier ttt.i (du langage C donc), et le traduit (avec optimisation) en langage assembler. Ce langage assembler est contenu dans le fichier ttt.s. Par paramètre, on peut arrêter la compilation à ce stade, par exemple pour venir modifier le langage assembler générer par le compilateur. Par exemple pour écrire des interfaces avec le matériel, c'est parfois nécessaire (de moins on moins heureusement). Inutile de te dire qu'il faut évidemment bien connaître le langage assemble et la façon dont le compilateur génère les instructions assembler. Le ficher ttt.i est détruit à la fin de cette phase. Par paramètre, tu peux demander à le conserver.
3) L'assembler
Traduit le fichier ttt.s (du langage assembler donc) et le traduit en langage machine binaire (en général sur une base 1 instruction assembler donne 1 instruction machine). Comme dit plus haut, ce langage machine est relogeable. Le fichier produit s'appelle ttt.o. Le ficher ttt.s est détruit à la fin de cette phase. Par paramètre, tu peux demander à le conserver.
4) Le link-édit, va prendre le fichier ttt.o ainsi que d'autres fichiers *.o utilisés par ttt.o plus les librairies statiques utilisées par ttt.o pour en faire un programme qui peut être chargé en mémoire. Pour chaque demande de librairie partagée (ou dynamique), il génére un petit code d'appel qui sera utilisé lors de l'exécution. Il produit un exécutable appelé a.out. Par paramètre, tu peux changer ce nom.
Donc, dans ton cas particulier, tu dois mettre dans ton source la ligne
#include <math.h>
cela aura pour effet de venir insérer dans ton programme les prototypes des fonctions mathématiques.
Puis, tu dois dire au link-edit que tu souhaites utiliser la librairie libm.o. Pour ce faire, en appelant gcc, tu rajoute l'option:
-lm
(gcc va automatiquement rajouter lib !)
Voilà, j'ai essayé d'être concis (ça n'est pas toujours évident) et clair (c'est encore moins évident).