• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wskazniki - C++

Aruba Cloud - Virtual Private Server VPS
0 głosów
557 wizyt
pytanie zadane 2 lipca 2022 w C i C++ przez polandonion Dyskutant (7,630 p.)
edycja 2 lipca 2022 przez polandonion

Witam,

pozno troche, ale mam pytanko:

#include <iostream>
using namespace std;
int main(){
    char a[]="Ala ma kota";
    char* b="Ala ma kota";
    //int *wsk=100;
    cout<<a<<'\n';
    cout<<b<<'\n';
    //cout<<wsk;
    return 0;
}

Jak widac 6. oraz 9. linie kodu dalem w komentarze, bo kompilator glupieje, i slusznie.

4. linia kodu jest jak najbardziej logiczna, bo mamy tablice char'ow, czyli jeden za drugim jakis znak w tablicy, ale:

Totalnie błędna byłaby sytuacja, kiedy chcemy nadać zmiennej wskaźnikowej określoną wartość, bez wcześniejszego przypisania wskaźnika do zmiennej.

Wlasnie zacytowalem slowa pewnego kursanta jezyka C++. Slowa te pochodza ze strony p-programowanie.pl. Natomiast w 5. linii kodu widzimy wlasnie pusty wskaznik (bo nie ma odwolania do zadnej zmiennej typu char), do ktorego wpisalem "Ala ma kota". Ten wskaznik nie odwoluje sie do zadnej zmiennej,a to oznacza, ze ten program nie powinien dzialac.

Dodatkowo jesli mialbym np. wskaznik:

int *wsk;

to ten wskaznik moze wskazywac tylko i wylacznie na zmienna typu int, a co my widzimy w przypadku, ktory przed chwila przytoczylem? Nie dosc, ze wskaznik nie wskazuje na inna zmienna, to przechowuje nie ten typ danych co potrzeba, bo "Ala ma kota" to raczej tablica char'ow, a nie char.

Wiem, ze w C++ mozna to zastapic (a nawet trzeba, bo kompilator daje ostrzezenie) string'ami, ale jednak... potrzebowalbym kogos, kto mi to dosadnie wytlumaczy. Tylko ten przypadek uzycia wskaznika.

Dziekuje i dobranoc.

komentarz 2 lipca 2022 przez Oscar Nałogowiec (29,340 p.)

Wyrwałeś zdanie z kontekstu:

Przed zapisaniem wartości do wskaźnika, czyli zapisaniu wartości do zmiennej na którą wskazuje wskaźnik, należy się upewnić, że wskaźnik nie jest pusty.

Totalnie błędna byłaby sytuacja, kiedy chcemy nadać zmiennej wskaźnikowej określoną wartość, bez wcześniejszego przypisania wskaźnika do zmiennej.

int *wsk;
*wsk = 666; //źle!!

Tu chodziło o zapis "pod zmienną wskaźnikową", czyli zapis w miejsce wskazywane przez wskaźnik. Tego nie należy robić bez zainicjowania wskaźnika, czyli nadania mu wskazania na jakąś zmienną (może być dynamiczna allokacja).

Nie chodziło o nadanie wartości wskaźnikowi. W linii 5 wskaźnik dostaje swoją wartość. Wskazuje "gdzieś w kodzie" na odpowiedni napis. W zasadzie zmienna b powinna być typu const char *, by nie można było próbować modyfikować tego "kodu", ale const wprowadzono do C później, jak już istniały programy, które tego nie miały, bo nie mogły.

komentarz 2 lipca 2022 przez polandonion Dyskutant (7,630 p.)

Totalnie błędna byłaby sytuacja, kiedy chcemy nadać zmiennej wskaźnikowej określoną wartość, bez wcześniejszego przypisania wskaźnika do zmiennej.

Do tej pory myslalem, ze wskaznik musi zawierac adres innej zmiennej, na ktora bedzie wskaywal np.

int nrTel=123456789;
int *wsk=&nrTel;

albo w przypadku tablic:

int tab[5];
int *wsk=tab; //opcjonalnie int *wsk=&tab[0];

ale dekleracja wskaznika w taki sposob:

/*const*/ char* b="Ala ma kota";

jest wogole nielogiczna. Powiedziales, ze:

W linii 5 wskaźnik dostaje swoją wartość. Wskazuje "gdzieś w kodzie" na odpowiedni napis.

To oznacza, ze wartoscia wskaznika, czyli adresem innej zmiennej, na ktora wskazuje jest napis? Komputer przechowuje zmienne pod adresami zapisanymi przez liczby calkowite, dodatkowo szestnastkowo, a nie przez napisy.

 

1 odpowiedź

0 głosów
odpowiedź 2 lipca 2022 przez jankustosz1 Nałogowiec (36,800 p.)
edycja 2 lipca 2022 przez jankustosz1
 
Najlepsza

Są to dwie różne sytuacje. Czym jest to wyrażenie - "Ala ma kota" ? Jest to nic innego jak adres w pamięci pod którym jest ten napis, zatem przypisanie tego adresu wskaźnikowi nie jest żadnym problemem.

Jest za to inny problem, ten napis został utworzony już w czasie kompilacji i wrzucony do twojego programu, do części która nie jest modyfikowalna. Z tego powodu próba modyfikacji tego tekstu zakończy się błędem.

Np. spróbuj:

char * w = "Ala ma kota";
w[0] = 'X';
std::cout << w;

A następnie zakomentuj drugą linię. W pierwszym przypadku program się wywali a w drugim nie. Dlatego dla bezpieczeństwa lepiej pisać const *char, aby nie musieć ciągle o tym przypadku pamiętać..

komentarz 2 lipca 2022 przez jankustosz1 Nałogowiec (36,800 p.)

Dodam jeszcze, że jak zrobisz tak to program przejdzie:

char w[] = "Ala ma kota";
w[0] = 'X';
std::cout << w;

W tym przypadku "Ala ma kota" również jest umieszczone w pamięci tylko do odczytu, ale kompilator implicite przekopiuje ten tekst do nowej tablicy.

Podobne pytania

0 głosów
1 odpowiedź 993 wizyt
pytanie zadane 13 kwietnia 2020 w C i C++ przez Hubertius Bywalec (2,970 p.)
0 głosów
1 odpowiedź 539 wizyt
pytanie zadane 26 czerwca 2022 w C i C++ przez polandonion Dyskutant (7,630 p.)
0 głosów
1 odpowiedź 596 wizyt
pytanie zadane 26 stycznia 2020 w C i C++ przez Oskardes Użytkownik (600 p.)

93,326 zapytań

142,323 odpowiedzi

322,391 komentarzy

62,655 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...