Forse sono solo vecchio e scontroso, ma le altre risposte Ho visto sembrano mancare completamente il punto.
C non esegue le assegnazioni di array, punto. Non è possibile assegnare un array a un altro array con un semplice compito, a differenza di altri linguaggi (PL/1, ad esempio, Pascal e molti dei suoi discendenti - Ada, Modula, Oberon, ecc.). Né C ha davvero un tipo di stringa. Ha solo matrici di caratteri e non è possibile copiare matrici di caratteri (non più di quanto è possibile copiare matrici di qualsiasi altro tipo) senza utilizzare un ciclo o una chiamata di funzione. [I valori letterali delle stringhe non contano realmente come tipo stringa.]
L'unica matrice di tempo che viene copiata è quando l'array è incorporato in una struttura e si esegue un'assegnazione di struttura.
Nella mia copia di K & R 2nd Edition, l'esercizio 1-19 richiede una funzione reverse(s)
; nella mia copia di K & R 1st Edition, era l'esercizio 1-17 invece di 1-19, ma è stata posta la stessa domanda.
Poiché i puntatori non sono stati trattati in questa fase, la soluzione deve utilizzare gli indici anziché i puntatori. Credo che porta a:
#include <string.h>
void reverse(char s[])
{
int i = 0;
int j = strlen(s) - 1;
while (i < j)
{
char c = s[i];
s[i++] = s[j];
s[j--] = c;
}
}
#ifdef TEST
#include <stdio.h>
int main(void)
{
char buffer[256];
while (fgets(buffer, sizeof(buffer), stdin) != 0)
{
int len = strlen(buffer);
if (len == 0)
break;
buffer[len-1] = '\0'; /* Zap newline */
printf("In: <<%s>>\n", buffer);
reverse(buffer);
printf("Out: <<%s>>\n", buffer);
}
return(0);
}
#endif /* TEST */
compilare questo con -DTEST per includere il programma di test e senza avere solo la funzione di reverse()
definita.
Con la firma della funzione indicata nella domanda, si evita di chiamare strlen()
due volte per riga di input. Nota l'uso di fgets()
- anche nei programmi di test, è una cattiva idea usare gets()
. Lo svantaggio di fgets()
rispetto a gets()
è che fgets()
non rimuove la riga finale finale dove lo fa gets()
. I lati positivi di fgets()
sono che non si ottiene un overflow di array e si può stabilire se il programma ha trovato una nuova riga o se ha esaurito lo spazio (oi dati) prima di incontrare una nuova riga.
K & R non ha utilizzato la soluzione: hanno scritto per C89, non C99, ma la soluzione utilizza un VLA (array a lunghezza variabile) che è stato aggiunto solo in C99. Inoltre, non vi è alcuna garanzia che ci sia una nuova riga nella stringa - AFAIK. E convenzionalmente, la lunghezza di una stringa esclude già il terminale null. Ciò significa che il tuo '-2' è probabilmente errato. La condizione nel primo ciclo while dovrebbe usare '<' invece di '<='; non c'è virtù nello scambiare il personaggio centrale con se stesso. La soluzione più veloce scambia l'array in situ senza array temporaneo. –
Grazie per l'intuizione. Hai ragione, stavo pensando al -2 stamattina dato che quello era un trucco che ho fatto ieri sera alle 3 del mattino solo per farlo funzionare. Probabilmente dovrei semplicemente mettere un if (s [i]! = '\ N' || s [i]! = '\ 0') nel ciclo in while. – felideon
Vecchio commento, ma (s [i]! = '\ N' || s [i]! = '\ 0') è sempre vero. – kyrias