i ntroduction au c. l angage c: www. developpez. com chaque fichier source entrant dans la...
Post on 04-Apr-2015
110 Views
Preview:
TRANSCRIPT
INTRODUCTION AU C
LANGAGE C: WWW.DEVELOPPEZ.COM
Chaque fichier source entrant dans la compositiond'un programme exécutable est fait d'une succession d'un nombre quelconque d'éléments indépendants, qui sont : des directives pour le préprocesseur (lignes
commençant par #), des constructions de types (struct, union,
enum, typedef), des déclarations de variables et de fonctions
externes, des définitions de variables et des définitions de fonctions.
INTRODUCTION AU LANGAGE C
En C on n'a pas une structure syntaxique englobant tout, comme en Pascale.
La règle généralement suivie par l'éditeur de liens est la suivante : parmi les fonctions données il doit en exister une
dont le nom est main
Bloc = suite d’instructions encadrés par {………}
#include <stdio.h>int main() {printf("Bonjour\n");return 0;}
#include <stdio.h>void main() {printf("Bonjour\n");}
MOTS CLÉS
Mots réservés au langage:auto break case char
const continue default dodouble else enum extern float
for goto If int long register return short signed sizeof
static struct switchtypedef union unsigned void volatile while
Commentaires : /* ceci est un commentaire */
IDENTIFICATEURS
Un identificateur est une suite de lettres et chiffres contigus, dont le premier est une lettre
une lettre majuscule est tenue pour différente de la lettre minuscule correspondante
Le caractère _ (appelé « blanc souligné ») est considéré comme une lettre
OPÉRATEURS
Symboles simples : ( ) [ ] . ! ~
< > ? : = , + - * / % |
& ^ Symboles composés :
-> ++ -- <= >= == != && || << >>
+= -= *= /= %= <<= >>= |= &= ^=
CARACTERE ET CHAINE DE CARACTERES
Une constante de type caractère se note en écrivant le caractère entre apostrophes. Une constante de type chaine de caractères se note en écrivant ses caractères entre guillemets.
Exemples, trois caractères : 'A' '2' ' " ' Quatre chaines de caractères : "A"
"Bonjour" " " " ' "
CARACTERES NON IMPRIMABLES
\n : nouvelle ligne (LF) \t : tabulation (HT) \b : espace-arrière (BS) \r : retour-chariot (CR) \f : saut de page (FF) \a : signal sonore (BELL) \\ : \ • ' : ' • " : " • \d3d2d1 : le caractère qui a pour code le nombre
octal d3d2d1. Exemple : "A\033B\"C\fD\\E«
033=27, Ascii 27 = escape
NOMBRE ENTIER
unsigned short : 16 bits pour représenter un nombre entier compris entre 0 et 65.535
short : 16 bits pour représenter un nombre entier compris entre -32.768 et 32.767
unsigned long : 32 bits pour représenter un nombre entier entre 0 et 4.294.967.296
long : 32 bits pour représenter un entier entre -2.147.483.648 et 2.147.483.647
Int = short; long.
NOMBRES FLOAT La norme ANSI prévoit trois types de nombres
flottants : float (simple précision), double (double précision) et long double (précision étendue).
Typiquement, sur des systèmes de taille moyenne, un float occupe 32 bits et un double 64
Les long double correspondent généralement aux flottants de grande précision manipulés par certains coprocesseurs arithmétiques ou les bibliothèques de sous-programmes qui les simulent. Mais il n'est pas exclu que sur un système particulier un long double soit la même chose qu'un double.
DECLARATION
Dans le cas le plus simple on a spécification var-init , var-init , ... var-
init ;ou spécification est de la forme :
Var-init :
Exemple :
Les déclarations de variables peuvent se trouver : en dehors de toute fonction, il s'agit alors de
variables globales ; à l'intérieur d'un bloc, il s'agit alors de variables
locales ; dans l'en-tête d'une fonction, il s'agit alors
d'arguments formels,
int x, y = 0, z;float a, b;unsigned short cpt = 1000;
OPÉRATEURS ARITHMÉTIQUES
Addition Soustraction Multiplication Division Modulo
expr1 / expr2
• si expr1 et expr2 sont toutes deux entières alors « / » est traduit par l'opération « division entière », et le résultat est entier,• si au moins une des expressions expr1 ou expr2 n'est pas entière, alors l'opération faite est la division flottante des valeurs de expr1 et expr2 toutes deux converties dans le type double. Le résultat est une valeur double qui approche le rationnel expr1.
COMPARAISON
égal, différent, inférieur, inférieur ou égal, supérieur, supérieur ou égal
CONNECTEURS LOGIQUES
Conjonction Disjonction
Pour évaluer exp1 && exp2 : exp1 est évaluée d'abord et• si la valeur de exp1 est nulle, exp2 n'est pas évaluée et
exp1 && exp2 vaut 0 ;• sinon exp2 est évaluée et exp1 && exp2 vaut 0 ou 1
selon que la valeur de exp2 est nulle ou non.
Pour évaluer exp1 || exp2 : exp1 est évaluée d'abord et• si la valeur de exp1 est non nulle, exp2 n'est pas évaluée
et exp1 || exp2 vaut 1 ;• sinon exp2 est évaluée et exp1 || exp2 vaut 0 ou 1 selon
que la valeur de exp2 est nulle ou non.
NEGATION
!exp
++ ET --
post-incrémentation : exp++ exp doit être de type numérique (entier ou
flottant) ou pointeur. pré-incrémentation : ++exp
exp doit être de type numérique (entier ou flottant) ou pointeur.
Exemple. y = x++ ; y = x ; x = x + 1 ; y = ++x ; x = x + 1 ; y = x ;
INSTRUCTIONS: AFFECTATION
Affectation: Var = expression
Une affectation a une valeur
A=b=c=0 est équivalente a A=(b=(c=0))
A=0;b=0;c=0;
Exemple X=5Y=5+ 3
AUTRES AFFECTATIONS
si OP représente l'un des opérateurs + - * / % >> << & ^ |, alors
exp1 OP= exp2
peut être vue comme ayant la même valeur et le même effet que
exp1 = exp1 OP exp2
Exemple
double puissance(double x, int n) {double p = 1;while (n != 0) {if (n % 2 != 0) /* n est-il impair ? */
p *= x;x *= x;n /= 2;}return p;}
If … else….if (expression)instruction1elseInstruction2
if (expression)instruction1
if (x<0) printf(" nombre negatif " );elseprintf(" nombre positif ");
•if (moy>=10)printf(" admis ");
On résoud le problème avecif (nombrePersonnes != 0)if (nombrePersonnes != nombreAdultes)printf("Il y a des enfants!");else;elseprintf("Il n'y a personne!");
if (nombrePersonnes != 0)if (nombrePersonnes != nombreAdultes)printf("Il y a des enfants!");elseprintf("Il n'y a personne!");
Ou bien avec
if (nombrePersonnes != 0) {if (nombrePersonnes != nombreAdultes)printf("Il y a des enfants!");};elseprintf("Il n'y a personne!");
WHILE ET DO…WHILE
while (expression)Instruction
Doinstructionwhile
(expression);
INSTRUCTION FOR
for ( expr1 ; expr2 ; expr3 )Instruction
expr1 est l'expression qui effectue les initialisations nécessaires avant l'entrée dans la boucle ;
expr2 est le test de continuation de la boucle ; il est évalué avant l'exécution du corps de la boucle ;
expr3 est une expression (par exemple une incrémentation) évaluée à la fin du corps de la
expr1 ;while (expr2) {instructionexpr3;}
INSTRUCTION FOR
Exemple
for (i = 0; i < 10; i++)t[i] = 0;
i=0;while (i<10){t[i] = 0;i++;}
INSTRUCTION SWITCH
switch ( expression )Corps
Le corps de l'instruction switch prend la forme d'un bloc f...g renfermant une suite d'instructions entre lesquelles setrouvent des constructions de la forme
case expression-constante :
Ou bien
default :
Exemple
j=0;switch (i) {case 3:j++;case 2:j++;case 1:j++;}
POINTEURS
Un pointeur est une variable dont la valeur est l'adresse d'une cellule de la mémoire.
Déclaration: type *variable
Référence *variable
Opération & : obtention de l'adresse d'un objet occupant un emplacement de la mémoire
Exemple : type x, *p; p=&x;
EXERCICES
Ecrire le programme C qui calcule la somme des 10 premiers nombres à partir de 0
Ecrire le programme C qui calcule le factoriel de 25.
LECTURE/ECRITURE
La bibliothèque standard <stdio> contient un ensemble de fonctions qui assurent la communication de la machine avec le monde extérieur. Les plus importantes:
printf() : écriture formatée de données scanf() : lecture formatée de données putchar() : écriture d'un caractère getchar() : lecture d'un caractère
ECRITURE printf() : utilisée pour transférer du texte, des valeurs
de variables ou des résultats d'expressions vers le fichier de sortie standard stdout (par défaut l'écran).
printf("<format>",<Expr1>,<Expr2>, ... )
"<format>" : format de représentation.Les spécificateurs de format commencent toujours par le symbole % et se terminent par un ou deux caractères qui indiquent le format d'impression.
<Expr1>,... : variables et expressions dont les valeurs sont à représenter
char B = 'A'; printf("Le caractère %c a le code %i !\n", B, B); va afficher sur l'écran: Le caractère A a le code 65 !
Spécification de format printf:
Pour pouvoir traiter correctement les arguments du type long, il faut utiliser les spécificateurs %ld, %li, %lu, %lo, %lx.
SYMBOLE TYPE IMPRESSION COMME
%d ou %i int entier relatif
%u int
entier naturel (unsigned)
%o int entier exprimé en octal
%x int entier exprimé en hexadécimal
%c char Caractère
%f floatrationnel en notation décimale
%e float rationnel en notation scientifique
%s char* chaîne de caractères
Les spécificateurs %f et %e peuvent être utilisés pour représenter des arguments du type float ou double. La mantisse des nombres représentés par %e contient exactement un chiffre (non nul) devant le point décimal. Cette représentation s'appelle la notation scientifique des rationnels.
Pour pouvoir traiter correctement les arguments du type long double, il faut utiliser les spécificateurs %Lf et %Le.
Exemple float N = 12.1234; double M = 12.123456789; long double P = 15.5;
printf("%f", N); ==> 12.123400 printf("%f", M); ==> 12.123457 printf("%e", N); ==> 1.212340e+01 printf("%e", M); ==> 1.212346e+01 printf("%Le", P); ==> 1.550000e+01
LECTURE
scanf() : symétrique à printf; elle nous offre pratiquement les mêmes conversions que printf, mais en sens inverse.
scanf("<format>",<AdrVar1>,<AdrVar2>, ...) <format>: format de lecture des données
<AdrVar1>,… : adresses des variables auxquelles les données seront attribuées
Les données reçues correctement sont mémorisées successivement aux adresses indiquées par <AdrVar1>,... .
L'adresse d'une variable est indiquée par le nom de la variable précédé du signe &.
Lors de l'entrée des données, une suite de signes d'espacement (espaces, tabulateurs, interlignes) est évaluée comme un seul espace. Dans la chaîne de format, les symboles \t, \n, \r ont le même effet qu'un simple espace.
Exemple int JOUR, MOIS, ANNEE; scanf("%i %i %i", &JOUR, &MOIS, &ANNEE);
les entrées suivantes sont correctes et équivalentes: 12 4 1980 ou 12 004 1980 ou 12 4 1980
Exemple
int JOUR, MOIS, ANNEE; scanf("%i/%i/%i", &JOUR, &MOIS, &ANNEE);
accepte rejette12/4/1980 12 4 1980
12/04/01980 12 /4 /1980
ECRITURE D’UN CARACTERE
putchar('a'); transfère le caractère a vers le fichier standard
de sortie stdout. Les arguments de la fonction putchar sont ou bien des caractères (c.-à-d. des nombres entiers entre 0 et 255) ou bien le symbole EOF (End Of File).
Exemples char A = 225; char B = '\a'; int C = '\a';putchar('x'); /* afficher la lettre x */ putchar('?'); /* afficher le symbole ? */ putchar('\n'); /* retour à la ligne */ putchar(65); /* afficher le symbole avec le code 65
(ASCII: 'A') */
Les valeurs retournées par getchar sont ou bien des caractères (0 - 255) ou bien le symbole EOF.
Comme la valeur du symbole EOF sort du domaine des caractères, le type résultat de getchar est int.
En général, getchar est utilisé dans une affectation:
int C; C = getchar();
FONCTIONS TypeRés NomFonct (TypePar1 NomPar1 , TypePar2
NomPar2, ... ) { déclarations locales instructions
}
Exemple :int MAX(int N1, int N2) {
if (N1>N2) return N1; else return N2;
}
Si une fonction ne fournit pas de résultat, il faut indiquer void (vide) comme type du résultat.
Si une fonction n'a pas de paramètres, on peut déclarer la liste des paramètres comme (void) ou simplement comme () .
Le type par défaut est int; autrement dit: si le type d'une fonction n'est pas déclaré explicitement, elle est automatiquement du type int.
Il est interdit de définir des fonctions à l'intérieur d'une autre fonction (comme en Pascal).
La fonction principale main est du type int. Elle est exécutée automatiquement lors de l'appel du programme.
int main(void)
PROTOTYPE D'UNE FONCTION
Toute fonction doit être déclarée avant son utilisation.
La déclaration d'une fonction se fait par un prototype de la fonction qui indique uniquement le type des données transmises et reçues par la fonction.
Déclaration : Prototype d'une fonction
TypeRés NomFonct (TypePar1 , TypePar2 , ... );
ou bien
TypeRés NomFonct (TypePar1 NomPar1 , TypePar2 NomPar2, ... );
RÈGLES POUR LA DÉCLARATION DES FONCTIONS De façon analogue aux déclarations de variables, nous
pouvons déclarer une fonction localement ou globalement.
Déclaration locale: Une fonction peut être déclarée localement dans la fonction qui l'appelle (avant la déclaration des variables). Elle est alors disponible à cette fonction.
Déclaration globale: Une fonction peut être déclarée globalement au début du programme (derrière les instructions #include). Elle est alors disponible à toutes les fonctions du programme.
Déclaration implicite par la définition:La fonction est automatiquement disponible à toutes les fonctions qui suivent sa définition.
APPEL DES FONCTIONS
L'appel d'une fonction se fait en écrivant son nom, suivi d'une paire de parenthèses contenant éventuellement une liste d'arguments effectifs.
Exemple: Déclaration
type nom_fonction ( type1 arg_formel1 , ... typek arg_formelk )
Appel nom_fonction ( arg_effectif 1 , ... arg_effectif k )
Transmission des valeurs des argumentsarg_formel1 = arg_effectif 1...arg_formelk = arg_effectif k
ARGUMENTS DES FONCTIONS
Passage des arguments:L'idée maitresse est qu'en C le passage des arguments des fonctions se fait toujours par valeur. Après avoir fait les conversions opportunes la valeur de chaque argument effectif est affectée à l'argument formel correspondant.
EXEMPLEvoid ETOILES(int N) { while (N>0) { printf("*"); N--; } printf("\n"); }
La fonction TRIANGLE, appelle la fonction ETOILES en utilisant la variable L comme paramètre:
void TRIANGLE(void) { int L; for (L=1; L<10; L++) ETOILES(L); }
PASSAGE PAR ADRESSE
Pour changer la valeur d'une variable de la fonction appelante, nous devons procéder comme suit: - la fonction appelante doit fournir l'adresse de
la variable et - la fonction appelée doit déclarer le paramètre
comme pointeur.
On peut alors atteindre la variable à l'aide du pointeur.
EXEMPLE
void PERMUTER (int *A, int *B) { int AIDE; AIDE = *A; *A = *B; *B = AIDE; }
Nous appelons la fonction par: PERMUTER(&X, &Y);
Résultat: Le contenu des variables X et Y est échangé.
PASSAGE D’ADRESSE D’UN TABLEAU
En général, on fournit l'adresse du premier élément du tableau, qui est donnée par le nom du tableau.
Dans la liste des paramètres d'une fonction, on peut déclarer un tableau par le nom suivi de crochets, type nom []
ou simplement par un pointeur sur le type des éléments du tableau: type *nom
Considérons la situation suivante: La fonction main appelle la fonction FA. La fonction FA appelle la fonction FB.
Nous obtenons donc la hiérarchie suivante:
A) DÉCLARATIONS LOCALES DES FONCTIONS ET DÉFINITION 'TOP-DOWN'/* Définition de main */ main() { /* Déclaration locale de FA */
int FA (int X, int Y); ... /* Appel de FA */ I = FA(2, 3); ...
} /* Définition de FA */ int FA(int X, int Y) {
/* Déclaration locale de FB */ int FB (int N, int M); ... /* Appel de FB */ J = FB(20, 30); ...
} /* Définition de FB */ int FB(int N, int M) { ... }
DÉFINITION 'BOTTOM-UP' SANS DÉCLARATIONS La définition 'bottom-up' commence en bas de la hiérarchie: La fonction main
se trouve à la fin du fichier. Les fonctions qui traitent les détails du problème sont définies en premier lieu.
/* Définition de FB */ int FB(int N, int M) { ... }
/* Définition de FA */ int FA(int X, int Y) { ... /* Appel de FB */ J = FB(20, 30); ... } /* Définition de main */ main() { ... /* Appel de FA */ I = FA(2, 3); ... }
DÉCLARATION GLOBALE DES FONCTIONS ET DÉFINITION 'TOP-DOWN'/* Déclaration globale de FA et FB */ int FA (int X, int Y); int FB (int N, int M); /* Définition de main */ main() { ... /* Appel de FA */ I = FA(2, 3); ... } /* Définition de FA */ int FA(int X, int Y) { ... /* Appel de FB */ J = FB(20, 30); ... } /* Définition de FB */ int FB(int N, int M) { ... }
1)DÉFINIR LA HIÉRARCHIE DES APPELS POUR LES 3 FONCTIONS2)DÉFINIR LES FONCTIONS SELON LES TROIS MÉTHODES EN AJOUTANT LES DÉCLARATIONS MANQUANTES
#include <stdio.h> main() { float R; printf("Introduire le rayon du cercle : "); scanf("%f",
&R); printf("La surface du cercle est %f. \n", SURFACE(R)); return 0; } double PI(void) { return 3.14159265; } double SURFACE(float RAYON) { return PI()*RAYON*RAYON; }
INSTRUCTION RETURN
1) return expression ;Ou bien 2) return ;
l'instruction return provoque l'abandon de la fonction en cours et le retour à la fonction appelante.
Dans la forme 1) expression est évaluée ; son résultat est la valeur que la fonction renvoie à la fonctionappelante
TABLEAUX
Déclaration : type indent [taille] Exemple : tableau de 5 entiers : int t[5]
En C, le nom d'un tableau est le représentant de l'adresse du premier élément du tableau. Les adresses des autres composantes sont calculées (automatiquement) relativement à cette adresse.
short A[5] = {1200, 2300, 3400, 4500, 5600};
INITIALISATION Lors de la déclaration d'un tableau, on peut initialiser les
composantes du tableau, en indiquant la liste des valeurs respectives entre accolades.
Exemples int A[5] = {10, 20, 30, 40, 50}; float B[4] = {-1.05, 3.33, 87e-5, -12.3E4}; int C[10] = {1, 0, 0, 1, 1, 1, 0, 1, 0, 1};
Il faut évidemment veiller à ce que le nombre de valeurs dans la liste corresponde à la dimension du tableau. Si la liste ne contient pas assez de valeurs pour toutes les composantes, les composantes restantes sont initialisées par zéro.
Réservation automatique Si la dimension n'est pas indiquée explicitement lors de
l'initialisation, alors l'ordinateur réserve automatiquement le nombre d'octets nécessaires.
Exemples int A[] = {10, 20, 30, 40, 50}; ==> réservation de 5*sizeof(int) octets (dans notre cas: 10 octets)
En déclarant un tableau par: int A[5]; nous avons défini un tableau A avec cinq composantes, auxquelles on peut accéder par: A[0], A[1], ... , A[4]
Important Considérons un tableau T de dimension N: - l'accès au premier élément du tableau : T[0] - l'accès au dernier élément du tableau : T[N-1]
TABLEAUX À DEUX DIMENSIONS
On appelle L le nombre de lignes du tableau et C le nombre de colonnes du tableau. L et C sont alors les deux dimensions du tableau. Un tableau à deux dimensions contient donc L*C composantes.
Déclaration : type identif [nbre_Ligne][nbre_Col];
Exemple float B[2][20];
Les composantes d'un tableau à deux dimensions sont stockées ligne par ligne dans la mémoire.
Lors de la déclaration d'un tableau, on peut initialiser les composantes du tableau, en indiquant la liste des valeurs respectives entre accolades.
Exemples int A[3][10] ={{ 0,10,20,30,40,50,60,70,80,90},
{10,11,12,13,14,15,16,17,18,19}, { 1,12,23,34,45,56,67,78,89,90}
};
Accès : Identif [Ligne][Colonne]
Première ligne, première colonne : Identif[0][0]
Dernière ligne; dernière colonne : Identif[L-1][C-1]
top related