/* CS203 - correction de la feuille 1 */
/* Credit : certains des programmes presentes ici ont ete realises par Pierre Cohort */

#include <stdio.h>

/* exercice 1 */
void affiche()
{
  printf("Leonard de Vinci\n\n\n"); 
  /* commentaire : le caractere de retour a la ligne \n doit etre
     inclus dans la chaine */
}
  
/* exercice 2 */
/* \n  : retour a la ligne
   \t  : insere une tabulation 
   \b  : fait reculer le curseur d'un caractere. Le curseur n'efface
         pas le caractere sur lequel il se place.
   \r  : ramene le curseur au debut de la ligne, sans effacer la ligne
   \0  : c'est le caractere de fin de chaine  
   \"  : imprime le caractere " (le \ permet au compilateur de ne pas
         confondre avec le signe de fin de chaine "  
	 \\  : imprime le caractere \   */

/* exercice 3 */
int fois_deux(int a)
{
  return 2*a;
  /* commentaire : il est inutile de placer le resultat dans
     une variable intermediaire avant de le retourner */ 
}

/* exercice 4 */
double LameLambda(double E, double v)
     /* commentaire : on doit specifier le type de tous les parametres de 
	la fonction. La syntaxe (double E,v) est interdite.  */
{
  return E*v/((1+v)*(1-2*v));
}
/* commentaires : 
    - lorsque l'on appelle la fonction avec v=-1 ou v=0.5,
      une division par zero est produite et le resultat renvoye est 
      inf (l'infini).
    - dans l'addition 1+v, le nombre 1 est de type entier mais le 
      compilateur le convertit automatiquement en un double car v
      est de type double. 
      On peut faire soi-meme la convertion en ecrivant 1.+v
    - penser a ecrire toute les multiplications. Par exemple,
      (1+v)(1-2*v) n'est pas interprete comme la multiplication
      des deux termes entre parentheses.  */ 

double LameMu(double E, double v)
{
  return E/(2*(1+v));
}

/* exercice 5 */
/* les identificateurs NON ACCEPTES sont :
      
      fonction-1   (a cause du signe - ; le compilateur comprend
                    qu'il faut retrancher 1 a l'identificateur fonction)
       
      3   (c'est un nombre) 
      
      3e_jour    (commence par un nombre)  */


/* exercice 6 */
void evalueExpressions()
{
  int A, B, C, D, X, Y;

  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("(5*X)+2*((3*B)+4)  = %d\n", (5*X)+2*((3*B)+4) );
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse :  98 . Aucune variable ne change de valeur. */

  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("(5*(X+2)*3)*(B+4)  = %d\n", (5*(X+2)*3)*(B+4) );
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse :  1890 . Different du precedent; attention aux priorites dictees 
     par les parentheses. Aucune variable ne change de valeur. */
  
  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("A == (B=5)  = %d\n", A == (B=5) );
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse : 0 . L'expression (B=5) vaut 5 car le programme affecte
     d'abord la valeur 5 a B puis evalue l'expression (B) qui vaut donc
     (5). Ensuite, (A == (B=5)) vaut (A == 5); cette
     expression n'est pas vraie et vaut donc 0 . Aucune variable ne change
     de valeur (B valait deja 5)*/

  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("A += (X+5)  = %d\n", A += (X+5) );
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse : 37 . L'expression (X+5) est d'abord evaluee : elle vaut
     17. Ce nombre est ensuite ajoute a la variable A (operateur +=) qui
     vaut donc finalement 37. L'expression initiale vaut A en fin
     de calcul, soit 37. La variable A change de valeur */ 
  
  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("A != (C *= (-D))  = %d\n", A != (C *= (-D)) );
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse : 0 . L'expression C *= (-D) multiplie C par -D et
     met le resultat dans C qui vaut alors 20 ( -10 * (-2) ).
     L'expression initiale vaut alors A != 20 ce qui est faux
     car A vaut 20. Le resultat retourne est donc 0. La variable
     C change de valeur. */

  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("A *= C+(X-D)  = %d\n", A *= C+(X-D) );
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse : 0 . L'expression C+(X-D) vaut 0 ( -10+(12-2) ).
     A est ensuite multiplie par ce nombre (operateur *=) et vaut
     donc finalement 0. La variable A change de valeur. */

  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("A \%= D++  = %d\n", A %= D++ );
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse : 0 . L'expression est d'abord evaluee comme
     A %= D et D est seulement ensuite incremente de 1 car l'operateur ++
     est place apres la variable D.
     L'expression vaut donc 20%2 = 0 . Les deux variables A et D changent
     de valeur.*/
  
  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("A \%= ++D  = %d\n", A %= ++D );
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse : 2 . Contrairement a l'exemple precedent, l'operateur ++
     est place avant la variable D : D est donc d'abord incrementee
     et l'expression est evaluee comme A %= (D+1). 
     L'expression vaut donc 20%3 soit 2*/
  
  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("(X++)*(A+C)  =%d\n",(X++)*(A+C)); 
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse : 120 . L'expression est en fait evaluee comme
     X*(A+C) et c'est seulement apres que la variable X est incrementee
     de 1. L'expression vaut donc 120. Seule la variable X change 
     de valeur. */

  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("A=X*(B<C)+Y*!(B<C)  = %d\n", A = X*(B<C)+Y*!(B<C) );
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse : 15 . L'expression (B<C) est fausse et vaut donc 0.
     L'expression !(B<C) est vraie et vaut donc 1. L'expression
     X*(B<C)+Y*!(B<C) vaut donc Y. Cette valeur est mise dans A.
     La valeur finale de l'expression est A, soit 15. La variable
     A change de valeur. */
  
  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("!(X-D+C)||D  = %d\n", !(X-D+C)||D );
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse : 1 . L'operateur ! est prioritaire sur ||. L'expression
     est donc evaluee comme (!(X-D+C))||(D). La variable D vaut 2 et, 
     en tant qu'expression booleenne, est consideree comme vraie. 
     Puisque l'operateur precedent D est || (ou), 
     la valeur finale de l'expression est 1 
     (pas besoin d'evaluer !(X-D+C) car on a la fois vrai||vrai=vrai
     et faux||vrai=vrai). Aucune variable ne change de valeur. */

  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("A&&B||!0&&C&&!D  = %d\n", A&&B||!0&&C&&!D );
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse : 1 . L'operateur && (et) etant prioritaire sur || (ou),
     l'expression est evaluee comme  (A&&B) || ((!0)&&C&&(!D)).
     Puisque A et B sont non nuls, ces variables, en tant 
     qu'expressions booleennes, sont considerees comme vraies :
     l'expression A&&B vaut donc 1. L'expression finale est donc 
     vraie et vaut donc 1. Aucune variable ne change de valeur. */ 
 
  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("((A&&B)||(!0&&C))&&!D  = %d\n", ((A&&B)||(!0&&C))&&!D );
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse : 0 . L'expression est evaluee comme
     ((A&&B)||(!0&&C)) && (!D). Or, Puisque D vaut 2, !D est 
     considere comme faux. L'expression initiale est donc fausse
     ( (...) && faux  est toujours faux, quel que soit la valeur
     de (...) ). Aucune variable ne change de valeur. */
  
  A=20; B=5; C=-10; D=2; X=12; Y=15;
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n",A,B,C,D,X,Y);
  printf("((A&&B)||!0)&&(C&&(!D))  = %d\n", ((A&&B)||!0)&&(C&&(!D)) );
  printf("A=%d; B=%d; C=%d; D=%d; X=%d; Y=%d\n\n\n",A,B,C,D,X,Y);
  /* reponse : 0 . L'expression C&&(!D) est fausse (voir exemple
     precedent. L'expression initiale est donc fausse et vaut 0.
     Aucune variable ne change de valeur. */     
}

/* exercice 7 */
int f(int x)  // declaration de la fonction f
     /* Fonction qui ajoute 1 a sont argument
   ENTREE : entier x 
   SORTIE : entier x+1
     */
{
  int y;      // declaration de la variable y de type entier
  y=++x;      // x est incremente puis affecte a y
  return y;   // la fonction retourne y
}

main_exercice7() 
{
  int x, y;   // declaration des variables x et y de type entier
  x=1;        // 1 est affecte a x
  y=f(x);     // y=f(x) donc y recoit 2
  printf("%d %d\n",x,y);  // affichage de x et y
  return 0;   // le programme retourne 0 au shell
}



int main()
{
  double E=1.23,v=2.45;

  printf("Exercice 1 :\n");
  affiche();

  printf("Exercice 3 :\n");
  printf("2*%d = %d\n\n\n\n",9,fois_deux(9));
  
  printf("Exercice 4 :\n");
  
  printf("E=%f , v=%f : Lambda=%f\n",E,v,LameLambda(E,v));
  printf("E=%f , v=%f : Mu=%f\n\n\n\n",E,v,LameMu(E,v));

  printf("Exercice 6 :\n");
  evalueExpressions();  

  printf("Exercice 7 :\n");
  main_exercice7();
 
  return 0;
}