2012-06-07 40 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成員中,但這可能是一個很好的理由)