我有两个分配和取消分配定时器的功能。
分配定时器分配一个定时器并将int返回给已分配的定时器
int allocate_timer(void)
{
int count = 0;
int allocated = 0;
/*Loop to find the first timer that is not allocated*/
for(count = 0; count< ARRAY_SIZE; count++)
{
if(allocated_timers[count] == '0')
{
/*When the next timer available timer is found it is set to allocated and timer is set to zero*/
allocated_timers[count] = '1';
timers[count] = 0;
break;
}
else if(allocated > ARRAY_SIZE - 1)
{
printf("No timers available\n");
exit(0);
}
else
{
allocated++;
}
}
/*Position of the allocated timer is returned*/
return count;
}
取消分配计时器,将int输入到将要解除分配的位置
void deallocate_one_timer(int position)
{
if(TIMER_ALLOCATED == allocated_timers[position])
{
allocated_timers[position] = '0';
timers[position] = 0;
}
}
我无法看到它们使它们比它们已经存在更强大。 关于如何让它们变得更好的任何建议?
答案 0 :(得分:3)
变量allocated
始终等于count
(因此可以删除),而IMO可能会因使用'0'
和'1'
作为allocated_timers
中的值而感到困惑{1}}数组。通常是0
和1
。
它们都没有影响代码的健壮性,但是代码越容易理解,它对未来的修改就越强大。
当你有两个“并行”数组时,就像你在这里每个计时器在timers
中都有一个条目和allocated_timers
中的相应条目一样,值得考虑是否更好具有两个成员的struct
的单个数组(在这种情况下可能名为value
和allocated
)。有时它并不好,但通常它有助于理解代码,因为读者不必发现并记住这两个数组密切相关。
deallocate_one_timer
在将position
作为数组使用之前检查0
是否在ARRAY_SIZE
到assert
范围内,则可以使 assert
更加健壮,以防止来电者误用指数。我并不是说函数有责任进行这些检查,但它们有时可以帮助诊断其他地方的错误。您可以使用timers[index]
进行非必要的检查。 {{1}}有两个好处。首先,它自我证明检查不是这个功能的责任,只是你检查别人做了他们应该拥有的东西。其次,如果需要使程序更小或更快,可以在程序的非调试版本中轻松禁用所有断言。
类似地,如果取消分配当前未分配的计时器,则退出并显示错误消息可能会有所帮助,因为这可能表示存在潜在问题。无论是谁解除分配,都可以在其他任何一方分配它,这意味着其他人突然发现他们不再独占使用他们的计时器。
最后,在分配和解除分配时将{{1}}设置为0。没有什么特别的错误,除了它混淆了哪个函数实际上负责的问题,以确保新分配的计时器具有正确的初始值。 deallocate函数无法执行任何操作,或者它可以将计时器设置为分配的计时器无法保持的值(可能为-1,假设计时器从0开始上升),因此在调试时您可以立即知道如果您是使用值为-1的计时器,出现了问题。
最后,最后,这个代码(显然)不是线程安全的,我认为这是一种非健壮性。编写无法在多线程程序中使用的代码并不羞耻,特别是对于甚至可能无法创建线程的嵌入式系统。只要这是一个刻意的决定,并且有记录。
答案 1 :(得分:1)
决定是否要使用'0'和'1'或常量,例如 TIMER_ALLOCATED,在deallocate_one_timer中使用,并且保持一致。
您对allocated
变量的使用是多余的。循环将是
更好的是:
int allocate_timer(void)
{
int count;
for (count = 0; count < ARRAY_SIZE; count++)
{
if (allocated_timers[count] == '0')
{
allocated_timers[count] = '1';
timers[count] = 0;
return count;
}
}
fprintf(stderr, "No timers available\n");
exit(EXIT_FAILURE);
}
或许最好还是不要在失败时退出,而是返回并发生错误。