/* CS 203. Correction de la feuille 3 */
/* Credit : certains des programmes presentes ici ont ete realises par Pierre Cohort */
#include <stdio.h>
/* exercice 1 */
/* commentaire : il faut passer l'adresse de lamdba et mu pour que la fonction
puisse modifier effectivement ces variables. */
void LameLambdaMu(double Young, double Poisson, double* Lambda, double* Mu)
{
*Lambda=Young*Poisson/((1.+Poisson)*(1.-2.*Poisson));
*Mu=Young/(2.*(1.+Poisson));
}
/* exercice 2 */
void crible(int maxcrible)
{
int Tableau[maxcrible-1];
int n, i;
/* Le tableau des entiers. Attention : la case i reprente l'entier i+2 */
/* a la fin de la procedure Tableau[n-2]=1 si n est premier et 0 sinon */
for (i=0;i<=maxcrible-2;i++)
Tableau[i]=1;
/* Tout entier est presume premier jusqu'a ce que la preuve de sa non primalite soit
apportee au cours de la bouble suivante */
for (n=2;n<=sqrt(maxcrible);n++)
if (Tableau[n-2]==1) // Si n est premier...
for (i=2;i<=maxcrible/n;i++) // ... alors n*2, n*3, ...
Tableau[i*n-2]=0; // ... ne le sont pas !
for (n=2;n<=maxcrible;n++)
if (Tableau[n-2]==1)
printf("%d ",n);
printf("\n");
}
/* exercice 3*/
/* question 3.1 */
typedef struct compl {
float re, im;
} complexe;
complexe CreerComplexe (float a, float b)
/* Creation d'un nombre complexe
ENTREE : a partie reelle et b partie imaginaire de type float
SORTIE : a+ib de type complexe
*/
{
complexe z;
z.re=a;
z.im=b;
return z;
}
float PartieReelle (complexe z)
/* Partie reelle d'un nombre complexe
ENTREE : z de type complexe
SORTIE : partie reelle de z, de type float
*/
{
return(z.re);
}
float PartieImaginaire (complexe z)
/* Partie imaginaire d'un nombre complexe
ENTREE : z de type complexe
SORTIE : partie imaginaire de z, de type float
*/
{
return(z.im);
}
complexe SommeComplexe (complexe z1, complexe z2)
/* Somme de deux nombres complexes
ENTREE : z1 et z2 de type complexe
SORTIE : z1+z2 de type complexe
*/
{
float a, b;
complexe z;
a=PartieReelle(z1)+PartieReelle(z2);
b=PartieImaginaire(z1)+PartieImaginaire(z2);
z=CreerComplexe(a,b);
return z;
}
complexe ProduitComplexe (complexe z1, complexe z2)
/* Produit de deux nombres complexes
ENTREE : z1 et z2 de type complexe
SORTIE : z1*z2 de type complexe
*/
{
float a, b;
complexe z;
a=(PartieReelle(z1))*(PartieReelle(z2))-(PartieImaginaire(z1))*(PartieImaginaire(z2));
b=(PartieReelle(z1))*(PartieImaginaire(z2))+(PartieImaginaire(z1))*(PartieReelle(z2));
z=CreerComplexe(a,b);
return z;
}
float ModuleComplexe (complexe z)
/* Module d'un nombre complexe
ENTREE : z de type complexe
SORTIE : |z| de type float
*/
{
return(sqrt((PartieReelle(z))*(PartieReelle(z))+(PartieImaginaire(z))*(PartieImaginaire(z))));
}
void AfficherComplexe (complexe z)
/* Affichage d'un nombre complexe
ENTREE : z de type complexe
EFFET : affichage du complexe sur stdout
*/
{
if (PartieImaginaire(z)>0)
printf("%.5f+%.5fi\n",PartieReelle(z),PartieImaginaire(z));
if (PartieImaginaire(z)<0)
printf("%.5f-%.5fi\n",PartieReelle(z),fabs(PartieImaginaire(z)));
if (PartieImaginaire(z)==0)
printf("%.5f\n",PartieReelle(z));
}
/* question 3.2*/
int EstDansM (complexe K)
/* Fonction indicatrice de l'ensemble de Mandelbrot
ENTREE : un complexe K
SORTIE : 1 si K est dans l'ensemble de Mandelbrot, 0 sinon.
REMARQUE : On suppose qu'une suite de complexes est bornee ssi
les modules des 250 premiers termes sont inferieurs a 4
*/
{
complexe z; // contient le zn
float module, MaxModule; // module et plus grand module
int n; // variable de boucle
z=CreerComplexe(0.0,0.0);
MaxModule=0.0;
for (n=1;n<=250;n++)
{
z=SommeComplexe(ProduitComplexe(z,z),K);
module=ModuleComplexe(z);
if (module>MaxModule) MaxModule=module;
}
return (MaxModule<=4);
}
/* question 3.3*/
int main_exercice3()
{
float x1, x2, y1, y2;
int n1, n2, j, l;
complexe z;
printf("Entrez x1 x2 y1 et y2 separes par des espaces\n");
scanf("%f %f %f %f",&x1,&x2,&y1,&y2);
printf("Entrez n1 et n2 separes par des espaces\n");
scanf("%d %d",&n1,&n2);
for (l=0;l<=n2;l++)
for (j=0;j<=n1;j++)
{
z=CreerComplexe(x1+j*(x2-x1)/n1,y1+l*(y2-y1)/n2);
if (EstDansM(z))
AfficherComplexe(z);
}
return 0;
}
/* exercice 4 */
/* question 4.1 */
int exercice4_question1()
{
int x;
int *y;
int **z;
x=1;
y=&x; // y pointe vers x
z=(int**)malloc(2*sizeof(int*));
z[0]=y; // Le premiere case du tableau z pointe vers un pointeur vers x
x=2; // maintenant x vaut 2 donc *y=2 et x[0] pointe vers un pointeur vers 2
z[1]=y; // // La deuxieme case du tableau z pointe vers un pointeur vers x
printf("%d %d\n",*(z[0]),*(z[1])); // Affichage de x deux fois soit 2 et 2
return(0);
}
/* question 4.2 */
int exercice4_question2()
{
int x, y;
int *T;
x=1;
y=2;
T=(int*)malloc(2*sizeof(int));
T[0]=++x; // La premiere case de T recoit 2 car x est incremente avant l'affectation
T[1]=y; // La deuxieme case de T recoit 2
x+=5; // les modifications sur x et y n'affecteront pas T
y--;
printf("%d %d\n",T[0],T[1]); // Affichage de 2 et 2
return(0);
}
/* exercice 5 */
void exercice5_expression1()
{
int n=2;
int* p;
p=&n;
printf("n=%d\n",n);
*(&(*p))=4;
/* *p est la variable pointee par p, soit n car on a initialise p avec
l'adresse de n. Donc &(*p) vaut &n et finalement *(&(*p)) designe l'entier n.
On a donc n=4 en fin d'execution. */
printf("n=%d\n",n);
}
void exercice5_expression2()
{
int n=2;
int* p;
p=&n;
printf("n=%d\n",n);
(*p)++;
/* ici, on incremente la variable pointee par p, soit n. L'entier n vaut
donc 3 en fin d'execution */
printf("n=%d\n",n);
}
int main()
{
printf("Exercice 1\n");
{
double E=1.,nu=0.7,lambda,mu;
LameLambdaMu(E,nu,&lambda,&mu);
printf("Lamdba=%f Mu=%f\n",lambda,mu);
}
printf("\n\n\n");
printf("Exercice 2\n");
crible(1000);
printf("\n\n\n");
printf("Exercice 3\n");
main_exercice3();
printf("\n\n\n");
printf("Exercice 4\n");
exercice4_question1();
exercice4_question2();
printf("\n\n\n");
printf("Exercice 5\n");
exercice5_expression1();
exercice5_expression2();
printf("\n\n\n");
return 0;
}