operator reinterpret_cast

0
int *wsk_int;
double *wsk_double;
wsk_double = (double *)wsk_int;

rozumiem że kompilator traktuje wskaźnik wsk_int jako wskaźnik na obiekt double i do wsk_double przypisuje adres do pokazywania na to samo co wsk_int.
Nie wiem co się dzieje w chwili przypisania do *wsk_double = 4.43 - gdzie są rezerwowane miejsca w pamięci na zapis takiej liczby z przecinkiem skoro to na co wskazuje *wsk_int to tylko obiekt 4 bajtowy?

	int a=2;
	int *wsk_int = &a;
	double *wsk_double;
	wsk_double = (double *)wsk_int;	
	*wsk_double = 3.14;
0

Nie do końca mogę się zgodzić z tym co napisałeś. Po 1 ten fragment kodu jest bez sensu :D a po 2 rozumiem, że to może być dla celów czysto dydaktycznych.

wsk_int to wskaźnik na adres pamięci typu int, wsk_double to wskaźnik na adres pamięcu typu double, natomiast przez

wsk_double = (double *)wsk_int

wskaźnik doublowy, że tak go nazwę, odnosi się do adresu pamięci wskaźnika intowego. I jeżeli coś przypiszesz do wskaźnika doublowego, to intowy nie zmieni swojej wartości.

0

To jest całkiem proste - w miejsce o rozmiarze zmiennej int przy przypisywaniu tak jak to robisz w przykładzie wpiszesz dane o rozmiarze double, a skoro double jest większy to w najlepszym przypadku od razu dostaniesz błąd ochrony pamięci, a jak nie to później znalezienie takiego błędu będzie bardzo trudne.

No i oczywiście dane, które były w zmiennej a zostaną zniszczone.

0

wskaźnik doublowy, że tak go nazwę, odnosi się do adresu pamięci wskaźnika intowego. I jeżeli coś przypiszesz do wskaźnika doublowego, to intowy nie zmieni swojej wartości

Przecież wskaźnik intowy (tzn int przez niego wskazywany) jak najbardziej zmieni swoją wartość. Inna sprawa że takie przypisanie może (powinno) spowodować błąd wykonania - zobacz ten kod - efekt będzie ciekawy:

#include <stdio.h>

int main()
{
	int a[2];
	a[0] = 1;
	a[1] = 1;
	
	double *d = (double*)&a[0];
	*d = 3.14;
	printf("%d\n", a[0]);
	printf("%d\n", a[1]);
}
0

A czy przypadkiem nie zabrakło tutaj:

wsk_double = (double *)wsk_int;

referencji? Żeby intowy zmienił swoją wartość, nie powinno być tak:

wsk_double = (double *)&wsk_int;

0

Ale nie o to autorowi tematu chodziło.

0

reinterpret_cast to wymuszenie traktowania zmiennej jako coś innego. Jeśli wskazywana zmienna nagle robi się większa niż była - mażemy po pamięci, czego skutkiem będzie uszkodzenie innych zmiennych albo wysypanie programu.

gdzie są rezerwowane miejsca w pamięci na zapis takiej liczby z przecinkiem

nigdzie. piszemy po bajtach bezpośrednio następnych za intem – cokolwiek tam będzie zostanie zniszczone. w najlepszym wypadku program się wywali. w najgorszym – nie.

0
MSM napisał(a)
&a[0]

No ładny potworek... Mam nadzieje że to było tylko tak dla autora tego tematu, na wypadek gdyby nie wiedział że zmiena tablicowa to tak naprawdę wskaźnik do jej pierwszego elementu...

0
olo16 napisał(a)
MSM napisał(a)
&a[0]

No ładny potworek... Mam nadzieje że to było tylko tak dla autora tego tematu, na wypadek gdyby nie wiedział że zmiena tablicowa to tak naprawdę wskaźnik do jej pierwszego elementu...

A może właśnie chcemy podkreślić, że chodzi nam o wskaźnik do pierwszego elementu, a nie o tablicę?

Poza tym tablica to tablica, nie wskaźnik. Niech dowodem będzie sizeof tablicy a sizeof wskaźnika.
Rzeczywiście, możliwe jest przypisanie tablicy do zmiennej wskaźnikowej

char tab[5];
char *wsk;
wsk=tab;

co wtedy oznacza pobranie adresu do początku tablicy

wsk=&tab[0];

ale nie powoduje że tablica jest wskaźnikiem.

0

Różnica miedzy tablicą a wskaźniekiem na jej pierwszy element to tylko sizeof i przekazywanie tablic wielowymiarowych do funkcji (lub szablonów funkcji parametryzowanych wielkością tablicy). Ja nie lubię takich potworków w kodzie - szczególnie kiedy początkujący się o coś pyta. Nauczycie go tak a potem przy jakiejś okazji sami skrytyujecie go za taki zapis...

0

Widzę że cię oburzyłem tymi 4 dodatkowymi literkami... Może się więc wytłumaczę z tego bezeceństwa.

Jeśli mam być szczery, na początku zamiast a[2] napisałem 2 zmienne - a i b - ale TO dopiero byłoby pokazanie bardzo złych zwyczajów (z tego co pamiętam kolejność zmiennych i fakt ich istnienia są UB).

Dalej - jeśli mam metodę powiedzmy taką (przykład bez sensu)

void do(bool pred, char *bit) 
{ if (pred) *bit = MAX; else *bit = MIN; }

i chcę ją wywołać dla pierwszego elementu tablicy buff to nie napiszę do(true, buff); (wrażenie z czytania: przekazujemy całą tablicę) tylko znienawidzone przez ciebie do(true, &buff[0]); (wrażenie z czytania: przekazujemy wskaźnik na pierwszy element - poprawnie). Co innego gdybym przekazywał w ten sposób (adres 1 elementu) całą tablicę, wtedy faktycznie miałbyś na co narzekać.

Jak dla mnie to żaden potworek.

1 użytkowników online, w tym zalogowanych: 0, gości: 1