HOWTO · Arduino
Arduino `memset()` 函式
在 Arduino C++ 中,`memset()` 會以重複的單一位元組填入指定範圍;若要設定數值陣列元素,請使用型別化指派。
本頁內容
memset() 會從指定的記憶體位址開始,以同一個位元組值填入指定數量的位元組。使用 sizeof 計算陣列的位元組數;若要將數值陣列的元素設為某個數值,請使用型別化指派。
Arduino 中的 memset() 函式
在 Arduino C++ 中,memset() 會以重複的單一位元組填滿連續的位元組範圍。它適合用於位元組緩衝區和字元陣列;它不會把多位元組數值複製到每個元素。第三個引數是位元組數,因此應根據要填入的儲存空間計算。
標準函式宣告於 <string.h>(也可透過 C++ 標頭 <cstring> 使用)。其形式為 memset(destination, value, byte_count):destination 指向第一個位元組,value 會轉換為無號位元組,而 byte_count 指定要寫入的位元組數。函式會重複該轉換後的位元組,不會取用原始值的位元組。
在 Arduino 中使用 memset() 函式
以下完整的 C++ 範例會填入字元陣列,再修改其中一段範圍。範例使用標準輸出,因此不需要依賴特定開發板的序列連線即可展示位元組操作。
#include <cstring>
#include <iostream>
int main() {
char letters[] = "hello";
std::memset(letters, '.', sizeof(letters) - 1);
std::memset(letters + 1, 'a', 2);
std::cout << letters << '\n';
return 0;
}
.aa..
這個陣列可存放五個字母和結尾的空字元。第一次呼叫只填入五個可見字元所占的位元組,保留結尾空字元。第二次呼叫從索引 1 開始寫入兩個位元組,因此會修改索引 1 和 2。在 Arduino sketch 中,memset() 也能對相同陣列進行這些操作;若要顯示結果字元陣列,可使用 Serial.print()。
若陣列元素不是字元,請根據陣列本身計算位元組數。例如,memset(values, 0, sizeof(values)) 會填入 values 的每個位元組。若要填入一段完整元素,請將起始位址往後移動指定的元素數,再將元素數乘以元素大小:memset(values + start, byte_value, count * sizeof(values[0]))。陣列索引從 0 開始,選取的元素數必須在陣列範圍內。
以位元組值 2 填入整數陣列,不等於將每個元素指派為整數 2。在採用 16 位元小端序 int 的目標上,每一組兩個位元組會變成 0x0202,其值為 514。其他整數寬度或表示方式可能得到不同結果。若目標是將每個元素設為型別化數值 2,請使用迴圈,例如 for (int i = 0; i < count; ++i) values[i] = 2;。
若要修改 Arduino String 中的字元,可透過索引直接指派,例如 text[i] = '.';。這是直接指派字元,並不是使用 memset()。
重要注意事項
請確認目的位址指向可寫入的儲存空間,而且位元組數不會超出該空間。對陣列使用 sizeof(array) 時,只有在該運算式仍指向陣列本身的情況下,才會得到陣列的總位元組大小;宣告為陣列的函式參數實際上是指標,因此必須另外傳入或計算長度。位元組數為 0 時不會寫入任何位元組,但依照函式契約,目的指標仍須有效。
重複的位元組模式不能通用地用來設定物件值。當你確實要指定位元組層級的表示方式時,例如填入字元緩衝區或清除位元組,這種做法才合適。請避免用它初始化非平凡的 C++ 物件,包括管理資源或依賴建構子與不變條件的物件。一般數值和物件請使用型別化指派、值初始化,或物件本身提供的 API。
結論
需要在已知的位元組範圍內重複同一個位元組時,才使用 memset()。請以位元組為單位計算範圍,處理陣列時留意元素寬度,並確保所有寫入都在目的儲存空間內。對整數值、字串和物件,除非你明確需要重複的位元組模式,否則應優先使用型別化指派或合適的初始化方式。