Doppia dichiarazione Libreria, linguaggio C

Peri

Nuovo Utente
Sto usando Code::Blocks 17.12 per programmare in C, motivi universitari.
Sto creando una libreria, ma visto che varie guide online non funzionavano, mi sono fatto aiutare da un mio amico che ci era riuscito ecco cosa ho fatto:

Creo un file Header, nel caso nostro stdMat.h
In esso scrivo il seguente codice:
C:
#include <stdio.h>
#define NMAX 50

void P_der(double [ ],double [ ],int,int);
Poi creo un file Body ossia stdMat.cpp
In esso scrivo il seguente codice:
C:
#include<stdio.h>
#include<stdlib.h>

void P_der(double [],double [],int,int);

void P_der(double a[ ],double b[ ],int n,int m){
    if(n<m) {printf("\n\n\n\t//Error in P_der function - uncorrect input.//");exit(1);}
    for(int i=0;i<m;i++) b[I]=a[i+1]*(i+1);
    return;
}
Poi creo un progetto nel quale includo i due file prima esposti (nel dubbio li ho messi anche direttamente nella medesima cartella).
E nel main inserisco il seguente codice:

C:
#include <stdio.h>
#include <stdlib.h> //non so se serve
#include "stdMat.h"

int main(){
    double A[3]={1,2,3};
double b[2];
    P_der(A,b,3,2);
    return 0;
}
A questo punto avvio il compilatore e mi risponde con il seguente errore:

=== Build: Debug in Project (compiler: GNU GCC Compiler) ===
In function 'int main()':
error: 'P_der' was not declared in this scope
=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===


A questo punto ho pensato che fosse un problema di come ho impostato la libreria ma ho provato ad inserire un'altra funzione correttamente sia nell'header che nel body e funzionava, ecco il codice:
C:
void read_vet(double [ ],int);

void read_vet(double v[ ],int n){
    printf("\n\nInserire componenti vettore: \n");
    for(int i=0;i<n;i++) {printf(" Componente %d= ",i+1);scanf("%lf",&v[I]);}
    return;}
nel main invece:
C:
#include <stdio.h>
#include <stdlib.h>
#include "stdMat.h"

int main(){
    double A[3]={1,2,3};
    read_vet(A,3);
    return 0;
}
A questo punto ho provato ad inserire nel main la funzione ' P_der ' per capire se l'errore riguardasse la libreria.
Ecco il codice così ottenuto:

C:
#include <stdio.h>
#include <stdlib.h>
#include "stdMat.h"

void P_der(double a[ ],double b[ ],int n,int m){
    if(n<m) {printf("\n\n\n\t//Error in P_der function - uncorrect input.//");exit(1);}
    for(int i=0;i<m;i++) b[I]=a[i+1]*(i+1);
    return;
}
int main(){
    double A[3]={1,2,3};
double b[2];
    P_der(A,b,3,2);
    return 0;
}
A questo punto il compilatore segnala una doppia dichiarazione della funzione P_der indicandomi sia la definizione nel main che nel Body:

===Build: Debug in Project (compiler: GNU GCC Compiler) ===
multiple definition of 'P_der(double*, double*,int ,int)'
first defined here
error: 1d returned 1 exit status
=== Build failed: 3 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===


Da cui la domanda…. "ma se prima non me la trovava nella libreria, perché ora la trova?"

Sappiate che ho imparato a programmare da un paio di mesi e non possiedo un linguaggio tecnico, vi chiedo dunque di non usare parole che non potrei capire :hihi:

PS: potrebbe leggersi quasi a metà tutto corsivo, ho controllato l'anteprima, non so come togliere questa anomalia :muro:
 
Ultima modifica da un moderatore:

pabloski

Utente Èlite
1,969
405
Hardware Utente
Dovevi usare il tag code per inserire il codice. Comunque...

Intanto

C++:
for(int i=0;i<m;i++) b=a[i+1]*(i+1);
è sbagliato. Lì è forse b? Perchè scritto così stai cercando di assegnare un valore ad un puntatore. Perchè la variabile b, essendo un array, è di fatto un puntatore all'array.

Inoltre i file di programma per il C hanno estensione .c e non .cpp ( che indica il C++ ).

Infine c'è una doppia dichiarazione di P_der nell'header e nel body. Non si fa così. La funzione va definita SOLO nell'header file e nel body devi usare l'include per includere l'header file relativo.

Detto questo, è possibile che sia Codeblocks a non segnalare gli errori opportunamente. Per esempio se crei quei 3 file, poi compili il main così

Bash:
g++ -o main main.cpp
ti darà un errore, ma ti dirà che non riesce a risolvere il simbolo P_der. Cioè lui il file header lo legge, conosce il prototipo di quella funzione, ma non sa dove trovarne l'implementazione.

Questo però sarebbe dovuto succedere pure con read_vet e comunque Codeblocks conosce tutti i file che fanno parte del progetto e sa come richiamare correttamente il compilatore. Per cui francamente è un mistero.
 
  • Mi piace
Reactions: Peri

Andretti60

Utente Èlite
3,714
2,497
Hardware Utente
Allora, hai due possibilita'.
La prima, più semplice, e' quella di non creare una libreria, bensì di includere il file stdMat.cpp nel tuo progetto. Che va bene nel tuo caso perché si tratta di un file solo e neanche grande.
Ma l'idea della libreria e' di creare un "oggetto" (ossia un file .dll) che vai poi "linkato" con il modulo principale. CodeBlock ti permette di creare un progetto di tipo libreria.
Decidere quando includere il codice o di creare una libreria e' un soggetto molto vasto che si dovrebbe insegnare a scuola, ma e' comunque istruttivo imparare entrambi i metodi, per poi capire benefici e problemi di entrambi.
 

BrutPitt

Utente Attivo
Ciao.
Avere quell'errore significa che il file stdMat.cpp (ove risiede il corpo della funzione in questione), non viene compilato e/o non e' aggiunto al progetto... sia esso in forma di sorgente o di libreria.

Prova da linea di comando:
Bash:
g++ -o main stdMat.cpp main.cpp
(e poi magari controlla il project in Code::Blocks)

Se hai invece creato una libreria con stdMat.cpp ... e.g. libstdMat.a ... invece di includere il file stdMat.cpp e' necessario aggiungere l'opzione per il linker -lstdMat (-l) ove includi la libreria in questione (ed eventualmente la directory dove cercare la library con -Lpath).

Bash:
g++ -o main main.cpp -lstdMat
 
Ultima modifica:

Entra

oppure Accedi utilizzando