c - while(tab[i+1] == 0) 和 while(tab[++i] == 0) 之间的区别
问题描述
我不明白为什么如果我使用
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;
}
解决方案
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
元素,所以可用的索引只有0
to SIZE-1
。这意味着你不能阅读tab[SIZE]
。您应该像这样将范围检查添加到循环中:
while (++i < SIZE && tab[i] == 0);
do {
i+=1;
} while (i < SIZE && tab[i] == 0);
推荐阅读
- ionic-framework - 离子后退按钮未显示在 Ionic 5 的工具栏中
- sql - 比较 SQL 中的列时如何打破平局
- python - 每次加入 virtualenv 时都需要重新安装 Tensorflow 吗?
- node.js - AWS DynamoDb 中的 Hash 和 Range 键到底是什么意思?
- javascript - 在 React 中使用 ReactRouter 进行条件路由
- python - sqlalchemy.exc.InvalidRequestError:一个或多个映射器未能初始化
- r - R data.table:按组滚动前 3 天的滞后总和
- jquery - 在选择下拉列表上方显示占位符
- python - Django:用“_code”或其他后缀替换外键属性名(以及列名)“_id”后缀
- laravel - 属性'toLowerCase'和'includes'错误Vue.js vuetify