-
Opérations sur les matrices...
salut!
Je suis en plein TD sur les matrices, on a géré la base (saisie de matrice, désallocation, matrice unité, affichage d'une matrice), mais là je bloque sur une fonction où je dois effectuer la transposée d'une matrice(m,n) (inversement ligne / colonne).
Voilà mon code source :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
float ** rempmat(int Nbl,int nbc)
{
float ** tab;
int i,j;
float nbre,tmp ;
/*Initialisation matrice*/
tab = (float**)malloc(Nbl*sizeof(float*));
for (i=0;i<Nbl;i++)
{
*(tab+i) = (float*)malloc(nbc*sizeof(float));
for (j=0;j<nbc;j++)
{
*(*(tab+i)+j)=0;
}
}
/*Saisie d'une matrice par l'utilisateur*/
for (i=0;i<Nbl;i++)
{
*(tab+i) = (float*)malloc(nbc*sizeof(float));
for (j=0;j<nbc;j++)
{
printf("saisir nombre reel \n") ;
scanf("%f",&nbre) ;
*(*(tab+i)+j)=nbre ;
}
}
/*Transposée matrice*/
for (i=0;i<Nbl;i++)
{
*(tab+i) = (float*)malloc(nbc*sizeof(float));
for (j=0;j<nbc;j++)
{
tmp=*(*(tab+i)+j)
*(*(tab+i)+j) = *(*(tab+j)+i) ;
*(*(tab+j)+i) = tmp;
}
}
return tab ;
} |
Je dois gérer le cas de toutes les matrices, pas seulement des matrices carrées, mais même pour ces dernières ca ne fonctionne pas.
Si quelqu'un a une idée... ;)
-
Re: Opérations sur les matrices...
Opinion personnelle : la notation *(*(tab+i) +j) est difficile à lire : tu devrais utiliser des tab[i] et tab[i][j] qui donne le même résultat mais sera bien plus lisible ...
Bon, mes commentaires dans ton code ..
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
float ** rempmat(int Nbl,int nbc)
{
float ** tab;
int i,j;
float nbre,tmp ;
/*Initialisation matrice*/
tab = (float**)malloc(Nbl*sizeof(float*));
if ( !tab )
{
return NULL;
}
for (i=0;i<Nbl;i++)
{
*(tab+i) = (float*)malloc(nbc*sizeof(float));
if ( !tab[i] )
{
for ( ; i >= 0 ; i--)
{
free ( tab[i]);
}
free ( tab );
return NULL;
}
/* Inutile, tu fais un scanf pour chaque valeur !!! for (j=0;j<nbc;j++)
{
*(*(tab+i)+j)=0;
} */
}
/*Saisie d'une matrice par l'utilisateur*/
for (i=0;i<Nbl;i++)
{
// *(tab+i) = (float*)malloc(nbc*sizeof(float)); // tu réalloues ce que tu as déjà alloué précédemment ...
for (j=0;j<nbc;j++)
{
printf("saisir nombre reel \n") ;
scanf("%f",&nbre) ;
*(*(tab+i)+j)=nbre ;
}
}
/*Transposée matrice*/
for (i=0;i<Nbl;i++)
{
//*(tab+i) = (float*)malloc(nbc*sizeof(float)); // Et encore une allocation
for (j=0;j<nbc;j++)
{
tmp=*(*(tab+i)+j) // tu prends une valeur non initialisée
*(*(tab+i)+j) = *(*(tab+j)+i) ; // ça ne peut marcher que si Nbl = nbc .. dangereux :)
*(*(tab+j)+i) = tmp;
}
}
return tab ;
} |
Le problème pour les matrices carrées est la réallocation de tab[i] qui écrase les valeurs à chaque fois ;)
-
Re: Opérations sur les matrices...
Citation:
Envoyé par DavG
Le problème pour les matrices carrées est la réallocation de tab[i] qui écrase les valeurs à chaque fois ;)
Non. realloc() preserve les valeurs de la précedente allocation, heureusement... Par contre, la zone nouvellement allouée n'est pas initialisée, ce qui peut surprendre parfois!
-
Re: Opérations sur les matrices...
Citation:
Envoyé par Emmanuel Delahaye
Citation:
Envoyé par DavG
Le problème pour les matrices carrées est la réallocation de tab[i] qui écrase les valeurs à chaque fois ;)
Non. realloc() preserve les valeurs de la précedente allocation, heureusement... Par contre, la zone nouvellement allouée n'est pas initialisée, ce qui peut surprendre parfois!
Je reformule : les "ré - allocations" .. en utilisant malloc et pas realloc, j'avoue que je me suis assez mal exprimé, mais comment dirais-tu de quelqu'un qui fait :
Code:
1 2 3 4 5
| tab = malloc ( ...
...
tab = malloc ( ...
...
tab = malloc ( ... |
A part dire une réallocation de la mémoire ??? :wink:
-
Re: Opérations sur les matrices...
Citation:
Envoyé par DavG
Opinion personnelle : la notation *(*(tab+i) +j) est difficile à lire : tu devrais utiliser des tab[i] et tab[i][j] qui donne le même résultat mais sera bien plus lisible ...
Bon, mes commentaires dans ton code ..
Voici une version plus modulaire. Je ne suis pas convaincu par l'effet de la 'transposition'...
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
#include <stdlib.h>
#include <stdio.h>
static float get_f (void)
{
char s[16];
fgets (s, sizeof s, stdin);
return (float) strtod (s, NULL);
}
/* Creation matrice */
float **cree_mat (int n)
{
float **tab = malloc (n * sizeof *tab);
if (tab != NULL)
{
int i;
for (i = 0; i < n; i++)
{
tab[i] = malloc (n * sizeof *tab[i]);
if (!tab[i])
{
for (; i >= 0; i--)
{
free (tab[i]);
}
free (tab), tab = NULL;
break;
}
}
}
return tab;
}
/* suppression matrice */
void del_mat (float **tab, int n)
{
if (tab != NULL)
{
int i;
for (i = 0; i < n; i++)
{
free (tab[i]);
}
free (tab);
}
}
/* Saisie d'une matrice par l'utilisateur */
void fill_mat (float **tab, int n)
{
if (tab != NULL)
{
int i;
for (i = 0; i < n; i++)
{
int j;
for (j = 0; j < n; j++)
{
printf ("saisir nombre reel \n");
tab[i][j] = get_f ();
}
}
}
}
void aff_mat (float *const*tab, int n)
{
if (tab != NULL)
{
int i;
printf ("matrice %d x %d\n", n, n);
for (i = 0; i < n; i++)
{
int j;
for (j = 0; j < n; j++)
{
printf ("%5.2f", tab[i][j]);
}
printf ("\n");
}
printf ("\n");
}
}
/* Transposee matrice */
void trans_mat (float **tab, int n)
{
int i;
for (i = 0; i < n; i++)
{
int j;
for (j = 0; j < n; j++)
{
float tmp = tab[i][j];
tab[i][j] = tab[j][i];
tab[j][i] = tmp;
}
}
}
int main (void)
{
int n = 3;
float **mat = cree_mat (n);
if (mat != NULL)
{
fill_mat (mat, n);
aff_mat (mat, n);
printf ("transpose\n");
trans_mat (mat, n);
aff_mat (mat, n);
del_mat (mat, n);
}
return 0;
} |
-
Re: Opérations sur les matrices...
Citation:
Envoyé par DavG
Citation:
Envoyé par Emmanuel Delahaye
Citation:
Envoyé par DavG
Le problème pour les matrices carrées est la réallocation de tab[i] qui écrase les valeurs à chaque fois ;)
Non. realloc() preserve les valeurs de la précedente allocation, heureusement... Par contre, la zone nouvellement allouée n'est pas initialisée, ce qui peut surprendre parfois!
Je reformule : les "ré - allocations" .. en utilisant malloc et pas realloc, j'avoue que je me suis assez mal exprimé, mais comment dirais-tu de quelqu'un qui fait :
Code:
1 2 3 4 5
| tab = malloc ( ...
...
tab = malloc ( ...
...
tab = malloc ( ... |
A part dire une réallocation de la mémoire ??? :wink:
Ok, désolé. J'ai compris ce que tu voulais dire en lisant son code...
une sur-allocation ?
-
Re: Opérations sur les matrices...
Citation:
Envoyé par Emmanuel Delahaye
J'ai compris ce que tu voulais dire en lisant son code...
une sur-allocation ?
Ça me va :wink:
-
Re: Opérations sur les matrices...
C'est vrai que pour la notation c'est moins clair, mais comme depuis quelques temps ils veulent des versions pointeur, j'ai écrit comme ca. :/
Pour les multiples allocations, c'est vrai qu'elles sont inutiles, je les enlève.
Le code d'échange ligne colonne en utilisant tmp, ne peut marcher qu'avec des matrices carrés, je m'en était rendu compte, mais je voulais au moins tester si ca marché pour celles-ci, puisque j'ai pas d'idée pour des matrices autres. :/
J'ai testé le codé que tu m'a donné, Emmanuel, mais je ne peux pas le compiler, il y a une erreur dans la fonction de création de la matrice,
"invalid conversion from "void" to float"", concernant ces deux lignes là :
Citation:
Envoyé par Emmanuel Delahaye
float **tab = malloc (n * sizeof *tab);
Citation:
Envoyé par Emmanuel Delahaye
tab[i] = malloc (n * sizeof *tab[i]);
Il y a confusion de types, mais je ne vois pas bien d'où ca peut venir...
Il y a également cette fonction que je ne comprend pas bien, tu peux me dire à quoi elle sert?
Citation:
Envoyé par Emmanuel Delahaye
Code:
1 2 3 4 5 6 7 8 9
|
static float get_f (void)
{
char s[16];
fgets (s, sizeof s, stdin);
return (float) strtod (s, NULL);
} |
Merci à tous ,c'est sympa de répondre. ;)
-
Re: Opérations sur les matrices...
Citation:
Envoyé par aokiseiichiro
J'ai testé le codé que tu m'a donné, Emmanuel, mais je ne peux pas le compiler, il y a une erreur dans la fonction de création de la matrice,
"invalid conversion from "void" to float"", concernant ces deux lignes là :
Citation:
Envoyé par Emmanuel Delahaye
float **tab = malloc (n * sizeof *tab);
Tu dois utiliser un compilateur C++, donc il te faut caster le malloc en (float *).
-
Re: Opérations sur les matrices...
Citation:
Envoyé par DavG
Tu dois utiliser un compilateur C++, donc il te faut caster le malloc en (float *).
Où plutot utiliser un compilateur C (vérifie l'extension du fichier source qui doit être *.c et non *.cpp ni *.C ).
-
Re: Opérations sur les matrices...
Citation:
Envoyé par aokiseiichiro
J'ai testé le codé que tu m'a donné, Emmanuel, mais je ne peux pas le compiler, il y a une erreur dans la fonction de création de la matrice,
"invalid conversion from "void" to float"", concernant ces deux lignes là :
Citation:
Envoyé par Emmanuel Delahaye
float **tab = malloc (n * sizeof *tab);
Citation:
Envoyé par Emmanuel Delahaye
tab[i] = malloc (n * sizeof *tab[i]);
Il y a confusion de types, mais je ne vois pas bien d'où ca peut venir...
Ce code est du C. Pour invoquer le compilateur C, il faut que l'extension soit .c et non .cpp ni .C.
Citation:
Il y a également cette fonction que je ne comprend pas bien, tu peux me dire à quoi elle sert?
Citation:
Envoyé par Emmanuel Delahaye
Code:
1 2 3 4 5 6 7 8
|
static float get_f (void)
{
char s[16];
fgets (s, sizeof s, stdin);
return (float) strtod (s, NULL);
} |
Elle sert à saisir un float. Elle n'est pas parfaite, mais elle couvre les cas principaux et ne laisee pas trainer de '\n' (sauf insistance maladive sur le clavier)
-
Re: Opérations sur les matrices...
Citation:
Envoyé par DavG
Tu dois utiliser un compilateur C++, donc il te faut caster le malloc en (float *).
Mauvaise réponse. On ne compile pas du C avec un compilateur C++. Ce sont 2 langages différents.
http://david.tribble.com/text/cdiffs.htm
-
Il ne faut quand même pas exagérer :
Code:
1 2 3 4 5 6 7
| #include <stdio.h>
int main(void)
{
puts("Hello World");
return 0;
} |
Ce pur programme C a été créé dans le fichier foo.cpp, compilé donc par le compilateur C++ et fonctionne parfaitement.
-
Re: Opérations sur les matrices...
Citation:
Envoyé par Emmanuel Delahaye
Mauvaise réponse. On ne compile pas du C avec un compilateur C++. Ce sont 2 langages différents.
C'est plus que du purisme ta réponse : tu peux prendre un fichier .c, le renommer .cpp et le compiler .. j'appelle ça compiler du C avec un compilateur c++ et pas "faire" du c++ :wink:
-
Re: Opérations sur les matrices...
Citation:
Envoyé par Emmanuel Delahaye
Ce code est du C. Pour invoquer le compilateur C, il faut que l'extension soit .c et non .cpp ni .C.
Non. Enfin, du moins pas si tu sais régler tes compilateurs : ça doit prendre 10 secondes pour demander à BC++ de compiler un source C (en mode C, bien sûr) dont l'extension serait ".PDF". Quant à la distinction majuscules/minuscules... Encore faut-il que l'OS en tienne compte.
Citation:
Envoyé par Emmanuel Delahaye
Mauvaise réponse. On ne compile pas du C avec un compilateur C++. Ce sont 2 langages différents.
Pas remarqué. Mes modules compilent indifféremment en C ou en C++, ça c'est de la vraie portabilité : non seulement entre plate-formes, mais carrément entre langages... :twisted:
-
Re: Opérations sur les matrices...
Citation:
Envoyé par Mac LAK
Mes modules compilent indifféremment en C ou en C++,
La seule contrainte est que tu dois mettre tous les cast pour les type void en cpp .. mais bon, si tu utilises un outil comme flexlint il te dit de les mettre de toute façon et après tu compiles indifféremment dans l'un ou l'autre !
-
Re: Opérations sur les matrices...
Citation:
Envoyé par DavG
Citation:
Envoyé par Mac LAK
Mes modules compilent indifféremment en C ou en C++,
La seule contrainte est que tu dois mettre tous les cast pour les type void en cpp .. mais bon, si tu utilises un outil comme flexlint il te dit de les mettre de toute façon et après tu compiles indifféremment dans l'un ou l'autre !
Mettre les casts explicites, c'est une habitude que j'ai prise depuis bien longtemps.
Y'a deux écoles sur le sujet, perso ça me vrille d'omettre un cast de ce type, même en C => donc, aucun problème.
-
Citation:
Envoyé par Trap D
Il ne faut quand même pas exagérer :
Code:
1 2 3 4 5 6 7
| #include <stdio.h>
int main(void)
{
puts("Hello World");
return 0;
} |
Ce pur programme C a été créé dans le fichier foo.cpp, compilé donc par le compilateur C++ et fonctionne parfaitement.
Et ça prouve quoi ?
En tout cas c'est du mauvais C++.
Code:
1 2 3 4 5 6 7
| #include <cstdio>
int main()
{
puts("Hello World");
return 0;
} |
-
Re: Opérations sur les matrices...
Citation:
Envoyé par DavG
Citation:
Envoyé par Emmanuel Delahaye
Mauvaise réponse. On ne compile pas du C avec un compilateur C++. Ce sont 2 langages différents.
C'est plus que du purisme ta réponse :
Non, c'est du bon sens.
Citation:
tu peux prendre un fichier .c, le renommer .cpp et le compiler .. j'appelle ça compiler du C avec un compilateur c++ et pas "faire" du c++ :wink:
Ben si, parce que c'est la sémantique du C++ qui va s'appliquer, et il peut y avoir des surprises. Moi, je me contente de mettre les gens en garde contres les mauvaiuses pratiques, après, ils font ce qu'ils veulent, je m'en tape. J'ai la conscience tranquille, ils ne pourront pas dire 'je ne savais pas', 'on m'a rien dit' etc.
-
Citation:
Envoyé par Emmanuel Delahaye
Citation:
Envoyé par Trap D
Ce pur programme C a été créé dans le fichier foo.cpp, compilé donc par le compilateur C++ et fonctionne parfaitement.
Et ça prouve quoi ?
En tout cas c'est du mauvais C++.
Je pense que c'est exactement ce qu'il dit : c'est du C et pas du C++, mais en renommant le .c en .cpp tu peux le compiler sans problème .. comme bien souvent les environnements sont des compilateurs C++ qui ouvrent des .cpp sans te le demander, rien ne t'empêche de faire du C compilé en mode C++ !
-
Re: Opérations sur les matrices...
Citation:
Envoyé par DavG
Citation:
Envoyé par Mac LAK
Mes modules compilent indifféremment en C ou en C++,
La seule contrainte est que tu dois mettre tous les cast pour les type void en cpp .. mais bon, si tu utilises un outil comme flexlint il te dit de les mettre de toute façon et après tu compiles indifféremment dans l'un ou l'autre !
Des casts quelle horreur. Pourquoi pas des gotos ?
-
Re: Opérations sur les matrices...
Citation:
Envoyé par Emmanuel Delahaye
Citation:
Envoyé par DavG
Citation:
Envoyé par Mac LAK
Mes modules compilent indifféremment en C ou en C++,
La seule contrainte est que tu dois mettre tous les cast pour les type void en cpp .. mais bon, si tu utilises un outil comme flexlint il te dit de les mettre de toute façon et après tu compiles indifféremment dans l'un ou l'autre !
Des casts quelle horreur. Pourquoi pas des gotos ?
J'ai dit que pour compiler du C dans un .cpp il va te falloir mettre les cast sinon ça ne compilera pas .. j'ai pas dit que c'était bien :D
Dans une application sur laquelle j'ai travaillé on avait des librairies C et des liens software des fichiers .c en .cpp pour une autre librairie cpp, donc les cast sont devenus une obligation !!
-
Re: Opérations sur les matrices...
Citation:
Envoyé par Emmanuel Delahaye
Des casts quelle horreur. Pourquoi pas des gotos ?
Pas plus horrible que d'ignorer ce que fait l'instruction "continue", mais bon...
Quant aux "goto", ils sont plus qu'intéressants pour implémenter une gestion d'erreurs complexe restant lisible, compacte, efficace et efficiente.
Les casts sont impératifs en C++ (erreur de compilation en général, et pas un "simple" warning, y'a même pas besoin d'un Lint), et autorisés en C => où est donc le problème ?
-
Citation:
Envoyé par DavG
Je pense que c'est exactement ce qu'il dit : c'est du C et pas du C++, mais en renommant le .c en .cpp tu peux le compiler sans problème .. comme bien souvent les environnements sont des compilateurs C++ qui ouvrent des .cpp sans te le demander, rien ne t'empêche de faire du C compilé en mode C++ !
Ben moi dans mes codes, y'a ça partout dans les .c:
Code:
1 2 3 4
|
#ifdef __cplusplus
#error This source file is not C++ but rather C. Please use a C-compiler
#endif |
Or mon bon vieux Borland C++ 3.1 enregistre les fichiers en majuscule (MS-DOS) ce qui fait que quand j'ai commencé à compiler avec Dev-C++, j'avais des erreurs étranges avec certains codes de test. Quand j'ai passé mon code de bibliothèque, j'ai vu apparaîtres les fameux messages d'erreur
Code:
This source file is not C++ but rather C. Please use a C-compiler
Après un sérieux grattage de tête, je me suis aperçu que l'extension .C invoquait g++. J'ai tout renommé comme il faut et ça marche.
Quand j'ai passé la bibliothèque sous Linux, elle a compilé du premier coup.
D'autre part, utiliser un compilateur C++ pour compiler du C, c'est appliquer au fichier source (qui n'est que du texte) des regles de syntaxes et de sémantiques différentes qui peuvent mener à des comportements différents (par exemple, un caractère est de type int en C et de type char en C++)? J'ai donné ce lien plusieurs fois :
http://david.tribble.com/text/cdiffs.htm
C et C++ sont véritablement deux langages différents. Prétendre le contraire, et donc échanger les compilateurs, est tout simplement erroné.
-
Re: Opérations sur les matrices...
Citation:
Envoyé par Mac LAK
Les casts sont impératifs en C++ (erreur de compilation en général, et pas un "simple" warning, y'a même pas besoin d'un Lint), et autorisés en C => où est donc le problème ?
L'école des ultra-ansi-puristes a banni les cast en même temps que les commandes POSIX :wink:
Citation:
Envoyé par Emmanuel Delahaye
Ben moi dans mes codes, y'a ça partout dans les .c:
Code:
Code:
1 2 3
| #ifdef __cplusplus
#error This source file is not C++ but rather C. Please use a C-compiler
#endif |
Ce qui est très limitatif ...
Citation:
C et C++ sont véritablement deux langages différents. Prétendre le contraire, et donc échanger les compilateurs, est tout simplement erroné.
VB et C sont deux langages différents, c'est vrai, mais C et C++ sont deux langages de la même famille (C++ étant, à mon avis, une énorme surcouche au C:D ) et, même si la réciproque n'est pas vrai, 90% des programmes C peuvent être compilés en C++ simplement en renommant le .c en .cpp en autant que tu as respecté certaines règles de compatibilité (comme les cast !!).
-
Re: Opérations sur les matrices...
Citation:
Envoyé par DavG
J'ai dit que pour compiler du C dans un .cpp il va te falloir mettre les cast sinon ça ne compilera pas ..
C'est bien la preuve que ce sont des langages différents, avec syntaxe et une sémantique différentes.
Citation:
j'ai pas dit que c'était bien :D
Dans une application sur laquelle j'ai travaillé on avait des librairies C et des liens software des fichiers .c en .cpp pour une autre librairie cpp, donc les cast sont devenus une obligation !!
Je ne vois pas à quoi ça sert. Il est parfaitement possible dans un même projet de mélanger des sources C et des sources C++, il suffit de bien respecter les extensions et les compilateurs. Chaque source respecte sa sémantique et c'est tout; Les interfaces C visibles du C++ doivent simplement être encadrées par
Code:
1 2 3 4 5 6 7 8 9
|
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef __cplusplus
}
#endif |
comme c'est fait systématiquement (enfin presque) dans ma bibliothèque.
http://emmanuel-delahaye.developpez.com/clib.htm
La seule contrainte du C est d'éviter les mots cles du C++ dans les interfaces, c'est pourquoi j'ai remplacé this par self, par exemple (dans les .h publics)
.
-
Re: Opérations sur les matrices...
Citation:
Envoyé par Emmanuel Delahaye
Citation:
Dans une application sur laquelle j'ai travaillé on avait des librairies C et des liens software des fichiers .c en .cpp pour une autre librairie cpp, donc les cast sont devenus une obligation !!
Je ne vois pas à quoi ça sert. Il est parfaitement possible dans un même projet de mélanger des sources C et des sources C++, il suffit de bien respecter les extensions et les compilateurs.
En fait c'était une préparation à un portage total d'application C compilée avec Watcom à une application C++ compilée gnu, donc une étape intermédiaire, .. sinon en effet tu as parfaitement raison et les #ifdef __cplusplus suffisent amplement :wink:
-
Re: Opérations sur les matrices...
Citation:
Envoyé par Mac LAK
Quant aux "goto", ils sont plus qu'intéressants pour implémenter une gestion d'erreurs complexe restant lisible, compacte, efficace et efficiente.
Ok. Mais vers le bas, on est bien d'accord ?
Citation:
Les casts sont impératifs en C++ (erreur de compilation en général, et pas un "simple" warning, y'a même pas besoin d'un Lint), et autorisés en C => où est donc le problème ?
Il peuvent cacher une erreur en rendant le compilateur silencieux. Ils sont donc une source de problèmes. Moins je vois de cast, mieux je me porte. (En C++, pas de cast avec new)
-
Re: Opérations sur les matrices...
Citation:
Envoyé par DavG
Citation:
Envoyé par Emmanuel Delahaye
Code:
1 2 3
| #ifdef __cplusplus
#error This source file is not C++ but rather C. Please use a C-compiler
#endif |
Ce qui est très limitatif ...
Meuh ? Pourquoi ? C'est sûr, c'est tout. Ca évite de faire n'importe quoi. C'est mal ?
Citation:
Citation:
C et C++ sont véritablement deux langages différents. Prétendre le contraire, et donc échanger les compilateurs, est tout simplement erroné.
mais C et C++ sont deux langages de la même famille <...>
La seule chose qui soit 100% compatible est le préprocesseur. Ils ont strictement la même définition en C et en C++. Le reste, c'est du domaine de la ressemblance et des faux amis. Je ne prend pas ce genre de risques.
Ce que je n'arrive pas à comprendre, c'est qu'en plus du fait que le comportement devient indéterminé (les regles sont différentes), à quoi ça sert de compiler du code C avec un compilateur C++. Quelle est la raison profonde de cette association contre nature ?
-
Re: Opérations sur les matrices...
Citation:
Envoyé par Emmanuel Delahaye
Citation:
Envoyé par Mac LAK
Quant aux "goto", ils sont plus qu'intéressants pour implémenter une gestion d'erreurs complexe restant lisible, compacte, efficace et efficiente.
Ok. Mais vers le bas, on est bien d'accord ?
Ben je parle explicitement d'une gestion d'erreurs : grosso-modo, l'équivalent d'une section "try/finally" ou "try/catch", donc obligatoirement descendant.
Pour une fois, on est 100% d'accord : un goto ascendant en C, ça mérite le bûcher. J'accepte même de mélanger la poix avec du miel et de te laisser jouer avec tes fourmis avant de jeter la torche... :twisted:
Citation:
Envoyé par Emmanuel Delahaye
Il peuvent cacher une erreur en rendant le compilateur silencieux. Ils sont donc une source de problèmes. Moins je vois de cast, mieux je me porte. (En C++, pas de cast avec new)
Je n'utilises pas "new" en général, sauf pour les classes (mais dans ce cas, pas de portabilité C/C++, bien évidemment), à cause de l'API "légèrement" gourmande de BC++ sur cette instruction et que j'estime rédhibitoire en embarqué.
Quant au "silence" du compilateur, on en a déjà discuté une fois, tu connais mon point de vue et moi le tien : tu sais également que les deux sont aussi valides l'un que l'autre, "tes" cas d'erreurs étant couverts par "ma" méthode et réciproquement. Aucune des deux n'est franchement plus fiable que l'autre.
Par contre, sur le sujet des "#ifdef _cplusplus" et des "extern "C" {", là, je bloque : ça rend le source imbuvable, et ça pose parfois des problèmes d'édition de liens assez infernaux à gérer (situation vécue, hélas...).
A quoi ça sert de compiler du C en C++ et réciproquement ? Ben à avoir le même source sur une cible possédant un compilo C++ (=> donc, on peut utiliser des trucs comme les classes ou les exceptions si nécessaire), et sur une cible ne possédant qu'un compilateur C... Très utile pour les protocoles de communication, par exemple.
On peut rapprocher ça, parcequ'en fait c'est exactement le même problème, d'une unité Pascal DOS compilée sous Delphi et réciproquement... Mais là, j'entends personne râler, alors que les deux langages sont au moins aussi différents que C et C++ !!
-
C'est bon pour le calcul d'une transposée de matrice carrée. Mais ca ne marche pas encore pour une matrice autre.
J'ai inversé le nomre de ligne et le nombre de colonne, et normalement avec l'algo ca marche...mais pas sur le programme. :/
Voici le code, si quel'qu'un a une idée :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
//calcul de la matrice transposée
int **transpose(int nblign, int nbcol) {
int i, j,nb,tmp=0;
int **tab;
int **trans;
tmp=nblign;
nblign=nbcol;
nbcol=tmp;
trans=(int**)malloc(nblign*sizeof(int*));
for (i=0;i<nblign;i++) {
*(trans+i)=(int*)malloc(nbcol*sizeof(int));
for (j=0;j<nbcol;j++) {
*(*(trans+i)+j)=*(*(tab+j)+i);
}
} |
Merci! ^^
-
si j'ai bien compris, dans ta fonction tab c'est la matrice d'origine et trans c'est la matrice transposee.
mais alors pourquoi tu declare tab dans cette fonction ?
quand tu utilise tab pour recopier ses valeurs dans trans, ce n'est meme pas alloué !
je pense que la signature de ta fonction devrai etre plutot :
int **transpose(int nbligne, int nbcolonne, int **tab)
en ayant pris soin d'allouer et de remplir tab avant d'appeller transpose
-
aokiseiichiro < Tester le retour de malloc, ca peut servir...