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. |
|
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. |
|
MTPR Temat założony przez niniejszego użytkownika |
» 2014-04-19 11:02:17 #include<iostream> int main() { using namespace std; char ok[ 10 ] = "lancuch"; cout <<( int ) ok << endl; cout << ok[ 0 ] << endl; * ok = 'p'; cout << ok << endl; cout <<( int ) ok << endl; cin >> ok; cout << ok << endl; cout <<( char * ) 2686710 << endl; }
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". |
|
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'; cout <<( int ) ok << endl;
To nie jest prawidłowy sposób drukowania adresów. |
|
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ą ? int element; std::cin >> element; int tablica[ element ]; |
|
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++. |
|
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: 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ą ?
int element; std::cin >> element; 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*cout << static_cast < const void *>( ok ) << endl;
|
|
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 ?
|
|
« 1 » 2 |