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

Zadanie ze wskażnikami - Stephen Prata Szkoła programowania C++

Object Storage Arubacloud
0 głosów
948 wizyt
pytanie zadane 30 maja 2017 w C i C++ przez Kamil Paradowski Użytkownik (620 p.)

Witam wszystkich, mam problem z niżej wymienionym zadaniem:

"Zmodyfikuj program z listungu 7.7, zamieniając trzy funkcje obsługujące tablice tak, aby każda z nich używała dwóch wskaźników określających zakres. Funkcja fill_array(), zamiast zwracać aktualną liczbę elementów, ma zwrócić wskaźnik elementu znajdującego się za ostatnim wypełnionym elementem. Inne funkcje mają używać tego wskaźnika jako drugiego parametru pozwalającego wykryć koniec danych.

Listing 7.7 z w/w treści zadania wygląda tak:

#include <iostream>
 
const int Max = 5;
 
int fill_array(double ar[],int limit);
void show_array(const double ar[],int n);
void revalue(double r, double ar[], int n);
 
int main()
{
    double properties[Max];
    int size =fill_array(properties, Max);
    show_array(properties,size);
    if (size>0)
    {
        std::cout<<"Podaj czynnik zmiany wartosci: ";
        double factor;
        while (!(std::cin>>factor))
        {
            std::cin.clear();
            while (std::cin.get() != 'n')
                continue;
            std::cout<<"Niepoprawna wartosc; podaj liczbe: ";
        }
        revalue(factor, properties, size);
        show_array(properties, size);
    }
    std::cout<<"Gotowe.n";
    std::cin.get();
    std::cin.get();
    return 0;
}
 
int fill_array(double ar[],int limit)
{
    double temp;
    int i;
    for (i=0; i<limit; i++)
    {
        std::cout<<"Podaj wartosc nr "<<(i+1)<<": ";
        std::cin>>temp;
        if (!std::cin)
        {
            std::cin.clear();
            while (std::cin.get() != 'n')
                continue;
            std::cout<<"Bledne dane, wprowadzenie danych przerwane.n";
            break;
        }
        else if (temp<0)
            break;
        ar[i]=temp;
    }
    return i;
}
void show_array(const double ar[], int n)
{
    for(int i=0; i<n; i++)
    {
        std::cout<<"Nieruchomosc nr "<<(i+1)<<": ";
        std::cout<<ar[i]<<std::endl;
    }
}
void revalue(double r, double ar[], int n)
{
    for(int i=0; i<n; i++)
        ar[i] *= r;
}

Będę szczery, nie potrafię jeszcze dobrze posługiwać się wskaźnikami w praktyce i to zadanie na dzień dzisiejszy wydaje mi się naprawdę trudne, może nawet zbyt trudne dla mnie. Oto kod (na brudno), który do tej pory napisałem, nie jest on kompletny w żadnym wypadku, w zasadzie to praktycznie przepisałem pierwszą funkcję z innego kodu, którego znalazłem w sieci:

#include <iostream>

const int Max = 5;

int* fill_array(short* a, short* b);
void show_array(const double ar[],int n);
void revalue(double r, double ar[], int n);

int main()
{
    double properties[Max];
    int size =fill_array(properties, Max);
    show_array(properties,size);
    if (size>0)
    {
        std::cout<<"Podaj czynnik zmiany wartosci: ";
        double factor;
        while (!(std::cin>>factor))
        {
            std::cin.clear();
            while (std::cin.get() != '\n')
                continue;
            std::cout<<"Niepoprawna wartosc; podaj liczbe: ";
        }
        revalue(factor, properties, size);
        show_array(properties, size);
    }
    std::cout<<"Gotowe.\n";
    std::cin.get();
    std::cin.get();
    return 0;
}

int* fill_array(short* a,short* b)
{
    int *i=0;
    short n=0;
    for (i=a; i!=b; i++,n++)
    {
        std::cout<<"Podaj wartosc nr "<<(n+1)<<": ";
        std::cin>>*i;
        if (!std::cin)
        {
            std::cin.clear();
            while (std::cin.get() != '\n')
                continue;
            std::cout<<"Bledne dane, wprowadzenie danych przerwane.\n";
            break;
        }
        else if (*i<0)
            break;
    }
    return *b;
}
void show_array(short* a,short* b)
{
    int *i=0;
    short n=0;
    for(int i=a; i!=b; i++,n++)
    {
        std::cout<<"Nieruchomosc nr "<<(n+1)<<": ";
        std::cout<<*i<<std::endl;
    }
}
void revalue(short* a,short* b)
{
    for(int i=0; i<n; i++)
        ar[i] *= r;
}

Samodzielnie nie jestem w stanie wykonać tego zadania, tak więc mam prośbę. Czy jakaś dobra osoba tutaj mogłaby mi rozwiązać to zadanie tak, aby wszystkie wymogi z treści były tutaj uwzględnione, a jednocześnie kod nie byłby zbyt długi/skomplikowany? Po prostu, żeby spełniał wymogi polecenia zadania. Myślę, że analiza takiego gotowego kodu da mi w tym przypadku o wiele więcej niż gdybym miał próbować godzinami przypadkowych kombinacji, których jeszcze do końca nie rozumiem.

komentarz 30 maja 2017 przez Szahid Pasjonat (20,930 p.)
Funkcja fillarray ma wypełniać całą tablicę ?
komentarz 30 maja 2017 przez Kamil Paradowski Użytkownik (620 p.)
Tak, do pełna albo aż do momentu kiedy podamy np. jakiś inny znak niż liczba, wtedy pętla się kończy.
komentarz 30 maja 2017 przez Szahid Pasjonat (20,930 p.)
Chodziło mi o to że w pętli w której wypełniam tablicę mógłbym (znając liczbę elementów tablicy) ją wypełnić bez zabawy w inkrementacje wskaźnika. Ale wtedy informacja o ostatnim elemencie jest zbędną więć autorowi zadania chodziło widoznie o to że wielkość tablicy nie jest znana.
komentarz 30 maja 2017 przez Kamil Paradowski Użytkownik (620 p.)
Właśnie problem z tą książką jest taki, że treści zadania są często dwuznaczne i trzeba kilka razy ją czytać, żeby zrozumieć co autor miał na myśli.

2 odpowiedzi

+1 głos
odpowiedź 30 maja 2017 przez Szahid Pasjonat (20,930 p.)
#include <iostream>

const int Max = 5;

double* fill_array(double* first,double* last);
void show_array( double* first, double* last);// last to tak naprawdę last +1
void revalue(double* first, double* last, double factor);

int main()
{
    double properties[Max];
    double* f=&properties[0];
    double* l=&properties[Max-1];
    double* wsk=fill_array(f, l);


    show_array(f,wsk);
    revalue(f,wsk,3);
    show_array(f,wsk);




    return 0;
}

double* fill_array(double*first,double* last)
{
    double temp;
    double* i;
    int licznik=1;
    for (i=first; i<=last; i++)
    {
        std::cout<<"Podaj wartosc nr "<<licznik<<": ";
        licznik++;
        std::cin>>temp;
        if (!std::cin)
        {
            std::cin.clear();
            while (std::cin.get() != 'n')
                continue;
            std::cout<<"Bledne dane, wprowadzenie danych przerwane.n";
            break;
        }
        else if (temp<0)
            break;
        *i=temp;
    }
    return i;
}

void show_array(double* first, double* last)
{
    for(double* i=first;i<last;i++)
    {
        std::cout<<*i<<std::endl;
    }
}

void revalue(double* first, double* last, double factor)
{
   for(double* i=first;i<last;i++)
    {
        *i=factor;
    }
}

 

komentarz 30 maja 2017 przez Szahid Pasjonat (20,930 p.)
Wyciąłem z maina fragment ale to wklej sobie z powrotem jak chcesz. ( przypadkowo mi się usunęło)
komentarz 30 maja 2017 przez Kamil Paradowski Użytkownik (620 p.)
Dzięki Ci wielkie! :)

Może to głupio zabrzmi, ale mógłbyś jednak jeszcze uzupełnić poprawnie dokładnię tę samą wyciętą zawartość w mainie? Po prostu mam obawę, że coś schranię znowu.
komentarz 30 maja 2017 przez Szahid Pasjonat (20,930 p.)
Jasne
komentarz 30 maja 2017 przez Szahid Pasjonat (20,930 p.)

Rozumiem że tam gdzie pisałeś size chodziło Co o sizeof 

#include <iostream>

const int Max = 5;

double* fill_array(double* first,double* last);
void show_array( double* first, double* last);// last to tak naprawdę last +1
void revalue(double* first, double* last, double factor);

int main()
{
    double properties[Max];
    double* f=&properties[0];
    double* l=&properties[Max-1];
    double* wsk=fill_array(f, l);


    show_array(f,wsk);

   if (sizeof (properties)>0)
    {
        std::cout<<"Podaj czynnik zmiany wartosci: ";
        double factor;
        while (!(std::cin>>factor))
        {
            std::cin.clear();
            while (std::cin.get() != 'n')
                continue;
            std::cout<<"Niepoprawna wartosc; podaj liczbe: ";
        }
        revalue(f, wsk, factor);
        show_array(f, wsk);
    }
    std::cout<<"Gotowe.n";
    std::cin.get();
    std::cin.get();




    return 0;
}

double* fill_array(double*first,double* last)
{
    double temp;
    double* i;
    int licznik=1;
    for (i=first; i<=last; i++)
    {
        std::cout<<"Podaj wartosc nr "<<licznik<<": ";
        licznik++;
        std::cin>>temp;
        if (!std::cin)
        {
            std::cin.clear();
            while (std::cin.get() != 'n')
                continue;
            std::cout<<"Bledne dane, wprowadzenie danych przerwane.n";
            break;
        }
        else if (temp<0)
            break;
        *i=temp;
    }
    return i;
}

void show_array(double* first, double* last)
{
    for(double* i=first;i<last;i++)
    {
        std::cout<<*i<<std::endl;
    }
}

void revalue(double* first, double* last, double factor)
{
   for(double* i=first;i<last;i++)
    {
        *i=factor;
    }
}

 

komentarz 30 maja 2017 przez Kamil Paradowski Użytkownik (620 p.)
Szczerze powiedziawszy nie jestem pewny, tak jak napisałem na samej górze, tak dosłownie był napisany ten kod w wersji standardowej.
komentarz 30 maja 2017 przez Szahid Pasjonat (20,930 p.)
Niemożliwe bo taki zapis jest błędny i bezsensowny. Może masz wydanie z błędem. Mam też tą książke. Podaj mi nr strony to zobacze o co chodzi
komentarz 30 maja 2017 przez Kamil Paradowski Użytkownik (620 p.)
298 i 299
komentarz 30 maja 2017 przez Szahid Pasjonat (20,930 p.)
To jest błąd na 100% . Taki kod  się nie  kompiluje. Autorowi napewno chodziło o sizeof i celem tego ifa jest sprawdzenie czy tablica nie jest pusta. (skoro jest to po co zmieniać jej wartość). A taki efekt daje sizeof.

 

size służy to sprawdzania długości stringa tak btw
komentarz 30 maja 2017 przez Kamil Paradowski Użytkownik (620 p.)
No cóż, to nie pierwszy błąd w treści jaki udało mi się wyłapać w tej książce :) Tutaj jest ich więcej: http://helion.pl/errata.php?ident=cppri6

Dzięki za pomoc jeszcze raz, doceniam to.
komentarz 30 maja 2017 przez Szahid Pasjonat (20,930 p.)
Jak w każdej książce o programowaniu.

Spoko, polecam się
+1 głos
odpowiedź 30 maja 2017 przez d0n Mądrala (6,440 p.)
edycja 30 maja 2017 przez d0n
#include <iostream>
  
const int Max = 5;
  
double* fill_array( double* pocz, int limit );
void show_array( double* pocz, double* kon );
void revalue(double r, double* pocz, double* kon );
  
int main()
{
    double* properties = new double [Max];
    double* kon = fill_array(properties, Max);
    show_array(properties, kon);
    if ( kon != properties )
    {
        std::cout<<"Podaj czynnik zmiany wartosci: ";
        double factor;
        while (!(std::cin>>factor))
        {
            std::cin.clear();
            while (std::cin.get() != 'n')
                continue;
            std::cout<<"Niepoprawna wartosc; podaj liczbe: ";
        }
        revalue(factor, properties, kon);
        show_array(properties, kon);
    }
    std::cout<<"Gotowe";
    std::cin.get();
    std::cin.get();
    return 0;
}
  
double* fill_array(double* pocz, int limit)
{
    double temp;
    double* kon = pocz;
    for ( int i = 0; i < limit; ++i, ++kon )
    {
        std::cout<<"Podaj wartosc nr "<<(i+1)<<": ";
        std::cin>>temp;
        if (!std::cin)
        {
            std::cin.clear();
            while (std::cin.get() != 'n')
                continue;
            std::cout<<"Bledne dane, wprowadzenie danych przerwane.n";
            break;
        }
        else if (temp<0)
            break;
        (*kon) = temp;
    }
    return kon;
}

void show_array( double* pocz, double* kon )
{
    double* tmp = pocz;
    int nr = 1;
    while ( tmp != kon )
    {
        std::cout <<"Nieruchomosc nr " << nr << ": ";
        std::cout << (*tmp ) << std::endl;
    	++tmp; ++nr;
    }
}

void revalue(double r, double* pocz, double* kon )
{
	double* tmp = pocz;
   	while ( tmp != kon )
   	{
   		(*tmp) *= r;
   		++tmp;
   	}
}

Nie spojrzałem, że kod już jest, więc może w ramach robienia tego do czego służy forum, a nie podawania gotowców pokrótce wyjaśnię wskaźniki. Otóż wskaźnik danego typu powstaje przez dodanie po nazwie typu gwiazdki ( np. string* wsk ). Wskaźnik ma zawsze 8 bajtów na platformach 64 bitowych i 4 bajty na 32 bitowych. Przechowuje on adres obiektu, który mu damy. Zapytasz więc, po co wskaźnikowi typ? przecież pokazuje tylko miejsce w pamięci, nie musi wiedzieć co tam jest.
Wskaźniki mają typy, by móc napisać (*nazwa_wsk), co oznacza wartość przechowywaną przez zmienną, na która wskaźnik wskazuje, natomiast sama nazwa_wsk oznacza przechowywany w nim adres. W różnych starych bibliotekach i API możesz napotkać typ void*, co oznacza wskaźnik na próżnię. Taki wskaźnik przechowuje tylko adres w pamięci, ale nie umie interpretować tego na co wskazuje, bo nie ma typu, więc (*nazwa_wsk) nie zadziała.

No i oprocz zmiennych wskaznik moze pokazywac miejsce w pamięci funkcji, ale to juz temat na inna historie...

komentarz 30 maja 2017 przez Kamil Paradowski Użytkownik (620 p.)
A czy przy pierwszej funkcji nie powinny być przekazane do parametru dwa wskaźniki a nie jeden (Tak jak jest to napisane w treści zadania)?
komentarz 30 maja 2017 przez d0n Mądrala (6,440 p.)
Nie bo ta funkcja ma znalezc miejsce w pamieci drugiego wskaznika i go zwrocic do uzywania dla reszty funkcji
komentarz 30 maja 2017 przez Szahid Pasjonat (20,930 p.)

Kolego przeczytaj polecenie.

"Zmodyfikuj program z listungu 7.7, zamieniając trzy funkcje obsługujące tablice tak, aby każda z nich używała dwóch wskaźników określających zakres. "

komentarz 31 maja 2017 przez d0n Mądrala (6,440 p.)
"Funkcja fill_array(), zamiast zwracać aktualną liczbę elementów, ma zwrócić wskaźnik elementu znajdującego się za ostatnim wypełnionym elementem. Inne funkcje mają używać tego wskaźnika jako drugiego parametru pozwalającego wykryć koniec danych."

Inne funkcje maja uzywac tego wskaźnika, więc skoro maja uzywac tego wskaźnika, to pewnie ten wskaźnik powstaje w fill_array.

Skoro ten wskaźnik mialby by obliczony w kodzie wczesniej, to po co fill_array miala by go zwracać?
komentarz 31 maja 2017 przez Szahid Pasjonat (20,930 p.)
Ten wskaźnik powstaje w fillarray. Zobacz na kod który wstawiłem.  Fillarray zwraca ten wskaźnik

Podobne pytania

0 głosów
1 odpowiedź 407 wizyt
pytanie zadane 9 września 2017 w C i C++ przez Modferno Początkujący (400 p.)
0 głosów
2 odpowiedzi 985 wizyt
0 głosów
4 odpowiedzi 845 wizyt

92,575 zapytań

141,424 odpowiedzi

319,649 komentarzy

61,960 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...