View Full Version : [C]Ciclo for infinito, non riesco ad individuare il problema
The-Revenge
19-11-2009, 12:20
Perchè questo cicli for mi và in un loop infinito?
for(t=0;t<dim2;t++)
for(i=0;i<dim;i++)
for(j=0;j<dim;j++){
if(A[i]==B[j]){
for(k=0;k<t;k++)
if(A[i]!=V[k])
V[t]=A[i];
else break;
}
}
banryu79
19-11-2009, 12:38
for (t=0; t<dim2; t++)
for (i=0; i<dim; i++)
for (j=0; j<dim; j++)
if (A[i]==B[j]) {
for (k=0; k<t; k++)
if (A[i]!=V[k])
V[t]=A[i];
else
break;
}
Sei sicuro che questi cicli annidati ti vadano in loop infinito? Non è che semplicemente ci vuole molto tempo per eseguire tutte le computazioni?
Che grandezze hai per dim2, dimm?
Perchè (sarò ciecato io) dal codice non mi pare ci sia nulla che possa riccondurre alla possibilità di un loop infinito.
The-Revenge
19-11-2009, 12:43
for (t=0; t<dim2; t++)
for (i=0; i<dim; i++)
for (j=0; j<dim; j++)
if (A[i]==B[j]) {
for (k=0; k<t; k++)
if (A[i]!=V[k])
V[t]=A[i];
else
break;
}
Sei sicuro che questi cicli annidati ti vadano in loop infinito? Non è che semplicemente ci vuole molto tempo per eseguire tutte le computazioni?
Che grandezze hai per dim2, dimm?
Perchè (sarò ciecato io) dal codice non mi pare ci sia nulla che possa riccondurre alla possibilità di un loop infinito.
in effetti ora che mi ci fai pensare in altri programmi mi andava in loop infinito e la finestra rimaneva aperta, mentre qua mi dà "il programma ha smesso di funzionare". Quindi non ha un ciclo infinito, ma qualche problema c'è di sicuro (il compilatore non me lo segnala però).
Le dimensioni di dim sono 100, dim 2 varia a seconda degli elementi uguali di dim 1, ma comunque è compreso tra 0 e 100
The-Revenge
19-11-2009, 12:46
questo è tutto il codice
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define VERO 1
#define FALSO 0
#define dim 100
void prim(int);
main(){
int min,mag,dif,dim2,i,j,k,t, A[dim],B[dim],V[dim2];
srand(time(NULL));
for(i=0;i<dim;i++){
A[i]=rand()%27+45;
B[i]=rand()%27+45;
}
printf("\nIl primo vettore e':\n");
for(i=0;i<dim;i++)printf("%d ",A[i]);
printf("\nIl secondo vettore e':\n");
for(i=0;i<dim;i++)printf("%d ",B[i]);
//calcolo dimensione del vettore intersezione
for(i=0;i<dim;i++)
for(j=0;j<dim;j++)
if(A[i]==B[j]){
dim2++;
break;
}
//fine
//calcolo elementi intersezione eliminando ripetuti
for(t=0;t<dim2;t++)
for(i=0;i<dim;i++)
for(j=0;j<dim;j++){
if(A[i]==B[j]){
for(k=0;k<t;k++)
if(A[i]!=V[k])
V[t]=A[i];
else break;
}
}
printf("\nIl vettore intersezione e':\n");
for(i=0;i<dim2;i++)printf("%d ",V[i]);
for(i=0;i<dim2;i++)if(V[i]>V[0])mag++;
min=dim-mag;
dif=mag-min;
prim(dif);
system("PAUSE");
return(0);
}
//funziona primalità
void prim(int num){
int i=3;
int primo = FALSO;
if((num%2)==0 || (num==1)) //Se il numero è 1 o 2 allora è primo
primo = VERO;
while((primo==FALSO) && (i<num)) //Qui arriva soltanto se il numero è maggiore di 2
{
if((num%i)==0) //Controlla se da una divisione esce il resto zero
primo=VERO;
i=i+2;
}
if (primo==FALSO)
printf("Il numero %d e' primo\n", num);
else
printf("Il numero %d non e' primo\n", num);
}
banryu79
19-11-2009, 15:59
Scusa, ma dim2 prima di essere incrementato, non ha bisogno di essere inizializzato?
main(){
int min,mag,dif,dim2,i,j,k,t, A[dim],B[dim],V[dim2];
srand(time(NULL));
for(i=0;i<dim;i++){
A[i]=rand()%27+45;
B[i]=rand()%27+45;
}
printf("\nIl primo vettore e':\n");
for(i=0;i<dim;i++)printf("%d ",A[i]);
printf("\nIl secondo vettore e':\n");
for(i=0;i<dim;i++)printf("%d ",B[i]);
//calcolo dimensione del vettore intersezione
for(i=0;i<dim;i++)
for(j=0;j<dim;j++)
if(A[i]==B[j]){
dim2++;
break;
}
//fine
Anzi, a essere onesto molte cose non mi tornano (sarà che sono stanco...); tipo il codice mi pare sia in linguaggio C.
Vedo delle variabili dichiarate, ma non inizializzate e poi utilizzate (tipo dim2, ma anche dim)... sono dolori a tutto spiano, da quel poco che ricordo del C.
yorkeiser
19-11-2009, 16:11
Questa dichiarazione è errata:
int min,mag,dif,dim2,i,j,k,t, A[dim],B[dim],V[dim2];
Non puoi dichiarare sulla stessa riga un intero (dim2) e contestualmente un vettore che ha dimensione dim2, visto che oltretutto, ammesso che dim2 sia stato inizializzato, varrebbe 0, quindi avresti un vettore di dimensione 0.
Puoi correggere ad esempio con:
int min,mag,dif,dim2,i,j,k,t, A[dim],B[dim];
dim2=100;
int V[dim2];
EDIT: Avevo lasciato il tab aperto prima di postare la risposta, vedo che Banryu mi ha preceduto ;)
Comunque, repetita iuvant ;)
banryu79
19-11-2009, 16:29
EDIT: Avevo lasciato il tab aperto prima di postare la risposta, vedo che Banryu mi ha preceduto ;)
Comunque, repetita iuvant ;)
No, no, vai vai anche tu, io il codice C non lo "frequento" più da anni ormai :D
The-Revenge
19-11-2009, 20:38
scusa ma se quindi dichiari
int dim;
int v[dim]
cosi va bene?o nemmeno? devo per froza dargli un numero alla dimensione?
Comunque ho modificato il programma in una maniera che forse dovrebbe essere più corretta, ma non funziona ugualmente, mi dà numeri random.
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define VERO 1
#define FALSO 0
#define dim 10
#define dim3 27
void prim(int);
main(){
int min=0,mag=0,dif=0,dim2=0,i=0,j=0,k=0,t=0, A[dim],B[dim],Atemp[dim3],Btemp[dim3];
srand(time(NULL));
for(i=0;i<dim;i++){
A[i]=rand()%27+45;
B[i]=rand()%27+45;
}
printf("\nIl primo vettore e':\n");
for(i=0;i<dim;i++)printf("%d ",A[i]);
printf("\nIl secondo vettore e':\n");
for(i=0;i<dim;i++)printf("%d ",B[i]);
//calcolo dimensione del vettore intersezione
for(i=0;i<dim;i++){
for(k=0;k<j;k++)if(A[i]==A[k])break;
for(j=0;j<dim;j++)
if(A[i]==B[j]){
dim2++;
break;
}
}
//fine
printf("%d",dim2);
int V[dim2];
//calcolo elementi intersezione eliminando ripetuti
for(i=0;i<dim3;i++)
for(j=0;j<dim;j++){
for(k=0;k<dim;k++)
if(A[j]==A[k])continue;
if(i+45==A[j])
Atemp[i]=1;
else Atemp[i]=0;
}
for(i=0;i<dim3;i++)
for(j=0;j<dim;j++){
for(k=0;k<dim;k++)
if(B[j]==B[k])continue;
if(i+45==B[j])
Btemp[i]=1;
else Btemp[i]=0;
}
for(i=0;i<dim2;i++)
for(j=0;j<dim3;j++)
if((Atemp[j]==1)&&(Btemp[j]==1))V[i]=i+45;
//calcolo maggiori, minori, primalità
printf("\nIl vettore intersezione e':\n");
for(i=0;i<dim2;i++)printf("%d ",V[i]);
for(i=0;i<dim2;i++)if(V[i]>V[0])mag++;
min=dim-mag;
dif=mag-min;
prim(dif);
system("PAUSE");
return(0);
}
//funziona primalità
void prim(int num){
int i=3;
int primo = FALSO;
if((num%2)==0 || (num==1)) //Se il numero è 1 o 2 allora è primo
primo = VERO;
while((primo==FALSO) && (i<num)) //Qui arriva soltanto se il numero è maggiore di 2
{
if((num%i)==0) //Controlla se da una divisione esce il resto zero
primo=VERO;
i=i+2;
}
if (primo==FALSO)
printf("Il numero %d e' primo\n", num);
else
printf("Il numero %d non e' primo\n", num);
}
yorkeiser
20-11-2009, 10:32
scusa ma se quindi dichiari
int dim;
int v[dim]
cosi va bene?o nemmeno? devo per froza dargli un numero alla dimensione?
#define dim 10
int v[dim];
va bene, dal momento che dim viene sostituito con il valore 10 e quindi alla seconda riga dichiari un array di 10 elementi.
int dim;
int v[dim];
non va bene perchè:
a) stai utilizzando una variabile (dim) non inizializzata, il cui valore è imprevedibile, e non ha senso dichiarare un array di grandezza casuale
b) la gran parte dei compilatori (ma non ne hai certezza) inizializza dim al valore 0 dopo la dichiarazione, quindi su questi compilatori stai dichiarando un array di 0 elementi.
Potresti avere array di grandezza variabile solo utilizzando l'allocazione dinamica, ma ti consiglio di fare un po' di esperienza col c prima di passare su quella sponda, che per esperienza risulta sempre un po' ostica.
The-Revenge
20-11-2009, 13:06
#define dim 10
int v[dim];
va bene, dal momento che dim viene sostituito con il valore 10 e quindi alla seconda riga dichiari un array di 10 elementi.
int dim;
int v[dim];
non va bene perchè:
a) stai utilizzando una variabile (dim) non inizializzata, il cui valore è imprevedibile, e non ha senso dichiarare un array di grandezza casuale
b) la gran parte dei compilatori (ma non ne hai certezza) inizializza dim al valore 0 dopo la dichiarazione, quindi su questi compilatori stai dichiarando un array di 0 elementi.
Potresti avere array di grandezza variabile solo utilizzando l'allocazione dinamica, ma ti consiglio di fare un po' di esperienza col c prima di passare su quella sponda, che per esperienza risulta sempre un po' ostica.
capisco...però non ho problemi se prima mi calcolo la dimensione, e poi gliela assegno, giusto?
Ad esempio se faccio un operazione su 2 vettori e questa operazione alla fine mi restituisce dim2, e nel rigo dopo scrivo
int v[dim2] cosi va bene vero?
The-Revenge
23-11-2009, 13:30
Ragazzi ho riscritto il codice, adesso mi funziona tutto tranne un pezzo in cui stampo i valori delle intersezioni.
Ecco tutto il programma
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define VERO 1
#define FALSO 0
#define dim 10
#define dim3 27
void prim(int);
main(){
int min=0,mag=0,dif=0,dim2=0,i=0,j=0,k=0;
int A[dim],B[dim],Atemp[dim3],Btemp[dim3];
srand(time(NULL));
for(i=0;i<dim;i++){
A[i]=rand()%27+45;
B[i]=rand()%27+45;
}
printf("\nIl primo vettore e':\n");
for(i=0;i<dim;i++)printf("%d ",A[i]);
printf("\nIl secondo vettore e':\n");
for(i=0;i<dim;i++)printf("%d ",B[i]);
//calcolo dimensione del vettore intersezione
for(i=0;i<dim;i++){
for(k=0;k<i;k++)if(A[i]==A[k])break;
for(j=0;j<dim;j++)
if(A[i]==B[j]){
dim2++;
break;
}
}
//fine
int V[dim2];
//calcolo elementi intersezione eliminando ripetuti
for(i=0;i<dim3;i++)
for(j=0;j<dim;j++){
if(A[j]==(i+45)){
Atemp[i]=1;
break;
}
else Atemp[i]=0;
}
for(i=0;i<dim3;i++)
for(j=0;j<dim;j++){
if(B[j]==(i+45)){
Btemp[i]=1;
break;
}
else Btemp[i]=0;
}
//inizio prova
printf("dim2 e' : %d",dim2);
printf("vettore Atemp: ");
for(i=0;i<dim3;i++)printf("%d ",Atemp[i]);
printf("vettore Btemp: ");
for(i=0;i<dim3;i++)printf("%d ",Btemp[i]);
for(i=0;i<dim2;i++)
for(j=k;j<dim3;j++)
if((Atemp[j]==1)&&(Btemp[j]==1)){
V[i]=(j+45);
k=j+1;
break;
}
//calcolo maggiori, minori, primalità
printf("\nIl vettore intersezione e':\n");
for(i=0;i<dim2;i++)printf("%d ",V[i]);
for(i=0;i<dim2;i++)if(V[i]>V[0])mag++;
min=dim-mag;
dif=mag-min;
prim(dif);
system("PAUSE");
return(0);
}
//funziona primalità
void prim(int num){
int i=3;
int primo = FALSO;
if((num%2)==0 || (num==1)) //Se il numero è 1 o 2 allora è primo
primo = VERO;
while((primo==FALSO) && (i<num)) //Qui arriva soltanto se il numero è maggiore di 2
{
if((num%i)==0) //Controlla se da una divisione esce il resto zero
primo=VERO;
i=i+2;
}
if (primo==FALSO)
printf("Il numero %d e' primo\n", num);
else
printf("Il numero %d non e' primo\n", num);
}
mentre questo è il pezzo che non funziona
for(i=0;i<dim2;i++)
for(j=k;j<dim3;j++)
if((Atemp[j]==1)&&(Btemp[j]==1)){
V[i]=(j+45);
k=j+1;
break;
}
Non funziona perchè l'ultimo valore me lo da casuale, un numero grandissimo
maulattu
23-11-2009, 22:50
capisco...però non ho problemi se prima mi calcolo la dimensione, e poi gliela assegno, giusto?
Ad esempio se faccio un operazione su 2 vettori e questa operazione alla fine mi restituisce dim2, e nel rigo dopo scrivo
int v[dim2] cosi va bene vero?
no, perché il compilatore a compile time non sa quanto varrà dim2.
vedila da questo punto di vista
int a;
int b;
int result;
scanf("Numero a: %d", &a);
scanf("Numero b: %d", &b);
result = a+b;
print("Risultato è: %d\n", result);
int v[result];
int i;
fot (i = 0; i <result; i++) {...}
tu a priori sai quanto varrà "result"? No :)
il compilatore nemmeno, dunque non saprà quanto spazio allocare per l'array v.
ah, a proposito: se non devi usare numeri con segno, dichiara le variabili come unsigned. Non è il massimo avere result = -1 e poi creare (dinamicamente) un array di dimensione result :read:
anzi, mi meraviglio che ti compili una cosa del genere. visual studio 2005 si incazza come una iena, e credo pure gcc.
l'unica cosa permessa è:
const unsigned result = 100;
int v[result];
essendo const, l'inizializzazione è obbligatoria dopo la dichiarazione e, di conseguenza, il compilatore saprà quando spazio allocare per l'array v
The-Revenge
24-11-2009, 11:56
no, perché il compilatore a compile time non sa quanto varrà dim2.
vedila da questo punto di vista
int a;
int b;
int result;
scanf("Numero a: %d", &a);
scanf("Numero b: %d", &b);
result = a+b;
print("Risultato è: %d\n", result);
int v[result];
int i;
fot (i = 0; i <result; i++) {...}
tu a priori sai quanto varrà "result"? No :)
il compilatore nemmeno, dunque non saprà quanto spazio allocare per l'array v.
ah, a proposito: se non devi usare numeri con segno, dichiara le variabili come unsigned. Non è il massimo avere result = -1 e poi creare (dinamicamente) un array di dimensione result :read:
anzi, mi meraviglio che ti compili una cosa del genere. visual studio 2005 si incazza come una iena, e credo pure gcc.
l'unica cosa permessa è:
const unsigned result = 100;
int v[result];
essendo const, l'inizializzazione è obbligatoria dopo la dichiarazione e, di conseguenza, il compilatore saprà quando spazio allocare per l'array v
ho capito. Però adesso il programma mi funziona dichiarandolo dopo. Cioè come ho scritto sopra, il programma funziona , dopo varie volte che lo modificato: prima ho fatto il calcolo di dim2, e poi ho dichiariato il vettore di dimensioni dim2. Tu hai detto che nn è possibile, e per motivi giustissimi, però il risultato me lo dà smepre corretto...mhà
tomminno
24-11-2009, 12:51
ho capito. Però adesso il programma mi funziona dichiarandolo dopo. Cioè come ho scritto sopra, il programma funziona , dopo varie volte che lo modificato: prima ho fatto il calcolo di dim2, e poi ho dichiariato il vettore di dimensioni dim2. Tu hai detto che nn è possibile, e per motivi giustissimi, però il risultato me lo dà smepre corretto...mhà
Il perchè è presto detto: il tuo codice è perfettamente valido col C99.
Non lo è in C++ e C89.
The-Revenge
24-11-2009, 15:43
Il perchè è presto detto: il tuo codice è perfettamente valido col C99.
Non lo è in C++ e C89.
capito..ammazza ci sono un sacco di regole e di standard :doh:
Ma io visual C++ non lo so usare, riesco a malappena a compilare
questo codice per esempio, che mi sembra del tutto normale e lineare, mi dà un errore sia in in visual c che in devc...mi dice "too few arguments in function "int confronto(int)
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define dim 50
void stampa(void);
int media(void);
void genera(void);
int confronto(int);
int A[dim][dim];
int i,j;
int main(){
srand(time(NULL));
genera();
stampa();
printf("\nIl numero e' %d",confronto());
system("PAUSE");
return(0);
}
void genera(void){
for(i=0;i<dim;i++)
for(j=0;j<dim;j++)
A[i][j]=rand()%5+13;
}
void stampa(void){
printf("\nIl vettore e':\n");
for(i=0;i<dim;i++){
printf("\n");
for(j=0;j<dim;j++)
printf("%d ",A[i][j]);
}
}
int confronto(int media()){
int count;
for(i=0;i<dim;i++)
for(j=0;j<dim;j++)
if((j<dim-1-i)&&(j>i)){
if(A[i][j]>media())count++;
}
return(count);
}
int media(void){
int med;
for(i=0;i<dim;i++)
for(j=0;j<dim;j++)
med=med+A[i][j];
med=med/(dim*dim);
return(med);
}
||ElChE||88
24-11-2009, 15:53
int confronto(int media())
?
The-Revenge
24-11-2009, 16:44
int confronto(int media())
?
la funzione confronto in ingresso ha bisogno del valore di uscita della funziona media.E' sbagliato?
cmq nn me lo da li l'errore, me lo da quando dichiaro confronto, fuori dal main.
tomminno
24-11-2009, 16:59
la funzione confronto in ingresso ha bisogno del valore di uscita della funziona media.E' sbagliato?
cmq nn me lo da li l'errore, me lo da quando dichiaro confronto, fuori dal main.
E' sbagliato come lo scrivi, quando dichiari e scrivi il corpo della funzione confronto devi semplicemente specificare un intero.
Poi nel tuo caso quando andrai a richiamarla potrai fare:
printf("\nIl numero e' %d",confronto(media()));
yorkeiser
24-11-2009, 17:20
la funzione confronto in ingresso ha bisogno del valore di uscita della funziona media.E' sbagliato?
cmq nn me lo da li l'errore, me lo da quando dichiaro confronto, fuori dal main.
La dichiarazione è errata; in questo caso, che è comunque anche concettualmente errato, dovresti usare un puntatore a funzione.
dichiarazione:
int (*puntatore)();
nel main:
puntatore=media;
A questo punto, puntatore punta alla funzione media, quindi puoi passarlo alla funzione confronto().
Ti spiego però perchè è errato anche dal punto di vista concettuale (non ti offendere, sono errori che fanno tutti e solo l'esperienza aiuta ad evitarli): media è sempre uguale e non cambia nel tempo, quindi non ha senso ricalcolarlo ogni volta che accedi alla funzione confronto, sprechi solo un sacco di cicli macchina.
Il modo corretto sarebbe di calcolare la media una volta sola, ad esempio con
int m=media();
e a questo punto passi direttamente m, che è stato già valutato, alla funzione confronto.
The-Revenge
24-11-2009, 18:26
La dichiarazione è errata; in questo caso, che è comunque anche concettualmente errato, dovresti usare un puntatore a funzione.
dichiarazione:
int (*puntatore)();
nel main:
puntatore=media;
A questo punto, puntatore punta alla funzione media, quindi puoi passarlo alla funzione confronto().
Ti spiego però perchè è errato anche dal punto di vista concettuale (non ti offendere, sono errori che fanno tutti e solo l'esperienza aiuta ad evitarli): media è sempre uguale e non cambia nel tempo, quindi non ha senso ricalcolarlo ogni volta che accedi alla funzione confronto, sprechi solo un sacco di cicli macchina.
Il modo corretto sarebbe di calcolare la media una volta sola, ad esempio con
int m=media();
e a questo punto passi direttamente m, che è stato già valutato, alla funzione confronto.
si è tutto chiaro..grazie mille...in effetti ora che mi hai fatto notare, era un suicidio di efficenza, invece cosi la media la calcola 1 volta sola ;)
Non ho ben capito il fatto dei puntatori, ma visto che sono uno studente e che i puntatori li ha solo accenati, credo che capirò più avanti...o meglio più che non li ho capiti, fino ad ora ho dato i puntatori come delle cose scontate, come se fossero impliciti ovvero come se il compilatore sapesse sempre dove andare a prendere i dati, cosa che non richiederebbe effettivamente l'uso dei puntatori, ma visto che questi errori che compio mi fanno capire che nn è cosi, tneterò di approfondire sui puntatori ...fermo restando che comunque col metodo di porre m=media() e poi confronto(m) il rpogramma funzione bene, ed è ciò che volevo dato che il problerma era solo una simulazione di una prova e quasi nessuno è riuscito a farla :fagiano:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.