operator reinterpret_cast

Odpowiedz Nowy wątek
2010-10-24 18:28

Rejestracja: 10 lat temu

Ostatnio: 2 lata temu

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;

Pozostało 580 znaków

2010-10-24 18:45

Rejestracja: 11 lat temu

Ostatnio: 6 lat temu

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.


Potrzebujesz programy do szkoły/na zaliczenie? Pomocy podczas kolosa lub egzaminu?
Zamów go!

http://proogramy.c0.pl

Pozostało 580 znaków

2010-10-24 19:09

Rejestracja: 9 lat temu

Ostatnio: 2 lata temu

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.


Pozostało 580 znaków

msm
2010-10-24 19:14
msm
Administrator

Rejestracja: 10 lat temu

Ostatnio: 2 dni temu

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]);
}

Pozostało 580 znaków

2010-10-24 20:47

Rejestracja: 11 lat temu

Ostatnio: 6 lat temu

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;


Potrzebujesz programy do szkoły/na zaliczenie? Pomocy podczas kolosa lub egzaminu?
Zamów go!

http://proogramy.c0.pl

Pozostało 580 znaków

2010-10-24 20:49

Rejestracja: 9 lat temu

Ostatnio: 2 lata temu

0

Ale nie o to autorowi tematu chodziło.


Pozostało 580 znaków

2010-10-24 21:19

Rejestracja: 16 lat temu

Ostatnio: 7 godzin temu

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.

Pozostało 580 znaków

2010-10-25 06:58

Rejestracja: 12 lat temu

Ostatnio: 7 lat temu

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...

Pozostało 580 znaków

2010-10-25 12:19

Rejestracja: 16 lat temu

Ostatnio: 7 godzin temu

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.

Pozostało 580 znaków

2010-10-26 14:28

Rejestracja: 12 lat temu

Ostatnio: 7 lat temu

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...

Pozostało 580 znaków

msm
2010-10-26 16:07
msm
Administrator

Rejestracja: 10 lat temu

Ostatnio: 2 dni temu

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.

Pozostało 580 znaków

Odpowiedz

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