while(tab[i+1] == 0) 和 while(tab[++i] == 0) 的区别是什么?

3

我不理解为什么如果我使用

    while (tab[i+1] == 0)
    {
        i+=1;
    }

我的程序卡住了,但是如果我使用

 while (tab[++i] == 0);

它按照预期的方式执行。我错过了什么吗?

完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <limits.h>

#define SIZE 100

typedef struct
{
    unsigned int prime;
    unsigned int size;
    unsigned int *tab;
} shared_data;

void *sieve(void *);

sem_t mutex;

int main()
{
    pthread_t tid;
    unsigned int tab[SIZE];

    sem_init(&mutex, 0, 0);

    for (unsigned int i = 0; i < SIZE; i++)
    {
        tab[i] = i;
    }

    unsigned int i = 2; //index startowy
    shared_data shared = {i, SIZE, tab};
    while (i < SIZE)
    {

        shared.prime = tab[i];

        pthread_create(&tid, NULL, sieve, &shared);

        sem_wait(&mutex);

        while (tab[++i] == 0);
    }
    pthread_join(tid, NULL); // czekaj az ostatni watek zakonczy dzialanie

    sem_destroy(&mutex);

    printf("Liczby pierwsze:\n");

    for (unsigned int i = 0; i < SIZE; i++)
        if (tab[i]) //pomin 0 przy wyswietlaniu
            printf("%d | ", tab[i]);
    printf("\n");

    return 0;
}

void *sieve(void *arg_p)
{
    shared_data arg = *(shared_data *)arg_p;
    shared_data io = arg;
    int unlock_thread = 1;
    for (unsigned int i = io.prime + 1; i < io.size; i++)
    {
        if (io.tab[i] % io.prime == 0)
            io.tab[i] = 0;
        else if (unlock_thread)
        {
            sem_post(&mutex);
            unlock_thread = 0;
        }
    }
    if (unlock_thread)
        sem_post(&mutex);
    return NULL;
}

请查看此C参考,您的C编译器文档(可能是GCC…),以及sem_overview(7)和优秀的Pthreads教程 - Basile Starynkevitch
1
看起来可能存在内存错误。你的循环使用了 "while (i < SIZE)",在循环内部你使用了 "tab[++i]",这将会访问无效的内存,如果 i = SIZE - 1。 - Roxxorfreak
1个回答

4
    while (tab[i+1] == 0)
    {
        i+=1;
    }

检查tab的下一个元素,当它为零时不更改i,这意味着i不会变成使得tab[i]为零的值。
另一方面,
 while (tab[++i] == 0);

首先进入tab的下一个元素,因此可以更改i以使tab[i]为零。

为了分离对tab的访问和对i的更新,你可以这样做:

do {
    i+=1;
} while (tab[i] == 0);

还要注意,您不能访问(既不能读也不能写)数组中超出范围的元素。数组tab只有SIZE个元素,可用索引仅为0SIZE-1。这意味着您不能读取tab[SIZE]。您应该在循环中添加范围检查,如下所示:

while (++i < SIZE && tab[i] == 0);

do {
    i+=1;
} while (i < SIZE && tab[i] == 0);

不建议使用tab[++i],因为它可能会导致多个未定义行为。 - user5550963

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接