Vous n'êtes pas identifié(e).
L'icône rouge permet de télécharger chaque page du wiki visitée au format PDF et la grise au format ODT →
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
utilisateurs:hypathie:tutos:memo-c [19/08/2014 07:25] Hypathie [Variables] |
utilisateurs:hypathie:tutos:memo-c [30/11/2014 07:39] Hypathie [mémo-C] |
||
---|---|---|---|
Ligne 4: | Ligne 4: | ||
* Niveau requis : {{tag>débutant avisé}} | * Niveau requis : {{tag>débutant avisé}} | ||
+ | |||
+ | Référence : [[http://www.squalenet.net/fr/ti/tutorial_c/sommaire.php5]] | ||
===== Introduction ===== | ===== Introduction ===== | ||
===installation gcc sous debian=== | ===installation gcc sous debian=== | ||
Ligne 91: | Ligne 93: | ||
<code>gcc -o nom-exécutable nom fichier-à-compiler</code> | <code>gcc -o nom-exécutable nom fichier-à-compiler</code> | ||
- | <code user>gcc main.x main.c</code> | + | <code user>gcc -o main.x main.c</code> |
<code user>ls</code> | <code user>ls</code> | ||
<code> | <code> | ||
Ligne 144: | Ligne 146: | ||
valeur age: 23 valeur taille: 175 | valeur age: 23 valeur taille: 175 | ||
</code> | </code> | ||
+ | |||
====char : caractère, chaîne de caractères ==== | ====char : caractère, chaîne de caractères ==== | ||
Ligne 1054: | Ligne 1057: | ||
=====Fonctions ===== | =====Fonctions ===== | ||
- | ====Explications ==== | + | ====Fonction "main" et fonction utilisateur ==== |
* Reprenons le code de base : | * Reprenons le code de base : | ||
<code c> | <code c> | ||
Ligne 1097: | Ligne 1101: | ||
> On peut aussi inscrire : **''void bonjour(void){''**. | > On peut aussi inscrire : **''void bonjour(void){''**. | ||
+ | <note tip> | ||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | </code> | ||
+ | > ce qui commence par un "#" sont des instructions pour le compilateur | ||
+ | > "include" : inclure -> inclure le fichier "stdio.h" | ||
+ | > c'est un fichier qui contient des commandes | ||
+ | > une commande comme printf se trouve dans le fichier "stdio.h" | ||
+ | </note> | ||
====Passer des éléments à une fonction ==== | ====Passer des éléments à une fonction ==== | ||
===explications=== | ===explications=== | ||
Ligne 1234: | Ligne 1246: | ||
</code> | </code> | ||
+ | =====Les pointeurs ===== | ||
+ | ====Définitions==== | ||
+ | __**Un pointeur est un objet Lvalue**__((left value : tout objet pouvant être placé à gauche d'un opérateur d'affectation.)) dont la valeur est égale à l'adresse d'un autre objet.\\ On déclare un pointeur par l'instruction : **''type *nom-du-pointeur;''**, où "type" est le type de l'objet pointé.\\ | ||
- | =====Les pointeurs ==== | + | Cette déclaration déclare un **identificateur**, nom-du-pointeur, associé à un objet dont la **valeur est l'adresse d'un autre objet de type "type"**.\\ |
- | ===Déclarer un pointeur === | + | |
+ | L'**identificateur nom-du-pointeur** est donc en quelque sorte un **identificateur d'adresse**. Comme pour n'importe quelle Lvalue\\ | ||
+ | |||
+ | __Une **Lvalue** est caractérisée par__ : | ||
+ | |||
+ | * **son adresse**, c'est-à-dire l'adresse-mémoire à partir de laquelle l'objet est stocké ; | ||
+ | * **sa valeur**, c'est-à-dire ce qui est stocké à cette adresse; sa valeur est modifiable. | ||
+ | |||
+ | Si le compilateur a placé la variable **''i''** à l'adresse 4831836000 en mémoire, et la variable **''j''** à l'adresse 4831836004, on a : | ||
+ | |||
+ | ^objet ^adresse ^valeur ^ | ||
+ | |i | 4831836000 | 3 | | ||
+ | |j | 4831836004 | 3 | | ||
+ | |||
+ | * Deux variables différentes ont des adresses différentes.\\ | ||
+ | L'affectation **''i = j;''** n'opère que sur les **valeurs** des variables.\\ | ||
+ | Les variables i et j étant de type **''int''**, elles sont stockées sur 4 octets.\\ | ||
+ | Ainsi la valeur de i est stockée sur les octets d'adresse 4831836000 à 4831836003.\\ | ||
+ | |||
+ | * Pour **un pointeur sur un objet de type char**, la valeur donne l'adresse de l'octet où cet objet est stocké. | ||
+ | |||
+ | * **L'opérateur ''&''** permet d'accéder à l'adresse d'une variable.\\ | ||
+ | Toutefois **''&i''** n'est pas une "Lvalue" mais une "constante" : on ne peut pas faire figurer **''&i''** à gauche d'un opérateur d'affectation.\\ | ||
+ | Pour pouvoir manipuler des adresses, on doit donc recourir un nouveau type d'objets, les **pointeurs**. | ||
+ | * **L'opérateur unaire d'indirection ''*''** permet d'accéder directement __à la valeur de l'objet pointé__.\\ | ||
+ | Ainsi, si **''p''** est un pointeur vers un entier **''i''**, **''*p''** désigne la **''valeur de i''**. | ||
+ | |||
+ | ===Exemple=== | ||
<code c> | <code c> | ||
- | int *p; | + | #include<stdio.h> |
- | p=&a | + | main() |
+ | { | ||
+ | int i = 3; | ||
+ | int *p; | ||
+ | |||
+ | p = &i; | ||
+ | printf("*p = %d \n",*p); | ||
+ | } | ||
+ | </code> | ||
+ | <code> | ||
+ | *p = 3 | ||
</code> | </code> | ||
- | <note tip> | + | On se trouve dans la configuration : |
- | * **''<nowiki>*</nowiki>''** : signifie pointeur | + | |
- | * **''<nowiki>*p</nowiki>''** : pointeur (*) est déclaré sous le nom de "p" | + | |
- | * **''<nowiki>int *p</nowiki>''** : le pointeur "p" pointe vers un entier (int) | + | |
- | * **''<nowiki>p=&a</nowiki>''** : le pointeur "p" a l'adresse (&) de "a" | + | |
- | * **''FONCTION1(type*n) ...FONCTION2(&m)''** :\\ signifie que la variable "n", de la FONCTION1, prend la valeur la variable "m", de la FONCTION2 | + | |
- | </note> | + | ^objet ^adresse ^valeur ^ |
+ | |i | 4831836000 | 3 | | ||
+ | |p | 4831836004 | 4831836000 | | ||
+ | |*p | 4831836000 | 3 | | ||
- | ===Exemples === | + | Pour aller plus loin, voir [[https://www.rocq.inria.fr/secret/Anne.Canteaut/COURS_C/chapitre3.html]] |
+ | |||
+ | ====Créer une fonction "inverser" avec des pointeurs ==== | ||
<code c> | <code c> | ||
Ligne 1305: | Ligne 1357: | ||
</note> | </note> | ||
+ | ====tableau bis ==== | ||
+ | Un tableau est pointeur qui pointe vers le premier élément du tableau. | ||
+ | ===tableau int=== | ||
+ | <code c> | ||
+ | #include<stdio.h> | ||
+ | int main(void){ | ||
+ | int tab[10]; | ||
+ | tab[0]=10; | ||
+ | tab[1]=20; | ||
+ | tab[2]=30; | ||
+ | printf("%d\t%d\t%d\n",tab[0],tab[1],tab[2]); | ||
+ | printf("%d\n",*(tab)); | ||
+ | printf("%d\n",*(tab+1)); | ||
+ | printf("%d\n",*(tab+2)); | ||
+ | printf("%d\n",*(tab+3)); | ||
+ | printf("\n"); | ||
+ | *(tab+2)=60; | ||
+ | printf("%d\n",tab[2]); | ||
+ | printf("\n"); | ||
+ | tab[2]=55; | ||
+ | printf("%d\n",*(tab+2)); | ||
+ | printf("%d\n",tab[2]); | ||
+ | } | ||
+ | </code> | ||
+ | <code> | ||
+ | 10 20 30 | ||
+ | 10 | ||
+ | 20 | ||
+ | 30 | ||
+ | 0 | ||
+ | 60 | ||
+ | 55 | ||
+ | |||
+ | </code> | ||
+ | |||
+ | >**''*tab''** : ce qui est pointé par tab | ||
+ | >**''tab[0]''** : premier élément du tableau | ||
+ | >**'' *(tab+2)''** et **''tab[2]''** ont la même valeur, on peut modifier la valeur par le biais de **''tab[2]''** ou de **'' *(tab+2)''**. | ||
+ | >**''*(tab+1)''** : premier élément du tableau + 4 octets (entier sur 4 octets), c'est-à-dire valeur du deuxième élément du tableau (le premier est ''tab[0]'' ou ''*(tab+0)'' ) | ||
+ | >**''*(tab+2)''** : premier élément du tableau + 8 octets, c'est-à-dire valeur du troisième élément du tableau. | ||
+ | > etc. | ||
+ | ===tableau char=== | ||
+ | |||
+ | <code c> | ||
+ | #include<stdio.h> | ||
+ | int main(void){ | ||
+ | char tab[27]; | ||
+ | tab[0]='a'; | ||
+ | tab[1]='b'; | ||
+ | tab[3]='c'; | ||
+ | tab[4]='d'; | ||
+ | tab[5]='e'; | ||
+ | tab[6]='f'; | ||
+ | tab[7]='g'; | ||
+ | tab[8]='h'; | ||
+ | tab[9]='i'; | ||
+ | tab[10]='j'; | ||
+ | tab[11]='k'; | ||
+ | tab[12]='l'; | ||
+ | tab[13]='m'; | ||
+ | tab[14]='n'; | ||
+ | tab[15]='o'; | ||
+ | tab[16]='p'; | ||
+ | tab[17]='q'; | ||
+ | tab[18]='r'; | ||
+ | tab[19]='s'; | ||
+ | tab[20]='t'; | ||
+ | tab[21]='u'; | ||
+ | tab[22]='v'; | ||
+ | tab[23]='w'; | ||
+ | tab[24]='x'; | ||
+ | tab[26]='y'; | ||
+ | tab[27]='z'; | ||
+ | printf("%c\t %c\t %c\t %c\t %c\t %c\n",tab[0],tab[5],tab[9],tab[15],tab[21],tab[26]); | ||
+ | *(tab+0)='A'; | ||
+ | tab[5]='E'; | ||
+ | printf("%c\t %c\n",tab[0],*(tab+5)); | ||
+ | } | ||
+ | </code> | ||
+ | <code> | ||
+ | a e i o u y | ||
+ | A E | ||
+ | </code> | ||
+ | |||
+ | * Idem en mieux (pour mémoire dure) : | ||
+ | <code c> | ||
+ | #include<stdio.h> | ||
+ | int main(void){ | ||
+ | char tab[27]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; | ||
+ | printf("%c\t %c\t %c\t %c\t %c\t %c\n",tab[0],tab[5],tab[9],tab[15],tab[21],tab[26]); | ||
+ | *(tab+0)='A'; | ||
+ | tab[5]='E'; | ||
+ | printf("%c\t %c\n",tab[0],*(tab+5)); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | =====fonction bis ===== | ||
+ | ====bibliothèque stdio.h ==== | ||
+ | ===fonction int et commande sizeof === | ||
+ | Un entier à une taille en octet. | ||
+ | <code c> | ||
+ | #include<stdio.h> | ||
+ | int main(void){ | ||
+ | printf("%d\n",sizeof(int)); | ||
+ | } | ||
+ | </code> | ||
+ | <code> | ||
+ | 4 | ||
+ | </code> | ||
+ | |||
+ | <note tip> | ||
+ | **Cela permet de comprendre l'utilisation de [[http://www.table-ascii.com/|la table ASCII]].**\\ | ||
+ | |||
+ | On pourrait faire : | ||
+ | <code c> | ||
+ | #include<stdio.h> | ||
+ | int main(void){ | ||
+ | printf("%d\n",sizeof(char)); | ||
+ | } | ||
+ | </code> | ||
+ | <code> | ||
+ | 1 | ||
+ | </code> | ||
+ | |||
+ | >1 octet = 8 bit | ||
+ | >8 bits permettent de coder 255 caractères différents. | ||
+ | >char peut donc "contenir la table ASCII qui va pour le code décimal des caractères alphanumériques (+des caractères spéciaux) qui va de 0 à 255. | ||
+ | |||
+ | <code c> | ||
+ | #include<stdio.h> | ||
+ | int main(void){ | ||
+ | int lettre=97; | ||
+ | printf("%c\n",lettre); | ||
+ | } | ||
+ | </code> | ||
+ | <code> | ||
+ | a | ||
+ | </code> | ||
+ | |||
+ | </note> | ||
+ | |||
+ | ===Pourquoi la fonction "main" renvoie-t-elle à un "int" ? === | ||
+ | Surtout qu'elle peut contenir des "char" ! | ||
+ | Rappel : "void" : quand la fonction ne retourne rien. | ||
+ | |||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | int somme(int x,int y){ | ||
+ | int result; | ||
+ | result=x+y; | ||
+ | return result; | ||
+ | } | ||
+ | int main(void){ | ||
+ | int addition; | ||
+ | addition=somme(2,3); | ||
+ | printf("%d\n",addition); | ||
+ | } | ||
+ | </code> | ||
+ | <code> | ||
+ | 5 | ||
+ | </code> | ||
+ | |||
+ | * ou en raccourci : | ||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | int somme(int x,int y){ | ||
+ | int result; | ||
+ | result=x+y; | ||
+ | return result; | ||
+ | } | ||
+ | void main(void){ | ||
+ | int addition; | ||
+ | int var1=2; | ||
+ | int var2=3; | ||
+ | addition=somme(var1,var2); | ||
+ | printf("%d\n",addition); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | >On affecte la variable "addition" de la fonction "somme" car elle a un "return". | ||
+ | > On met **''int main(void){''** car il possible de faire renvoyer des information par la fonction "main". | ||
+ | > Quand elle ne renvoie rien on peut aussi mettre **''void main(void){''**. | ||
+ | |||
+ | >**C'est au système d'exploitation que le "int" renvoie des informations**. | ||
+ | |||
+ | ===Se servir du "int" dans la fonction "main"=== | ||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | int somme(int x,int y){ | ||
+ | int result; | ||
+ | result=x+y; | ||
+ | return result; | ||
+ | } | ||
+ | int main(void){ | ||
+ | int addition; | ||
+ | int var1=2; | ||
+ | int var2=3; | ||
+ | addition=somme(var1,var2); | ||
+ | printf("%d\n",addition); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | <code user> | ||
+ | gcc -o fct.x fct.c; ./fct.x; echo $? | ||
+ | </code> | ||
+ | <code> | ||
+ | 5 | ||
+ | 0 | ||
+ | </code> | ||
+ | > 0 est le code de retour. | ||
+ | |||
+ | |||
+ | ====Bibliothèque string.h==== | ||
+ | ===fonction strcpy === | ||
+ | |||
+ | Elle permet d'utiliser la fonction **''strcpy''**. | ||
+ | Cette fonction "strcpy" permet la manipulation des chaînes de caractères. | ||
+ | |||
+ | strcpy(nom-de-la-variable-declaree,"nlle-valeur"); | ||
+ | |||
+ | |||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | #include <string.h> | ||
+ | int main(void){ | ||
+ | char nom[5]="toto"; | ||
+ | strcpy(nom,"tata"); | ||
+ | printf("%s\n",nom); | ||
+ | } | ||
+ | </code> | ||
+ | <code> | ||
+ | tata | ||
+ | </code> | ||
+ | |||
+ | => Voir le fichier "string.h" pour voir quelle autre fonction il contient. | ||
+ | |||
+ | ===fonction strcat=== | ||
+ | |||
+ | Elle permet de rajouter à la suite.\\ | ||
+ | "cat", comme "concaténer" ! | ||
+ | |||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | #include <string.h> | ||
+ | int main(void){ | ||
+ | char nom[15]="bonjour"; | ||
+ | strcat(nom," toto"); | ||
+ | printf("%s\n",nom); | ||
+ | } | ||
+ | </code> | ||
+ | <code> | ||
+ | bonjour toto | ||
+ | </code> | ||
+ | |||
+ | ===for dans chaîne de caractères=== | ||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | #include <string.h> | ||
+ | int main(void){ | ||
+ | char nom[25]="Hello"; | ||
+ | strcat(nom," Toto, are you ok ?"); | ||
+ | int i; | ||
+ | for(i=0;i!=25;i++){ | ||
+ | printf("nom[%d]=%c\n",i,nom[i]); | ||
+ | } | ||
+ | printf("\n"); | ||
+ | |||
+ | } | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | nom[0]=H | ||
+ | nom[1]=e | ||
+ | nom[2]=l | ||
+ | nom[3]=l | ||
+ | nom[4]=o | ||
+ | nom[5]= | ||
+ | nom[6]=T | ||
+ | nom[7]=o | ||
+ | nom[8]=t | ||
+ | nom[9]=o | ||
+ | nom[10]=, | ||
+ | nom[11]= | ||
+ | nom[12]=a | ||
+ | nom[13]=r | ||
+ | nom[14]=e | ||
+ | nom[15]= | ||
+ | nom[16]=y | ||
+ | nom[17]=o | ||
+ | nom[18]=u | ||
+ | nom[19]= | ||
+ | nom[20]=o | ||
+ | nom[21]=k | ||
+ | nom[22]= | ||
+ | nom[23]=? | ||
+ | nom[24]= | ||
+ | </code> | ||
+ | > L'espace réservé peut-être plus large que les éléments. | ||
+ | |||
+ | ===Fonction strcmp=== | ||
+ | |||
+ | Elle permet de comparer. | ||
+ | |||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | #include <string.h> | ||
+ | int main(void){ | ||
+ | char nom[10]="Hello b"; | ||
+ | printf("%d\n",strcmp(nom,"Hello")); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | 32 | ||
+ | </code> | ||
+ | |||
+ | =====Les structures ===== | ||
+ | Elles permettent d'utiliser plusieurs types de variable dans le "main". | ||
+ | |||
+ | ====Syntaxe ==== | ||
+ | ===Création d'une structure=== | ||
+ | * **Dans le "struct"** : \\ On crée une structure constituée de plusieurs types de variable afin de pouvoir tous les utiliser dans un seul "main".\\ __Pour ce faire__,\\ - on utilise la commande **''struct''**,\\ - on nomme la structure qu'on crée,\\ - enfin entre les accolades ouvrante et fermante, on annonce chacun des types de variables qui compose la structure.\\ Ne pas oublier le __point-virgule__ après l'accolade fermante de **''struct''**.\\ | ||
+ | * **Dans le "main"**:\\ on __associe__ à chaque variable déclarée, un __type de variable permis__ par la création de la structure.\\ **''var.type''** : Le point permet "d'associer" à "var", un type de variable annoncé dans le **''struct''**.\\ C'est **''var.type''** qu'on affecte __d'une valeur__ : **''var.type=valeur''**.\\ C'est donc **''var.type''** qui permet d'__appeler la valeur__ qu'on lui a affecté : **''("%type",var.type); ''**. | ||
+ | |||
+ | <code c> | ||
+ | #include<stdio.h> | ||
+ | #include<string.h> | ||
+ | struct nom-structure{ | ||
+ | type-chaine; | ||
+ | type-caractère[n]; | ||
+ | type-entier; | ||
+ | }; | ||
+ | int main(void){ | ||
+ | struct nom-structure var | ||
+ | strcpy(var.type-chaine,"chaine de caractère"); | ||
+ | var.type-caractère='c'; | ||
+ | var.type-entier=n; | ||
+ | |||
+ | printf("%s",var.type-chaine) | ||
+ | printf("%c",var.type-caractère) | ||
+ | printf("%d",var.type-entier) | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ====Exemple ==== | ||
+ | |||
+ | <code c> | ||
+ | #include<stdio.h> | ||
+ | #include<string.h> | ||
+ | struct earthborn{ | ||
+ | char sex; | ||
+ | char name[20]; | ||
+ | int age; | ||
+ | }; | ||
+ | int main(void){ | ||
+ | struct earthborn person1; | ||
+ | person1.age=78; | ||
+ | person1.sex='M'; | ||
+ | strcpy(person1.name,"Paul Dupont"); | ||
+ | printf("age:%d\t sex:%c\t name:%s\n",person1.age,person1.sex,person1.name); | ||
+ | struct earthborn person2; | ||
+ | person2.age=84; | ||
+ | person2.sex='F'; | ||
+ | strcpy(person2.name,"Agath Montsoirie"); | ||
+ | printf("age:%d\t sex:%c\t name:%s\n",person2.age,person2.sex,person2.name); | ||
+ | } | ||
+ | </code> | ||
+ | <code> | ||
+ | age:78 sex:M name:Paul Dupont | ||
+ | age:84 sex:F name:Agath Montsoirie | ||
+ | </code> |