循环和char数组如何在C中工作?

时间:2015-11-13 00:24:23

标签: c arrays for-loop

我有一个程序可以按我希望的方式运行:

#define BUF_SIZE 15

void passwordCheck (int digit)
{
static char buf[BUF_SIZE] ;
  static int  i = 0;
  char pw[]="1234" ;
  int pw_size = sizeof(pw)-1 ;
  int ret ;

  if (digit == 13)
  {
    for(i=0;i<BUF_SIZE;i++){                     //why do I need this? 
    }
    ret = memcmp(buf, pw, 4) ;                      //compares the array with the pw
      if (ret == 0 && buf[pw_size] == 0) 
      {
      printf("Access granted\n") ;
      }
      else
      {
      printf("Access denied\n") ;
      }
  }

  else {
     if (i > ((int)sizeof(buf) - 2))          //sets all values to 0 ?  
     {
        i = 0;
        memset(buf, 0, sizeof(buf)) ;
     }
     buf[i] = digit ;                  //stores a value
     buf[i++] = digit ;                //stores a values at the next stage   
  }
}

它检查用户是否输入了正确的密码,如果是,则如果拒绝访问则授予访问权限。这是Demo

但我对理解有疑问。

所以使用static int i,以便每次调用0时我都不会成为passwordCheck

因此,如果用户没有按13passwordCheck会通过这两行将所有值存储在数组中

buf[i] = digit ; 
buf[i++] = digit ;

如果第一次调用该函数,则此if语句将数组中的所有值设置为0:

 if (i > ((int)sizeof(buf) - 2))
     {
        i = 0;
        memset(buf, 0, sizeof(buf)) ;
     }

然后,当用户按下13时,将检查并通过阵列的内容 memcmp如果匹配,则授予Access,否则拒绝访问。

但是在这里,特别是,我想知道为什么我需要这个for循环:

 for(i=0;i<BUF_SIZE;i++){
        }

如果我发表评论,那么程序只会让我访问一次,然后再也不会。所以我假设它的作用是将区域中的所有值重置为NULL,所以与memset(buf, 0, sizeof(buf)) ;相同?如果是这样的话,为什么,它不仅仅是一个循环?

提前致谢

3 个答案:

答案 0 :(得分:2)

由于您的for循环为空,因此只有副作用(您可以将其替换为):

i = BUF_SIZE;

作为旁注,编译器/优化器很可能已经在输出中生成了该代码,并且没有(不需要的)for的开销。

只有在您发送密码终止符13时才会调用此方法。之后,在下次调用时(对于另一个密码),该函数将再次使用主else分支,并且因为i之前已设置为BUF_SIZE,将执行此操作,重置您的计数器:

    i = 0;
    memset(buf, 0, sizeof(buf)) ;

您的主要if可以简化,并且可以使用相同的内容:

  if (digit == 13)
  {
    ret = memcmp(buf, pw, pw_size) ;   //compares the array with the pw
      if (ret == 0 && i == pw_size) 
      {
      printf("Access granted\n") ;
      }
      else
      {
      printf("Access denied\n") ;
      }
    i = 0; // Reset for next password input
  }

  else {
     buf[i++] = digit ; //store the value on current position and after increment the pos
  }

答案 1 :(得分:1)

如果没有此for循环,则在else完整或大小为15之前无法检查buf语句。因为当digit为13时,您通过检查值重置缓冲区使用i循环在else语句中15的{​​{1}} for这只是浪费时间。所以你可以写i=15//max size of buffer

答案 2 :(得分:1)

代码是一个字解析器,一次消化一个字符。解析完整个单词后重置。完整的单词以回车\r ascii(13)结束。

如果主代码不显示函数的调用方式,函数本身就没有意义。

让我们消化代码中的每个块。

if (digit == 13)

检查它是否是密码\r的结尾。在此块中,它会将i重置为大于buf - 2的大小。这是使用for循环完成的,但它只需设置i = 15即可。这是必要的,所以下次重新尝试代码知道它是一个全新的密码。您会注意到,在此代码中,它将buf的前4个字节与pw的前4个字节进行比较,并确保buf\0终止。如果它没有检查终止,则12345将通过。

else条件处理buf的初始化以及传递给它的字符的存储。

在此块中,您会注意到它会检查i是否大于sizeof (buf) -2。这是他们用来表示buf需要重置为0的条件。因此,通过使用赋值表达式for设置i的值,可以简化上一个块中的i = 15循环。

将数字存储到buf的第二行与前一行相同,另外它增加了i。前一行变得不必要了。

使用静态存储会使i的值在每个函数调用中保持不变。最后,这不是线程安全的。