[英]memcpy start index really needed?
問題是當我們使用memcpy()
復制任何字節數組時,我們是否應該為目標緩沖區顯式聲明起始(0)索引,或者簡單地提及它就足夠了。 讓我舉例說明我在說什么。 前提是我們正在嘗試將源緩沖區復制到目標緩沖區的啟動。
BYTE *pucInputData; // we have some data here
BYTE ucOutputData[20] = {0};
代碼1
memcpy((void*)&ucOutputData, (void*)pucInputData, 20);
代碼2
memcpy((void*)&ucOutputData[0], (void*)pucInputData, 20);
在您的情況下,考慮到這是一個C代碼片段,而ucOutputData
是一個數組
memcpy(ucOutputData, pucInputData, 20);
memcpy(&ucOutputData[0], pucInputData, 20);
兩者都相同 ,可以互換使用。 數組的名稱實際上為您提供了數組中第一個元素的地址。
現在,根據以下評論中非常有用的討論,值得一提的是
memcpy(&ucOutputData, pucInputData, 20);
也會在這里完成這項工作,但是數組名稱的使用和數組名稱的 地址之間存在根本區別 。 考慮到問題中的例子,對於像BYTE ucOutputData[20]
這樣的定義,
ucOutputData
指向20個BYTE
的數組的第一個元素的地址。 &ucOutputData
是一個指向20個BYTE
數組的指針。 因此,它們是不同類型的,C尊重變量的類型。 因此,為了避免任何可能的誤用和誤解,使用它的推薦和安全的方法是前兩個表達式中的任何一個。
FWIW,這里的演員真的不需要。 可以隱式地將任何指針類型轉換為C中的void *
。
由於表達式&array[0]
是相同的array
,而且由於任何指針可以被隱式轉換為void*
,你應該這樣做,而不是:
memcpy(ucOutputData, pucInputData, 20);
此外,由於您正在編寫整個ucOutputData
,因此不需要將其內容清零,因此可以刪除初始化程序:
BYTE ucOutputData[20]; // no "= {0}" part
不,你的兩個例子都不是最佳的。
請記住,C中的所有數據指針都轉換為/來自void *
(這是memcpy()
的第一個參數的類型),而不會丟失信息,並且不需要強制轉換。
還要記住,數組的名稱求值為許多上下文中第一個元素的地址,例如此處。
還記得盡可能使用sizeof
,當你不需要時,永遠不要引入文字常量。
所以,副本應該只是:
memcpy(ucOutputData, pucInputData, sizeof ucOutputData);
請注意,我們使用sizeof
而沒有括號,它不是一個函數。 我們也在目標緩沖區上使用它,這似乎是更安全的選擇。
原生數組可以在沒有轉換的情況下衰減到指針,因此在下面的代碼段中,對p
的三個賦值都會產生相同的值; p
將指向數組的開頭。 不需要顯式轉換,因為轉換為void*
是隱式的。
typedef char BYTE;
BYTE ucOutputData[20] = {0};
void *p = &ucOutputData;
p = ucOutputData;
p = &ucOutputData[0];
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.