2 Stimmen

Lehrt K&R schlechte Lesbarkeit?

Es ist schon eine Weile her, dass ich mich mit C beschäftigt habe (ich lerne immer noch), und ich habe mich gerade wieder mit dem K&R-Buch beschäftigt.

Ich hatte gerade einen Besuch bei Übung 5-3 (p107).

Schreiben Sie eine Zeigerversion der Funktion strcat, die wir in Kapitel 2 gezeigt haben: strcat(s,t) kopiert die Zeichenkette t an das Ende von s.

Ich habe mir Folgendes ausgedacht este ...

void strcat(char *s, char *t);

void strcat(char *s, char *t) {

    while (*s++ != '\0');
    s--;
    while (*t != '\0') {
        *s++ = *t++;
    }

    *--t = '\0';

}

int main() {
   char str[] = "Hey, hello";
   char str2[] = " are you?";

   strcat(str, str2);

   printf("%s\n", str);

   return 0;

}

Es scheint zu funktionieren.

Was mich wundert, ist, dass das K&R-Buch oft Übungen mit so wenig Zeilen wie möglich schreibt - ich würde erwarten, dass, wenn sie ihr eigenes Code-Beispiel für oben zur Verfügung gestellt hätten, man Dinge bekommen würde wie este ...

void strcat(char *s, char *t) {

    while (*s++ != '\0');
    s--;
    while ((*s++ = *t++) != '\0');
    *--t = '\0';

}

Für mich ist das weniger lesbar (vielleicht ist das Beispiel nicht so gut, aber ich schaue mir oft ihren Code an und denke wenn das in ein paar Zeilen aufgeteilt wäre, würde ich es viel besser verstehen ). Die Beispiele im Buch scheinen diese Art der Zuweisung im Bedingungsteil einer Schleife zu befürworten, und in der Tat so viel Code wie möglich pro Zeile zu pauken.

Ist es richtig, dass das Buch versucht, so viel wie möglich zu tun, auch wenn die Lesbarkeit darunter leidet?

Ist das nur Der C-Weg ?

13voto

gregjor Punkte 20302

K&R erklären die Bedeutung von Redewendungen in dem Buch. Ja, die Kürze des C-Codes wird von C-Programmierern geschätzt, aber er ist nicht absichtlich knapp gehalten, um Anfänger zu bestrafen. Nach einiger Zeit des Lesens und Schreibens von C fängt man an, Muster zu erkennen, und wenn man sie im Code eines anderen sieht, weiß man, woran man ist.

Gehen Sie durch die Iterationen von strcpy() in K&R als Beispiel angeführt - sie erklären ihre Philosophie der Kürze gegenüber der Klarheit und sprechen über Redewendungen.

5voto

Roland Illig Punkte 38839

Sie sollten nicht erwarten, dass Ihr Programm funktioniert, denn Sie rufen undefiniertes Verhalten .

Sie definieren zwei Puffer mit einer bestimmten Größe ( str ist 11 Bytes lang, str2 ist 10 Bytes lang). Dann, während strcat versuchen Sie zu schreiben an str[11] die es nicht gibt. Ab diesem Zeitpunkt gibt es keinerlei Garantie mehr für die Ausführung Ihres Programms. Es kann abstürzen, es kann das tun, was Sie erwartet haben, oder es kann einfach "42" ausgeben und Sie fragen, warum.

Darüber hinaus sollten Sie nicht ändern *t en strcat , da in neueren Versionen von C t hat Typ const char * .

Und drittens, wenn Sie eine Funktion neu implementieren, die auch von Ihrer Umgebung bereitgestellt wird, geben Sie ihr einen anderen Namen. Andernfalls könnte Ihr Compiler sie durch einen eingebauten Code ersetzen, der dem Funktionsaufruf entspricht. Zum Beispiel hat GCC __builtin_strlen die manchmal die Aufrufe von strlen .

Die feste Version des Codes sieht wie folgt aus:

#include <stdio.h>

/* renamed strcat to str_cat to avoid confusing the compiler */
void str_cat(char *s, const char *t) { /* added the const qualifier to t */

    while (*s++ != '\0');
    s--;
    while (*t != '\0') {
        *s++ = *t++;
    }
    /* removed the needless modification of *t */
    *s = '\0'; /* edit: added this line after the comment from Jonathan Leffler */
}

int main() {
   char str[80] = "Hey, hello"; /* note the large array size here */
   char str2[] = " are you?";

   str_cat(str, str2);
   printf("%s\n", str);

   return 0;

}

0voto

dawg Punkte 89931

Andere besser lesbare, effizientere Beispiele kann gefunden werden durch die Verwendung von Google Codesuche .

Der Quellcode für Android und BSD ist ein gutes Beispiel für eine moderne C-Implementierung von strcat .

Anstelle von strcat sollten Sie eine Implementierung von strlcat y zahlreiche Beispiele dieser Quelle finden Sie ebenfalls.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X