2 / 3
Jul 2021

Właśnie w wieku 60++ rozpocząłem kurs programowania w C++
Pracuję na laptopie Dell Precision M4800 (Windows 10Home wersja 10.0.19041, CodeBloks-20.03mingw )
Przerabiając temat o wskaźnikach natrafiłem na problemy które mnie przerastają i potrzebuję pomocy, HELP!!!

Problem 1.
Nie działa u mnie rzutowanie zmiennej typu HEX na typ int - program się nie uruchamia a CodeBloks wyrzuca komunikat; " error: cast from ‘int*’ to ‘int’ loses precision {- fpermissive] "
Ten sam program bez rzutowania zmiennej HEX na typ int uruchamia się ale długo, a kompilator zamiast zwrócić returned (0) wyrzuca bardzo dużą liczbę
Do tej pory nie zauważyłem takich anomalii w działaniu programów z poszczególnych lekcji kursu uruchamianych na moim laptopie.
Odinstalowałem i ponownie zainstalowałem CodeBloks’a ale to nie pomogło - podejrzewam jakiś problem z Windowsem

Problem 2

W załączonym programie ćwiczebnym chcę wrócić wskaźnikiem na komórkę zerową tablicy Zastosowałem rozwiązanie nieprofesjonalne (tablica=tablica-ile;) Jak to zrobić fachowo aby działało skutecznie bez względu w którym miejscu tablicy aktualnie się znajduję?

Problem 3
W tym samym programie po wyjściu z pętli for wskaźnik jest poza tablicą ??? Czy to jest normalne? Gdzie tkwi błąd?

Będę wdzięczny jeśli ktoś zechce mi pomóc:slight_smile:

#include
#include
#include <conio.h>

using namespace std;

int ile;

int main()
{
cout << "Ile liczb w tablicy: ";
cin>>ile;

int*tablica;
tablica=new int[ile];

cout<<"Podaj kolejno liczby do tablicy: "<<endl;
for(int i=0; i<ile; i++)
{
cout<<"Liczba nr “<<i+1<<” ";
cin>>tablica[i];
cout<<endl;
// cout<< (int)tablica <<endl;
}

cout<<endl;
for(int i=0; i<ile; i++)
{
cout<<tablica<<" "<<*tablica<<endl;
tablica++;
}
cout<<endl<<tablica<<endl;
tablica=tablica-ile;
cout<<endl<<tablica<<endl;

delete [] tablica;

return 0;

}

  • created

    Jul '21
  • last reply

    Jul '21
  • 2

    replies

  • 661

    views

  • 3

    users

  • 3

    likes

  • 3

    links

Czesc

Problem 1: error: cast from ‘int*’ to ‘int’

‘int *’ to jest wskaznik na typ int.
To jest adres komorki w pamieci, w ktorej znajduje sie typ int.
Ten adres w obecnyh komputerach jest zawarty w 64 bitach, czyli 8 bajtach.
Dla uproszczenia (bo to jest bardziej skompilokwany temat) mozna sobie o nim pomyslec,
ze jest to zwykla liczba okreslajaca numer bajta w pamieci RAM.

‘int’ to jest zwykla liczba calkowita.
W obenych komputerach jest to standardowo wartosc 32 bitowa (4 bajtowa).

Ten ‘error’ oznacza, ze nastapila proba wcisniecia liczby, ktora sklada
sie z 64 bitow (8 bajtow) do zmiennej, ktora moze pomiescic jedynie 32 bity (4 bajty).

Moze sie to udac, jezeli ta ‘liczba’ jest mala, przykladowo:

'int *' ===> 0x0000000011223344 (dec: 287454020)
'int'   ===>         0x11223344 (dec: 287454020)

Jezeli liczba jest za duza to sie nie zmiesci i zostanie obcieta:

'int *' ===> 0x1122334455667788 (dec: 1234605616436508552)
'int'   ===>         0x55667788 (dec: 1432778632)

Generlanie konwersja jakiegokolwiek wskaznika na typ calkowity
nie jest prawidlowa. Takich rzeczy sie nie powinno robic.

W obecnych komputerach typ long jest w stanie pomiescic 64 bity.

Podejrzewam, ze ten kurs bazowal na architekturze 32 bitowej, gdzie standrdowo int to 32 bity i wskaznik ‘int *’ takze miescil sie w 32 bitach. Takie problemy wynikaja prawdopodbnie z tego, ze autor nie trzymal sie standardu C/C++.

Problem 2: "chce wrocic wskaznikiem na komorke zerowa tablicy"
Generalnie nie powinno sie ruszac adresu otrzymanego od funkcji new / malloc itd.
Taki kod przewaznie zadziala, ale nie jest poprawny.

{
  int * tablica = new int [ile];
  tablica += 345;
  ...
  tablica -= 345;
  delete [] tablica;
}

Operacja delete WYMAGA podania dokladnie tej samej wartosci otrzymanej podczas alokacji.
Nalezy pamietac, ze w tym przypadku tablica jest to adres (wskaznik) komorki w pamieci,
a wskazniki maja to do siebie, ze moga podlegac specjalnemu traktowaniu.
Moze byc sytuacja, ze rozne wartosci wskaznikow wskazuja tak na prawde
na ta sama komorke w pamieci (porownywanie wskaznikow musi byc robione z ta swiadomoscia).
Tutaj wazne info, delete wymaga, aby ta wartosc byla dokladnie taka sama jak podczas alokacji,
nie moze to byc inna wartosc, nawet, gdyby wskazywala na ta sama komorke w pamieci.
Najlepsze rozwiazanie, w ktorym nie trzeba sie o to martwic to uzycie dodatkowego wskaznika bazowego,
ktorego nie ruszamy podczas dzialania programu:

{
  int * tablica_base = new int [ile];
  int * tablica = tablica_base;
  ...
  tablica += 345;
  ...
  tablica -= 123;
  ...
  delete [] tablica_base;
}

Problem 3: "po wyjsciu z petli for wskaźnik jest poza tablica"
Tak na prawde ten wskaznik wskazuje adres konca tablicy.
Jest to ok, gdyz koniec tablicy (zaalokowanego obszaru) to tez jest adres poprawny.
Nie mozna tam juz nic wpisac, ale adres jest poprawny.
Generalnie wskanikiem mozna ‘latac’ po calym obszarze zaalokowanym,
wliczajac w to adres konczacy ten obszar.

Pzdr.

Nie mogłem wcześniej …

“Rzutowanie zmiennej na inny typ np. HEC na DEC)”

W C++, o ile wiem, nie ma typu DEC, ani HEX, a jeżeli chcesz wyświetlić liczbę w takiej postaci, lub konwertować z jednego systemu liczbowego na inny, to rzutowanie nic tu nie pomoże, chyba że znowu jestem niedoinformowany.

Zakładanie nowego wątku, do tego samego tematu jest złą praktyką. Powinieneś po prostu, w starym swoim wątku poprawnie wkleić swój kod, ale na razie ciągle masz z tym problemy. Czytałeś, to co powinieneś przeczytać koniecznie/? Kliknij na zakładkę Forum po lewej stronie na pl.spoj.com, Jak wkleić link do ideone? --> poczytaj wątek: KULKI - Zabawa w kulki(python). Jeżeli masz problemy na swoim komputerze, to możesz testować na dowolnej stronie z kompilatorem online, jest tego od zatrzęsienia, chociażby ideone.com. Ale koniecznie wyrzuć wcześniej, ze swojego kodu, bibliotekę conio.h.

Czy widzisz jakąś różnicę między swoim wklejeniem a moim:

#include <iostream>
#include <iomanip>
#include <conio.h>

using namespace std;

int ile;

int main()
{
    cout << "Ile liczb w tablicy: ";
    cin>>ile;

    int*tablica;
    tablica=new int[ile];

cout<<"Podaj kolejno liczby do tablicy: "<<endl;
    for(int i=0; i<ile; i++)
    {
        cout<<"Liczba nr "<<i+1<<"  ";
        cin>>tablica[i];
        cout<<endl;
       // cout<< (int)tablica <<endl;
    }

cout<<endl;
 for(int i=0; i<ile; i++)
 {
   cout<<tablica<<"  "<<*tablica<<endl;
   tablica++;
 }
 cout<<endl<<tablica<<endl;
 tablica=tablica-ile;
 cout<<endl<<tablica<<endl;

    delete [] tablica;

    return 0;
}

Pomijając, mówiąc oględnie czystość twojego kodu, ale czy to takie trudne, poprawne wklejenie, zaznaczenie i kliknięcie myszą w jeden guzik/przycisk?

Jak byś miał ++60, ale przecież masz trylko 60++ :wink: W końcu człowiek uczy się całe życie. Jaki masz sprzęt i oprogramowanie jest mało istotne, przecież możesz testować swoje kody online [np ideone], jak już napisałem wyżej.
Inne problemy rozwiał chyba list od @m_labanowicz ?

A i oczywiście jak już radziłem wcześniej wybierz lepsze źródła wiedzy do nauki języka C++ i nauki programowania.