Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Parentesi del while e istruzioni if-else (linguaggio C)

Linguaggi e sistemi

Moderatori: Foto UtentePaolino, Foto Utentefairyvilje

0
voti

[1] Parentesi del while e istruzioni if-else (linguaggio C)

Messaggioda Foto UtenteLuigi97 » 6 ago 2017, 0:41

Salve,
Innanzitutto spero che la seguente domanda sia un po' più intelligente di quelle che ho postato di recente. Stavolta ciò che non capisco è come si comporta un'istruzione else sotto ad un ciclo while che non ha le parentesi graffe. Per capire meglio ciò che intendo prediamo in considerazione il seguente algoritmo di ricerca, guardate sotto al commento "RICERCA SEQUENZIALE":
Codice: Seleziona tutto
#include <stdio.h>
#include <time.h>

int main() {
srand(time(NULL)); /*inizializzo la funzione rand con l'orario corrente per avere numeri ogni volta diversi*/
const int N=20; /*dichiaro la dimensione N del vettore*/
const int MAX=50; /*dichiaro il valore massimo contenuto nelle celle del vettore*/
int vet[N]; /*dichiaro un vettore di N interi*/
int x;
int numero_da_cercare; /*dichiaro la variabile che conterrà il valore da cercare*/

/*RIEMPIMENTO DEL VETTORE*/
for(x=0; x<N; x++) {
vet[x]=rand()%MAX; /*assegno un valore casuale tra 0 e MAX-1 alla cella vet[x]*/
printf("vet[%2d] = %2d\n", x, vet[x]); /*visualizzo i valori del vettore*/
}

/*INSERIMENTO DEL VALORE DA RICERCARE*/
do {
printf("\nInserisci il valore da cercare (valore tra 0 e %d): ", MAX-1);
scanf("%d", &numero_da_cercare);
}while(numero_da_cercare<0 || numero_da_cercare>MAX-1); /*finché non è tra 0 e MAX continuo a chiedere
l'inserimento*/

/*RICERCA SEQUENZIALE*/
x=0;
while(vet[x]!=numero_da_cercare && x<N) /*scandisco il vettore finché non trovo il valore cercato o sono in
fondo*/
x++;
/*COMUNICAZIONE DEL RISULTATO DELLA RICERCA*/
/*verifico la condizione d'uscita dal ciclo*/
if(vet[x]==numero_da_cercare) { /*se sono uscito perché ho trovato il valore cercato*/
printf("\nIl valore %d e' presente in posizione %d.\n", numero_da_cercare, x);
}else { /*se sono uscito perché ho scandito tutto il vettore*/
printf("\nIl valore %d non e' stato trovato.\n", numero_da_cercare);
}


    return 0;
}

perché il printf di else non viene stampato per tutte le volte che "vet[x]!=numero_da_cercare" ? Se si fanno 5 paragoni e tutti e 5 sono che "vet[x]!=numero_da_cercare", com'è scritto il codice, io mi aspetto che il printf di else venga stampato 5 volte (ed è ciò che accade se metto le parentesi graffe al ciclo while), in realtà però così come è stato scritto il codice (senza le parentesi graffe) il ciclo while fa prima tutti i paragoni, poi se tutti i valori risultano che "vet[x]!=numero_da_cercare" allora si attiva else. Però non ne comprendo il motivo (tale codice l'ho preso da questo sito, lo trovate come primo allegato, verso la fine)...

Io per esempio per creare un algoritmo di ricerca mi sono arrangiato così:
Codice: Seleziona tutto
#include <stdio.h>

/*determinare se un carattere è già presente all’interno di un vettore*/

#define MAX_ELE 99 /*limite del vettore*/

main(void) {
int x, grandezza_vettore;
int volte=0;
char carattere;
char vettore[MAX_ELE];

/*inserimento della grandezza del vettore*/
printf("Inserisci la grandezza del vettore (massimo %d): ", MAX_ELE);
scanf("%d", &grandezza_vettore);
if(grandezza_vettore>MAX_ELE || grandezza_vettore<1) {
do {
printf("Grandezza non valida. Inserisci una grandezza valida: ");
scanf("%d", &grandezza_vettore);   
}while(grandezza_vettore>MAX_ELE || grandezza_vettore<1);   
}

/*inserimento dei caratteri all'interno del vettore*/
printf("\nInserisci i caratteri all'interno del vettore:\n");
for(x=0; x<grandezza_vettore; x++) {
vettore[x]=EOF;   
printf("Posizione %2d:  ", x);
while(vettore[x]=='\n' || vettore[x]==EOF) {
scanf("%c", &vettore[x]);
}
}

/*inserimento del carattere da cercare*/
carattere=EOF;
printf("\nInserisci il carattere da cercare: ");
while(carattere=='\n' || carattere==EOF) {
scanf("%c", &carattere);
}

/*ricerca del carattere inserito*/
for(x=0; x<grandezza_vettore; x++) {
if(carattere==vettore[x]) {   
volte++;   
}   
}
if(volte==1) {
printf("\nLa ricerca ha prodotto un risultato. Il carattere %c si trova nella posizione n.", carattere);   
for(x=0; x<grandezza_vettore; x++) {
if(carattere==vettore[x]) {   
printf("%d.", x);
}
}
}else if(volte>1) {
printf("\nLa ricerca ha prodotto %d risultati. Il carattere %c si trova nelle seguenti posizioni:", volte,
carattere);
for(x=0; x<grandezza_vettore; x++) {
if(carattere==vettore[x]) {   
printf("\nPosizione n.%d", x);
}
}
}else {
printf("\nIl carattere %c risulta assente.", carattere);      
}

printf("\n");


    return 0;
}

Ci sono i famosi EOF poiché sennò le variabili char danno problemi. Comunque l'algoritmo di ricerca è semplicissimo: c'è una variabile che ho chiamato "volte" (forse non è proprio un nome adatto) che è inizializzata a 0. C'è un ciclo for che incrementa la variabile "x" per un numero di volte pari alla grandezza del vettore. All'interno del ciclo for c'è un'istruzione if che dice: "se il carattere da cercare è uguale al valore di vettore[x] allora la variabile "volte" viene incrementata di 1", poi proseguono le altre istruzioni if-else che si basano sulla variabile "volte"...
Tale algoritmo però non è tra i migliori... comunque ritornando alla domanda, potete spiegarmi il meccanismo che regola l'istruzione else presente nel ciclo while di cui ho parato prima?
Avatar utente
Foto UtenteLuigi97
40 4
 
Messaggi: 49
Iscritto il: 17 giu 2017, 16:35

0
voti

[2] Re: Parentesi del while e istruzioni if-else (linguaggio C)

Messaggioda Foto UtenteWALTERmwp » 6 ago 2017, 1:10

Non so se interpreto correttamente la tua domanda ma, questo while:
Codice: Seleziona tutto
...
while(vet[x]!=numero_da_cercare && x<N) /*scandisco il vettore finché non trovo il valore cercato o sono in
fondo*/
x++;
...
esegue ripetutamente solo l'istruzione "x++;" sino a che le condizioni stesse imposte al while risultano soddisfatte.
Quando non lo sono più il ciclo while si interrompe e il programma prosegue con il codice successivo ovvero esegue lo statement if / else producendo una sola volta una printf (che sia dello if o che sia dello else).

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[3] Re: Parentesi del while e istruzioni if-else (linguaggio C)

Messaggioda Foto Utentegac » 6 ago 2017, 6:42

È semplicemente dovuto a quanto scritto da Foto UtenteWALTERmwp. Se non inserisci la coppia di parentesi graffe dopo un while, if o for il compilatore considera associata al costrutto solo la prima istruzione successiva ai suddetti.

Mi permetto di inserire un altro esempio più compatto e senza commenti; se scrivessi

Codice: Seleziona tutto
while (x!=6) x=rand()%7;
printf("x diverso da 6\n");


Non verrebbe stampata la frase ogniqualvolta x è diverso da 6, in quanto il compilatore considera interna al ciclo solo la generazione del numero casuale. Invece, scrivendo

Codice: Seleziona tutto
while(x!=6){
x=rand()%7;
printf("x diverso da 6");
}


Avrei un printf ad ogni iterazione.

Per evitare errori di questo tipo, è sempre consigliabile l'inserimento di parentesi graffe dopo uno dei tre costrutti while, if e for.
Avatar utente
Foto Utentegac
925 3 6
Frequentatore
Frequentatore
 
Messaggi: 216
Iscritto il: 8 dic 2015, 22:29

0
voti

[4] Re: Parentesi del while e istruzioni if-else (linguaggio C)

Messaggioda Foto UtenteLuigi97 » 6 ago 2017, 7:15

Non capisco... il ciclo while senza parentesi graffe considera interno ad esso soltanto la prima istruzione. La prima istruzione è "x++;" di conseguenza l'if-else non è interno al ciclo while. Se l'if-else non è interno al ciclo while, l'istruzione "if(vet[x]==numero_da_cercare)" come fa a funzionare? se l'if-else non fosse interno al ciclo while la variabile "x" tra le parentesi quadre di "vet[...]" assumerebbe soltanto l'ultimo valore di quando finisce il ciclo. Esempio: facciamo che:
Codice: Seleziona tutto
x=0;
while(x<5) {
x++;
}
if(vet[x]==numero_da_cercare)

La "x" all'interno del ciclo while assumerà i seguenti valori: 0,1,2,3,4, 5 (quando raggiunge il valore 5 però il ciclo while non si riavvia di nuovo).
A questo punto, l'istruzione "if(vet[x]==numero_da_cercare)" presente sotto al ciclo while, non dovrebbe eseguire soltanto "if(vet[5]==numero da_cercare)" ? In sostanza, ciò che adesso non capisco è: come fa la variabile "x" presente nell'istruzione "if" ad essere incrementata ogni volta come accade nel ciclo while se questa è esterna al ciclo?
Avatar utente
Foto UtenteLuigi97
40 4
 
Messaggi: 49
Iscritto il: 17 giu 2017, 16:35

0
voti

[5] Re: Parentesi del while e istruzioni if-else (linguaggio C)

Messaggioda Foto Utenteluxinterior » 6 ago 2017, 9:17

A me non è chiaro quale sia il dubbio perciò rischio di dire cose note e banali
x è una scatola
prima del ciclo while la svuoti (x=0)
Nel ciclo while ci metti dentro oggetti x++ finché non ne contiene 5 (x<5)
In uscita dal while e da lì in avanti x =5

Comunque un codice del genere è pericoloso se il while termina perché l'indice del vettore è arrivato
all'ultimo elemento nel successivo if fai un confronto farlocco
Avatar utente
Foto Utenteluxinterior
4.311 3 4 9
Master EY
Master EY
 
Messaggi: 2690
Iscritto il: 6 gen 2016, 17:48

0
voti

[6] Re: Parentesi del while e istruzioni if-else (linguaggio C)

Messaggioda Foto Utentegac » 6 ago 2017, 9:26

Luigi97 ha scritto:A questo punto, l'istruzione "if(vet[x]==numero_da_cercare)" presente sotto al ciclo while, non dovrebbe eseguire soltanto "if(vet[5]==numero da_cercare)" ?


Funziona esattamente così.

Luigi97 ha scritto:In sostanza, ciò che adesso non capisco è: come fa la variabile "x" presente nell'istruzione "if" ad essere incrementata ogni volta come accade nel ciclo while se questa è esterna al ciclo?


La stessa variabile x è adoperata nel while - ed in esso viene incrementata - e nell'if. Come già detto in precedenza, la x che arriva al costrutto if è solo x=5. Se vuoi applicare if(vet[x]==numero_da_cercare) per ogni x dell'iterazione devi mettere l'if dentro il ciclo.
Avatar utente
Foto Utentegac
925 3 6
Frequentatore
Frequentatore
 
Messaggi: 216
Iscritto il: 8 dic 2015, 22:29

0
voti

[7] Re: Parentesi del while e istruzioni if-else (linguaggio C)

Messaggioda Foto UtenteLuigi97 » 6 ago 2017, 10:07

gac ha scritto:La stessa variabile x è adoperata nel while - ed in esso viene incrementata - e nell'if. Come già detto in precedenza, la x che arriva al costrutto if è solo x=5. Se vuoi applicare if(vet[x]==numero_da_cercare) per ogni x dell'iterazione devi mettere l'if dentro il ciclo.

Riprendiamo di nuovo il codice in questione:
Codice: Seleziona tutto
x=0;
while(vet[x]!=numero_da_cercare && x<N) {
x++;
}
if(vet[x]==numero_da_cercare) {
printf("\nIl valore %d e' presente in posizione %d.\n", numero_da_cercare, x);
}else {
printf("\nIl valore %d non e' stato trovato.\n", numero_da_cercare);
}

Adesso, se la "x" arriva al costrutto if soltanto con un valore di 5, come si spiega il fatto che tale costrutto scandisce caso per caso tutti i valori per vedere se vet[x] è uguale al numero da cercare? Se la "x" valesse soltanto 5, l'if analizzerebbe soltanto vet[5] con il numero da cercare. Cerco di spiegarmi meglio: abbiamo un vettore di 5 posti:
Codice: Seleziona tutto
vet[0] = a;
vet[1] = b;
vet[2] = c;
vet[3] = d;
vet[4] = e.

E abbiamo un costrutto if che ci dice "se vet[x] è uguale al numero da cercare, allora si esegue l'istruzione". Adesso, se la "x" arriva al costrutto if solo quando termina il ciclo while, cioè solo quando "x=5", l'if si trova ad analizzare soltanto il valore della posizione numero 5. Quindi non può funzionare. In realtà però tale algoritmo, almeno da ciò che penso io, funziona come se il costrutto if-esle facesse parte del while, solo però l'if viene attivato caso per caso incrementando la variabile "x" al suo interno (tale variabile poi serve anche per indicare la posizione del valore da cercare. Se "x" fosse "5" si visionerebbe sempre posizione 5), mentre l'else viene attivato solo se la ricerca completa ha esito negativo. Il problema è che, in base a ciò che so adesso, come è scritto quel codice di regola non dovrebbe funzionare.

Comunque grazie a tutti per le risposte, se vi arrendete a spiegarmi capisco :-)
Avatar utente
Foto UtenteLuigi97
40 4
 
Messaggi: 49
Iscritto il: 17 giu 2017, 16:35

0
voti

[8] Re: Parentesi del while e istruzioni if-else (linguaggio C)

Messaggioda Foto Utenteluxinterior » 6 ago 2017, 10:17

Io continuo a non capire
Regola base il sistema è sequenziale se fa una cosa non può farne un'altra.
Se l'if è fuori dal ciclo while viene eseguito sempre e solo alla fine quando una delle due condizioni
(vet[x]!=numero_da_cercare && x<N)
è soddisfatta cioè vet[x] è uguale a numero da cercare oppure x=5
quindi
se il numero non c'è esci dal while con x=N
se il numero da cercare c'è esci dal while con x= indice della poszione del vettore corrispondente al numero

Ripeto che secondo me è sbagliato scrivere while ((vet[x]!=numero_da_cercare && x<N)
e anche in uscita dal while devi essere sicuro che x sia un indice valido per il vettore (5 non è un indice valido)
Avatar utente
Foto Utenteluxinterior
4.311 3 4 9
Master EY
Master EY
 
Messaggi: 2690
Iscritto il: 6 gen 2016, 17:48

0
voti

[9] Re: Parentesi del while e istruzioni if-else (linguaggio C)

Messaggioda Foto Utentexyz » 6 ago 2017, 10:38

Per me è più pulito, comprensibile e vengono fatti meno confronti utilizzando un indice in questo modo:

Codice: Seleziona tutto
int x:
bool found=false;

for (x=0; x<N; x++) {
   if (vet[x] == numero_da_cercare) {
        found = true;
        break;
   }
}

if (found) {
  printf("\nIl valore %d e' presente in posizione %d.\n", numero_da_cercare, x);
}
else {
  printf("\nIl valore %d non e' stato trovato.\n", numero_da_cercare);
}
Avatar utente
Foto Utentexyz
6.864 2 4 6
G.Master EY
G.Master EY
 
Messaggi: 1778
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin

0
voti

[10] Re: Parentesi del while e istruzioni if-else (linguaggio C)

Messaggioda Foto UtenteLuigi97 » 6 ago 2017, 10:45

luxinterior ha scritto:Se l'if è fuori dal ciclo while viene eseguito sempre e solo alla fine quando una delle due condizioni
(vet[x]!=numero_da_cercare && x<N)
è soddisfatta cioè vet[x] è uguale a numero da cercare oppure x=5
quindi
se il numero non c'è esci dal while con x=N
se il numero da cercare c'è esci dal while con x= indice della poszione del vettore corrispondente al numero

Ripeto che secondo me è sbagliato scrivere while ((vet[x]!=numero_da_cercare && x<N)
e anche in uscita dal while devi essere sicuro che x sia un indice valido per il vettore (5 non è un indice valido)

Ho capito! Mi ero fatto ingannare dall'istruzione presente nel ciclo while :oops:
Prometto che da oggi in poi porrò più attenzione.
Grazie a tutti per le risposte!
O_/
Avatar utente
Foto UtenteLuigi97
40 4
 
Messaggi: 49
Iscritto il: 17 giu 2017, 16:35

Prossimo

Torna a PC e informatica

Chi c’è in linea

Visitano il forum: Nessuno e 7 ospiti