[C++] wskaźnik char*

0

Witam!
Dopiero zaczynam się uczyć C++ i dotarłem do wskaźników. I mam mały problem odnośnie nich,. Mianowicie chodzi mi o wskaźnik do zmiennej typu char. Gdy próbuję zrobić coś takiego:

char *wskaznik;
cout << wskaznik;

To program się wykrzacza. Natomiast gdy zamiast char jest wskaźnik do np. zmiennej typu int, float itp., to program działa i wyświetla adres jakiejś tam komórki.

Ponadto czy mógłby mi ktoś wytłumaczyć dlaczego możliwa jest instrukcja

char *wskaznik="Jakis tam tekst";

Skoro jest to wskaźnik to dlaczego taka instrukcja przypisująca mu tekst jest możliwa i program w przypadku instrukcji

cout << wskaznik;

wyświetla ów tekst przypisany wskaźnikowi.

Wiem, że moje pytania są zapewne lamerskie, ale proszę o wyrozumiałość gdyż dopiero zaczynam naukę programowania i z góry dziękuję za wszelką pomoc.

0

Jeżeli twój kompilator pozwala na instrukcję:

char *wskaznik="Jakis tam tekst";

to odbiega od standardu. Natomiast instrukcja :

const char *wskaznik="Jakis tam tekst";

jest poprawna, gdyż kompilator traktuje "Jakis tam tekst" jako stały literał, który musi zapamiętać i umieścić gdzieś w pamięci. Instrukcja ta zwraca adres miejsca w którym umieszczony jest ten literał i przypisuje do wskaźnika. Co do drugiego pytania: operator<< dla char* jest właśnie tak zaimplementowany, że nie wyświetla adresu a literał na jaki adres wskazuje.

0

Używam Dev'a 4.9.9.2 :) W innym kompilatorze nie próbowałem.

0

Standardowo wypisywanie char* powoduje wypisywanie stringa na którego pierwszą literkę wskazuje ten wskaźnik (aż do napotkania znaku \0). Twój wskaźnik na nic nie wskazuje, więc program będzie próbował wypisywać jakieś losowe dane z losowego fragmentu pamięci i w efekcie poleci segfault.
Instrukcja:

char *wskaznik="Jakis tam tekst";

przypisuje do wskaźnika adres pierwszej literki stringa, nic więcej.

0

No dobrze więc dlaczego instrukcja

cout << wskaznik; 

wypisuje mi "jakis tam tekst" w przypadku gdy jest to wskaźnik char*, a nie adres pierwszej komórki, w której zapisana jest pierwsza litera napisu czyli "j". Natomiast gdy wskaźnik jest typu innego (int, float etc.), to na ekranie wyświetlone zostaje coś takiego "0x14", a po przypisaniu wskaźnikowi jakiejś zmiennej

int* wskaznik;
int x;
wskaznik=&x;

cout << wskaznik;
 

na ekranie pojawia się adres 0x22ff74.

Przepraszam, że tak męczę ale chciałbym to zrozumieć raz a porządnie. :)

0

Wskaźnik zaimplementowany jest jako liczba oznaczająca numer komórki.
Jeżeli dasz deklarację:
int x;
i natychmiast wyświetlisz tego x:
cout<<x;
to dostaniesz jakieś śmieci.
tak samo jest ze wskaźnikiem, deklaracja:
char w;
to "w" ma w sobie jakieś śmieci, które nawet możesz obejrzeć:
cout<<(void
)w;
Natomiast jak każesz komputerowi wydrukować napis który jest pod tym adresem:
cout<<w;
to on grzecznie próbuje to wykonać.

0

Mi się wydawało, że instrukcja

char *w;
cout << x;

sprawia, że wyświetlony zostanie adres komórki na którą w wskazuje (nawet jeśli ów wskaźnik wskazuje gdzieś w maliny), a nie wypisanie napisu który się od tej komórki zaczyna. Tym bardziej, że bez przypisania wskaźnikowi "w" jakiegoś tekstu program się wykrzacza, a przy innych typach nie. Chyba, że to co widzę na ekranie w przypadku innych typów czyli wspomniane 0x14 czy też 0x22ff74 to wartość liczby, która zaczyna się tam gdzie wskazuje w (choć dziwne czemu jest to w systemie 16kowym), a nie adres jakiejś komórki w pamięci. Chyba, że chodzi o to, że kompilator traktuje inaczej wskaźnik char* (czyli jako napis i próba jego wyświetlenia jest próbą wyświetlenia napisy zaczynającego się od komórki wskazywanej przez ten wskaźnik) od wskaźników innych typów. Teraz już się totalnie pogubiłem ;/

Popnadto (taka mała dygresja):

program

int x;
cout << x;

pokazuje mi ciągle 2 (dla typu int). Z ciekawości też sprawdziłem, że coś takiego

char *w="tekst";
cout << *w;

Zgodnie z oczekiwaniami powoduje wyświetlenie na ekranie samej litery t, czyli tak jak być powinno.

0

@mariaan masz rację, wydawało ci się.
Operator wypisywania jest INACZEJ zaimplementowany dla różnych typów danych. Dla każdego wskaźnika oprócz char* wypisze ci adres na który wskaźnik wskazuje. Dla char* wypisze ci C-stringa, czyli ciąg znaków począwszy od miejsca na które wskazuje wskaźnik aż do znaku \0

0

No i teraz wszystko już jest jasne (tak mi się właśnie wydaje) :) Dzięki, o to mi właśnie chodziło. :)

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