background image

Ć

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; 

background image

int tablica[wymiar]; 
 
Przykłady definicji różnego rodzaju tablic: 

 

 
Przykład możliwości wypełniania tablicy: 

 

background image

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ę.  
 

background image

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.  

 
 
 

background image

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; 
     

background image

    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() 

background image

    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 
 

background image

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? "; 

background image

    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 
 
 

background image

#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> 

background image

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:  
  

background image

#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.