Sign in to follow this  
Martin Decker

Un paio di domande per programmatori C

Recommended Posts

Ciao a tutti,

faccio di nuovo riferimento a questo forum per avere qualche chiarimento, precisando che non sono un programmatore professionista (e si vede anche dalle domande che faccio!!!).

Io uso, per programmare in C, Xcode versione 2.4.1 su Tiger 10.4.11 e MacBookPRO intel 2.2 GHZ.

Ho dei problemi nell'uso delle variabli double. Se dichiaro una variabile come double e poi decido di stamparla con una printf normalissima come

printf ("%g", c);

dove c è una variabile regolarmente dichiarata double, il compilatore stampa un valore senza senso.

Qualcuno sa dirmi dove sbaglio?

La seconda domanda è un po' più filosofica e riguarda l'uso delle funzioni. Normalmente io dichiaro le funzioni mettendo il prototipo a monte del main(). Ma mi sono imbattuto in codici che hanno la funzione dichiarata internamente al main(). Qual è la differenza? Ho fatto delle prove e ho notato che dichiarando la funzione esternamente al main si può usare direttamente in altre espressione semplicemente invocandola. Mi spiego meglio: se la funzione atof che restituisce un double è dichiarata esternamente (prima del main()) posso fare:

printf("%g", atof(s));

ma se dichiaro atof all'interno del main la chiamata precedente non funziona e bisogna prima assegnare il valore ritornato da atof ad un'altra variabile e poi eseguire la printf; così:

c=atof(s);

printf("%g",c);

Qualcuno sa spiegarmi il motivo di questo comportamento? Non è che non ci dorma la notte, però mi sembra una cosa piuttosto importante per capire il funzionamento del compilatore.

A questo punto se avete letto fin qua senza cambiare thread siete dei grandi e vi ringrazio. Ciao a tutti,

MD

Share this post


Link to post
Share on other sites

prova ad usare %f...

cioé, tu dici di usare %f sia per i double che per i float? Non è che poi mi converte il double in float e a me sembra che va tutto bene e in realtà lo spazio riservato alla variabile è più piccolo?

MD

Share this post


Link to post
Share on other sites

Ho vaghi ricordi di un %lf, almeno nella printf, nella scanf mi pare che sia sempre %f. E' per questo genere di cose che quando programmo in quel linguaggio mi tengo sempre il K&R a fianco... non c'è verso per me di imparare a memoria quei codici :|

Share this post


Link to post
Share on other sites

Ho vaghi ricordi di un %lf, almeno nella printf, nella scanf mi pare che sia sempre %f. E' per questo genere di cose che quando programmo in quel linguaggio mi tengo sempre il K&R a fianco... non c'è verso per me di imparare a memoria quei codici :|

Il K&R ce l'ho sotto il naso adesso e qui dicono di usare %g.

Vabbé, il tipo float basta e avanza per quello che devo fare io. Però se voglio dichiarare la variabile double non capisco proprio come fare.... anche perché ci sono parecchie funzioni nelle librerie che ritornano proprio quel tipo.

MD

Share this post


Link to post
Share on other sites

Ho vaghi ricordi di un %lf, almeno nella printf, nella scanf mi pare che sia sempre %f. E' per questo genere di cose che quando programmo in quel linguaggio mi tengo sempre il K&R a fianco... non c'è verso per me di imparare a memoria quei codici :|

Non vorrei sbagliarmi ma credo che sia il contrario. Ovvero, per la scanf ci vuole un %lf, siccome altrimenti la scanf scrive solamente i primi 32 bit della variabile, invece con %lf funziona correttamente.

La printf non dovrebbe invece farsi molti problemi a riguardo.

Share this post


Link to post
Share on other sites

Hai inizializzato la variabile prima di stamparne il valore? Altrimenti è normale che contenga un valore random.

Per quanto riguarda la riflessione sulle funzioni non so che dirti. Non mi ricordo di aver mai visto funzioni dichiarate dentro altre funzioni (ma è possibile in C ?).

Share this post


Link to post
Share on other sites

Ho controllato con il man, %g %f e %lf sono la stessa cosa per la printf:

         Modifier    a, A, e, E, f, F, g, G         [b]l[/b] (ell)     double (ignored, same behavior as without it)
Mentre per la scanf ci vuole %lf.

Non ho capito bene il problema delle funzioni, il C normalmente non permette di dichiarare funzioni dentro altre funzioni (o meglio, si può fare, sono le nested function, ma non so se stai parlando di questo).

Ad ogni modo se io faccio qualcosa del genere:

printf("%f\n", atof("2.32"));
funziona correttamente, al patto di aver incluso stdlib.h

Share this post


Link to post
Share on other sites

funzione dichiarata internamente al main()

Cancella dalla tua mente quanto appena detto. :)

Riguardo ai float ho sempre usato %f con le varie opzione per dire quante cifre visualizzare dopo la virgola, del tipo %.2f, ecc...

Ciao

Cpu86

Share this post


Link to post
Share on other sites

Cancella dalla tua mente quanto appena detto. :)

Riguardo ai float ho sempre usato %f con le varie opzione per dire quante cifre visualizzare dopo la virgola, del tipo %.2f, ecc...

Ciao

Cpu86

Io ho scritto questo programma:

#include <stdio.h>

#define MAXLINE 100

int main ()

{

double sum=0.0;

char line[MAXLINE];

double merdel (char s[]);

int getline (char s[], int lim);

while (getline (line, MAXLINE)>0)

printf ("\n%g\n", (sum+=merdel(line)));

return 0;

}

che funziona perfettamente. Tra l'altro, come si può vedere, ho usato il double. Il problema era proprio l'inizializzazione della variabile, almeno credo, anche se non ho ancora provato con la scanf. Comunque ringrazio gli utenti del forum per l'imbeccata!

Le funzioni "merdel" (scusate il nome) e "getline", che, come puoi vedere sono dichiarate internamente al main(), sono in altri due rispettivi files nello stesso progetto e compilate assieme al file sorgente. A questo punto forse dovresti rivedere le tue certezze.

Mi sarebbe piaciuto fare un po' di chiarezza su questa faccenda.

Riporto per completezza le due funzioni. In pratica "merdel" è una atof un po' artigianale fatta per esercizio.

#include <stdio.h>

int getline (char s_f[], int lim_f)

{

int i, c;

for (i=0;--lim_f>0 && (c=getchar())!=EOF && c!='\n';i++)

s_f=c;

if (c=='\n')

s_f[i++]='\0';

return (i);

}

#include <stdio.h>

#include <ctype.h>

double merdel(char s_f[])

{

double val, power;

int i, exp, sign=0;

for (i=0; isspace(s_f);i++)

;

if (s_f=='+' || s_f=='-')

{

sign =((s_f=='-') ? -1 : 1);

i++;

}

for (val =0.0;isdigit(s_f);i++)

val=10*val + (s_f -'0');

if (s_f=='.' || s_f==',')

i++;

for (power=1.0; isdigit(s_f); i++)

{

val=10*val + (s_f - '0');

power *= 10;

}

if (sign==0)

sign=1;

val = sign*val/power;

sign=0;

if (s_f=='e' || s_f=='E')

{

i++;

if (s_f=='-')

{

sign=-1;

i++;

}

else if (s_f=='+')

{

sign=1;

i++;

}

for (exp=0; isdigit(s_f);i++)

exp=10*exp + (s_f -'0');

if (sign==0 || sign==1)

while (exp>0)

{

val*=10;

exp--;

}

else if (sign==-1)

while (exp>0)

{

val/=10;

exp--;

}

}

return val;

}

Saluti a tutti!!

MD

Share this post


Link to post
Share on other sites

Le funzioni "merdel" (scusate il nome) e "getline", che, come puoi vedere sono dichiarate internamente al main(), sono in altri due rispettivi files nello stesso progetto e compilate assieme al file sorgente. A questo punto forse dovresti rivedere le tue certezze.

Mi sarebbe piaciuto fare un po' di chiarezza su questa faccenda.

Il tuo modo, seppur sintatticamente corretto, non lo e' semanticamente.

Devi far capire al tuo sorgente che le funzioni mendel e getline sono implementate in files esterni, quindi o usi degli header nei quali dichiari i prototipi di tali funzioni, oppure usi extern.

Cpu86

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this