Wat is *(uint32_t*)?

Ik kan *(uint32_t*)moeilijk begrijpen.

Stel dat ik heb:

uint32_t* ptr;
uint32_t num
*(uint32_t*)(ptr + num); // What does this do? Does it 

Antwoord 1, autoriteit 100%

uint32_tis een numeriek type dat 32 bits garandeert. De waarde is niet ondertekend, wat betekent dat het waardenbereik van 0 tot 232– 1 gaat.

Dit

uint32_t* ptr;

declareert een aanwijzer van het type uint32_t*, maar de aanwijzer is niet geïnitialiseerd, dat
is dat de aanwijzer nergens in het bijzonder naar verwijst. Als u via die aanwijzer toegang probeert te krijgen tot het geheugen, veroorzaakt dit ongedefinieerd gedrag en kan uw programma crashen.

Dit

uint32_t num;

is gewoon een variabele van het type uint32_t.

Dit

*(uint32_t*)(ptr + num);

ptr + numgeeft je een nieuwe aanwijzer. Het wordt pointer-rekenkunde genoemd. Het is net als gewone rekenkunde, alleen neemt de compiler de grootte van typen in
overweging. Beschouw ptr + numals het geheugenadres op basis van de originele ptrpointer plus het aantal bytes voor numuint32_tobjecten.

De (uint32_t*) xis een cast. Dit vertelt de compiler dat hij de uitdrukking xmoet behandelen alsof het een uint32_t*is. In dit geval is het niet eens nodig,
omdat ptr + numal een uint32_t*is.

De *aan het begin is de dereferentie-operator die wordt gebruikt om toegang te krijgen tot het geheugen via een aanwijzer. De hele uitdrukking is gelijk aan

ptr[num];

Omdat geen van deze variabelen is geïnitialiseerd, is het resultaat rommel.

Als u ze echter als volgt initialiseert:

uint32_t arr[] = { 1, 3, 5, 7, 9 };
uint32_t *ptr = arr;
uint32_t num = 2;
printf("%u\n", *(ptr + num));

dit zou 5 afdrukken, omdat ptr[2]5 is.


Antwoord 2, autoriteit 19%

uint32_tis gedefinieerd in stdint.h, dus het kan nodig zijn om het op te nemen

#include <stdint.h>

Antwoord 3, autoriteit 6%

Dit doet niet echt iets. Laat me je een ander voorbeeld geven:

uint32_t data;
void *pointer = &data;
*(uint32_t *)pointer = 5;

Allereerst betekent void*een “generieke” aanwijzer. Het kan verwijzen naar objecten van elk type.

Nu, (uint32_t *)betekent “interpreteer pointerals een verwijzing naar een object met het type uint32_t.

De rest van de uitdrukking betekent gewoon “opslaan 5 op de locatie die door deze aanwijzer is opgeslagen”.

Als je wilt weten wat uint32_tis, is dat een geheel getal zonder teken met precies 32 bits. En pointer + numis hetzelfde als het adres van pointer[5].


Antwoord 4

Dit type uitdrukking wordt meestal gebruikt in woordspelingen. Als je niet bekend bent met typewoordspelingen, is het belangrijkste idee om het typesysteem te omzeilen, zodat je iets als een ander type kunt behandelen dan het in werkelijkheid is (dwz behandel een int a als dubbel)

Het belangrijkste idee achter type woordspelingen is dat je een aanwijzer naar een huidige variabele neemt en deze vervolgens in een ander type plaatst door deze in een aanwijzer van dat type te gieten en deze vervolgens te derefereren, vandaar de veelgebruikte cast en dereference waarnaar je verwijst to ( *(uint32_t *)= cast naar niet-ondertekende 32-bits int-aanwijzer en vervolgens dereferentie).

Zoals anderen al hebben opgemerkt, “doet uw code niets” omdat u een int naar een int vervormt, wat geen effect heeft. Als je echter een int in een dubbel wilt omzetten…

uint32_t num=5;
double& myvar=*(double*) &num;

Nu kun je het geheugen van numals een double manipuleren via myvar, ook al is numnog steeds een Int. Dit is een verschrikkelijk idee en is alleen bedoeld als speelgoedvoorbeeld van het gebruik van woordspelingen.

Other episodes