2010-08-13 62 views
1

請幫助我瞭解兩件事我在C代碼中發現:Ç請幫忙解釋一下小碼

首先,是整個代碼:

usbMsgLen_t usbFunctionSetup(uchar data[8]) 
{ 
usbRequest_t *rq = (void *)data; 
static uchar dataBuffer[4]; /* buffer must stay valid when usbFunctionSetup returns */ 
if(rq->bRequest == CUSTOM_RQ_ECHO){ /* echo -- used for reliability tests */ 
     dataBuffer[0] = rq->wValue.bytes[0]; 
     dataBuffer[1] = rq->wValue.bytes[1]; 
     dataBuffer[2] = rq->wIndex.bytes[0]; 
     dataBuffer[3] = rq->wIndex.bytes[1]; 
     usbMsgPtr = dataBuffer;   /* tell the driver which data to return */ 
     return 4; 
    }else if(rq->bRequest == CUSTOM_RQ_SET_STATUS){ 
     if(rq->wValue.bytes[0] & 1){ /* set LED */ 
      LED_PORT_OUTPUT |= _BV(LED_BIT); 
     }else{       /* clear LED */ 
      LED_PORT_OUTPUT &= ~_BV(LED_BIT); 
     } 
    }else if(rq->bRequest == CUSTOM_RQ_GET_STATUS) { 
     dataBuffer[0] = ((LED_PORT_OUTPUT & _BV(LED_BIT)) != 0); 
     usbMsgPtr = dataBuffer;   /* tell the driver which data to return */ 
     return 1;      /* tell the driver to send 1 byte */ 
    } 
    return 0; /* default for not implemented requests: return no data back to host */ 
} 

現在,usbFunctionSetup得到的8個無符號字符數組。現在有線:

usbRequest_t *rq = (void *)data; 

所以,我得到了左側的聲明,但是什麼是右側?我知道(void *)被轉換爲這種類型,但爲什麼?

而第二個問題是,心不是這個代碼效率低下?因爲第一個函數接收8個字節的數據,並且它爲它們創建了額外的指針。並且創建額外的指針,至少如果我是正確的,只是爲了能夠通過在usbRequest_t結構中定義的名稱來訪問單個數據。那豈不是更簡單,更高效的只是在代碼中使用,而不是僅僅rq->bRequest == something例如 data[2]==something或者bRequest比一個字節大,例如data[1] == low_byte_of_something && data[2]== high_byte_of_something

回答

0

功能是獲取數據的「原始」緩衝液,和線:

usbRequest_t *rq = (void *)data; 

只是創建一個指向該緩衝區使用由usbRequest_t結構中指定的數據佈局來訪問它。

但絕對沒有談到這個操作昂貴 - 編譯器將可能甚至沒有實際的優化構建創建一個新的指針變量。

在那裏另一方面,也有可能是便攜性的擔憂,但可能不適合您的特定應用很重要。

0

問題1:由於datauchar *,你需要將其轉換爲另一種類型。如果您願意,您可以直接將它投射到usbRequest_t *

問題2:地址rq->bRequest需要花費盡可能多的時間來計算地址data[2]。在這兩種情況下,您都會將指針從堆棧中取出併爲其添加固定的偏移量。使用結構指針會產生更清晰的代碼。

0

您的第一行(RQ =(空隙)..)告訴編譯器把作爲usbRequest_t

通過了8個字節假定這是從一個設備或網絡的分組和編碼要看着它,彷彿它相匹配的結構

是它創建了一個指針 - 但在生成的代碼幾乎肯定會發生的是,第一個字節的地址被簡單地加載到寄存器。因此,有沒有開銷

反過來你rq-> bRequest的建議==東西實際上將數據複製 - 這是一個(V小8個字節)的開銷

這是映射結構一個很常見的技術到串行化數據流上

0

關於您聲稱代碼效率低下的問題,我在訪問data[x]rq->x之間幾乎沒有區別。在這兩種情況下,代碼以基址開始,並偏移幾個字節(顯然最多爲8個字節)。

[Base Address] + [Offset]將會是相同的,無論你是按數組還是按結構來做。如果簡單的添加是程序中效率低下的根源,那麼您的問題會更大。