簡體   English   中英

真的需要memcpy start index嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM