我不明白当 phnum 是测试中的局部变量时,如何在程序开始时使用 define LEFT(phnum + 4)%N



我不明白如何允许 #define LEFT (phnum + 4( % N 因为甚至没有定义 phnum。

#define N 5 
#define LEFT (phnum + 4) % N 
#define RIGHT (phnum + 1) % N 

int state[N]; 
int phil[N] = { 0, 1, 2, 3, 4 }; 

sem_t mutex; 
sem_t S[N]; 

void test(int phnum) 
{ 
if (state[phnum] == HUNGRY 
&& state[LEFT] != EATING 
&& state[RIGHT] != EATING) { 
// state that eating 
state[phnum] = EATING; 

sleep(2); 


} 

语句#define LEFT (phnum + 4) % N定义了一个名为LEFT的"宏",其替换列表为(phnum + 4) % N。编译器不需要知道有关替换列表中的名称的任何信息;它只是记住它。

稍后在源代码中看到LEFT时,编译器会将其替换为替换列表(phnum + 4) % N。因此,state[LEFT] != EATING变得state[(phnum + 4) % N] != EATING

替换后,编译器根据它看到的名称来解释名称。

从概念上讲,所有"预处理器"操作,例如定义宏,用替换列表替换它们,以及处理#if和其他标有#的语句,都发生在程序的语义分析之前。它之所以被称为"预处理",是因为从历史上看,它是在编译前的单独处理阶段完成的,即使使用单独的程序也是如此。在现代编译器中,预处理器操作可能与编译的其余部分交错,但结果是相同的。

#define LEFT (phnum + 4) % N定义宏。宏替换由预处理器在编译器实际编译代码之前执行。换句话说,在编译器处理代码之前,state[LEFT]会被state[(phnum + 4) % N]替换。

如果您使用的是 GCC:传递-E参数会告诉 GCC 在预处理阶段后停止,以便您可以检查输出。请注意,预处理器还负责#include行,因此您可能需要在输出中搜索感兴趣的部分。

最新更新