TE 7 Procédures en fortran et C Éléments de correction A Notions fondamentales

TE 7 Procédures en fortran et C Éléments de correction A Notions fondamentales Exercice 1 : Introduction aux pointeurs A Notions de base sur les pointeurs exo1-pointeurs.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define ULI (unsigned long int) // conversion 5 6 int main(void) { 7 int i=1, j=2; 8 int *pi=NULL, *pj=NULL, *pk; 9 float x, *px=NULL; 10 11 pi = &i; 12 pj = &j; 13 printf("i=%d, j=%d, *pi=%d, *pj=%d\n", 14 i, j, *pi, *pj); 15 printf("pi=%lu , pj=%lu\n", ULI pi, ULI pj); 16 exit(EXIT_SUCCESS); // fin etape 1 17 18 i *= 10; 19 printf("i=%d, *pi=%d, pi=%lu\n", i, *pi, ULI pi); 20 *pi *= 10; 21 printf("i=%d, *pi=%d, pi=%lu\n", i, *pi, ULI pi); 22 exit(EXIT_SUCCESS); // fin etape 2 23 24 printf("pk=%lu\n", ULI pk); 25 pk = pj; // memes types 26 printf("*pk=%d, pk=%lu\n", *pk, ULI pk); 27 if (pk == &j) { 28 printf("pk pointe vers j\n"); 29 } 30 exit(EXIT_SUCCESS); // fin etape 3 31 32 *pk = *pi; 33 printf("i=%d, *pk=%d\n", i, *pk); 34 exit(EXIT_SUCCESS); // fin etape 4 35 36 x = 3.5f; 37 px = &x; 38 printf("x=%g , *px=%g, px=%lu\n", x, *px, ULI px); 39 *px = *pj; 40 printf("j=%d , *px=%g, px=%lu\n", j, *px, ULI px); 41 exit(EXIT_SUCCESS); // fin etape 5 42 } exo1-pointeurs.f90 program pointeur 1 2 implicit none 3 4 integer, target :: i=1, j=2 5 integer, pointer :: pi=>null(), pj=>null(), pk 6 real, target :: x 7 real, pointer :: px=>null() 8 9 pi => i 10 pj => j 11 write (*,*) "i =", i, ", j =", j 12 write (*,*) "pi =", pi, ", pj =", pj 13 write (*, *) "pi => i :", associated(pi, i) 14 stop ! fin etape 1 15 16 i = i*10 17 write (*,*) "i =",i,", pi =",pi 18 pi = pi*10 19 write (*,*) "i =",i,", pi =",pi 20 stop ! fin etape 2 21 22 23 pk => pj 24 if (associated(pk, j)) then 25 write (*,*) "pk pointe vers j" 26 write (*,*) "pk =", pk, "j =", j 27 endif 28 stop ! fin etape 3 29 30 pk = pi ! memes types 31 write (*,*) "i =", i, " pk =", pk 32 stop ! fin etape 4 33 34 x = 3.5 35 px => x 36 write (*,*) "x =", x, "px =", px 37 px = pj 38 write (*,*) "j =", j, " x =", x, "px =", px 39 stop ! fin etape 5 40 41 end program pointeur 42 Le code fourni dans les fichiers exo1-pointeurs.c et exo1-pointeurs.f90 permet d’expérimenter les opé- rations sur les pointeurs en dehors de tout passage de paramètre dans des procédures. Exécuter ce code étape par étape en passant en commentaire au fur et à mesure les instructions d’arrêt (exit en C et stop en fortran). À chaque étape du programme, représenter schématiquement les zones mémoire des différentes variables et noter leur valeur ; préciser vers quelle zone pointent les variables pointeurs ainsi que les valeurs des variables pointées. 1 TE 7. Procédures en fortran et C UPMC M1 : MNI j x pi pj pk px i Précautions à prendre avec les pointeurs Reprendre la même démarche avec les fichiers exo2-pointeurs.c et exo2-pointeurs.f90. Expliquer avec précision quelles instructions provoquent des erreurs ou des avertissements lors de la compilation. Certains comportements peuvent apparaître aléatoires à l’exécution. Modifier les programmes pour les éviter (quitte à supprimer certaines instructions). exo2-pointeurs.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define ULI (unsigned long int) 5 6 int main(void) { 7 int i=1; 8 int *pi=NULL, *pj; 9 float x, *px=NULL; 10 11 printf("pi=%lu\n", ULI pi); 12 *pi = 4; // essayer d’executer 13 exit(EXIT_SUCCESS); // fin etape 1 14 15 pi = &i; 16 printf("pi=%lu\n", ULI pi); 17 *pi *= 10; 18 printf("i=%d, *pi=%d, pi=%lu\n", i, *pi, ULI pi); 19 exit(EXIT_SUCCESS); // fin etape 2 20 21 printf("pj=%lu\n", ULI pj); 22 // resultat aleatoire 23 *pj = 5; // essayer d’executer 24 pj = NULL; 25 printf("pj=%lu\n", ULI pj); 26 // resultat certain 27 exit(EXIT_SUCCESS); // fin etape 3 28 29 x = 3.5f; 30 px = &x; 31 printf("x=%g , *px=%g, px=%lu\n", x, *px, ULI px); 32 *px = *pi; 33 printf("i=%d , *px=%g, px=%lu\n", i, *px, ULI px); 34 exit(EXIT_SUCCESS); // fin etape 4 35 36 px = pi; // essayer pour etape 5 37 printf("i=%d , *px=%g, px=%lu\n", i, *px, ULI px); 38 exit(EXIT_SUCCESS); // fin etape 5 39 } exo2-pointeurs.f90 program pointeur 1 2 implicit none 3 4 integer, target :: i=1 5 integer, pointer :: pi=>null(), pj 6 real, target :: x 7 real, pointer :: px=>null() 8 9 write(*,*) " pi assoc :", associated(pi) 10 pi = 4 ! essayer d’executer 11 stop ! fin etape 1 12 13 pi => i 14 write(*,*) " pi assoc :", associated(pi) 15 pi = 4 16 write (*,*) "i =",i,", pi =",pi 17 stop ! fin etape 2 18 19 write(*,*) " pj assoc :", associated(pj) 20 ! resultat aleatoire 21 pj = 5 ! essayer d’executer 22 nullify(pj) 23 write(*,*) " pj assoc :", associated(pj) 24 ! resultat certain 25 stop ! fin etape 3 26 27 x = 3.5 28 px => x 29 write (*,*) "x =", x, "px =", px 30 px = pi 31 write (*,*) "i =", i, " x =", x, "px =", px 32 stop ! fin etape 4 33 34 px => pi ! essayer de compiler 35 write (*,*) "i =", i, "px =", px 36 stop ! fin etape 5 37 38 end program pointeur 39 2 27 novembre 2012 2012-2013 UPMC M1 : MNI TE 7. Procédures en fortran et C exo2-pointeurs+.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define ULI (unsigned long int) 5 6 int main(void) { 7 int i=1; 8 int *pj, *pi=NULL; 9 float x, *px=NULL; 10 11 printf("pi=%lu\n", ULI pi); 12 //*pi = 4; // essayer d’executer 13 //exit(EXIT_SUCCESS); // fin etape 1 14 15 pi = &i; 16 printf("pi=%lu\n", ULI pi); 17 *pi *= 10; 18 printf("i=%d, *pi=%d, pi=%lu\n", i, *pi, ULI pi); 19 //exit(EXIT_SUCCESS); // fin etape 2 20 21 printf("pj=%lu\n", ULI pj); 22 // resultat aleatoire 23 //*pj = 5; // essayer d’executer, peut echouer 24 pj = NULL; 25 printf("pj=%lu\n", ULI pj); 26 // resultat certain 27 //exit(EXIT_SUCCESS); // fin etape 3 28 29 x = 3.5f; 30 px = &x; 31 printf("x=%g , *px=%g, px=%lu\n", x, *px, ULI px); 32 *px = *pi; // garder pour voir l’effet ! (warning) 33 printf("i=%d , *px=%g, px=%lu\n", i, *px, ULI px); 34 //exit(EXIT_SUCCESS); // fin etape 4 35 36 // des entiers en octal correspondant 37 // en float a des "valeurs speciales" 38 i = 017740000000; // +Inf en float 39 i = 037740000000; // -Inf en float 40 i = 017740000001; // +NaN (quiet) 41 i = 037740000001; // -NaN (quiet) 42 i = 037750000001; // -NaN (signaling) 43 px = pi; // essayer pour etape 5 44 printf("i=%d , *px=%g, px=%lu\n", i, *px, ULI px); 45 exit(EXIT_SUCCESS); // fin etape 5 46 } En fortran, l’association entre pointeurs de types dif- férents provoque une erreur dès la compilation. px => pi ! essayer de compiler 1 Error: Different types in pointer assignment at (1) Cela prévient des erreurs graves qui pourraient en ré- sulter. Il faut donc supprimer cette instruction pour réussir à compiler y compris pour mettre en œuvre les étapes précédentes. En langage C, au contraire, elle ne produit qu’un war- ning à la compilation : warning: assignment from incompatible pointer type En C, on peut donc par exemple pointer une variable de type entier via un pointeur de float : le motif de 32 bits représentant un entier signé ne peut pas toujours être interprété en tant que float valide. Il correspond soit à des valeurs très différentes de la valeur de l’en- tier, soit à des codes de nombres réels dénormalisés (de valeur absolue inférieure à FLT_MIN, cf. annexe du polycopié fortran sur la norme IEEE), voire des codes spéciaux pour les NaN, +Inf ou -Inf. Le programme exo2-pointeurs+.c permet de stocker les valeurs oc- tales d’un entier signé qui codent ces valeurs non nu- mériques en float. En fortran, on peut affecter des motifs de bits à des variables réelles via des lectures en format B (norme fortran 2008, avec gfortran ou ifort). Mais il n’est pas possible de faire pointer un pointeur de réel vers un entier : une solution pour lire le motif binaire comme un entier est d’utiliser la fonction intrinsèque transfer. 2012-2013 27 novembre 2012 3 TE 7. Procédures en fortran et C UPMC M1 : MNI Exercice 2 : Fonctions avec retour sans effet de bord A Éditer les fichiers suivants, produit.c en C, puis produit.f90 en fortran 90. À chaque question, prendre soin de faire une copie en incrémentant le nom de façon à conserver toutes les versions. produit.c 1 #include uploads/Litterature/ correction-te7-point-fcts.pdf

  • 13
  • 0
  • 0
Afficher les détails des licences
Licence et utilisation
Gratuit pour un usage personnel Attribution requise
Partager