Ć
wiczenia 8 maja 2012
TABLICE
to typ pochodny, ciąg obiektów tego samego typu zajmujących ciągły obszar w pamięci, wynika stąd, że nie
musimy szeregowi potrzebnych zmiennych nadawać nazwy, tylko stworzyć z nich tablicę i odwoływać się
do określonego elementu tablicy.
Przykład:
int tabela[15], czyli ta definicja sprawi, że w pamięci zostanie zarezerwowane miejsce dla 15 liczb typu int.
Co sprawi, że poszczególne elementy tablicy będą to:
tabela[0], tabela[1], tabela[2], tabela[3], tabela[4], tabela[5], tabela[6], tabela[7], tabela[8], tabela[9],
tabela[10], tabela[11], tabela[12], tabela[13], tabela[14].
Zatem, numeracja elementów tablicy zaczyna się od 0! Czyli, element tabela[15] po prostu nie będzie istniał.
Jeśli spróbujemy coś w nim zapisać zniszczymy w ten sposób obiekt położony w pamięci jako kolejny (po
tablicy).
Przy czym, kompilator musi wiedzieć jakiego rozmiaru jest ta tablica, nie można tego podać dopiero w
trakcie działania programu, zatem nie można postąpić następująco:
Nieprawidłowy przykład:
cout << ”Podaj wymiar swojej tablicy”;
int wymiar;
cin >> wymiar;
int tablica[wymiar];
Przykłady definicji różnego rodzaju tablic:
Przykład możliwości wypełniania tablicy:
w wyniku otrzymamy:
Inicjalizacja zbiorcza
Jest innym sposobem nadania wartości początkowej każdemu elementowi naszej tablicy, czyli
Przykład:
int tabela[5] = {9, 6, 13, 7, 9};
zatem tabela[2] jest równe 13
Przykład:
int tabela[5] = {9, 6, 13};
w takiej sytuacji elementy tabela[3] oraz tabela[4] zostaną zainicjalizowane zerami.
Przykład:
int tabela[] = {9, 6, 13, 7, 9};
nie będzie to błąd, ponieważ kompilator sam przeliczy, że mamy mieć pięcioelementową tablicę.
Samo wypisanie tabeli nie wiele wnosi, ale wykonywanie określonych funkcji na rozbudowanej tablicy jest
już czym pożytecznym. Jak zatem to zrobić?
Chcemy np. unormować daną tablicę (czyli podzielić każdy element przez wartość maksymalną, którą już
znamy). Możemy, oczywiście, każdy element dzielić, korzystając z pętli for, ale wypisanie wyniku np. dla
tablicy o 10000 elementów nie jest praktyczne. Lepszym wyjściem jest przekazanie tablicy do określonej
funkcji, np. funkcja(tablica); czyli funkcja zadziała na każdy element tablicy. Ale przy tablicy nie znajduje
się żaden nawias []??? Ponieważ w C++ nazwa tablicy jest jednocześnie adresem zerowego elementu!!!
Natomiast zapis tablica + 4 (lub & tablica[4]) oznacza adres elementu o indeksie 4, czyli tablica[4].
Zadanie 8.1.
Napisz program obliczający odchylenie standardowe jakieś próbki danych.
Zadanie 8.2.
Napisz program wypisujący liczby powyżej średniej wartości w danym ciągu.
Zadanie 8.3.
Napisz program umożliwiający wczytanie, a następnie wyświetlanie kilku (np. 10) liczb rzeczywistych
przechowywanych w tablicy, który następnie wypisze całą tablicę, poda ile wynosi suma elementów,
ś
rednia, minimum i maksimum w danym ciągu.
TABLICE TEKSTOWE
Podobnie jak liczby można wczytać jeden znak, a co z całym wyrazem? Ciąg znaków alfanumerycznych
(string, po polsku łańcuch), to znaki kolejno zapisane w pamięci. Najlepiej do zapisania użyć tablicy
przechowującej znaki (typ char). Kończymy zawsze znakiem specjalnym NULL (‘\0’)
Przykład
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
char ciag_znak[ 10 ] = { 'I', 'N', 'F', 'o ', '-', ' ',
'C', '+', '+', '\0' };
char wyraz[ 50 ];
cout << "Podaj swoj tekst: ";
cin >> wyraz;
cout << "Wprowadziles nastepujace znaki: \"" << wyraz
<< "\"" << endl;
cout << "Natomiast poprawny ciag znakow wyglada tak: \""
<< ciag_znak
<< "\"" << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Jeśli wprowadzamy tekst o długości n znaków, to znak n+1 będzie zawsze równy 0. Dla większości funkcji,
które operują na łańcuchach znaków, jest to informacja, aby zakończyć wyświetlanie kolejnych znaków z
tablicy, czyli tak oznaczamy koniec tekstu.
char niepoprawana_tablicaZnakow[ 5 ] = { 'i', 'n', 'f ', '', 'C' };
nie posiada znaku NULL, dlatego nie przechowuje łańcucha znaków.
Przykład
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
char ciag_znak[ 40 ];
char tekst[ 20 ] = "uczymy sie C++ ";
cout << "Podaj swoje imie i nazwisko programisto:) "
<< endl;
cin >> ciag_znak;
cout << "Nazywasz sie: " << ciag_znak
<< endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Wczytaliśmy łańcuch za pomocą strumienia cin. Warto zauważyć, że wczytuje on znaki do zmiennej, aż do
napotkania białego znaku (spacja, tabulator, enter,…). Powyżej napisaliśmy dwa wyrazy oddzielone spacją i
drugi nie został wczytany. Pamiętajmy również, iż zmiana jakiegokolwiek znaku w łańcuchu na znak
zerowy, będzie oznaczało jego skrócenie.
TABLICE WIELOWYMIAROWE
Do tej pory operowaliśmy na tablicach jedno wymiarowych, przyjrzyjmy się jak tworzy i stosuje tablice
wielowymiarowe. Załóżmy, że chcemy napisać program, która będzie przechowywać określone dane w
macierzy
Przykład
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
const short LICZBA_Wierszy = 6;
const short LICZBA_kolumn = 8;
int i, j;
using namespace std;
char tab1[ LICZBA_Wierszy ][ LICZBA_kolumn ] = {
{ '4', '1', '1', '2', '3', '2', '5', '3' },
{ '3', '1', '1', '3', '9', '9', '7', '3' },
{ '3', '5', '3', '2', '1', '8' , '2', '1'},
{ '8', '1', '1', '4', '3', '3', '2', '1' },
{ '4', '1', '1', '2', '1', '3', '2', '1' },
{ '4', '3', '3', '2', '1', '2', '1', '9' },
};
cout<<" element z ktorego wiersza chcesz wyswietlic? ";
cin>>i;
cout<<" element z ktorej kolumny chcesz wyswietlic? ";
cin>>j;
cout<<" element do wyswietlenia to " << tab1[i][j]<<"\n";
system("PAUSE");
return EXIT_SUCCESS;
}
Zadanie 8.4.
Napisz program
,
który dla tablicy dwuwymiarowej policzy sumę elementów oraz element maksymalny.
PSEUDOLOSOWE LICZBY CAŁKOWITE
Generowanie losowe liczb całkowitych.
Funkcja losująca liczby całkowite pochodzi ze standardowej biblioteki języka C. Bibliotekę, którą należy
dołączyć jest cstdlib.
Funkcja losująca po prostu losuje liczbę całkowitą, która mieści się w przedziale od 0 do RAND MAX (jest
to stała, która zależy od kompilatora i załączonych bibliotek).
Przykład
#include <iostream>
#include <cstdlib>
int main()
{
cout << "Wylosowanie pierwsze: " << rand() << endl;
int liczba = rand();
cout << "Wylosowanie drugie: " << liczba << endl;
liczba = rand();
cout << "Wylosowanie trzecie: " << liczba << endl;
return 0;
}
Konfiguracja maszyny losującej
Jeżeli uruchomimy kilka razy powyższy program to zauważymy, że komputer wylosował nam za każdym
razem te same liczby. Takie zachowanie oczywiście nie jest pożądane, dlatego też wymagane jest
skonfigurowanie generatora liczb losowych.
srand( time( NULL ) );
Powyższą linijkę wystarczy wywołać tylko raz na samym początku programu, kod wygląda teraz tak:
#include <iostream>
#include <cstdlib>
#include <ctime>
int main()
{
srand( time( NULL ) );
cout << "Wylosowanie pierwsze: " << rand() << endl;
int liczba = rand();
cout << "Wylosowanie drugie: " << liczba << endl;
liczba = rand();
cout << "Wylosowanie trzecie: " << liczba << :endl;
return 0;
}
Jeżeli potrzebujemy zminić zakres to wykorzystać musimy działanie modulo i dodawanie. Najpierw
ustalamy ile liczb mieści się w przedziale z którego chcemy losować, np. 50 liczb. Następnie ustalamy
pierwszą losowaną liczbę np. 7.
int wylosowana_liczba =( rand() % ile_liczb_w_przedziale ) + startowa_liczba;
a dokładnie:
int wylosowana_liczba =( rand() % 50 ) + 7;
Ostatecznie program losujący liczby z przedziału od 7 do 56 będzie więc wyglądał tak:
#include <iostream>
#include <cstdlib>
#include <ctime>
int main()
{
srand( time( NULL ) );
cout << "Wylosowanie pierwsze: " <<(( rand() % 50 ) + 7 ) << endl;
int liczba =( rand() % 50 ) + 7;
cout << "Wylosowanie drugie: " << liczba << endl;
liczba =( rand() % 50 ) + 7;
cout << "Wylosowanie trzecie: " << liczba << endl;
return 0;
}
Zadanie 8.5. (domowe)
Napisać grę, która ma działać następująco:
1. Program losuje liczbę z przedziału od 1 do 1000.
2. Użytkownik zgaduje liczbę, która została wylosowana.
3. Jeżeli podana liczba jest za duża (za mała) gra wypisuje stosowny komunikat i powraca do kroku 2.
4. Jeżeli gracz trafi liczbę wylosowaną to pogram kończy działanie, wypisując na ekran wylosowaną liczbę
oraz liczbę 'strzałów', które oddał gracz.
Gra ma być zabezpieczona przed możliwością wprowadzenia błędnych wartości liczbowych.