Compilation C gcc

tize

Nouveau membre
Bonjour,
je m'adresse à vous car je cherche depuis quelque temps sans trouver de solution. Je précise que je ne suis pas étudiant et ne cherche donc pas à avoir la correction d'un exercice, je fais de la programmation en amateur (pour mon plaisir personnel) mais c'est pas tous les jours facile.
Voilà le problème, j'ai créé deux fichiers : main.c et initgn.c, le premier faisant appel au second et le but étant de créer un programme genre test de primalité sur des grand nombre (tableau d'entiers)...
Je suis sous linux et quand je compile : gcc -o main main.c, j'ai le message d'erreur suivant :
In file included from main.c:4:
initgn.c:5: erreur: syntax error before «*» token
initgn.c: Dans la fonction «initgn» :
initgn.c:8: erreur: «T» undeclared (first use in this function)
initgn.c:8: erreur: (Chaque identificateur non déclaré est rapporté une seule fois
initgn.c:8: erreur: pour chaque fonction dans laquelle il apparaît.)
initgn.c:9: erreur: «N» undeclared (first use in this function)

Voici mon main.c :
[cpp]#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "initgn.c"
//#include "printgn.c"
#define tmax 100

typedef struct{
int bit[tmax] ; //chiffres
int coma; // virgule
char sg; //signe
int ta; //nombre de chiffres significatifs
}GN;


int main(void)
{
GN nbre;
initgn(&nbre,tmax);
//printgn(&nbre);
return 0;
}[/cpp]
et voici mon initgn.c
[cpp]#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int initgn(GN *N,int T)
{
int i;
for(i=0;i<T;i++)
N->bit=0;
N->sg="+";
N->coma=1;
N->ta=1;
printf("\n%d",T);

return 1;
}
[/cpp]

Voilà, c'est pas forcément propre :( mais c'est tout ce que je sais faire, si vous avez une idée, merci d'avance pour ceux qui auront pris la peine de lire ce message en entier...
 

zeb

Modérateur
Regarde dans ton dico se que signifie to include.

Et compilation est un abus de langage. Ce n'est qu'une des quatre étapes pour transformer des fichiers .c et .h en binaires exécutables :
■ Pré-processing (cpp)
■ Compilation (cc/gcc)
■ Assemblage (as)
■ Edition de lien (ld)

Le préprocesseur va remplacer ta ligne #include "initgn.c" par le contenu du fichier initgn.c :
Code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

  #include <stdio.h>
  #include <stdlib.h>
  #include <math.h>

  int initgn(GN *N,int T)
  {
  int i;
  for(i=0;i<T;i++)
      N->bit[i]=0;
  N->sg="+";
  N->coma=1;
  N->ta=1;
  printf("\n%d",T);

  return 1;
  }

#define tmax 100

typedef struct{
int bit[tmax] ;    //chiffres
int coma;       // virgule
char sg;        //signe
int ta;         //nombre de chiffres significatifs
}GN;

int main(void)
{
GN nbre;
initgn(&nbre,tmax);
//printgn(&nbre);
return 0;
}
Je n'ai pas remplacé les autres includes, je ne suis pas un pré-processeur, moi :o

Tu remarques donc que la définition de GN, ligne 24, est postérieur à son utilisation ligne 9. D'où l'erreur.

Par principe :

Indenter ton code. C'est moche. Donc je n'aime pas le lire, donc je dois faire un gros effort pour t'aider, donc la prochaine fois, je t'envoie sur les roses :fou:

NE JAMAIS INCLURE DU CODE .C. Les includes sont faits pour ne pas avoir à répérer les définitions, les prototypes.

Donc il te faut faire un fichier initgn.h qui contient le prototype de initgn(..) et dans ce même .h ou dans un autre, il faut définir le type GN.

Inclus ce ou ces .h dans le fichier main.c et compile les deux fichiers .c ensemble :[fixed]$> gcc main.c initgn.c -o main[/fixed]
 

tize

Nouveau membre
Bonjour et merci pour la réponse, je pense avoir compris l'essentiel mais comme je l'ai dit plus tôt je ne programme qu'en amateur (mon travail dans la vie est totalement différent), je n'ai jamais fais d'info. moi, j'apprend tout, tout seul, alors oui je sais ce que veux dire to include mais je ne sais pas comment marche un compilo et si il parait évident qu'il va effectuer ce que tu as dit et bien désolé je n'en avais pas conscience tout comme le fait "d'identer un code" ??? et je ne vois pas en quoi "m'envoyer sur les roses" arrangerait le cas désespéré que je suis, de même je n'ai qu'une vague idée de ce qu'est un prototype et de à quoi il sert (le peu que j'ai lu dans des bouquins...)
Néanmoins, très sincèrement merci, et je tâcherai de ne plus poster de message pour ne plus t'enerver par mon ignorance.
 

zeb

Modérateur
Mais non. Tu es un grand débutant et nous sommes là pour t'aider.
Sinon, les roses... ce serait déjà fait. [:nyghost]

Mais il est des choses rédibitoires. J'ai dit indenter (et pas identer.) Et hop, Wikipedia : S'il existe une page indenter / informatique sur Wikipedia, dis-toi qu'il y a une bonne raison.

Fais pareil avec tous les mots difficiles.

Et n'hésite jamais à poser des questions, même TRES bêtes. (Tu ne seras pas le premier). Mais renseigne-toi par toi-même quand même un peu avant :o

Par contre, si un vieux [strike]con[/strike] briscard te dit de faire comme si ou comme ça, évite de revenir en ne suivant pas ces conseils, ou prépare un argumentaire solide :sarcastic: Ou alors demande-lui pourquoi ;)
 

tize

Nouveau membre
Ok, merci encore à toi,
j'ai fais (je pense :( ) ce que tu m'as dit, j'ai créé dans mon répertoire un fichier grandnombre.h dans lequel j'ai mis la définition de la structure et les prototypes des fonctions (je me suis renseigné ici : ). mais quand je tente de compiler il me dit " grandnombre.h : Aucun fichier ou répertoire de ce type" alors que tous mes fichiers sont dans le même répertoire...j'en déduis qu'il faut signaler la présence de mon fichier grandnombre.h au moment ou je lance la compilation ?
 

zeb

Modérateur
Code ?

Attention à ne pas confondre les deux :[fixed]#include <toto.h>
#include "toto.h"[/fixed]

Tu veux une explication ?
 

zeb

Modérateur
Un compilateur est fourni avec des exécutables (cpp, cc, as, ld) des bibliothèques de codes déjà compilés (.o souvent rangés dans des .a) et des headers (.h)

Dans /bin ou /usr/bin, les exécutables,
Dans /usr/lib ou /usr/local/lib, les bibliothèques,
Dans /usr/include ou /usr/local/include, les headers.

gcc connaît ces chemins grâce à des variables d'environnement que tu peux afficher avec les commandes env ou set. Les variables qui nous intéressent sous LIB et INCLUDE.

Si tu veux dire à gcc d'aller voir ailleurs, utilise les options -I et -L (man gcc ;)) En interne, LIB et INCLUDE seront modifiés.

Donc nous voilà avec des fichiers bien rangés à leur place.
Oui mais voilà, toi, tu veux en ajouter d'autres :
initgn.h, main.c, etc.

Pour les .c, pas de problème, tu les indiques à gcc sur sa ligne de commande. Mais où chercher les .h ?

#include <toto.h> signifie que le fichier est à chercher dans INCLUDE.
#include "toto.h" signifie que le fichier est à chercher dans le répertoire courant.

Bon. Encore une chose. (déjà vu d'ailleurs :o)
Quand tu fais :[fixed]#include <stdio.h>[/fixed]Il va chercher l'include dans /usr/local/include/stdio.h et la bibliothèque correspondante dans /usr/local/lib/libc.a comme tout ce qui est standard.

Mais quand tu fais :[fixed]#include <math.h>[/fixed]Il va chercher l'include dans /usr/local/include/math.h et la bibliothèque correspondante dans ???? Ben il ne sais pas parce que ce n'est pas standard. Alors il faut le dire à gcc. Mais que dire à gcc ?

Pour info, la bibliothèque est /usr/local/lib/libm.o
comme /usr/local/lib/libXXXXX.o, c'est valable pour tous, seule l'info XXXXX est utile. Dans le cas de libm.o, c'est juste m.

Donc on dit à gcc :[fixed]$> gcc ... -l m[/fixed](c'est un L minuscule)
L'espace est facultatif. en général, on écrit juste -lm.

Enjoy.
 

guillaumech

Expert
Moi j'adore :) C'est incroyable tout se que l'on peut apprendre ici ! En tout cas merci bien.
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 098
Messages
6 717 055
Membres
1 586 282
Dernier membre
Yannick3553
Partager cette page
Haut