Programma in C sul Macintosh

valentina921
Salve a tutti,
ho appena comprato un mac; ho sempre usato windows e ho sempre programmato lì, adesso devo farlo in questo nuovo sistema operativo. Per farlo uso Xcode; se c'è qualcuno che ce l'ha o che sa come funziona, volevo chiedere questa cosa: ho scritto un programma che compila ed esegue correttamente se lo metto su cygwin di windows, ma se lo faccio andare sul mac a un certo punto mentre esegue si ferma senza motivo; in particolare, se inserisco i dati più velocemente funziona fino alla fine, se li inserisco a una velocità normale (se ad es. li copio da u n foglio) si interrompe da solo a un certo punto . Qualcuno sa che cosa significa? Ci può essere una sorta di funzione tempo?

Grazie in anticipo

Valentina

Risposte
Raptorista1
Non mi è chiaro in cosa consiste questa esecuzione: ci sono delle scanf con cui leggi dei valori? È su quelle che si inchioda il programma?

valentina921
Si ci sono delle scanf, ma la cosa strana è che a volte il programma esegue, altre volte no e va via la schermata in cui mi eseguiva. Poi non è che quando si ferma lo fa sempre sullo stesso punto, dipende, se metto i dati veloce non lo fa, se li metto normali lo fa poco prima della fine (ma non mi stampa il risultato finale) , se li metto ancora più lenta si interrompe ancora prima. Poi ho provato a farlo funzionare anche su altri mac di amici, e là funziona perfettamente. E' proprio come se ci fosse un tempo, non lo so... e nessuno riesce a capire cosa può essere!!

apatriarca
Sei certa che il punto in cui il programma si fermi sia sempre diverso? L'inserimento dei valori di input non è necessariamente legato al punto del programma in cui vengono letti. Puoi infatti in alcuni casi passare tutto l'input del programma in una sola riga (o rindirizzandolo da file) senza che il programma abbia ancora ricevuto nulla. Vedere il codice potrebbe essere utile, ma siccome il problema si verifica solo sul Mac.. credo che il problema sia diverso: stai facendo partire il codice da XCode? Hai provato a farlo partire da console? Sei certa di non aver inserito per sbaglio dei breakpoint nel programma?

valentina921
Si si sono sicura sia del fatto che non si ferma sempre sullo stesso punto, ho fatto un sacco di prove! Per quanto riguarda i breakpoint, se mi ricordo bene sono quelle righe verdi, ce n'erano e le ho tolte tutte, ma lo fa lo stesso. Lo faccio partire da XCode; invece non so che vuol dire farlo partire da console! Se vuol dire farlo partire da terminale, me l'avevano consigliato, ma non sono stata capace, quindi mi servirebbe una spiegazione :)

apatriarca
Non uso il Mac per cui non ti saprei dire la procedura esatta da seguire per farlo partire da terminale (sì.. intendevo quello.. ). Continuo a pensare che il problema dev'essere per forza legato ad un qualche uso sbagliato di XCode. Inserisci una riga di lettura da standard input alla fine del programma, cerca la cartella nel quale è contenuto il progetto e l'eseguibile e prova ad eseguirlo da lì..

Raptorista1
Dovrebbe essere come su linux, quindi se il programma è nella cartella /home/valentina/programma1/ devi entrare nel terminale e scrivere
cd /home/valentina/programma1

premere Invio e poi lanciare il programma con il comando
./programma.run

o come si chiama il tuo eseguibile.

Se vuoi, dovresti anche riuscire a compilarlo col comando
gcc main.c

[o equivalente]

vict85
"Raptorista":
Dovrebbe essere come su linux, quindi se il programma è nella cartella /home/valentina/programma1/ devi entrare nel terminale e scrivere
cd /home/valentina/programma1

premere Invio e poi lanciare il programma con il comando
./programma.run

o come si chiama il tuo eseguibile.

Se vuoi, dovresti anche riuscire a compilarlo col comando
gcc main.c

[o equivalente]


Se non sbaglio Xcode usa Clang+llvm

Raptorista1
"vict85":
Se non sbaglio Xcode usa Clang+llvm

Magari gcc è già installato per conto proprio...
In caso contrario, il terzo comando non funzionerà.

giozh
Prima di eseguire il sorgente C su una piattaforma diversa da dove lo hai scritto, innanzitutto ricompilalo. Inoltre, hai per caso utilizzato delle system call "particolari" nel tuo codice? perchè un conto è che scrivi codice C per windows, un altro è se lo fai per mac... Credo che la soluzione migliore sia quella di postare il codice

valentina921
Ecco il codice, è molto elementare:

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

int main() {
    
    
    int n, i, r;
    double x[1000]={0}, y[1000]={0}, sumx=0, sumy=0, sumxquad=0, sumxy=0, a, b, persigmay=0, sigmay, erra, errb, k, sumylnx=0, sumlnquad=0;
    
    
    printf ("\nQuesto programma utilizza il metodo dei minimi quadrati per stimare i parametri di funzioni lineari (retta di equazione y=ax+b, oppure funzione logaritmica y=klnx)a partire da un campione di dati sperimentali ottenuti da misure dirette. \nE' importante specificare che i valori che il programma restituisce sono validi solo nel caso in cui le varianze di tutte le y dei valori siano uguali.");
    
    printf ("\nInserire 0 se si vogliono stimare i parametri di una retta, 1 per il parametro della funzione logaritmica: ");
    scanf ("%d",&r);
    
    printf ("\n\nInserire il numero di dati del campione (numero delle coppie): ");
    scanf ("%d",&n);
    
    for (i=0; i<n; i++) {
        printf ("\nInserire il dato x: ");
        scanf ("%lf", &x[i]);
    }
    
    for (i=0; i<n; i++) {
        printf ("\nOra inserire il dato y: ");
        scanf ("%lf", &y[i]);
    }
    
    if (r==0) {
        
        printf ("\nStimiamo i parametri a e b di una retta di equazione y=ax+b.");
        
        for (i=0; i<n; i++) {
            sumx+=x[i];
            sumy+=y[i];
            sumxquad+=pow(x[i],2);
            sumxy+=x[i]*y[i];
        }
        
        a=(n*sumxy-sumy*sumx)/(n*sumxquad-pow(sumx,2));
        b=(sumy*sumxquad-sumx*sumxy)/(n*sumxquad-pow(sumx,2));
        
        printf ("\nDella retta y=ax+b, il valore di a è %f", a);
        printf ("\nDella retta y=ax+b, il valore di b è %f", b);
        
        printf ("\nInserire la varianza delle y(inserire 0 se non è nota): ");
        scanf ("%lf",&sigmay);
        
        if (sigmay==0) {
            
            for (i=0; i<n; i++) {
                persigmay+=pow((y[i]-b-a*x[i]),2);
            }
            
            sigmay=sqrt(persigmay/(double)(n-2));
        }
        
        printf ("\npersigmay=%f", persigmay);
        printf ("\nsigmay=%f", sigmay);
        
        erra=sigmay*sqrt(n/(n*sumxquad-pow(sumx,2)));
        errb=sigmay*sqrt(sumxquad/(n*sumxquad-pow(sumx,2)));
        
        printf ("\nL'indeterminazione associata al parametro a della retta y=ax+b è %f", erra);
        printf ("\nL'indeterminazione associata al parametro b della retta y=ax+b è %f", errb);
        
    }
    
    else {
        printf ("\nStimiamo il parametro k della funzione y=klnx.");
        
        for (i=0; i<n; i++) {
            sumylnx+=y[i]*log(x[i]);
            sumlnquad+=pow(log(x[i]),2);
        }
        
        k=sumylnx/sumlnquad;
        
        printf ("\nIl valore del parametro k della funzione y=klnx è %f", k);
        
    }
}

comunque se sul terminale scrivo clang dice che non lo conosce...

vict85
L'ho provato su eclipse con il plug-in di clang e llvm e ho avuto qualche problema con lo scanf quanto facevo partire il programma nella console di eclipse. Mentre se uso la console di windows va tutto liscio. Il mio suggerimento è quello di provare a vedere se usando la console di Mac riesci a far partire normalmente il codice. Se funziona fai partire il codice sempre attraverso la console normale.

valentina921
Che vuol dire "attraverso la console"? Scusa, ma anche se sto imparando a programmare so ancora molto poco di computer in generale!

Raptorista1
La console è il terminale, sempre.
Se una cosa va fatta "da console", "con la console", "attraverso la console"..... Significa che devi aprire il terminale ed usare il comando che fa quella cosa.

valentina921
Ok, lo farò e poi vi farò sapere, grazie :)

giozh
due cose che noto nel tuo codice:
la prima è che hai dichiarato che il main ritorna un intero, ma non c'è traccia di return nel tuo codice. Questa cosa non è influente ai fini dell'esecuzione del programma, ma è sempre buona norma fare attenzione ai valori di ritorno delle funzioni. Visto che il tuo codice fa solo delle stampe, puoi benissimo dichiarare il main come void.
La seconda, che molto probabilmente fa sballare il tuo software, risiede proprio nel primo argomento della scanf. Infatti dopo che dichiari il tipo di dato che stai per acquisire, mettici subito dopo un bel \n, ovvero

scanf("%i\n", &array[i]);


se non ricordo male, la scanf non va a leggere i caratteri nel buffer "quando gli pare" e non contestualmente al tuo inserimento. Inserendo lo \n "obblighi" in qualche modo la scanf ad andarsi a prelevare il dato che hai appena inserito. Fai queste modifiche e guarda se il software va.

apatriarca
Visto che il tuo codice fa solo delle stampe, puoi benissimo dichiarare il main come void.

Lo standard C richiede espressamente che il main restituisca un int. Per cui NO, non si può benissimo dichiarare il main come void. La cosa giusta da fare è scrivere un misero return 0; alla fine del main che non costa poi tanta fatica.

Il '\n' nello scanf ha il solo scopo di dire allo scanf di leggere da standard input, e ignorare, un numero arbitrario di spazi o a capo o tabulazioni inserite dopo l'intero. Il comportamento di scanf non è poi quello da te descritto. Lo scanf blocca l'esecuzione del programma finché non abbia letto tutto quello che devi leggere (e in effetti inserendo '\n' la situazione peggiora in quanto devi inserire un carattere diverso dallo spazio o dall'andare a capo perché la chiamata a scanf termini e il codice continui). Prima di inserire una risposta sarebbe meglio verificare le proprie affermazioni.

giozh
ehm, si, sulla scanf ho fatto confusione con un'altra sys call.
resta il fatto che spesso e volentieri mi è capitato che l'aver omesso lo \n in una scanf, mi ha portato a dei problemi di esecuzione. Non avendo eseguito il suo codice, quella è stata una delle prime cose che mi sono venute in mente.
Per quanto riguarda il tipo di ritorno del main, anche se va contro lo standard, il fatto di mettere un void al posto di un int, non mi ha mai causato problemi, almeno per codice "base"

apatriarca
Molti compilatori accettano il void come valore di ritorno per il main come estensione per cui in pratica non ci sono quasi mai problemi. Ma il codice comunque sembra funzionare, l'ho provato e riesco a compilarlo ed eseguirlo senza problemi. In effetti, anche Valentina riesce a compilarlo ed eseguirlo su cygwin (ci sono comunque soluzioni molto migliore per programmare su Windows che usare cygwin..). Il problema non credo che sia nel codice, ma nell'uso di Xcode..

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.