static const vs #define或#defining constants in C++并未对此做出完全回答。
当我在C中进行大量编程时,ANSI C是全新的。我们大多使用#define来定义常量。我已经意识到这不再是最佳做法(https://codereview.stackexchange.com/questions/123848/verifying-e-mail-address-in-c/123856#123856)。
使用#define我可以使用先前的常量来定义当前常量,例如
#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
我有一个程序(下面),我试图使用静态const而不是#define,但是当我尝试使用前面的常量使用静态const时,常量MINIUMUM_EMAIL_LENGTH不会编译。有没有办法在静态const TYPE声明中使用先前定义的常量?
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 :(得分:0)
C除了枚举常量(总是类型为int
)之外没有符号常量。 #define
是一个宏,是 pre 处理器的一部分。它是实际C语言编译之前的文本替换。
const
限定变量在语义上仍然是变量。限定符是程序员的保证,他不会更改值。编译器可能依赖此保证。打破合同会调用未定义的行为,但它不一定由运行时环境强制执行。
文件级的静态初始化程序和数组索引需要常量表达式,因此需要输入错误。简而言之,常量表达式必须在编译时产生一个常量值,因此不能使用变量。
请注意,函数中的数组参数存在类似问题。但是在这里你可以使用一个可变长度的数组。但是,您可以使用空长度([]
)或将长度作为前置参数显式传递;全局变量不起作用:
int isEmailAddressProper(size_t len, const char EmailAddress[len])
C ++是一种具有相似语法/语法的不同语言,即使对于相同的语法也有很多不同的语义。你经常无法将语言知识应用到另一方。