// deklaracja zmiennej typu int oraz wskaźnika na zmienne tego typu int zmienna = 10;



Podobne dokumenty
Programowanie strukturalne i obiektowe. Funkcje

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

Zadeklarowanie tablicy przypomina analogiczną operację dla zwykłych (skalarnych) zmiennych. Może zatem wyglądać na przykład tak:

Wskaźnik może wskazywać na jakąś zmienną, strukturę, tablicę a nawet funkcję. Oto podstawowe operatory niezbędne do operowania wskaźnikami:

> C++ wskaźniki. Dane: Iwona Polak. Uniwersytet Śląski Instytut Informatyki 26 kwietnia 2017

Lab 9 Podstawy Programowania

Informatyka I: Instrukcja 4.2

7. Pętle for. Przykłady

Podstawy informatyki. Elektrotechnika I rok. Język C++ Operacje na danych - wskaźniki Instrukcja do ćwiczenia

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.

ZASADY PROGRAMOWANIA KOMPUTERÓW

Język C++ zajęcia nr 2

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Ok. Rozbijmy to na czynniki pierwsze, pomijając fragmenty, które już znamy:

W dowolnym momencie można zmienić typ wskaźnika.

Jak napisać program obliczający pola powierzchni różnych figur płaskich?

Część XVII C++ Funkcje. Funkcja bezargumentowa Najprostszym przypadkiem funkcji jest jej wersja bezargumentowa. Spójrzmy na przykład.

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Wstęp do Programowania, laboratorium 02

Języki i metodyka programowania. Wskaźniki i tablice.

Wskaźniki w C. Anna Gogolińska

1 Wskaźniki. 1.1 Główne zastosowania wskaźników

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?

Argumenty wywołania programu, operacje na plikach

for (inicjacja_warunkow_poczatkowych(końcowych); wyrazenie_warunkowe; wyrazenie_zwiekszajace(zmniejszające)) { blok instrukcji; }

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 26 marca kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40

4. Funkcje. Przykłady

1 Podstawy c++ w pigułce.

Algorytmy i język C++

Warsztaty dla nauczycieli

6. Pętle while. Przykłady

Podstawy programowania w C++

for (inicjacja_warunkow_poczatkowych; wyrazenie_warunkowe; wyrazenie_zwiekszajace) { blok instrukcji; }

Programowanie w C++ Wykład 4. Katarzyna Grzelak. 19 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 37

DYNAMICZNE PRZYDZIELANIE PAMIECI

Wykład nr 3. Temat: Wskaźniki i referencje. Edward Morgan Forster

Typy wyliczeniowe Konwersje napis <-> liczba Struktury, unie Scanf / printf Wskaźniki

Konwersje napis <-> liczba Struktury, unie Scanf / printf Wskaźniki

Podstawy programowania w języku C++

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 16 kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 27

Struktury, unie, formatowanie, wskaźniki

IX. Wskaźniki.(3 godz.)

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Programowanie - wykład 4

Materiał Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Wskaźniki Tablice dynamiczne Referencje Funkcje

Wstęp do wskaźników w języku ANSI C

Lekcja : Tablice + pętle

Program 6. Program wykorzystujący strukturę osoba o polach: imię, nazwisko, wiek. W programie wykorzystane są dwie funkcje:

Języki programowania C i C++ Wykład: Typy zmiennych c.d. Operatory Funkcje. dr Artur Bartoszewski - Języki C i C++, sem.

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Podstawy algorytmiki i programowania - wykład 4 C-struktury

6 Przygotował: mgr inż. Maciej Lasota

1 Podstawy c++ w pigułce.

Laboratorium nr 9. Temat: Wskaźniki, referencje, dynamiczny przydział pamięci, tablice dynamiczne. Zakres laboratorium:

Podstawy programowania w języku C++

Wstęp do informatyki- wykład 12 Funkcje (przekazywanie parametrów przez wartość i zmienną)

Przedrostkowa i przyrostkowa inkrementacja i dekrementacja

Struktury Struktura polami struct struct struct struct

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Rekurencja (rekursja)

Programowanie w języku Python. Grażyna Koba

> C++ dynamiczna alokacja/rezerwacja/przydział pamięci. Dane: Iwona Polak. Uniwersytet Śląski Instytut Informatyki

Warunek wielokrotnego wyboru switch... case

Rozdział 4 KLASY, OBIEKTY, METODY

Język C, tablice i funkcje (laboratorium, EE1-DI)

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

C++ wprowadzanie zmiennych

Programowanie w C++ Wykład 3. Katarzyna Grzelak. 12 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 35

Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Ćwiczenie 1. Podstawy. Wprowadzenie do programowania w języku C. Katedra Metrologii AGH

Funkcje. Spotkanie 5. Tworzenie i używanie funkcji. Przekazywanie argumentów do funkcji. Domyślne wartości argumentów

Przykład 1: Funkcja jest obiektem, przypisanie funkcji o nazwie function() do zmiennej o nazwie funkcja1

Podstawy programowania. Wykład 6 Wskaźniki. Krzysztof Banaś Podstawy programowania 1

Podstawy programowania. Wykład PASCAL. Zmienne wskaźnikowe i dynamiczne. dr Artur Bartoszewski - Podstawy prograowania, sem.

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania

Pętle i tablice. Spotkanie 3. Pętle: for, while, do while. Tablice. Przykłady

Podczas dziedziczenia obiekt klasy pochodnej może być wskazywany przez wskaźnik typu klasy bazowej.

XV. Wskaźniki Odczytywanie adresu pamięci istniejących zmiennych Wskaźniki pierwsze spojrzenie.

STL: Lekcja 1&2. Filozofia STL

Pytania sprawdzające wiedzę z programowania C++

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk. Wydział Inżynierii Metali i Informatyki Przemysłowej

Tablice - podstawowa organizacja danych

TEMAT : KLASY DZIEDZICZENIE

Tablice mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

Materiał. Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Funkcje Wskaźniki Referencje Tablice dynamiczne Typ string Przeładowania funkcji

2. Tablice. Tablice jednowymiarowe - wektory. Algorytmy i Struktury Danych

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Wskaźniki. Przemysław Gawroński D-10, p marca Wykład 2. (Wykład 2) Wskaźniki 8 marca / 17

Wskaźniki. Informatyka

PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec

Programowanie komputerowe. Zajęcia 4

int suma; pralka czerwona; // definicja egzemplarza obiektu pralka * wskaŝ; // definicja wskaźnika pralka & ruda = czerwona; // definicja referencji

W języku C/C++ pomiędzy wskaźnikami a tablicami istnieje bardzo ścisły związek. Do onumerowania elementów w tablicy służą tzw. INDEKSY.

Operator przypisania. Jest czym innym niż konstruktor kopiujący!

Pętle. Dodał Administrator niedziela, 14 marzec :27

2. Zmienne i stałe. Przykłady Napisz program, który wypisze na ekran wynik dzielenia 281 i 117 w postaci liczby mieszanej (tj. 2 47/117).

Transkrypt:

Wskaźniki Wygodnie jest wyobrażać sobie pamięć operacyjną jako coś w rodzaju wielkiej tablicy bajtów. W takiej strukturze każdy element (nazwiemy go komórką) powinien dać się jednoznacznie identyfikować poprzez swój indeks. I tutaj rzeczywiście tak jest numer danego bajta w pamięci nazywamy jego adresem. W ten sposób dochodzimy też do pojęcia wskaźnika: Wskaźnik (ang. pointer) jest adresem pojedynczej komórki pamięci operacyjnej. Jest to więc w istocie liczba, interpretowana jako unikalny indeks danego miejsca w pamięci. Specjalne znaczenie ma tu jedynie wartość zero, interpretowana jako wskaźnik pusty (ang. null pointer), czyli nie odnoszący się do żadnej konkretnej komórki pamięci. Wskaźniki służą więc jako łącza do określonych miejsc w pamięci operacyjnej; poprzez nie możemy odwoływać się do tychże miejsc. Wskaźniki na zmienne Wskaźnik jest przede wszystkim liczbą - adresem w pamięci, i w takiej też postaci istnieje w programie. Język C++ ma ponadto ścisłe wymagania dotyczące kontroli typów i z tego powodu każdy wskaźnik musi mieć dodatkowo określony typ, na jaki wskazuje. Innymi słowy, kompilator musi znać odpowiedź na pytanie: Jakiego rodzaju jest zmienna, na którą pokazuje dany wskaźnik?. Dzięki temu potrafi zachowywać kontrolę nad typami danych w podobny sposób, w jaki czyni to w stosunku do zwykłych zmiennych. Zobaczmy teraz elementarny przykład deklaracji oraz użycia wskaźnika: // deklaracja zmiennej typu int oraz wskaźnika na zmienne tego typu int zmienna = 10; int* wskaznik; // nasz wskaźnik na zmienne typu int // przypisanie adresu zmiennej do naszego wskaźnika i użycie go do // wyświetlenia jej wartości w konsoli wskaznik = &zmienna; // wskaznik odnosi się teraz do zmienna cout << *wskaznik; // otrzymamy 10, czyli wartość zmiennej Dobra wiadomość jest taka, iż mimo prostoty ilustruje on większość zagadnień związanych ze wskaźnikami na zmiennej. Oczywiście najpierw mamy deklarację zmiennej (z inicjalizacją), lecz nas interesuje bardziej sposób zadeklarowania wskaźnika, czyli: int* wskaznik; Poprzez dodanie gwiazdki (*) do nazwy typu int informujemy kompilator, że oto nie ma już do czynienia ze zwykłą zmienną liczbową, ale ze wskaźnikiem przeznaczonym do przechowywania adresu takiej zmiennej. wskaznik jest więc wskaźnikiem na zmienne typu int, lub, krócej, wskaźnikiem na (typ) int. A zatem mamy już zmienną, mamy i wskaźnik. Przydałoby się zmusić je teraz do współpracy: niech wskaznik zacznie odnosić się do naszej zmiennej! Aby tak było, musimy pobrać jej adres i przypisać go do wskaźnika - o tak: wskaznik=&zmienna; Zastosowany tutaj operator & służy właśnie w tym celu - do uzyskania adresu miejsca w pamięci, gdzie egzystuje zmienna. Potem rzecz jasna zostaje on zapisany w wskaznik; odtąd wskazuje on więc na zmienną zmienna. Na koniec widzimy jeszcze, że za pośrednictwem wskaźnika możemy dostać się do zmiennej i użyć jej w ten sam sposób, jaki znaliśmy dotychczas, choćby do wypisania jej wartości w oknie konsoli: Cezary Obczyński i Rafał Kamocki 1/5

cout << *wskaznik; Z pewnością domyślamy się, że operator * nie dokonuje tutaj mnożenia, lecz podejmuje wartość zmiennej, z którą połączony został wskaznik; nazywamy to dereferencją wskaźnika. W jej wyniku otrzymujemy na ekranie liczbę, którą oryginalnie przypisaliśmy do zmiennej zmienna. Bez zastosowania wspomnianego operatora zobaczyliśmy wartość wskaźnika (a więc adres komórki w pamięci), nie zaś wartość zmiennej, na którą on pokazuje. To oczywiście wielka różnica. Zaprezentowana próbka kodu faktycznie realizuje zatem zadanie wyświetlenia wartości zmiennej zmienna w iście okrężny sposób. Zamiast bezpośredniego przesłania jej do strumienia wyjścia posługujemy się w tym celu dodatkowym pośrednikiem w postaci wskaźnika. Samo w sobie może to budzić wątpliwości co do sensowności korzystania ze wskaźników. Pomyślmy jednak, że mając wskaźnik możemy umożliwić dostęp do danej zmiennej z jakiegokolwiek miejsca programu - na przykład z funkcji, do której przekażemy go jako parametr (w końcu to tylko liczba!). Potrafimy wtedy zaprogramować każdą czynność (algorytm) i zapewnić jej wykonanie w stosunku do dowolnej ilości zmiennych, pisząc odpowiedni kod tylko raz. Deklaracje wskaźników Stwierdziliśmy, że wskaźniki mogą z powodzeniem odnosić się do zmiennych - albo ogólnie mówiąc, do danych w programie. Czynią to poprzez przechowywanie numeru odpowiedniej komórki w pamięci, a zatem pewnej wartości. Sprawia to, że wskaźniki są w rzeczy samej także zmiennymi. Wskaźniki w C++ to zmienne należące do specjalnych typów wskaźnikowych. Taki typ łatwo poznać po obecności przynajmniej jednej gwiazdki w jego nazwie. Jest nim więc choćby int* - typ zmiennej wskaznik z poprzedniego przykładu. Zawiera on jednocześnie informację, na jaki rodzaj danych będzie nasz wskaźnik pokazywał - tutaj jest to int. Typ wskaźnikowy jest więc typem pochodnym, zdefiniowanym na podstawie jednego z już wcześniej istniejących. Deklarowanie wskaźników jest zatem niczym innym, jak tylko wprowadzeniem do kodu nowych zmiennych - tyle tylko, iż mają one swoiste przeznaczenie, inne niż reszta ich licznych współbraci. Czynność ich deklarowania, a także same typy wskaźnikowe zasługują przeto na szersze omówienie. Dowiedzieliśmy się już, że pisząc gwiazdkę po nazwie jakiegoś typu, uzyskujemy odpowiedni wskaźnik na ten typ. Potem możemy użyć go, deklarując właściwy wskaźnik; co więcej, możliwe jest uczynienie tego aż na cztery sposoby: int* wskaznik; int *wskaznik; int*wskaznik; int * wskaznik; Widać więc, że owa gwiazdka nie trzyma się kurczowo nazwy typu (tutaj int) i może nawet oddzielać go od nazwy deklarowanej zmiennej, bez potrzeby użycia w tym celu spacji. Zadanie 1. Stworzyć plik wskaznik1.cpp i wpisać w nim następujący kod: int *wsk; wsk = &liczba; // deklaracja zmiennej i przypisanie wartości w znany do tej pory sposob // deklaracja zmiennej wskaźnikowej o nazwie wsk //przypisanie do zmiennej wsk adresu zmiennej liczba Cezary Obczyński i Rafał Kamocki 2/5

cout << "Jej adres (zapisany kodem heksadecymalnym) w pamieci komputera to: " << wsk << endl; cout << "Jej adres (rozkodowany) w pamieci komputera to: " << (unsigned long)wsk << endl; cout << "wyluskana za pomoca wskaznika wartość liczby to " << *wsk <<endl; następnie skompilować plik oraz uruchomić program. Zadanie 2. Zmodyfikować powyższy program następująco: int *wsk; wsk = &liczba; *wsk = 15; cout << "Po zmianie mamy: " << endl; cout << "Liczba wyluskana wskaznikiem : " << *wsk << endl; następnie skompilować plik oraz uruchomić program. Zalety stosowania wskaźników. Rozważmy następujący program: void zmien_wartosc(int a) a=5; Cezary Obczyński i Rafał Kamocki 3/5

zmien_wartosc(liczba); cout << "Po wywolaniu funkcji mamy: " << endl; Niestety nie otrzymaliśmy tego czego oczekiwaliśmy. Liczba 10 nie została zamieniona na liczbę 5. Pytanie dlaczego tak się stało. Odpowiedź na to pytanie wiąże się ze sposobem przekazywania argumentu do funkcji. W naszym przypadku do funkcji zmien_wartosc przekazywana jest wartość zmiennej liczba, czyli 10 (nazywamy tę operację przekazywaniem przez wartość), a dokładniej kopia tej zmiennej. A zatem wszystko co się dzieje wewnątrz naszej funkcji dotyczy kopii, a nie oryginału. Powoduje to, że funkcja zmienia wartość kopii zmiennej, a nie oryginału. Dlatego też wartość oryginalna zmiennej liczba to nadal 10 i taka wartość powtórnie zostanie wyświetlona na ekranie monitora. Co zatem zrobić, aby nasz program działał poprawnie. Domyślamy się, trzeba w jakiś inny sposób przekazać argument do funkcji. Z pomocą przychodzą tutaj wskaźniki. Wówczas działamy wewnątrz funkcji już na adresie zmiennej, a nie na jej wartości, czyli odwołujemy się do konkretnej zmiennej (zmienna ma przypisany jeden adres). W naszym przypadku odwołamy się do zmiennej liczba (nie do kopii) poprzez jej adres, i zmienimy jej wartość na 5. W wywołaniu funkcji należy użyć operatora &. Zrealizujemy to w następujący sposób: void zmien_wartosc(int *a) *a=5; zmien_wartosc(&liczba); cout << "Po wywolaniu funkcji mamy: " << endl; Kolejną zaletą stosowania wskaźników jest możliwość zwracania (ale bez użycia słowa return) przez funkcję więcej niż jednej wartości. Rozważmy następujący kod: void suma_iloczyn(int a, int b, int *suma, int *iloczyn) *suma = a + b; *iloczyn = a * b; Cezary Obczyński i Rafał Kamocki 4/5

int liczba1 = 10; int liczba2 = 6; int suma=0; int iloczyn=0; suma_iloczyn(liczba1, liczba2, &suma, &iloczyn); cout << "Suma liczb wynosi " << suma <<", a iloczyn "<< iloczyn << endl; Widzimy, że funkcja suma_iloczyn oblicza sumę i iloczyn liczb a i b przy użyciu wskaźników. Należy w definicji funkcji zadeklarować wskaźnik na zmienne suma, iloczyn, a następnie wyłuskać wartość sumy i iloczynu za pomocą operatora *. Gdybyśmy parametry suma oraz iloczyn przekazali do funkcji poprzez wartość, to nie uzyskalibyśmy takiego efektu (znów działalibyśmy na kopii, a nie na oryginale, czyli w wyniku otrzymalibyśmy wartości oryginalne sumy i iloczynu, czyli 0). Zadanie 3. Napisz funkcję, która oblicza pierwiastki trójmianu kwadratowego i wypisuje je na ekranie monitora. Cezary Obczyński i Rafał Kamocki 5/5