这个指针在这个函数的参数中做了什么?

时间:2012-06-07 15:27:44

标签: c pointers

我是一个电子产品的人,请好好对待我。

我正在阅读有关8位微控制器实时操作系统的this文章。我遇到了一个奇怪的观点,我遇到了这个函数。我无法理解它在做什么。我知道void意味着“没有类型”。我猜测(*Task)是投射。我真的不知道那之后那些括号是做什么的。

这个函数的论点是什么?

另外,我无法理解*(int*)((NewTCB->Stack) + (STACK_DEPTH-2)) = (int)Task;做了什么?

enter image description here

3 个答案:

答案 0 :(得分:7)

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

所以你可以这样称呼它:

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

TaskCreate(my_task);

当然,编写void my_task(void) {也是安全的。在编码c时,我个人更喜欢明确地说“没有参数”

最后,*(int*)((NewTCB->Stack) + (STACK_DEPTH-2)) = (int)Task;正在做一些施法魔法。

让我们解读它:

(int)Task首先将Task转换为int(这是有问题的,但对于您的特定架构/操作系统可能没问题。就个人而言,我会使用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 */
}

答案 1 :(得分:0)

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

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的索引)。
其余的只是处理将Task移动到适当位置所需的转换。

答案 2 :(得分:0)

Evan Teran的回答是正确的。我将通过代码来扩展它,它似乎是指向在选择运行任务时执行的函数的指针。

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

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