Wskaźniki w języku C++ - posługiwanie się typem wskaźnikowym w programowaniu, wykorzystanie wskaźników w operowaniu tablicami. Dynamiczny przydział pamięci
Cel ćwiczenia:
Umiejętność posługiwania się wskaźnikiem przy wywoływaniu obiektów
Budowanie własnych programów przy użyciu typu wskaźnikowego
Operowanie tablicami za pomocą wskaźników.
Zapoznanie się z dynamicznym przydziałem pamięci.
Budowanie własnych funkcji z przekazywaniem parametrów przez adres
Nowe zagadnienia:
adres obiektu (zmiennej)
wskaźnik do obiektu
inkrementacja / dekrementacja wskaźnika
nazwa tablicy a wskaźnik do pierwszego elementu tablicy,
poruszanie się po tablicy za pomocą wskaźnika,
dynamiczny przydział pamięci zmiennej prostej,
dynamiczny przydział pamięci tablicy.
Definicje nowych pojęć:
Wskaźnik - obiekt, w którym zapisany jest adres do innego obiektu.
Składnia deklaracji użycia wskaźnika:
float *d;
Nazwa wskaźnika
Gwiazdka oznacza, że jest to wskaźnik
Typ obiektu wskazywanego przez wskaźnik
Składnia ustawienia wskaźnika na dany obiekt:
int z, *w; (1)
w = &z; (2)
(1) deklaracja obiektu o nazwie z (obiekt typu całkowitego - int) oraz wskaźnika do obiekty typu całkowitego o nazwie w,
(2) zapisanie do obiektu w (do wskaźnika) adresu obiektu z (&z - adres obiektu z)
Od tego momentu można odwoływać się do obiektu z na dwa sposoby:
(1) bezpośrednio, np.: z = z + 1;
(2) poprzez wskaźnik: *w = *w + 1;
Obie operacje dają ten sam rezultat (zwiększenie wartości zapisanej w obiekcie z o 1).
Zadanie 1
Napisz program zwiększający parametry a=1 i b=1 o stałe wartości (np. 100 i 10, odpowiednio). Zwiększenie wartości parametrów powinno odbywać się w oddzielnej funkcji wywoływanej ze wskaźnikami do parametrów a i b.
Kod źródłowy
#include <iostream.h>
#include <conio.h>
void zwiekszenie(int *wsk1, int *wsk2);
main()
{
int a = 1, b = 1, *wsk_a, *wsk_b;
cout<<"Przed zwiekszeniem wartosci a = "<<a<<" i b = "<<b<<endl;
wsk_a = &a;
wsk_b= &b;
zwiekszenie(wsk_a, wsk_b);
cout<<endl<<"Po zwiekszeniu wartosci a = "<<a<<" i b = "<<b<<endl;
getch();
return(0);
}
void zwiekszenie(int *wsk1, int *wsk2)
{
*wsk1 += 100;
*wsk2 += 10;
}
Wskaźniki i tablice
W języku C++ istnieje ścisła zależność pomiędzy wskaźnikami i tablicami. Każda operacja na zmiennej indeksowanej może być wykonana za pomocą wskaźników (za pomocą wskaźników operacje są wykonywane szybciej).
Podczas kompilacji nazwa tablicy jest automatycznie przekształcana na wskaźnik jej pierwszego elementu.
tab[ ] kompilacja wtab=tab równoważne wtab=&tab[0]
Inkrementując wskaźnik tablicy możemy poruszać się po całej tablicy:
działanie wtab=wtab+1 zmienia wskazanie na wtab=&tab[1] itd.
Wydruk tablicy tab przy użyciu wskaźników
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
int tab[]={0,1,2,3,4,5,6,7,8,9},*wtab;
wtab=tab; //lub wtab=&tab[0] poniewaz tab==&tab[0];
for (int i=0;i<10;i++)
cout<<"tab["<<i<<"]="<<*wtab++<<” adres: ”<<wtab<<endl;
getch();
return 0;
}
dynamiczne przydzielanie pamięci - umożliwia programiście tworzenie i usuwanie zmiennych a tym samym pełne sterowanie czasem ich istnienia. Zmienne przechowywane są w specjalnie wydzielonym obszarze pamięci zwanym stosem zmiennych dynamicznych (ang. heap). Do przydzielania i zwalniania służą słowa kluczowe new i delete. Dostęp do zmiennych dynamicznych umożliwiają wskaźniki.
new - do przydzielania pamięci dynamicznej
delete - do zwalniania pamięci dynamicznej
dynamiczny przydział pamięci zmiennej prostej
Składnia
int *w; deklaracja wskaźnika w
w=new int (45); alokacja pamięci dynamicznej zainicjowanie wartości 45
delete w; zwalnianie pamięci dynamicznej
Można alokować pamięć w jednym wierszu z deklaracją wskaźnika:
int *w=new int (45);
Programowe zabezpieczenie przed brakiem przydziału pamięci
if(w==0)
{
cout<<"nie przydzielono pamieci"<<endl;
return 1;
}
dynamiczny przydział pamięci tablicy
Składnia
float *wtab; deklaracja wskaźnika wtab
wtab=new float [10]; alokacja pamięci dynamicznej
delete []wtab; zwalnianie pamięci dynamicznej tablicy
Można alokować pamięć w jednym wierszu z deklaracją wskaźnika:
float *wtab=new float [10];
Zadanie 2
Napisz program, który pobiera z klawiatury liczbę rzeczywistą, następnie oblicza i drukuje jej pierwiastek kwadratowy, logarytm naturalny i logarytm dziesiętny. Zadeklaruj zmienną dynamiczną oraz zabezpiecz program przed brakiem alokacji pamięci dynamicznej.
#include<iostream >
#include<cmath >
#include<conio.h>
using namespace std;
int main()
{
float *w=new float;
if(w==0) //zabezpieczenie przed brakiem alokacji pamieci
{
cout<<"nie przydzielono pamieci"<<endl;
return 1;}
cout<<"Podaj liczbe rzeczywista dodatnia: ";
cin>>*w;
cout<<"*w="<<*w<<endl;
cout<<"sqrt="<<sqrt(*w)<<endl;
cout<<"log="<<log(*w)<<endl;
cout<<"log10="<<log10(*w)<<endl;
delete w;
getch();
return 0;
}
Zadanie 3
Napisz program, który pobiera z klawiatury liczbę naturalną, następnie oblicza i wypełnia tablicę 10-cio elementową pierwiastkiem kwadratowym tej liczby. Zadeklaruj dynamicznie tablicę oraz zabezpiecz program przed brakiem alokacji pamięci dynamicznej.
#include<iostream>
#include<cmath>
#include<conio.h>
using namespace std;
int main()
{
int i,n;
float *wtab=new float[10];
if(wtab==0) //zabezpieczenie przed brakiem alokacji pamieci
{
cout<<"nie przydzielono pamieci"<<endl;
return 1;}
cin>>n;
for(i=0;i<10;i++)
{
*wtab=sqrt(n);
cout<<*wtab++<<endl;
}
delete []wtab;
getch();
return 0;
}
Zadania C++ - 9
Napisz program, który zapyta o dwie wartości liczbowe. Program ma za zadanie:
stworzyć wskaźniki do obiektów, gdzie zapisano podane wartości,
wyświetlić zawartość obiektów oraz ich adresy przy użyciu wskaźników.
Stwórz program zamieniający wartości dwóch zmiennych, wprowadzone z klawiatury. Zamianę wartości powinna wykonywać funkcja zamiana wywoływana z dwoma wskaźnikami do obiektów, gdzie przechowywane są wartości zmiennych.
Napisz program obliczający silnię dla liczby podanej z klawiatury. Obliczenia powinny być przeprowadzone w oddzielnej funkcji wywoływanej ze wskaźnikiem.
Napisz program, w którym do kolejnych elementów tablicy jednowymiarowej będą wpisywane kolejne wartości potęgi liczby 2 (tzn. element [0] = 20, element [1] = 21 itd.). Liczbę elementów tablicy należy wprowadzić z klawiatury. Do zapisania elementów w tablicy użyj funkcji wywoływanej ze wskaźnikiem.
Napisz program realizujący mnożenie jednowymiarowej tablicy o dziewięciu elementach przez dowolną liczbę. Do mnożenia użyj funkcji wywoływanej ze wskaźnikiem do tablicy.
Stwórz program służący do odwracania kolejności znaków w dowolnym stringu. Użyj wskaźników.
Napisz program, który pobiera z klawiatury n liczb całkowitych, zapamiętuje je w tablicy a następnie wyszuka spośród nich liczbę największą i najmniejszą. Wykorzystaj wskaźniki.
Napisz program, który wstawia do tablicy n-elementowej kolejne wyrazu ciągu
drukuje tablicę a następnie sumuje wszystkie elementy tej tablicy i pokazuje wynik. Użyj wskaźniki przy operacjach na tablicy.
Napisz program, który sumuje wszystkie elementy w wierszach tablicy o 3 wierszach i 4 kolumnach i wynik umieszcza w odpowiednim wektorze. Użyj wskaźników.
Napisz program, który wstawia do tablicy jednowymiarowej n-elementowej liczby całkowite, a następnie kopiuje wszystkie liczby większe od zera do innej tablicy również n-elementowej w miejsca o tych samych indeksach, a pozostałe miejsca wypełnia zerami. Wydrukuj tablicę wyjściową i wynikową. Zastosuj wskaźniki.
Napisz program, który obliczy i wyświetli tabliczkę mnożenia liczb całkowitych od 1 do 10 w postaci ogólnie znanej tj. zmiennej wynik mnożenia przydziel dynamiczną pamięć
Napisz program, który oblicza i drukuje kolejne wyrazy ciągu:
oraz oblicza sumę n wyrazów ciągu. Wykorzystaj zmienne dynamiczne.
Pracownik dokonywał pomiaru temperatury powietrza T razy w miesiącu i ciśnienia P razy w miesiącu i wyniki zapisywał w tablicach. Napisz program do wprowadzania wyników pomiarów i obliczania średniej temperatury i ciśnienia w analizowanym miesiącu. Utwórz tablice dynamiczne.
Napisz program do analizy zużycia paliwa w twoim samochodzie. Ilość zużytego paliwa oraz ilość przejechanych kilometrów mają być zapisywane w odpowiednich tablicach z dynamiczną alokacją. Skonstruuj także funkcje do sumowania elementów tablic oraz obliczania średniego zużycia paliwa na 100 km.
Ćwiczenia laboratoryjne nr 9
„Język Programowania” str. 5
5
Ćwiczenia laboratoryjne
„Język programowania” nr 7.1
6
Zwiększenie wartości a i b
ZWIĘKSZENIE
a = 1 b = 1
wsk_a = &a
wsk_b = &b
STOP
START
Po zwiększeniu
a= 101 b = 11
Przed zwiększeniem
a= 1 b = 1
wskaźnik tablicy
nazwa tablicy
Pamiętaj po wykonaniu pętli wskaźnik wtab jest ustawiony na obiekt o adresie &tab[9]+1 czyli poza obszarem tablicy. Powrót wskaźnika:
wtab=wtab-10 wtedy znowu wtab=tab
równoważne z tab[i]