Wiadomości na temat języka C i C++ pozwalające poznać język na poziomie podstawowym

Język programowania C/C++

Informatyka Programowanie Windows Różne Linki

Ogólna budowa programu

#include < > <= dyrektywa (instrukcja) preprocesora, dołą-czenie biblioteki lub pliku nagłówkowego.

#include < iostream.h > // <= jeden ze standardowych plików nagłówkowych.
main ()
 {
  cout << "C++"; //   "<<" - wejście, ">>" - wyjście.
 return 0;//<= informacja dla systemy operacyjnego 
          //o poprawnym zakończeniu programu.
 } 

W przykładzie chcemy, aby program wyświetlał określony komunikat. W C++ nie ma standardowych instrukcji Wejścia / Wyjścia. Jeżeli program ma wyświetlać lub pobrać dany komunikat to musi posłużyć się specjalnych funkcji. Funkcje te znajdują się w standardowych bibliotekach Wejścia / Wyjścia, dołączonych razem z kompilatorem języka, aby można było jej użyć, trzeba kompilatorowi dostarczyć pewnych informacji, umieszczonych w specjalnym pliku określanym mianem pliku nagłówkowego (*.h - ang. header). Dla biblioteki funkcji Wejścia / Wyjścia jest to plik "iostream.h", podzielony na dwie klasy istream i ostream. Włączanie tego pliku odbywa się za pomocą dyrektywy #include. Do tekstu można włączyć pewne znaki, które mają specjalne znaczenie:

Znaki znaczenie
\? znak ?
\\ znak \
\' znak '
\" znak "
\a sygnał dźwiękowy
\b backspace
\f nowa strona
\n przejście kursora do nowej linii
\r powrót karetki
\t tabulator poziomy
\v tabulator pionowy

Stałe i Zmienne

Stała może być liczbą, pojedynczym znakiem lub tekstem. Zmienna jest nazwą, pod którą mogą być podstawione różne wartości. Zarówno stałą jak i zmienną jest związany jej typ: char - typ znakowy, int - typ całkowity, float - typ rzeczywisty, double - typ zmiennoprzecinkowy (rzeczywisty) o podwójnej precyzji, enum - typ wyliczeniowy (to typy podstawowe). Niektóre z typów mogą być dodatkowo modyfikowane za pomocą kwali-fikatorów short (krótki), long (długi), signed (ze znakiem), unsigned (bez znaku, dodatnie)

Są jeszcze inne typy: near (bliski), far (daleki). Istnieje jeszcze jeden szczególny typ void, (nieistniejący, pusty). Możliwe jest deklarowanie wskaźników na ten typ np. void a (void *a) co powoduje, że staje się on wskaźnikiem uniwersalnym niekiedy zwanym wskaźnikiem adresowym, któremu można przypisać wskaźniki na dowolne typy, odwrotne stwierdzenie jest dla C++ nieprawdziwe. Przypisanie wskaźnika na typ void wskaźnikowi na inny typ zawsze wymaga jawnego użycia operatora konwersji. Słowo kluczowe void można rozumieć jako brak wartości (zero, nic), ma ono kilka charakterystycznych znaczeń:

    void main () <= użyte jako typ wyniku funkcji oznacza, że funkcja nie zwraca żadnej wartości,
    main (void) <= użyte na liście parametrów (jako argument) oznacza, że funkcja nie ma parametrów (zapis 'main ()'),
    użyte w operatorze konwersji wobec jakiegoś wyrażenia, powoduje odrzucenie wartości tego wyrażenia,
    użyte jako bazowy typ wskaźnika, oznacza wskaźnik uniwersalny (wskazanie adresowe), które ma oczywiście swoją wartość i nie należy go mylić ze wskaźnikiem na 'nic' (NULL).

Na wskaźnikach na typ void, nie można wykonywać żadnych operacji arytmetycznych ale można je porównywać ze sobą i z zerem. Ta ostatnia własność jest bardzo ważna w zaawansowanych programach, kiedy trze-ba np. stwierdzić czy jakiś wskaźnik wskazuje ten sam obiekt, niezależnie od tego jakiego typu może być ten obiekt.

Stałe całkowite - są przykładami literałów stałych. Literałów, dlatego, że mówimy jedynie o ich wartościach stałych, ponieważ ich wartości nie możemy zmieniać. Typ stałej całkowitej przyjmowany domyślnie przez kompilator, zależy od jej postaci, wartości i przyrostka. Jeżeli jest to liczba dziesiętna i nie ma przyrostka to typ domyślny zależy od jej wartości i jest typem int, long int, unsigned long int. Jeżeli jest to liczba oktanalna lub szesnastkowa (heksadecymalna) i nie ma przedrostka, to typ domyślny zależy od jej wartości i jest typem int, unsigned int, long int bądź unsigned long int. Dodając specyfikator u lub U (unsigned) i/lub l lub L (long) możemy wymusić inny sposób reprezentacji stałej całkowitej.

Stałe zmiennopozycyjne - należą do podzbioru liczb rzeczywistych, można je zapisywać w notacji dziesiętnej z kropką dziesiętną np. 0.0, .2, 2. , -84.21 lub w notacji wykładniczej np. 1.11e12, -3.14159E-13. Jeżeli po liczbie nie podano specyfikatora typu, to kompilator nadaje jej typ domyślny double. Dokładność stałej zmiennopozycyjnej można wymusić dodając po zapisie liczby modyfikatora f lub F (float) i/lub l lub L (long double) np. -84.11f, .234L, 1.0L.

Stałe znakowe - stała (literał) znakowa jest to ciąg złożony z jednego lub większej liczby znaków ujęty w pojedyncze apostrofy np. 'A'. Stałe znakowe są typu char. Wartością stałej jednoznakowej jest wartość numeryczna znaku w maszynowym kodzie znaków np. dla zbioru znaków ASCII wartością A jest 65 (dziesiętne), zaś typem stałej wieloznakowej jest typ int.

Deklaracje zmiennych

Składnia: Typ nazwa_zmiennej_tego_typu ;

#include 
main ()
{
 int a = 1 ;
 cout << "Zmienna int 'a' =" << a << "\n";
 float e = 2.71;
 cout << "zmienna float 'e' =" << e << "\n";
 int b = 2 ;
 cout << "zewnetrzna zmienna 'b' =" << b << "\n";
 {
  int b = 21 ;
  cout << "wewnetrzna zmienna 'b' =" << b;
 }
} 

Zmienna jest widoczna tylko wewnątrz bloku, w którym została zade-klarowana. Wynika z tego, że w jednym programie możemy bez problemu użyć dowolnej liczby zmiennych o tej samej nazwie, pod warunkiem, że nie będą się one znajdować wewnątrz tego samego bloku, modułu lub instrukcji grupującej.

int a = 1 ;
cout << a << " " ; // <= spacja
{
 int a = 10 ;
 cout << a << "\n" ;
 { int a = 100 ;
 cout << a ;
 }
} 

Deklarowanie stałych

Składnia: const typ_zmiennej nazwa_zmiennej = wartość ;

Jeżeli deklarację int a = 7 ; poprzedzimy słowem kluczowym const to przekształcimy symboliczną zmienną a w stałą symboliczną o tej samej nazwie. Wartość tak zdefiniowanej stałej symbolicznej pozostaje niezmienna w programie, a każda próba zmiany tej wartości będzie sygnalizowana jako błąd. Słowo kluczowe const, które zmienia interpretację definiowanej wielkości nazywany jest modyfikatorem typu.

! Stała symboliczna po zdefiniowaniu musi być zainicjowana !

np. zapis const double e ; jest błędny ponieważ e nie zostało za-inicjowane.

W przypadku stałych znakowych istnieją dwa bardzo wygodne, równo-ważne sposoby ich definiowania:

const char LITERA = 'A';
const char LITERA = '0x41';

oba zapisy deklarują stałą znakową będącą literą 'A' ma ona kod ASCII dziesiętny 65, szesnastkowy 41.

Stałe są widoczne tylko w pliku źródłowym, w którym zostały zadekla-rowane.

Arytmetyczne operatory przypisania

Operator Długa forma Krótka forma
=+ x = x + y x += y
-= x = x - y x -= y
*= x = x * y x *= y
/= x = x / y x /= y
%= x = x % y x %= y

Operatory inkrementacji i dekrementacji

C++ umożliwia dostęp do specjalnych operatorów inkrementacji czyli zwiększania i dekrementacji czyli zmniejszania. W zapisie wygląda to '++', '--'. Operatory te umożliwiają zwiększanie i zmniejszanie o jeden wartości przechowywanej w zmiennej.

Operatory inkrementacji:

  • Zmienna ++ ; // wersja przyrostkowa (postinkrementacja)
  • ++ Zmienna ; // wersja przedrostkowa (preinkrementacja)

Operatory dekrementacji:

  • Zmienna -- ; // wersja przyrostkowa (postdekrementacja)
  • -- Zmienna ; // wersja przedrostkowa (predekrementacja)

Przykład:

int i, j, k, = 5 ;
k++ ; // k ma wartość 6, tu taki sam efekt jak ++k
--k ; // k ma wartość 5, tu taki sam efekt jak k-
 k = 5 ;
 i = 4 * k++ ; // k = 6, i = 20
 k = 5 ;
 j = 4 * ++k ; // k = 6, j = 24

Funkcje znakowego wejścia i wyjścia

Funkcje te znajdują się w pliku nagłówkowym . Funkcje znakowego wejścia:

  • getche () <= zwraca znak z konsoli i wyprowadza go jednocze-śnie na ekran
  • getch () <= zwraca znak z konsoli ale nie wyprowadza go na ekran
  • getchar () <= zwraca znak z konsoli ale nie wyprowadza go na ekran

funkcje znakowego wyjścia:

  • putch ()
  • putchar ()

Funkcje putchar () i getchar () działają z urządzeniami wejścia wyjścia w ogólności (konsola, porty COM, drukarki)

Przykład:

char a, b, c ;
 cout << "Podaj pierwszy znak" ;
 a = getche () ;
 cout << "\n Podaj drugi znak" ;
 b = getch () ;
 putch (b) ;
 cout << "\n Podaj trzeci znak" ;
 c = getch () ;
 put (c) ;
 cout << "\n\n Podales znaki " ;
 putch (a) ;
 putch (b) ;
 putch (c) ;

Sterowanie ekranem

  • clrscr () đ czyści ekran i umieszcza kursor w lewym górnym rogu.
  • clreol () đ czyści zawartość wiersza od pozycji kursora do końca linii.

Operatory relacji

  • < - mniejsze
  • <= - mniejsze lub równe
  • > - większe
  • >= - większe lub równe
  • == - równe
  • != - różne

    Sterowanie kursorem

    • gotoxy () - umieszcza kursor w podanym położeniu x, y.
    • wherex () - zwraca numer wiersza, w który znajduje się kursor.
    • wherey () - zwraca numer kolumny, w której znajduje się kursor.

    Przykład:

    char c = ' ' ; //spacja
    clrscr () ;
    while (c != 'g')
     {
     if (wherex () >= 79) gotoxy (1, wherey ()) ;
     if (wherey () >= 24) gotoxy (wherex (), 1);
     putch ('O') ;
     c = getch () ;
     gotoxy (wherex () -1, wherey ()) ;
     putch (' ') ; ď spacja
    }
    

    Decyzje C++

    Składnia if: if (warunek) instrukcja ; np.

    double x ;
    clrscr () ;
    cout << "Podaj liczbe" ; cin >> x ; // funkcja sqrt () w pliku 
    if (x >= 0)
     cout << "Pierwiastek kwadratowy z" << x << "to" << sqrt (x) << "\n" ; 

    Składnia if…else…: if (warunek) instrukcja1 ; else in-strukcja2 ; Przykład:

    char c ;
    clrscr () ;
    cout << "Podaj liczbe" ; cin >> c ;
    c = toupper (c) ; // zamiana małych liter na duże
    if (c == 'A' || c == 'I' || c == 'O' || c == 'E' ||
     c == 'U' || c == 'Y')
     cout << "wprowadzona litera jest samogłoska" ;
    else cout << "wprowadzona litera nie jest samogłoska" ; 

    Wielokrotna instrukcja if...else...

    Zagnieżdżona instrukcja if...else... wykonuje serię testów aż wystąpi jedna z poniższych sytuacji:

    • jeden z warunków w instrukcji if lub else if jest prawdziwy. W tym wypadku wykonują się instrukcje występujące po tym warunku.
    • żaden z testowanych warunków nie jest prawdziwy. Program wykonuje instrukcję z ostatniej instrukcji else (jeżeli występuje)
    • jeżeli warunek jest spełniony, po prostu wykonuje instrukcje.

    Przykład:

    char c ;
    clrscr () ;
    cout << "Podaj znak" ;
    cin >> c ;
    if (c >= 'A' && c <= 'Z') cout << "litera duza\n" ;
    else if (c >= 'a' && c <= 'z') cout << "litera mala\n" ;
    else if (c >= '0' && c <= '9') cout << "cyfra/n" ;
    else cout << "inny znak\n" ; 

    Instrukcja wyboru switch ()

    • instrukcja wymaga wartości całkowitej, wartość ta może być stałą zmienną, wywołaniem funkcji lub wyrażeniem. Switch nie działa ze zmiennoprzecinkowymi typami danych.
    • wartość występująca po każdej etykiecie case musi być stałą.
    • C++ nie zezwala na użycie etykiet case z zakresem wartości, każda wartość musi występować w oddzielnej etykiecie case.
    • po każdej grupie wykonywanych instrukcji, trzeba użyć instrukcji break. Powoduje ona wyjście programu z instrukcji switch. Jeżeli nie użyje się instrukcji break program przejdzie do wykonania instrukcji po kolejnych etykietach case.
    • zbiór instrukcji dla każdej etykiety lub etykiet musi być zawarty w nawiasach klamrowych.
    • instrukcja po etykiecie default jest wykonywana gdy nie natrafiono na żadną etykietę else.

    Przykład:

    char c ;
    clrscr () ;
    cout << "Podaj znak" ; cin >> c ;
    switch (c) 
    {
     case "A":
     case "B":
     .
     .
     .
     cout << "Duza litera" ;
     break ;
     case "a":
     case "b":
     .
     .
     .
     cout << "Mala litera" ;
     case "0":
     case "1":
     .
     .
     .
     cout << "Cyfra" ;
     break ;
     default :
     cout << "Inny znak" ; }

    Pętle

    for, pętla ta w C ma bardzo rozpowszechnione zastosowanie może obsługiwać zarówno stałe jak i warunkowe iteracje.

    Składnia: for ( ; ; ) instrukcja ; // {}

    Przykład:

    for (i = 0 ; i < 10 ; i++)
     cout << "kwadrat z " << i << " = " << i * i << '\n' ;
    for (;;) // pętla otwarta 

    Instrukcja pętli for zawiera trzy elementy, ale są one opcjonalne. Pierwszy element inicjuje zmienną sterującą pętli. Druga część pętli jest warunkiem, który określa czy pętla będzie wykonywać kolejne iteracje. Ostatnia część pętli for jest instrukcją zwiększającą lub zmniejszającą zmienne sterujące pętli, takie zmienne istnieją tylko w obrębie tej pętli.

    Przykład:

    {
     double a = 10 ;
     int n ;
     cout << "Podaj liczbe z zakresu [1..30]: " ;
     cin << n ;
     if (n > 0 && n <= 30)
      {
       for (int i = 1 ; i <= n ; i++) a += (double)i ;
       cout << n << " != " << a << '\n' ;
      }
     else cout << "Liczba z poza zakresu" ;
     return 0 ; }

    Pętla deklaruje zmienną sterującą pętli i. Pętla wykorzystuje tę zmienną do uaktualnienia wartości przechowywanej zmiennej a. Pętla inicjuje zmienną sterującą pętli przypisując jej wartość 1. Testem pętli jest wyrażenie i <= n. Instrukcją inkrementującą pętli jest i++ co zwiększa zmienną sterującą pętli o jeden.

    Inne sposoby zapisu tej pętli:

    • for (int i = 1 ; i <= n ; i += 1)
    • for (int i = 1 ; i <= n ; i = i + 1)
    • for (int i = 1 ; i > 0 ; i - - )

    Modyfikacja programu:

    {
     double a = 10 ;
     int n, i = 1 ;
     cout << "Podaj liczbę z zakresu [1..30]: " ;
     cin >> n ;
     if (n > 0 && n <= 30)
      {
       for (; i <= n ;) a *= (double) i++ ;
       cout << n << " != " << a << '\n' ;
      }
     else cout << "Liczba z poza przedziału" ;
     return 0 ; }

    Program jest tak zmodyfikowany, że pętla korzysta tylko z testu pętli (drugiego elementu) pozostałe elementy zmienna sterująca pętli i jest zadeklarowana razem z innymi zmiennymi lokalnymi w funkcji main. Zmienna i jest inicjowana wartością 1 w konsekwencji pętla for nie musi deklarować ani inicjować zmiennej sterującej pętli. Jeżeli chodzi o inkrementację tej zmiennej operator inkrementacji jest używany w instrukcji uaktualniającej wartość silni (a) to podejście zwalnia pętlę for z samodzielnego inkrementowania zmiennej sterującej.

    Operator warunkowy ?:

    Jest to jedyny operator trójargumentowy w C++.

    Składnia: ? :

    Wartość tak utworzonego wyrażenia jest obliczana następująco, najpierw wartościowane jest wyrażenie1, jeżeli jest to wartość niezerowa (prawda) to wartościowane jest wyrażenie2 i wynikiem obliczeń jest jego wartość przy zerowej wartości wyrażenia (wyrażenie 1 - fałsz) wynikiem obliczeń będzie wartość wyrażenia3.

    Przykład:

    int a, b, z ;
    cin >> a >> b ;
    z = (a > b) ? a : b ; // z == max (a, b)
    cout << z << endl ; <= opróżnia bufor wyjściowy return 0 ; 

    Rzutowanie czyli konwersja typów

    W języku C++ normą jest niż wyjątkiem tzw. arytmetyka mieszana, to jest sytuacja gdy w instrukcjach i wyrażeniach arytmetycznych argumenty operatorów są np. różnych typów. Możemy np. dodawać wartości wyrażeń typu int do wyrażeń typu long, wartość typu float do wartości typu double itd. W takich przypadkach argumenty każdego operatora muszą zostać przekształcone do jednego, tego samego typu dopuszczalnego dla danego operatora. Operacja ta nazywa się rzutowaniem lub konwersją. Konwersja może być niejawna, wykonywana automatycznie przez kompi-lator bez udziału programisty. Język C++ programiście dokonać także konwersji jawnych oferując mu odpowiednie operatory konwersji. Zarówno konwersja jawna jak i niejawna muszą być bezpieczne tzn. takie, aby w wyniku konwersji nie była tracona żadna informacja. Jest pewne, że jeśli liczba bitów maszynowej reprezentacji wielkości podlegającej konwersji nie ulega zmianie bądź wzrasta po konwersji to taka konwersja jest bezpieczna. Bezpieczna konwersja argumentu węższego (mniej bitów) do szerszego typu nazywana jest promocją typu. Typowym przykładem promocji jest automatyczna konwersja typu char do int. Powód, wszystkie predefiniowane operacje na literałach i zmiennych typu char są faktycznie wykonywane na liczbach porządkowych znaków pobieranych ze zbioru kodów maszynowych (tj. ASCII). Powyższe dotyczy także typu short i enum.

    Podane zestawienie typów od najwęższego do najszerszego określa, który argument operatora binarnego będzie przekształcany.

    int
    unsigned int
    long
    unsigned long
    float
    double
    long double
    Typ, który występuje jako pierwszy w wykazie podlega promocji do typu występującego jako następny np. jeśli argumenty operatora są int i long to argu-ment int zostanie przekształcony do typu long. Jeżeli typu argumentów są long i long double to operand typu long będzie przekształcony do typu long double.

    Przykład:

    int n = 3 ;
    long double z ;
    z = n + 3.14159 ;
    

    W ostatniej instrukcji najpierw zmienna n zostaje przekształcona do ty-pu double i jej wartość stanie się wartość równa 3.0 wartość ta zostanie dodana do 3.14159 dając wynik 6.14159 typu double a następnie otrzymany wynik zostanie przekształcony do typu long double.

    Przykład konwersji zwężającej:

    int n = 10 ;
    n *= 3.1 ;
    

    W drugiej instrukcji mamy dwie konwersje najpierw n jest promowane do typu double i ma wartość 10.0 po wymnożeniu przez 3.1 wynik 31.0 zostaje następnie zwężony do typu int. Ta zwężona wartość zostaje przypisana do zmiennej n.

    Konwersja jawna - może być wymuszona przez programistę za po-mocą jednoargumentowego operatora konwersji o składni:

    (typ) wyrażenie ; lub typ (wyrażenie) ;

    w obu przypadkach wyrażenie zostaje przekształcone do typu typ zgodnie z regułami konwersji. Przykład:

    double (25) ;
    (double) 25 ;
    

    Oba przypadki dadzą wynik 25.0 typu double. Konwersja jawna bywa stosowana dla uniknięcia zbędnych konwersji np. wykonanie instrukcji z = n + 3.14159 ; wymaga promocji n do double a następnie zawęże-nie sumy do int. Modyfikując tę instrukcję n = n + int (3.14159) ; mamy tylko jedną konwersję z typu double do int wynik konwersji nie jest jedną wartością (wyjątek typ referencyjny), a więc można go przypi-sywać float f = float (10) ; Przykład:

    char a ;
    int b ;
    main ()
    {
     cout << "a==" << a << '\n' ;
     cout << "b==" << b << '\n' ;
     a = 'A ' ;
     cout << "a po przypisaniu == " << a << endl ;
     b = int (a) ;
     cout << "(b = int (a)) == " << b << endl ;
     a = char (b) ;
     cout << "(a = (char) b) == " << a << endl ;
     return 0 ; } 

    Zadeklarowanym zmiennym globalnym a i b kompilator nada automatycznie zerowe wartości początkowe:

    a == '\0' ; // teoretycznie
    b == 0 ;

    wydruk ma postać:

    a ==
    b == 0
    

    a po przypisaniu == A

    (b = int (a)) == 65
    (a = (char) b) == A
    

    Tablice

    Składnia:

    typ NazwaTablicy [LiczbaElementów] ;
    można deklarować tablice dla predefiniowanych typów danych a także dla typów zdefiniowanych przez użytkownika. C++ dopuszcza tablice różnych rozmiarów ale wymaga zastosowania pewnych reguł:

    • dolna granica każdego wymiaru tablicy w C++ jest ustawiana na zero, nie można zmieniać tej dolnej granicy,
    • deklarowanie tablicy polega na określeniu liczby elementów w każdym wymiarze, należy mieć na uwadze, że górna granica jest równa LiczbieElementów - 1
    • deklarowanie i korzystanie z tablicy w wyrażeniu wymaga umieszczenia indeksów tablicy dla każdego wymiaru w oddzielnych nawiasach kwadratowych.

    Przykład:
    Program deklaruje tablicę silnia do przechowywania silni liczb od 0 do 8. Do obliczania silni dla elementów tablicy o indeksach od 1 do 8 sto-sowana jest pętla for. Każda iteracja wykorzystuje element:

    silnia [i - 1], otrzymany albo z poprzedniej iteracji pętli albo z inicjacji dokonanej przed pętlą. Program wykorzystuje drugą pętlę for do wy-świetlenia wartości silni w tablicy silnia.

    const max_liczba = 8 ;
    main ()
    {
     double silnia [max_liczba + 1] ;
     int n ;
     silnia [0] = 1 ;
     for (int i = 1 ; i <= max_liczba ; i++)
      silnia [i] = i * silnia [i - 1] ;
     for (i = max_liczba ; i >= 0 ; i++)
      cout << i << " != " << silnia [i] << '\n' ;
     return 0 ;
    }

    C++ umożliwia deklarację i inicjację tablicy w jednym kroku np. silnia może być zadeklarowana przy pomocy następującej funkcji:

    double silnia [max_liczba + 1] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320} ;

    Liczba elementów umieszczona na liście wartości początkowych musi być mniejsza lub równa maksymalnej. Jeżeli lista jest mniejsza niż rozmiar tablicy, to kompilator przypisuje zera pozostałym elementom tablicy, które nie otrzymują bezpośrednio wartości początkowych.

    Macierze

    Są dwuwymiarowymi tablicami, które korzystają z dwóch indeksów w celu uzyskania dostępu do swoich elementów. Składnia:
    typ NazwaTablicy [LiczbaWierszy] [LiczbaKolumn] ;
    Przykład:

    char Screen [25][80] ;
    Przykładowy program:
    #include < iostream.h >
    #include < conio.h >
    #include < stdlib.h >
    const MaxRows = 10 ;
    const MaxCols = 3 ;
    main ()
    {
     double mat [MaxRows][MaxCols] ;
     double sumcol [MaxCols} ;
     int row, col ;
     clrscr ();
     randomize () ;
     for (row = 0 ; row < MaxRows ; row++) 
      for (col = 0 ; col < MaxCols ; col++)
       {
        sumcol [col] = 0 ;
    	mat [row][col] = random(1000)/(random(500) + 1;
       }
     for (row = 0 ; row < MaxRows ; row++)
      for (col = 0 ; col < MaxCols ; col++)
       {
        sumcol [col] += mat [row][col] ;
       }
     for (col = 0 ; col < MaxCols ; col++)
      cout << "Suma kolumn #" << col << " = " << sumcol [col] << '\n' ;
     return 0 ;
    }

    Przykładowy wydruk:

    Suma kolumn #0 = 133
    Suma kolumn #1 = 82
    Suma kolumn #2 = 452
    

    Ponieważ program ten wykorzystuje liczby losowe generuje różne wyni-ki przy każdym jego uruchomieniu. Program demonstruje użycie macie-zy. Wykonuje on następujące zadania:

    • deklaruje macierz mat typu double o 10 wierszach i 3 kolum-nach,
    • deklaruje tablicę sumcol typu double o trzech elementach,
    • przypisuje losowe liczby elementom macierzy. Zadanie to wykorzy-stuje parę zagnieżdżonych pętli for w celu przebiegnięcia wszyst-kich kolumn i wierszy macierzy. Zewnętrzna pętla przypisuje rów-nież zera elementom tablicy sumcol. Funkcje randomize i ran-dom zadeklarowane są w pliku . Funkcja randomize inicjuje generator liczb losowych, funkcja random (n) zwraca wartości losowe z przedziału 0 - n,
    • sumuje wartości każdej kolumny macierzy i wpisuje wynik w ele-mentach tablicy sumcol. Zadanie to również wykorzystuje parę zagnieżdżonych pętli for,
    • wyświetla sumy zapisane w tablicy sumcol.

    Wychodzenie z pętli

    C++ umożliwia standardowo zastosowanie instrukcji break do opusz-czania pętli. Instrukcja ta powoduje przejście programu do końca aktualnej pętli.
    Składnia dla pętli for:

    for (inicjalizacja, test, uaktualnienie)
    {
    //sekwencja instrukcji nr 1
    if (warunek wyjścia z pętli) break ;
    //sekwencja instrukcji nr 2
    }
    //sekwencja instrukcji nr 3
    

    Instrukcja break działa podobnie również w innych pętlach mechanizm wychodzenia z pętli jest niezależny od typu pętli. Przykład:

    char s [8], FindChar ;
    // Podaj ciąg znaków (string) s
    // znak do wyszukiwania FindChar
    for (i = 0 ; i < strlen (s) ; i++) <= strlen() - zwraca długość łańcucha
    if (s [i] == FindChar) break ;
    if (i < strlen (s)) cout << " " << i << '\n' ; 

    Przykładowy kod pokazuje jak instrukcja if wewnątrz pętli for może wyszukać znak w łańcuchu. Podczas gdy pętla for obrabia każdy znak w łańcuchu, instrukcja if wewnątrz pętli for określa czy znak odpowiada poszukiwanemu znakowi (FindChar). Jeśli znaleziono pasujący znak, wykonywana jest instrukcja break i pętla for kończy działanie, sterowa-nie przechodzi do instrukcji if (i < strlen (s)). Funkcja strlen () zwraca długość łańcucha podanego jako jej argument i zadeklarowana jest w pliku nagłówkowym < string.h >.


    Wykaz źródeł:

    • Notatki z wykładów

  • <<POPRZEDNIA | NASTĘPNA>> | E-MAIL |