需要帮助使我的代码高效

时间:2017-10-22 13:07:32

标签: c arrays

所以我刚开始学习结构,我最近的问题要求我检查用户输入的屏幕时间,唯一有效的范围是下午2点,下午5点,晚上8点和晚上11点。我为它做了一个很长的屁股代码并按预期工作,但我不认为它是有效的?我尝试为有效屏幕时间创建一个数组,并在4号数组中输入所有4个值,并在用户输入他们的选择时进行循环检查数组中的每个值,但是当用户输入错误选项时,它会显示4条错误消息因为它检查数组中的所有4个值,所以它是错误的。无论如何,这是我的代码:

void main(){

typedef struct{

char movieName[20];
int screenTime;
float price;
int seatNum;
} MovieTicket;

MovieTicket ticket;

//int validTime[4] = {2, 5, 8, 11};

do{
printf("Enter your screen time: ");
scanf("%d", &ticket.screenTime);

if(ticket.screenTime != 2 && ticket.screenTime != 5 && ticket.screenTime != 8 && ticket.screenTime != 11){
    printf("Invalid Screen Time! Enter again please!\n");
}

} while(ticket.screenTime != 2 && ticket.screenTime != 5 && ticket.screenTime != 8 && ticket.screenTime != 11);

system("pause");
}

感谢您的时间,我只是一个初学者,所以请耐心等待:(

3 个答案:

答案 0 :(得分:0)

使用这样的幻数是相当不可维护的(添加新的允许时间不干净,你必须编辑条件等),你的版本与数组更好。本答案的其余部分侧重于使解决方案按照您希望的方式工作:

它非常有效(使用std::setstd::unordered_set可以提高效率,但对于如此少量的允许值,它可以忽略不计),这不是问题。您当前的版本与带阵列的版本一样快,因为您仍然比较相同数量的数字。

如果您的问题是它打印错误4次,那么保留一个布尔标志以指示用户输入了有效值,并在循环后检查

const unsigned int VALID_TIMES_SIZE = 4;
bool validTime = false;
for (unsigned int i = 0; i < VALID_TIMES_SIZE; ++i)
{
    if (ticket.screenTime == validTimes[i])
    {
        validTime = true;
        break;
    }
}
if (!validTime)
{
    printf("Invalid Screen Time! Enter again please!\n");
    // Redo the loop using continue, for example
}

答案 1 :(得分:0)

检查scanf的返回以确保它成功。如果不是,则需要清除输入流中的待处理字符。

#include <stdio.h>

typedef struct{
    char movieName[20];
    int screenTime;
    float price;
    int seatNum;
} MovieTicket;

int main( void) {
    MovieTicket ticket;
    int result = 0;
    int validTime[] = {2, 5, 8, 11};
    int limit = sizeof ( validTime) / sizeof ( validTime[0]);
    int match = 0;


    do{
        match = 0;
        printf("Enter your screen time: ");
        if ( 1 == ( result = scanf("%d", &ticket.screenTime))) {
            //check for matching validTime
            for ( int each = 0; each < limit; each++) {
                if ( validTime[each] == ticket.screenTime) {
                    match = 1;
                    break;
                }
            }
            if ( !match) {
                printf("Invalid Screen Time! Enter again please!\n");
                result = 0;
            }
        }
        else {
            //scanf could not parse an int
            printf("Enter Screen Time! Enter again please!\n");
            while ( '\n' != getchar ( )) { }//clear input stream
        }

    } while ( result != 1);

    system("pause");
}

答案 2 :(得分:-1)

为了使某些内容易于理解,您可以避免使用这些神奇的数字或将它们包装在像checkTime这样的有意义的结构中,然后将其用于此类检查。这种方式假设下次你被要求在不同时间建立一个检查时间时,你不必寻找硬编码时间并用新东西替换它。

例如,你可以做这样的事情,

struct checkTime{
  int *checkedTimes;
  int length;
  int (*checkIfTimeExists)(const struct checkTime* ch, int tm);
};
int checkTimerExistAux(const struct checkTime* ch,int tm)
{
    for(int i=0;i<ch->length;i++)
      if(ch->checktedTimes[i]==tm) return 1;
    return 0;
}

Then you create an `initilaize` function which will allocate memory and do this hardcoded thing. (like putting times and all that)[2,5,8,11] in your case.

initialize(); // here you created the structure `checkTimeInst`
// struct checkTime* checkTimeInstPtr = malloc(sizeof(struct checkTime));
// checkTimeInstPtr->checkedTimes = malloc(sizeof(int)*N);
// checkTimeInstPtr->length = 0;
// checkTimeInstPtr->checkIfTimeExists = checkTimerExistAux;
 do{
printf("Enter your screen time: ");
scanf("%d", &ticket.screenTime);

if(checkTimeInstPtr->checkIfTimeExists(checkTimeInstPtr,ticket.screenTime)==0){
    printf("Invalid Screen Time! Enter again please!\n");
}

} while(checkTimeInstPtr->checkIfTimeExists(checkTimeInstPtr,ticket.screenTime)==0);

这不是关于加速,而是关于可维护性。

这里没有关于加速的事情。但是,如果您正在努力缩短时间,请尝试使用getchar()或类似的方式自行使用阅读器或扫描仪。

最初发布的代码假定为C ++,其中OP要求C语言特定的答案或修改。在 Paul Griffiths 评论之后,我已将其修改为遵循该标准。