2016-03-26 4 views
0

Dies wird von static const vs #define oder #defining constants in C++ nicht ganz beantwortet.Wie definiert man eine statische Konstante mit zuvor definierten Konstanten in C?

In wenn ich eine Menge Programmierung in C hat, ANSI C war ganz neu. Wir verwendeten meistens #define, um Konstanten zu definieren. Ich wurde darauf aufmerksam gemacht, dass dies keine bewährte Methode mehr ist (https://codereview.stackexchange.com/questions/123848/verifying-e-mail-address-in-c/123856#123856).

#define I kann vorherige Konstanten verwenden den Strom konstant zu definieren, ein exampe ist

#define EMAIL_CHAR_ARRAY_SIZE 40 
#define GOOD_EMAIL_ADDRESS 1 
#define BAD_EMAIL_ADDRESS 0 
#define MIMIMUM_USER_NAME_LENGTH 1 
#define AT_SIGN_LENGTH 1 
#define DOT_LENGTH 1 
#define MINIMUM_DOMAIN_LENGTH 1 
#define MINIMUM_ROOT_DOMAIN_LENGTH 2 
#define MINIUMUM_EMAIL_LENGTH MIMIMUM_USER_NAME_LENGTH + AT_SIGN_LENGTH + MINIMUM_DOMAIN_LENGTH + MINIMUM_ROOT_DOMAIN_LENGTH 

Ich habe ein Programm (unten), wo ich versucht hat, eher static const zu verwenden als #define jedoch die constant MINIUMUM_EMAIL_LENGTH wird nicht kompiliert, wenn ich versuche, const mit den vorherigen Konstanten zu verwenden. Gibt es eine Möglichkeit, zuvor definierte Konstanten in einer statischen const TYPE-Deklaration zu verwenden?

const_testemail.c:12:5: error: initializer element is not constant 
    static const int MINIUMUM_EMAIL_LENGTH = (MIMIMUM_USER_NAME_LENGTH + AT_SIGN_LENGTH + MINIMUM_DOMAIN_LENGTH + MINIMUM_ROOT_DOMAIN_LENGTH); 


#include <stdio.h> 
#include <string.h> 

static const int EMAIL_CHAR_ARRAY_SIZE = 40; 
static const int GOOD_EMAIL_ADDRESS = 1; 
static const int BAD_EMAIL_ADDRESS = 0; 
static const int MIMIMUM_USER_NAME_LENGTH = 1; 
static const int AT_SIGN_LENGTH = 1; 
static const int DOT_LENGTH = 1; 
static const int MINIMUM_DOMAIN_LENGTH = 1; 
static const int MINIMUM_ROOT_DOMAIN_LENGTH = 2; 
/* Doesn't compile 
* static const int MINIUMUM_EMAIL_LENGTH = MIMIMUM_USER_NAME_LENGTH + AT_SIGN_LENGTH + MINIMUM_DOMAIN_LENGTH + MINIMUM_ROOT_DOMAIN_LENGTH; 
* */ 

#define MINIUMUM_EMAIL_LENGTH (MIMIMUM_USER_NAME_LENGTH + AT_SIGN_LENGTH + MINIMUM_DOMAIN_LENGTH + MINIMUM_ROOT_DOMAIN_LENGTH) 

int isEmailAddressProper(const char EmailAddress[EMAIL_CHAR_ARRAY_SIZE]) 
{ 
    int  EmailAddressIsGood = GOOD_EMAIL_ADDRESS; 
    int  LengthOfEmailAddress; 
    char *AtSignLocation, *pos2; 
    int  rootDomainLength; 

    LengthOfEmailAddress = strlen(EmailAddress); 
    if (LengthOfEmailAddress < MINIUMUM_EMAIL_LENGTH) 
    { 
     printf("The length of the email address is less than the minimum lenght %d\n", MINIUMUM_EMAIL_LENGTH); 
     EmailAddressIsGood = BAD_EMAIL_ADDRESS; 
    } 

    AtSignLocation = strchr(EmailAddress, '@'); /* get the first instance of @ */ 
    if (!AtSignLocation) 
    { 
     printf("There is no @ in the email address\n"); 
     EmailAddressIsGood = BAD_EMAIL_ADDRESS; 
     return EmailAddressIsGood; 
    } 

    if (AtSignLocation == EmailAddress) { /* Is @ the first character? */ 
     printf("There is no user name in the email address, @ is the first character\n"); 
     EmailAddressIsGood = BAD_EMAIL_ADDRESS; 
    } 

    pos2 = strrchr(EmailAddress, '@'); /* find any other @ */ 
    if ((pos2) && (AtSignLocation != pos2)) { 
     printf("There is more than 1 @ in the email address\n"); 
     EmailAddressIsGood = BAD_EMAIL_ADDRESS; 
    } 

    pos2 = strrchr(EmailAddress, '.'); /* get the last instance of '.' */ 
    if (AtSignLocation > pos2) /* is . before @ ? */ 
    {   printf("There is no root domain in the email address\n"); 
     EmailAddressIsGood = BAD_EMAIL_ADDRESS; 
    } 

    pos2++; 
    rootDomainLength = LengthOfEmailAddress - ((int)(pos2 - EmailAddress)); 
    /* if root domain less than length 2 */ 
    if (rootDomainLength < MINIMUM_ROOT_DOMAIN_LENGTH) 
    { 
     printf("The root domain length (%d) is less than the minimum length required (%d) in the email address\n", rootDomainLength, MINIMUM_ROOT_DOMAIN_LENGTH); 
     EmailAddressIsGood = BAD_EMAIL_ADDRESS; 
    } 

    return EmailAddressIsGood; 
} 

void GetAndValidateEmailAddress(char EmailAddress[EMAIL_CHAR_ARRAY_SIZE]) 
{ 
    int EmailAddressIsGood = BAD_EMAIL_ADDRESS; 
    char TempEmail[EMAIL_CHAR_ARRAY_SIZE]; 

    while (!EmailAddressIsGood) 
    { 
     scanf("%39s", TempEmail); 
     EmailAddressIsGood = isEmailAddressProper(TempEmail); 
     if (!EmailAddressIsGood) { 
      printf("The email address is not in the proper format, please re-enter the email address\n"); 
     } 
    } 

    strcpy(EmailAddress, TempEmail); 
} 

main() 
{ 
    char EmailAddress[EMAIL_CHAR_ARRAY_SIZE]; 

    printf("Please enter the email address\n"); 
    GetAndValidateEmailAddress(EmailAddress); 
    printf("The email address you entered is %s\n", EmailAddress); 
} 
+0

@Olaf Was mir deine Antwort Staaten ist, dass es keine Möglichkeit, Konstanten zu erstellen, ist C-Sprache. Dies wäre eine sehr schlechte Programmierpraxis. – pacmaninbw

+0

Nein, das habe ich nicht gesagt. Denn dafür werden Makros verwendet. Beachten Sie, dass C sehr gut Konstanten hat! "1" ist eine Konstante vom Typ "int", "0.3f" ist eine "float" -Konstante usw. Das Problem, das Sie haben, sind ** symbolische ** Konstanten mit einem benutzerdefinierten Typ. Verwenden Sie Makros für sie. Unterschiedliche Übersetzungsphase, aber so funktioniert es in C. Wenn Sie in Rom sind, benehmen Sie sich wie ein Roman. – Olaf

+0

Nicht sicher, wie Ihr Compiler funktioniert, aber Sie haben einen Tippfehler in Ihrem kommentierten Makro. Beheben Sie das Problem und versuchen Sie es erneut. Bist du das, ist das rein C? –

Antwort

0

C nicht über symbolische Konstanten andere als Enum-Konstanten (die int immer vom Typ sind). #define ist ein Makro und Teil des vor Prozessors. Es ist ein textueller Ersatz vor der eigentlichen C-Kompilation.

const qualifizierte Variablen sind semantisch noch Variablen. Der Qualifier ist eine Garantie für den Programmierer, er ändert den Wert nicht. Der Compiler kann sich auf diese Garantie verlassen. Das Brechen des Vertrags ruft nicht definiertes Verhalten auf, wird jedoch nicht unbedingt von der Laufzeitumgebung erzwungen.

Statische Initialisierer und Array-Indizes auf Dateiebene erfordern einen konstanten Ausdruck , daher der Fehler. Kurz gesagt, ein konstanter Ausdruck muss einen konstanten Wert zur Kompilierzeit ergeben, daher können Sie keine Variablen verwenden.

Beachten Sie die Array-Parameter in Ihrer Funktion hat ein ähnliches Problem. Aber hier können Sie ein Array variabler Länge verwenden. Sie können jedoch entweder eine leere Länge ([]) verwenden oder die Länge explizit als vorherigen Parameter übergeben. globale Variablen nicht funktionieren:

int isEmailAddressProper(size_t len, const char EmailAddress[len]) 

C++ ist eine andere Sprache mit ähnlichen Syntax/Grammatik und ganz einige andere Semantik auch für die gleiche Grammatik. Sie können oft nicht das Wissen von der Sprache auf die andere anwenden.

+0

Ok, da static const int immer noch eine Variable ist, kann sie nicht verwendet werden um eine Konstante zu definieren, das ist es was du sagst. Ich habe die Fehlermeldung hinzugefügt, es gibt keine Warnungen. – pacmaninbw

Verwandte Themen