我应该使用什么而不是goto语句?

时间:2017-03-05 11:00:40

标签: c

srand(time(NULL));
for(i=0;i<9;i++)
{
    random: temp=rand()%9;
    for(j=0;j<=i;j++)
    {
        if(temp==randarr[j])
        {
            goto random;
        }
    }
    randarr[i]=temp;
       //   printf("%d ",randarr[i]);
}

我想生成0到8之间的随机数,而不重复任何数字。我使用这个代码它完美地工作。但我想从我的代码中删除goto语句。如何在没有goto的情况下编写代码? 谢谢!!

5 个答案:

答案 0 :(得分:6)

您不想随意生成每个数字。您希望以某种随机顺序将数字从0改为8。

更简单的方法(也消除了goto的使用)是从排序数组开始并选择索引以随机交换每次迭代。

srand(time(NULL));
int randarr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
for(int i = 0; i < 9; ++i)
{
    int swap_idx = rand() % 9;
    int temp = randarr[swap_idx];
    randarr[swap_idx] = randarr[i];
    randarr[i] = temp;
}

HolyBlackCat 所述,天真的方法倾向于给出各种排列的不均匀分布。如果您对此感到担忧,可以通过Fisher-Yates (or Knuth) shuffle

的形式进行改进
srand(time(NULL));
int randarr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
for(int i = 0; i < 9; ++i)
{
    int swap_idx = i + rand() % (9 - i);
    int temp = randarr[swap_idx];
    randarr[swap_idx] = randarr[i];
    randarr[i] = temp;
}

答案 1 :(得分:1)

如另一个答案中所述,这是随机选择数字0-8的一种非常糟糕的方式。你应该随意洗牌。

但是,如果您发现自己遇到似乎需要goto的类似问题,则可以通过设置标记来删除它们。如下所示:

srand(time(NULL)); // Make sure you only execute this *ONCE* per program.
                   // Do not put it inside a function called repeatedly, or a loop.

for(i=0;i<9;) {
    int temp=rand()%9;
    bool matched = false;
    for(j=0;j<=i;j++) {
        if(temp==randarr[j]) {
            matched = true;
            break;
        }
    }
    if (! matched) {
        randarr[i]=temp;
        i++;
    }
}

goto的相应代码相比,这是否更容易阅读或更难阅读。就个人而言,我很高兴使用像

这样的代码
     // acquire resources 
     ...

     // do work
     ret = function(...);
     if (ret) goto error:
     ....

     // release resources
 error:
     ....
     return ret;

但是我会避免向后跳(正如你的原始代码所做的那样)。

答案 2 :(得分:0)

srand(time(NULL));
for(i=0;i<9;i++)
{
    temp=rand()%9;
    for(j=0;j<=i;j++)
    {
        if(temp==randarr[j])
        {
           break;
        }
    }
    if(j > i) 
        randarr[i]=temp;
    else 
      i--;
}

答案 3 :(得分:0)

  • 内循环中的条件应为j < i,randarr [i]尚未分配
  • 不需要指标变量,你可以在内循环之后通过j != i检测到内环的突破。
for(i=0; i < 9;) {
    int temp=urand(9);  /* to be supplied */
    for(j=0; j < i; j++ ) { /* Note j< i, *NOT* j<= i */
        if(temp==randarr[j]) break;
        }
    if ( j != i) continue; /* inner loop ended prematurely */
    randarr[i]=temp;
    i++;
    }
}

BTW:不需要临时变量:

for(i=0; i < 9; ) {
    randarr[i] = urand(9);  
    for(j=0; j < i; j++ ) { 
        if(randarr[j] == randarr[i]) break;
        }
    if (j != i) continue; /* inner loop ended prematurely */
    i++;
    }
}

答案 4 :(得分:-1)

srand(time(NULL));
i = 0;
while(i < 9)
{
    temp = rand() % 9;
    int doesExist = 0;
    for(j = 0; j <= i; j++)
    {
        if(temp == randarr[j])
        {
            doesExist = 1;
            break;
        }
    }

    if (doesExist == 0)
    {
        randarr[i] = temp;
        i++;
    }
    //printf("%d ",randarr[i]);
}