Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Wskaźniki i łańcuchy

Ostatnio zmodyfikowano 2014-04-22 18:38
Autor Wiadomość
MTPR
Temat założony przez niniejszego użytkownika
Wskaźniki i łańcuchy
» 2014-04-18 21:53:20
Witam,
chyba najprościej będzie jak zacytuję z książki:

-Niektóre kompilatory traktują literały łańcuchowe jako stałe tylko do odczytu, więc przy próbie nadpisania ich zawartości zgłaszają błąd. W zasadzie standard wymaga, aby literały łańcuchowe były traktowane jako stałe, ale jeszcze nie wszystkie kompilatory to robią.
-Niektóre kompilatory stosują jedną kopię literału, aby obsłużyć wszystkie jego wystąpienia w programie.

Krótko mówiąc, chodzi tu o to że adresu literału łańcuchowego nie można zmienić czy zawartości pod tym adresem ?
Prosiłbym też o wyjaśnienie drugiego przypadku.
P-108357
pekfos
» 2014-04-18 22:39:55
Krótko mówiąc, chodzi tu o to że adresu literału łańcuchowego nie można zmienić czy zawartości pod tym adresem ?
Niczego z wymienionych nie możesz zmienić.

Prosiłbym też o wyjaśnienie drugiego przypadku.
Tu nie ma czego wyjaśniać. Literał łańcuchowy to stała tablica znaków - nie można zmieniać stałych.
P-108360
MTPR
Temat założony przez niniejszego użytkownika
» 2014-04-19 11:02:17
C/C++
#include<iostream>
int main()
{
    using namespace std;
    char ok[ 10 ] = "lancuch";
    cout <<( int ) ok << endl; /// sprawdzam adres, u mnie 2686710
    cout << ok[ 0 ] << endl; /// pod tym adresem znajduje sie litera l
    * ok = 'p'; /// nadpisanie zawartosci pierwszego elementu
    cout << ok << endl; /// otrzymujemy pancuch
    cout <<( int ) ok << endl; /// po nadpisaniu zawartosci ten sam adres 2686710
    cin >> ok; /// uzywam tablicy na dane wejsciowe, wpsiuje 1 litere np. z
    cout << ok << endl; /// otrzymuje z, a nie zancuch
    cout <<( char * ) 2686710 << endl; /// sprawdzam co teraz znajduje sie pod adresem, pod którym wczesniej litera l
}
Skoro zawartości pod adresem łańcucha nie można zmienić, to wytłumacz mi np. 5, 8 linijkę.
A także czy kompilator utworzył kopię tego literału ? Jeżeli tak to powinna mieć ona chyba inny adres w pamięci,
tymczasem ostatnia linijka nie pokazuje literału "lancuch".
P-108366
Monika90
» 2014-04-19 12:29:52
ok to nie jest literał, to jest lokalna tablica znaków.
Chcesz zmodyfikować literał? Spróbuj tego:
"abc"[ 0 ] = 'x';


C/C++
cout <<( int ) ok << endl; /// sprawdzam adres, u mnie 2686710
To nie jest prawidłowy sposób drukowania adresów.
P-108367
MTPR
Temat założony przez niniejszego użytkownika
» 2014-04-19 16:15:15
Monika90 Jeśli mówisz o rzutowaniu w tej instrukcji to zastosowałem dla lepszej czytelności.
Co do
"abc"[ 0 ] = 'x';
 kompilator faktycznie zgłosił błąd.
Definicja łańcuchów mówi: łańcuch to ciąg znaków zapisanych za sobą kolejno w pamięci, zakończony znakiem NUL.
W dodatku łańcuch taki jak
"abc"
 wewnętrznie zapisany jest jako tablica.
Więc między innymi dlatego potraktowałem, że tablica znakowa inicjalizowana literałem
"lancuch"
 to tak jakby łańcuch.
Dobra, do rzeczy, skoro wystąpił błąd kompilacji to oznacza to, że kompilator zalicza się do tych co nie stosują kopii literałów ? A także czy moglibyście zaprezentować program w którym kompilator stosuję taką kopię, wraz z wyjaśnieniem jak to działa ?
Z góry dzięki.
Przy okazji chciałbym się upewnić czy taki kod można nazwać tablicą dynamiczną ?
C/C++
int element;
std::cin >> element; /// w końcu wielkość tej tablicy jest ustalona podczas wykonywania programu
int tablica[ element ];
P-108374
pekfos
» 2014-04-19 16:41:04
Przy okazji chciałbym się upewnić czy taki kod można nazwać tablicą dynamiczną ?
Ten kod nawet nie jest poprawny, z punktu widzenia standardu C++.
P-108376
Monika90
» 2014-04-19 16:42:43
"abc"[ 0 ] = 'x';
 to będzie błąd kompilacji w każdym przyzwoitym kompilatorze.

Możesz spróbować tego:
const_cast < char *>( "abc" )[ 0 ] = 'x';
, teraz zachowanie jest niezdefiniowane, typowo - crash at runtime.

Jeżeli Ci chodzi o to

-Niektóre kompilatory stosują jedną kopię literału, aby obsłużyć wszystkie jego wystąpienia w programie.

To mozesz sprawdzić tak:
C/C++
const void * p1 = "abcdefgh";
const void * p2 = "abcdefgh";
std::cout << p1 << ' ' << p2;
jeżeli wydrukowane adresy bedą te same, to znaczy, że kompilator rozpoznał, że to ten sam literał napisowy i umieścił tylko jedną kopię w pliku wykonywalnym. Jak będą różne, to znaczy że nie był aż tak sprytny.


Przy okazji chciałbym się upewnić czy taki kod można nazwać tablicą dynamiczną ?
C/C++
int element;
std::cin >> element; /// w końcu wielkość tej tablicy jest ustalona podczas wykonywania programu
int tablica[ element ];
To nie jest standardowe C++, choć może będzie za jakiś czas. Niektóre kompilatory udostępniają takie coś jako niestandardowe rozszerzenie języka.

Jeśli mówisz o rzutowaniu w tej instrukcji to zastosowałem dla lepszej czytelności.
Rzutowanie na int po to by wydrukować wskaźnik jest błędne. Rzutuj na const void*
C/C++
cout << static_cast < const void *>( ok ) << endl;
P-108377
MTPR
Temat założony przez niniejszego użytkownika
» 2014-04-19 19:58:38
W porządku, dzięki wam przebrnąłem przez ten temat w książce. Jeszcze tylko ostatnie pytanie, po czym zamykam.
Możesz wyjaśnić dlaczego rzutowanie na tym int wskaźnika jest błędne ?
P-108389
« 1 » 2
  Strona 1 z 2 Następna strona