簡體   English   中英

C ++ / Arduino了解uint8_t和*的用法

[英]C++ / Arduino understanding the usage of uint8_t and *

有人可以向我解釋此代碼塊中發生了什么嗎? 特別是在第3行上。在ptr顯着之前,我有一個*的預感。 而且(uint8_t *)看起來像是(uint8_t *)為一個字節...但是*怎么了? 看起來r,g和b的取值都相同。

case TRUECOLOR: { // 24-bit ('truecolor') image (no palette)
  uint8_t  pixelNum, r, g, b,
          *ptr = (uint8_t *)&imagePixels[imageLine * NUM_LEDS * 3];
  for(pixelNum = 0; pixelNum < NUM_LEDS; pixelNum++) {
    r = *ptr++;
    g = *ptr++;
    b = *ptr++;
    strip.setPixelColor(pixelNum, r, g, b);
  }

我主要使用C#工作。

第二和第三行可以更清晰地表達:

uint8_t pixelNum;
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t *ptr = (uint8_t *)&imagePixels[imageLine * NUM_LEDS * 3];

前四個變量聲明應該非常簡單,第五個是C#沒有的。 它聲明ptr作為指向 uint8_t 該指針設置為值的地址,該值是imagePixels數組中的imageLine * NUM_LEDS * 3imageLine * NUM_LEDS * 3個元素。 由於這可能是另一種類型(可能是指向char的指針,誰知道),因此將該值uint8_t轉換為指向uint8_t

星號( * )的下一次出現在for循環主體中,在該處用作取消引用運算符 ,該運算符基本上會解析指針以獲取實際值。

指針101

指針就像房子的街道地址。 它向您顯示房子的位置,以便您可以找到它,但是當您繞過它時,就不會繞過整個房子。 您可以取消引用它,這意味着您可以實際訪問房屋。

與指針結合使用的兩個運算符是星號( * )和與號( & )。 星號用於指針的聲明並取消引用指針,“與”號用於獲取某對象的地址。

看下面的例子:

int x  = 12;
int *y = &x;

std::cout << "X is " << *y; // Will print "X is 12"

我們將x聲明為一個擁有值12int 現在,我們將y聲明為一個指向 int指針 ,並通過存儲x的地址將其設置為指向x 通過使用*y ,我們可以訪問x的實際值,即y指向的int

由於指針是引用的一種,因此通過指針修改值會更改所指事物的實際值。

int x = 12;
int *y = &x;

*y = 10;

std::cout << "X is " << x; // Will print "X is 10"

指針102

指針是一個很大的主題,建議您花些時間從不同的來源閱讀有關指針的信息。

在變量定義中使用*表示ptr是一個指針。 它存儲的值是內存中另一個變量或另一個變量的一部分的地址。 在這種情況下, ptr是指向imagePixels內部的內存塊的指針,從涉及的變量名稱來看,它是圖像中的一行。 由於類型為uint8_t ,因此將使用任何imagePixels並將其用作單個字節的塊。

在變量定義之外使用*具有不同的含義:取消引用指針。 轉到指針中存儲的內存中的位置並獲取值。

是的, *還可以用於乘法,從而提高了代碼讀取的樂趣水平。

遞增( ++ )指針可將地址移動到下一個地址。 如果您有uint32_t *該地址將前進4以指向下一個uint32_t 在這種情況下,我們有uint8_t ,因此地址提前了一個字節。 所以

r = *ptr++;

A)在指針處獲取值。

A)之后前進指針。

在A)之后,將值分配給r。

“前進指針”階段所處的位置確實很棘手。 它在步驟A之后。在C ++ 17或更高版本中,它在“分配值”之前,因為等號的右側和左側的內容之間存在分隔。 但是在C ++ 17之前,我們只能說是在步驟A之后。搜索關鍵術語:“序列點”。

g = *ptr++;
b = *ptr++;

再次執行此操作,獲取並在ptr處分配當前值,前進指針。

strip.setPixelColor(pixelNum, r, g, b);

根據命名,我認為這會將給定的像素設置為上面讀取的顏色。

你不能只是

strip.setPixelColor(pixelNum, *ptr++, *ptr++, *ptr++);

因為再次測序。 無法保證參數的計算順序。 這是為了允許編譯器開發人員對速度和大小進行優化,如果指定了順序,它們將無法進行優化,但這對於那些希望從左到右分辨率的開發者來說是一個捷徑。 我的理解是,這在C ++ 17標准中仍然適用。

好。 那這是做什么的?

您需要一個很大的內存塊,並且只有一行。

*ptr = (uint8_t *)&imagePixels[imageLine * NUM_LEDS * 3];

查明該行的開頭並將其設置為被視為愚蠢的字節數組。

for(pixelNum = 0; pixelNum < NUM_LEDS; pixelNum++) {

通用的for循環。 對於LED行上的所有像素。

r = *ptr++;
g = *ptr++;
b = *ptr++;

以標准的8位RGB格式獲取行中一個像素的顏色,然后指向下一個像素

strip.setPixelColor(pixelNum, r, g, b);

將讀取的顏色寫入一個像素。

然后for循環將循環並開始處理下一個像素,直到該行上沒有更多像素為止。

星號(*)是指針的符號。 因此,(uint8_t *)是對指向uint8_t的指針的強制轉換。 然后在循環中,在星號的前面加上一個取消引用該指針的符號(即* ptr)。 取消引用指針將返回指針指向的數據。

我建議閱讀一些有關指針的內容,因為它們對於理解C / C ++至關重要。 這是指針上C ++文檔

消息靈通,我將需要更多代碼來運行它來解釋它。 我發現一個非常有用的工具是C可視化工具。 這是一個在線調試工具,可幫助您逐步一步一步地了解代碼中正在發生的事情。 可以在以下位置找到它: http : //www.pythontutor.com/visualize.html#mode=edit

即使該URL談論的是python,它也可以使用C語言和多種語言。 我本來可以發表評論而不是發布答案,但我的代表不夠高。 我希望這有幫助!

(我不隸屬於上述網站,只是在困惑時偶爾使用它)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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