2012-06-07 37 views
1

我是个电子家伙,请好好对待我。这个指针在这个函数的参数中做了什么?

我正在阅读this关于8位微控制器实时操作系统的文章。我用一个奇怪的看起来的论点来看这个函数。我无法理解它在做什么。我知道void的意思是“没有类型”。我猜测(*Task)是铸造。我真的不知道那些括号之后做了什么。

这个函数的参数包括什么?

另外,我不明白*(int*)((NewTCB->Stack) + (STACK_DEPTH-2)) = (int)Task;做什么?

enter image description here

+0

请不要发布文本的图像;张贴文本本身。 –

+0

@OliCharlesworth我很抱歉,我担心我会将错误转换为文本,并且我认为它是合理可读的(但Google无法找到)。 –

回答

7

void (*Task)()实际上是一个函数指针。基本上,它是说:“参数名称为Task,它是返回void和(因为这是C不是C++)接受任何数量的参数的函数

所以,你可以这样调用它:

void my_task() { 
    /* do something */ 
} 

TaskCreate(my_task); 

当然,也可以安全地写void my_task(void) {以及当编码C,我个人更喜欢明确地说:“没有参数”

最后,*(int*)((NewTCB->Stack) + (STACK_DEPTH-2)) = (int)Task;做一些铸造神奇。

让我们disect它:

(int)Task首先转换Taskint(这是有问题的,但可能确定为特定的建筑/ OS。就个人而言,我会使用long以保证安全)。

((NewTCB->Stack) + (STACK_DEPTH-2))只是在NewTCB->Stack上做了一些简单的算术运算,得到一个指向TCB堆栈中某个位置的指针。

*(int*)说:“这个转换为int *,然后顺从(读或写),它指向的位置

我们可以更简单地写出如下这样:

int f = (int)Task; 
int s = ((NewTCB->Stack) + (STACK_DEPTH-2)); /* I don't know the type of `NewTCB->Stack`, so we'll pretend 'int' for now */ 
int *stack_ptr = (int*)s; 
*stack_ptr = f; 

这可能是更。明确

跟进:我想指出,我如何使用倾向于使用函数指针,因为语法可能有时有点混乱,我觉得这是一个。方法是非常有帮助的。基本上,我喜欢创造的函数指针并使用它,我发现了很多更容易得到正确的一个typedef

例如:

/* typedef func_t to be a pointer to a function taking no arguments and returning void */ 
typedef void (*func_t)(void); 

再后来......

void CreateTask(func_t task) { 
    /* same work as your example, just a little easier to read */ 
} 
+0

哇,stackoverflow SE太棒了! 3分〜5分钟回答?哇!希望我们在电子SE中拥有它。 –

+0

@abdullahkahraman:很高兴能帮到:-) –

+0

还没有读完整个答案,但是与void *(task)()'相同'void(* task)()'? –

0

*(int*)((NewTCB->Stack) + (STACK_DEPTH-2)) = (int)Task;需要Task并将其转换为一个整数。然后,它发现NewTCB的堆栈(某种形式的数组)。它需要这个堆栈并找到倒数第二个成员。然后它将其视为整型变量的地址,并将转换后的任务分配给该地址处的变量。

NewTCB->stack使用C++指针 - 成员语法。 NewTCB是一个指向TCB对象的指针,而TCB对象显然具有Stack属性。
添加STACK_DEPTH - 2与编写(NewTCB->Stack)[STACK_DEPTH - 2](以明文形式:NewTCB->Stack:在STACK_DEPTH - 2处获取对象)相同,区别在于堆栈对象是动态分配的数组。
如果NewTCB->Stack的长度为STACK_DEPTH,则索引STACK_DEPTH - 2处的对象是倒数第二个成员(基于0的索引)。
其余部分仅处理将任务移至适当位置所需的转换。

+0

'NewTCB-> stack'不是C++特性。它恰好**和**(* NewTCB)相同.stack' –

+0

正确,但C不支持对象。这就是我的意思。尽管它支持'struct',但它支持 – user1417475

+0

。 'struct T {int n; }; struct T * x = malloc(sizeof(struct T)); x-> n = 10;'完全有效的c。 –

0

Evan Teran的回答是正确的。我将通过从代码中说它看起来是一个指向当选择任务运行时执行的函数的指针。

至于*(int*)((NewTCB->Stack) + (STACK_DEPTH-2)) = (int)Task;

我在您的环境int假设是16位?如果是这样,这将是-2。这个代码在这个结构中保存了任务'main'函数的地址(这很奇怪,因为它已经保存在->Task成员中,但这可能是一个很好的理由)