2009-02-12 17 views
14

In der Programmiersprache C verstehe ich, dass Variablen nur am Anfang eines Codeblocks definiert werden können und die Variable den Umfang des Blocks hat, in dem sie deklariert wurde. In diesem Sinne fragte ich mich, ob es ist ein schlechte Praxis betrachtet, um künstlich einen neuen Bereich wie in diesem Beispiel zu erstellen:Ist if (TRUE) eine gute Idee in C?

void foo() 
{ 
    ... Do some stuff ... 

    if(TRUE) 
    { 
     char a; 
     int b; 

     ... Do some more stuff ... 
    } 

    ... Do even more stuff ... 
} 

TRUE Unter der Annahme zu 1 in einer Makro-Definition festgelegt ist, würde dieser Code ‚guter Code‘ in Betracht gezogen wird oder ist es erfahrene Programmierer zusammenzuzucken beim bloßen Gedanken daran?

Vielen Dank für Ihre Eingabe!

EDIT: Als Antwort auf einige der Antworten muss der Code, mit dem ich arbeite, mit einigen ziemlich alten Legacy-Systemen arbeiten. Obwohl es schön wäre, auf der Annahme von C99 zu agieren, können wir nicht garantieren, dass sie es haben werden.

+0

afaik, {} hat einen eigenen Bereich sine ansi C (das ist circa 1990) – George

+0

Der typische Anwendungsfall dafür ist das Debugging, bei dem man einfach zwischen if (42) und if (0) wechseln kann, statt kommentieren zu müssen. – ypnos

+0

Ihr Titel beschreibt die Frage nicht wirklich. Es scheint, als ob Sie gefragt haben, ob es sinnvoll ist, WAHR zu definieren. – BobbyShaftoe

Antwort

49

Sie brauchen nicht einmal eine if-Anweisung. Sie können Blöcke mit {}

erstellen Das sollte wahrscheinlich eine separate Funktion jedoch sein.

Beispiel hier:

#include <stdio.h> 

int 
main(int argc, char **argv) { 
    int i = 0; 
    { 
     int i = 10; 
     printf("%d\n", i); 
    } 
    printf("%d\n", i); 
} 
+0

Ist das jemals in Produktionscode verwendet? Mein Gedanke ist, dass ich Zugriff auf alle Variablen in der vorhandenen Funktion haben möchte, aber einige neue Variablen gelten nur für einen kleinen Abschnitt. Eine Funktion würde bedeuten, dass ich eine ganze Reihe von Variablen übergeben müsste, und die Variablen zum Haupt hinzufügen würde ... – Tim

+0

... Funktion würde die vorhandenen Variablen der Funktion – Tim

+0

stören meine Firma nutzt dies ausgiebig. Ich war wirklich dagegen, als ich anfing hier zu arbeiten, aber jetzt mag ich es. Ich mag es immer noch nicht, wie wir es benutzen, das ist im Allgemeinen, um Stücke von 1000 Linienfunktionen zu zerlegen, die ihre eigene Funktion sein sollten ... – rmeador

7

Wahrscheinlich möchten Sie eine neue Funktion für diesen Bereich erstellen.
Wenn es wirklich seinen eigenen Bereich haben muss, ist es wahrscheinlich sowieso eine separate logische Funktion.

+2

Nicht unbedingt. Ich habe oft ein Bedürfnis nach einer sehr lokalen Variable (mit einem netten mnemonischen Namen) gefunden, um einen Zwischenwert für nur ein paar Zeilen zu halten. Durch Verwendung eines verschachtelten Bereichs verdeutlichen Sie dessen beabsichtigte (eingeschränkte) Verwendung. –

3

Ich würde mich selbst nicht gewürzt nennen, aber ich bin ein bisschen erschrocken.

Mein Problem damit ist, dass die if-Anweisung jemanden dazu bringen würde zu glauben, dass etwas tatsächlich ausgewertet wird ... aber zur Laufzeit ist das Makro entweder wahr oder falsch, es gibt keine Änderung daran, dass es etwas anderes ist. Sie sollten entweder den Code hinzufügen oder nicht.

Wenn das, was meinen Sie zu tun, um so etwas wie #ifdef DEBUG ist dann Sie, dass für den Leser, um anzuzeigen, tun sollten, dass diese Debug-Code ist ...

+0

Das Makro wird zur Kompilierzeit ausgewertet, nicht zur Laufzeit. –

2

Ich glaube nicht, dass Sie die if (true) benötigen Portion.

Nur die {} sind erforderlich, um die Variablen zu definieren.

2

Meine Antwort lautet wie folgt:

Das macht erfahrene Programmierer ganz am Gedanken daran erschaudern.

6

Da können Sie einfach den Umfang Block ohne die Wenn, das ist eine bessere Idee.

void foo() { 
    ... Do some stuff ... 
    { 
     char a; 
     int b; 
     ... Do some more stuff ... 
    } 
    ... Do even more stuff ... 
} 
16

Soweit ich weiß, können Sie einen Bereich erstellen, ohne wenn.

Sie werden die Klammern wie folgt aus:

{ 
    int x; 

} 

Und ich empfehle gegen

if (TRUE) 

, da es bessere Lesbarkeit erschwert.

+6

vor allem, wenn Sie #define TRUE 0 –

4

können Sie die

if(TRUE) 

entfernen und lassen Sie die Klammern, die für sich einen neuen syntaktischen Block definieren - eine compound statement.

Das ist definitiv sauberer als das falsche, wenn Sie vorher schon einmal gehabt haben, aber Sie könnten sich trotzdem fragen, warum Sie einen neuen Block erstellen wollen - wäre es besser ein Unterprogramm zu definieren?

5

Zunächst muss ein neuer Block kein if-Block sein. Es könnte einfach ein Code-Abschnitt von Klammern, wie dies umgeben sein:

void foo() { 
... Do some stuff ... 

{ 
    char a; 
    int b; 

    ... Do some more stuff ... 
} 

... Do even more stuff ... 
} 

Zweitens, in jedem modernen C-Compiler, die an den C-Standard entspricht (ich glaube, C99), können Sie Variablen überall in der deklarieren blockieren, sodass Sie keinen neuen Block erstellen müssen.

3

läßt die Tür offen für einige kreativ Leute:

#define TRUE 0 
#define FALSE 1 

einfach die Klammern verwenden, den Umfang zu erklären.

1

C99 ermöglicht es Ihnen, Variablen fast überall zu deklarieren. Aber tun Sie es ohne einen sehr guten Grund nicht. Versuchen Sie zuerst, Ihre Funktion in kleinere (möglicherweise inline) Funktionen aufzuteilen.

Der einzige Ort, an dem so etwas Sinn macht, ist, wenn Sie eine Variable haben, die in der Mitte Ihrer Funktion initialisiert wird, z. ähnlich dem Erstellen eines Objekts in C++.

+0

Ich bin mir nicht sicher warum du sagst davon Abstand zu nehmen. Wenn ich ein einfaches int oder char brauche, scheint es sauberer zu sein, es nahe an dem Code zu deklarieren, der es benutzen wird, anstatt es an den Anfang der Funktion zu senden. Was gebe ich damit auf? – rtperson

+0

Das Deklarieren von Variablen zum Zeitpunkt der ersten Verwendung wird in C++ als bewährte Methode betrachtet. Warum nicht in C99? –

+0

@David Thornley: C erlaubt normalerweise dem Programmierer, sehr lange Funktionen zu schreiben, wahrscheinlicher als C++, weil die OOP-Sprachfunktionen fehlen. Viele Variablen am Anfang einer Funktion sind ein gutes Zeichen, dass sie zu lang sind. Übung kann zur Gewohnheit werden. Aber die Deklaration kurz vor der ersten Verwendung kann legitim sein –

1

Ich denke, Sie arbeiten mit einigen veralteten Annahmen. Ich habe gerade C mit GCC für ein paar Monate codiert, und Sie müssen Variablen am Anfang eines Blocks nicht deklarieren, obwohl die zweite Ausgabe von K & R besagt, dass Sie müssen.

char* palstring; 
palstring = malloc(LARGEST_STRING); 
memset(palstring, 0, sizeof palstring); 
fgets(palstring, LARGEST_STRING, fin); 

char* cur = palstring; 
char letter; 
letter = *cur; 

So gibt es keine Notwendigkeit zu tun, was Sie vorschlagen: Sie können Ihre Variable überall, wie wie diese nicht-sehr-nützliches Beispiel erklären. Die Sprache ist weitergezogen.

Eine weitere gute Ergänzung zur C-Sprache sind Variable Length Arrays, mit denen Sie ein Array zusammen mit seiner Größe an eine Funktion übergeben können. In den alten Tagen war alles, was Sie tun konnten, einen Zeiger zu übergeben.

+0

Sorgfältige GCC-Arrays variabler Länge sind nicht C99 Standard –

+0

Ah, gut zu wissen. Vielen Dank. Ich benutze es hauptsächlich, um allein herumzuspielen, also mache ich mir keine Sorgen, aber wenn ich es jemals professionell benutzen muss, schulde ich dir ein Bier. :) – rtperson

4

Wie so viele Antworten schon gesagt haben, brauchen Sie das "if" Zeug nicht. Erstellen Sie einfach den leeren Block. Aber ich möchte an einem anderen Punkt kommen. In C können Sie Variablendeklarationen an beliebiger Stelle in einem Block erstellen, nicht nur am Anfang. In C89 hatten Sie diese Einschränkung. Beginnend mit C99 (das ist jetzt 10 Jahre), haben Sie diese Einschränkung nicht mehr, obwohl einige Compiler sowieso stöhnen werden. GCC wird jedoch nicht, wenn Sie sagen, dass es den "neuesten" C-Standard mit der Option -std = c99 verwenden soll.

Da es immer noch Compiler gibt, die standardmäßig stöhnen, würde ich nicht lieber Deklarationen und Code mischen. Ich würde aus Kompatibilitätsgründen weiterhin Anmeldungen am Anfang der Blöcke machen.

+0

Ja, ich denke diese schlechte Praxis in C. Wenn Sie mit -Wall -ansi -pedantic kompilieren, werden Sie Warnungen erhalten. Meine Faustregel ist, wenn es diese Flaggen nicht sauber gibt, ist es im Allgemeinen falsch. – BobbyShaftoe

+0

Bobby Shaftoe. Nun, das ist ein gültiger Punkt. aber ich denke nicht, dass es eine schlechte Übung ist. Ich vermeide die Verwendung von -Werror genau, weil der Compiler manchmal falsch warnen kann. wenn es dann für "... {...} ..." warnt, was richtig kommentiert wird, ist das ein falsches Positiv für mich. –

6

Beachten Sie, dass in C99 lokale Variablen in der Mitte von Blöcken deklariert werden können.

C99 ist die Version des C-Standards aus dem Jahr 1999; Modernste C-Compiler unterstützen es.

1

Angenommen, Sie verwenden einen alten Compiler (wie ich, ist es für alte Hardware), Sie überspringen die Wenn (TRUE) wie andere vorgeschlagen haben, und Sie haben eine wirklich große Funktion (die Sie nicht haben sollten) der erste Ort), dann denke ich, es ist in Ordnung. Ich habe es getan, aber es fühlte sich nicht gut ...

1

Anscheinend bin ich in der Minderheit, aber ich finde "nur Klammern" viel schwieriger zu lesen, weil es vom üblichen Muster abweicht. Auf den (zugegebenermaßen selten) Gelegenheiten, wo ich ohne zu definieren, eine andere Funktion einen scoped Block will, ziehe ich die „if“ zu schließen, aber ohne Makros und mit einem Kommentar zu erklären, warum:

if(1) // just to establish scope 
{ 
    // do stuff here 
} 
2

Sie Ihre Variablen definieren am Anfang des Blocks oder verwenden Sie eine andere Funktion. Das Hinzufügen eines künstlichen Bereichs mit leeren {} s oder einer der Alternativen ist keine gute Übung.

Verwandte Themen