Frage

Beim Bekommen mein Code wurde hier überprüft die Frage der Verwendung des const stichwort kam auf.Ich verstehe, dass es zum Implementieren von schreibgeschütztem Verhalten für Variablen verwendet wird.

Ich bin verwirrt darüber, in welchen verschiedenen Situationen es nützlich sein kann.

  • Sollte es aus Gründen der Übersichtlichkeit in Funktionsprototypen verwendet werden?
  • Sollte es als Sicherheitsmaßnahme während der Codeentwicklung verwendet werden?
  • Sollte es im Rahmen verschiedener Funktionen zum Deklarieren von Laufzeitkonstanten verwendet werden?
  • Sollte es überhaupt verwendet werden?

Diese Frage sind nur Beispiele für die Verwirrung, mit der ich konfrontiert bin.Die allgemeine Verwirrung ist

  • Wann sollte der sein const schlüsselwort in der C-Programmierung verwendet?
  • Was sind die verschiedenen Arten von Vorteilen, die durch die Verwendung dieses Schlüsselworts in C erzielt werden können?
  • Gibt es irgendwelche Nachteile bei der Verwendung von const stichwort?


Es wurde darauf hingewiesen, dass diese Frage aufgrund all dieser Fragen im Detail meiner Frage zu weit gefasst sein könnte.Ich wollte nur klarstellen, dass diese Fragen nur dazu dienen, die Verwirrung in Bezug auf die Hauptfrage zu klären.

Wann und zu welchen Zwecken sollte das Schlüsselwort const in C für Variablen verwendet werden?

Es kann auch umformuliert werden als

Die richtige Verwendung von const stichwort in C' mit den Vor- und Nachteilen desselben.

War es hilfreich?

Lösung

Bei der Überprüfung des Codes wende ich die folgenden Regeln an:

  • Immer verwenden const für Funktionsparameter, die als Referenz übergeben werden, wobei die die Funktion ändert (oder gibt) die Daten, auf die verwiesen wird, nicht frei.

    int find(const int *data, size_t size, int value);
    
  • Immer verwenden const für Konstanten, die sonst mit einem #define oder einer Aufzählung definiert werden könnten.Der Compiler kann die Daten dadurch im Nur-Lese-Speicher (ROM) lokalisieren (obwohl der Linker in eingebetteten Systemen oft ein besseres Werkzeug für diesen Zweck ist).

    const double PI = 3.14;
    
  • Verwenden Sie niemals const in einer Funktion Prototyp für einen Parameter übergeben von Wert.Es hat keine Bedeutung und ist daher nur 'Lärm'.

    // don't add const to 'value' or 'size'
    int find(const int *data, size_t size, int value); 
    
  • Gegebenenfalls verwenden const volatile an Orten, die vom Programm nicht geändert werden können, sich aber noch ändern können.Hardwareregister sind hier der typische Anwendungsfall, zum Beispiel ein Statusregister, das einen Gerätezustand widerspiegelt:

    const volatile int32_t *DEVICE_STATUS =  (int32_t*) 0x100;
    

Andere Verwendungen sind optional.Zum Beispiel die Parameter zu einer Funktion innerhalb der Funktion Umsetzung kann als const markiert werden.

// 'value' and 'size can be marked as const here
int find(const int *data, const size_t size, const int value)  
{
     ... etc

oder Funktionsrückgabewerte oder Berechnungen, die erhalten werden und sich dann nie ändern:

char *repeat_str(const char *str, size_t n) 
{
    const size_t len = strlen(str);
    const size_t buf_size = 1 + (len * n);
    char *buf = malloc(buf_size);
    ...

Diese Verwendungen von const geben Sie einfach an, dass Sie die Variable nicht ändern werden;sie ändern nicht, wie oder wo die Variable gespeichert ist.Der Compiler kann natürlich herausfinden, dass eine Variable nicht geändert wird, sondern indem er hinzufügt const sie erlauben ihm, das durchzusetzen.Dies kann dem Leser helfen und etwas Sicherheit hinzufügen (obwohl, wenn Ihre Funktionen groß sind oder kompliziert genug, dass dies einen großen Unterschied macht, haben Sie wohl andere Problem). Bearbeiten - zB.eine 200-zeilige dicht codierte Funktion mit verschachtelten Schleifen und vielen langen oder ähnliche Variablennamen, in dem Wissen, dass sich bestimmte Variablen möglicherweise nie ändern erleichtert das Verstehen erheblich.Solche Funktionen wurden schlecht entworfen oder gewartet.


Probleme mit const.Sie werden wahrscheinlich den Begriff "Const-Vergiftung" hören.Dies geschieht beim Hinzufügen von const zu einem Funktionsparameter bewirkt, dass 'Konstanz' zu propagieren.

Bearbeiten - Konstante Vergiftung:zum Beispiel in der Funktion:

int function_a(char * str, int n)
{
    ...
    function_b(str);
    ...
}

wenn wir uns ändern str zu const, müssen wir dann sicherstellen, dass fuction_b nimmt auch a const.Und so weiter, wenn function_b übergibt die str auf zu function_c, usw.Wie Sie sich vorstellen können, könnte dies schmerzhaft sein, wenn es sich in viele ausbreitet separate Dateien / Module.Wenn es sich in eine Funktion ausbreitet, die nicht sein kann geändert (z. B. eine Systembibliothek), dann wird ein Cast notwendig.Also streuen const herum im vorhandenen Code bittet vielleicht um Ärger.Im neuen Code obwohl es am besten ist const qualifizieren Sie sich gegebenenfalls konsequent.

Das heimtückischere Problem von const ist das, dass es nicht im Original war sprachlich.Als Add-on passt es nicht ganz.Für den Anfang hat es zwei Bedeutungen (wie in den obigen Regeln, was bedeutet "Ich werde das nicht ändern" und "das kann nicht geändert werden").Aber mehr als das, es kann gefährlich sein.Zum Beispiel kompilieren und führen Sie diesen Code aus und (abhängig vom Compiler / den Optionen) kann er abstürzen, wenn laufen:

const char str[] = "hello world\n";
char *s = strchr(str, '\n');
*s = '\0';

strchr gibt ein zurück char* nicht ein const char*.Da sein Aufrufparameter ist const es muss werfen der Aufrufparameter für char*.Und in diesem Fall das verwirft die echte schreibgeschützte Speichereigenschaft. Bearbeiten:- dies gilt allgemein für Variablen im Nur-Lese-Speicher.Mit 'ROM' meine ich nicht nur physisches ROM, sondern jeden Speicher, der schreibgeschützt ist, wie es beim Codeabschnitt von Programmen der Fall ist, die auf einem typischen Betriebssystem ausgeführt werden.

Viele Standardbibliotheksfunktionen verhalten sich auf die gleiche Weise, also Vorsicht:wenn Sie haben Real konstanten (dh.im ROM gespeichert), müssen Sie sehr vorsichtig sein, nicht zu verliere ihre Konstanz.

Andere Tipps

Im Allgemeinen wird in jeder Programmiersprache die Verwendung empfohlen const oder der äquivalente Modifikator seit

  • Es kann dem Anrufer klarstellen, dass sich das, was er übergeben hat, nicht ändern wird
  • Mögliche Geschwindigkeitsverbesserungen, da der Compiler sicher weiß, dass er bestimmte Dinge weglassen kann, die nur relevant sind, wenn sich der Parameter ändern kann
  • Schutz davor, dass Sie versehentlich den Wert ändern

In Übereinstimmung mit den Aussagen von TheLQ:

Bei der Arbeit mit einem Team von Programmierern deklarieren const ist eine gute Möglichkeit, um anzuzeigen, dass diese Variable nicht geändert werden sollte, oder um sich nur an große Projekte zu erinnern.Es ist in diesem Sinne nützlich und kann viele Kopfschmerzen ersparen.

Ja, das ist im Grunde die Antwort von TheLQ.

Ist eine Sicherheitsmaßnahme für den Programmierer, damit Sie eine Variable nicht ändern und keine Funktionen aufrufen, die sie ändern könnten.In einem Array oder einer Struktur gibt der Bezeichner const an, dass die Werte ihres Inhalts nicht geändert werden, und selbst der Compiler lässt dies nicht zu.Sie können den Wert der Variablen jedoch immer noch leicht mit nur einer Umwandlung ändern.

In dem, was ich normalerweise gesehen habe, wird es hauptsächlich verwendet, um konstante Werte im Code hinzuzufügen und um anzuzeigen, dass das Array oder die Struktur nicht geändert werden, wenn Sie eine bestimmte Funktion aufrufen.Dieser letzte Teil ist wichtig, denn wenn Sie eine Funktion aufrufen, die Ihr Array oder Ihre Struktur ändert, möchten Sie möglicherweise die Originalversion beibehalten, sodass Sie eine Kopie der Variablen erstellen und sie dann an die Funktion übergeben.Wenn dies nicht der Fall ist, benötigen Sie die Kopie natürlich nicht, also können Sie zum Beispiel ändern,

int foo(Structure s);

zu

int foo(const Structure * s);

und den Kopieraufwand nicht zu bekommen.

Nur um hinzuzufügen, beachten Sie, dass C bestimmte Regeln mit dem const Spezifizierer hat.Beispielsweise,

int b = 1;
const int * a = &b;

ist nicht dasselbe wie

int b = 1;
int * const a = &b;

Mit dem ersten Code können Sie a nicht ändern.Im zweiten Fall ist der Zeiger konstant, sein Inhalt jedoch nicht, sodass der Compiler Folgendes zulässt * a = 3; ohne einen Compilerfehler, aber Sie können nicht machen a ein Hinweis auf eine andere Sache zu sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
scroll top