2014-11-15 1 views
6

ich eine rekursive Funktion gefunden, die mich ein wenig überrascht, diese Funktion verlassen zählt alle negativen Zahlen, die in einer Reihe erscheinen:merkwürdige Ausdruck in der return-Anweisung

int count_negative(int arr[], int n) 
{ 
    if (n > 0) 
    return (*arr < 0) + count_negative(++arr, n - 1); 
    return 0; 
} 

Kann jemand diese Linie erklären:

return (*arr < 0) + count_negative(++arr, n-1); 

Danke

+1

Dies ist eine ziemlich schlechte Implementierung der Rekursion; Es kann nicht in einen Tail-Call konvertiert werden, so dass die Leistung im Vergleich zu einer iterativen Implementierung leidet. – cdhowie

+3

Ist das nicht '(* arr ...) + count_negative (++ arr, ...' provozieren UB? – alk

+0

@cdhowie: GCC scheint zu TCO es ist in Ordnung. – ninjalj

Antwort

6

(*arr < 0) vergleicht erstes Element des Arrays mit Null. Das Ergebnis des Ausdrucks kann entweder 1 (erstes Element ist negativ) oder 0 (erstes Element ist positiv oder Null) sein. Daher ist die Anzahl der negativen Elemente die Summe dieses Ausdrucks und der Anzahl der negativen Elemente im Endbereich des Arrays.

3

*arr zeigt auf das erste Element der arr Array (oder, genauer gesagt, der Teil des arr, die an die Funktion in diesem bestimmten Aufruf übergeben wurde).

count_negative(++arr, n-1) ist eine rekursive Aufruf, sondern wegen ++arr, innerhalb dieses Aufrufs zählen wir das nächste Element des Arrays und n-1 Argument, togeher mit den if (n > 0) garantiert, dass wir nur Elemente innerhalb des arr Array zählen.

2

Das Prinzip besteht darin, dass anstelle der einen Index für das Element zu halten inspiziert wird, da arr ein Zeiger ist und die Änderung wird es die Daten nicht ändern, kann man stattdessen arr sich als Iterator auf den Array-Daten verwenden.

So *arr < 0 überprüft, ob das aktuelle spitze Element negativ ist (es wird 1 ergeben, wenn der so ist, 0 wenn nicht) und ++arr inkrementiert den Cursor auf die nächste Stelle in der Anordnung, die dann weitergeleitet wird rekursiv die überprüfen Rest des Arrays.

Dies ist eine sehr bekannte Idee in funktionalen Sprachen mit Listen arbeiten, wo man oft auf dem ersten Element der Liste arbeiten (der Kopf) und auf der verbleibenden der Liste Rekursion (die Schwanz).

+2

Jetzt verstehe ich ie (* arr <0) wird entweder 1 oder 0 sein, je nachdem, ob es eine negative Zahl ist – cheroky

+0

Genau. '1' und' true' sind die gleichen Werte in C – didierc

+1

2 ist auch wahr ... ;-) – alk

Verwandte Themen