C# Programmazione in C

gerardo99

Utente Iron
5 Gennaio 2019
2
1
0
14
Salve,
sono nuovo nel forum quindi chiedo scusa in primis se ho sbagliato sezione.

Devo scrivere un programma che cerchi la maggiore e la minore tra una serie di parole. Ho suddiviso il programma in una semplice funzione oltre al main, ma mi da questo errore quando passo l'array di stringhe ala funzione:

small_large_words.c: In function ‘main’:
small_large_words.c:58:16: warning: passing argument 1 of ‘small_large’ from incompatible pointer type [-Wincompatible-pointer-types]
small_large(parole,i,small,large);
^~~~~~
small_large_words.c:7:6: note: expected ‘char **’ but argument is of type ‘char (*)[21]’

void small_large (char *parola[], int n, char small[], char large[])

Premessa: ho provato per sfizio tutto nel main e funziona senza errori, per il momento. Sicuramente si può sviluppare qualche altro algoritmo, ma essendo un programmino da esercizio non sono andato oltre. Il problema per ora più grande è l'errore che mi dice.

Grazie,
GD.


CODICE PROGRAMMA:

#include <stdio.h>
#include <string.h>
#define SIZE 20 //Lunghezza massima della parola
#define N_MAX 50//Numero massimo di lettere
void small_large (char *parola[], int n, char small[], char large[])
{
int j;
strcpy(small,parola[0]);
strcpy(large,parola[0]);
for( j=0; j<n; j++)
{

if( strcmp(parola[j],small) < 0)
strcpy(small,parola[j]);
if( strcmp(parola[j],large) > 0)
strcpy(large,parola[j]);
}

}
int main(void)
{
char parole[N_MAX][SIZE+1];
char buf[SIZE+1], small[SIZE+1], large[SIZE+1];
int i,j,n,count;
i=0;
for( ; ; )
{
printf("Inserisci la parola: ");
scanf("%s",buf);
n = strlen(buf);
if(n>4)
break;
strcpy(parole,buf);
if(i==N_MAX)
break;
i++;

}

small_large(parole,i,small,large);
printf("%s %s",small,large);
return 0;


}
 
L'unico errore è strcpy(parole, buf) che dovrebbe essere strcpy(parole[i], buf), ovvero salva la parola attuale buf in posizione i-esima dell'array parole. Per il resto sono sottigliezze.

Quello che leggi sul compilatore non è un errore (error), ma è un avviso (warning). In particolare ti sta dicendo che quella cosa che gli stai passando non è del tipo che lui si aspetta. Non è un errore perché quei tipi vengono convertiti implicitamente, però lui ti avvisa che è probabile che tu ti stia sbagliando. Se ti vuoi disfare di quel warning dovresti definire la funzione in questo modo: void small_large (char parola[][SIZE + 1], int n, char small[], char large[]).

Ci sono altre cose che andrebbero ritoccate, in particolare quel ciclo infinito con i break dentro è proprio brutto, ma visto che sei agli inizi e stai imparando credo che possa essere un buon esercizio provare a migliorare quel codice autonomamente.

PS. Per la programmazione e in particolare per il C e il C++ c'è una sezione apposta (link).
 
  • Mi piace
Reazioni: gerardo99
Ora prova a vedere se risolve il warming. Per quel che riguarda le “sottigliezze” cosa intendi? Cosa potrei migliorare come impostazione diciamo di un programma in generale?
Grazie mille per la risposta!
 
In primis, come già ti ho segnalato, quel for infinito che in realtà non è un ciclo infinito: sai quando inizia (i=0), sai quando termina (i==N_MAX) e sai come si incrementa (i++); poi hai un'ulteriore condizione di uscita che potresti anche lasciare così com'è, ma sarebbe meglio se riesci a disfarti anche di quel break (non è difficile). Usare in modo appropriato i cicli migliora ed evitare i salti (break nel tuo caso) migliora notevolmente la leggibilità del codice.

È buona prassi limitare lo scope delle variabili il più possibile (o quasi) definendole vicino a dove le usi. Il tuo codice dev'essere facile da leggere: programs are meant to be read by humans and only incidentally for computers to execute. Quella cosa di definire tutte le variabili in cima allo scope si faceva con lo standard ANSI del 1989 ed era giustificato dal fatto che si capiva facilmente quanto fosse necesario abbassare lo stack per far spazio alle variabili. Tu le stai definendo tutte all'inizio della funzione, che ha anche un significato semantico un po' differente.

Un'altra cosa molto importante è la formattazione del codice. Non ho idea se il tuo codice sia indentato in modo sensato anche perché hai usato il tag [i][/i] invece del tag [code=c][/code] (lo trovi nell'editor del forum, sui tre puntini affianco al tasto per inserire le emoticons ;)).

Tra le cose ancora più sottili, ti segnalo che la scanf sarebbe meglio scriverla limitando il numero di caratteri inseriti, con scanf("%20s",buf).

Infine ti segnalo anche che per trovare l'elemento minimo e massimo esiste un algoritmo ottimo che effettua 3/4n comparazioni invece che 2n comparazioni. Con algoritmo ottimo intendo proprio che da un punto di vista teorico effettua il numero minimo di comparazioni (non è difficile la dimostrazione formale). È un algoritmo didatticamente ricorsivo (divide-et-impera -- divide-and-conquer), ma che potresti altrettanto anche implementarlo in modo iterativo (più memory efficient). Te lo posso anche spiegare se vuoi, ma se cerchi la spiegazione su un libro o su internet penso che facciamo prima entrambi... poi se non capisci, chiedi pure.