2012-12-30 20 views
5

W jaki sposób można przypisać adres do takiej zmiennej całkowitej, kompilator nie będzie podawał błędu. Zawsze jednak można przypisać tylko wartości całkowite z całkowitą zmiennejPrzypisanie adresu do zmiennej całkowitej

int a=0x28ff1c 

Można zrobić to samo dla zmiennej char The kompilator nie da się błąd

char b=0x28ff1c 

Będzie wyjście na konsoli ekran wartość śmieci dla char b i losową wartość int a

cout<<b 
    <<endl; 
cout<<a; 

Czy ktoś może mi wyjaśnić, dlaczego istnieje różnica w wynikach dla char i int a, b. Czy ktoś może mi wyjaśnić dlaczego zmienna char i zmienna całkowita mogą mieć przypisane adresy

+3

'0x28ff1c' _jest_ wartość całkowitą. – Mat

Odpowiedz

5

Numer 0x28ff1c jest po prostu szesnastkową (podstawową 16) reprezentacją dziesiętnej (bazowej-10) liczby 2686748. Ponieważ domyślnie drukowane są wartości dziesiętne dla liczb całkowitych, domyślnie jest to liczba wydrukowana przez użytkownika.

Sprawa z char b = 0x28ff1c jest nieco inna, ponieważ

  1. char nie jest wystarczająco duży, aby pomieścić tę wartość. Praktycznym wynikiem jest to, że zostaje obcięty do 0x1c.
  2. cout leczy w szczególności, ponieważ jest zwykle używany do przechowywania danych tekstowych, więc cout drukuje znak, który ma kod 0x1c, który jest pewnego rodzaju znakiem kontrolnym. Możesz spróbować na przykład z 0x41 (która reprezentuje 'A' w ASCII i UTF-8).

Należy zauważyć, że nic nie oznacza, że ​​0x28ff1c jest adresem. Adres zostanie utworzony przez &a lub (void*)0x28ff1c.

+0

dzięki dziękuję – Computernerd

+0

'(char *) 0x28ff1c' jest bezpieczniejsze (chyba że można zagwarantować, że' 0x28ff1c' jest poprawnie ustawione dla 'int') - cc. Pytanie @Lim Bonus - czy wynik jest skrócony, czy jest to niezdefiniowane zachowanie z powodu przepełnienia (należy wziąć pod uwagę, że 'char' jest podpisany)? –

+0

@LuchianGrigore Implementacja zdefiniowana (chyba że 'CHAR_BIT> = 23'), może nasycić, skrócić, zamapować wszystkie wartości poza zasięgiem do 13, implementacja musi tylko udokumentować, co robi. W języku C może nawet podnieść sygnał zdefiniowany w implementacji. –

8

0x28ff1c to nie jest sam adres - to tylko liczba szesnastkowa.

Poniżej są równoważne:

int a = 2686748; //decimal number 
int a = 0x28ff1c; //hexadecimal number 
int a = 012177434; //octal number 

Adres jest reprezentowany przez wskaźnik - jeśli to tylko, że adres, można użyć void*:

void* p = (void*)0x28ff1c; 

W takim przypadku

int a = p; 

nie skompilowałoby się. p to adres, sam numer nie jest.

+0

@Luchin jak wyjaśnić różnicę w wynikach int a i char b i jak to się dzieje, że kompilator nie daje błędu przy przypisywaniu wartości całkowitej do char b – Computernerd

+0

@Lim char jest tylko 1 bajt, więc nie może pomieścić cała wartość. Ostrzeżenie * może * zostać wydane, ale nie jest wymagane. Zasadniczo przepełniasz zmienną 'char' (tak, że drukuje niepoprawny wynik). –

+0

@ Luchin dzięki – Computernerd

1

Ponieważ w dowolnym dosłownym początkowym 0x jest w rzeczywistości liczbą całkowitą. Jest to dozwolone. Adres to może czasami być liczbą całkowitą.

+0

Adresy nie są liczbami całkowitymi. W wielu implementacjach możliwa jest konwersja adresów na liczby całkowite bez problemów. W niektórych implementacjach adresy mogą mieć strukturę, która nie jest dobrze reprezentowana w jednej liczbie całkowitej (np. Dodanie 1 do kodowania adresu może nie wytworzyć adresu o 1 bajt w pamięci). –

+0

Dobry punkt @EricPostpischil. Powiem "Czasami adres może być liczbą całkowitą" –

+0

@EricPostpischil Nie widzę, jak to ma znaczenie. To prawda, że ​​'int' nie ma pewności posiadania adresu, ale tutaj nie chodzi o arytmetykę wskaźnika. To, co wskazałeś (dodanie do adresu) jest o wiele bardziej skomplikowane (może nawet doprowadzić do UB). –

0

Można również użyć *(int *)(Address) = value jako konstrukt do assigne value do Address i używać odpowiedź przez @Luchian Grigore