5433


Podstawy programowania C/C++ Wykład 3

semestr II - studia dzienne zawodowe

Zakres tematyczny:

  1. Instrukcje skoku

    1. break,

    2. continue,

    3. return,

    4. goto.

  1. Modyfikator const (stałe nazwane)

  2. Operatory języka C/C++

    1. operatory arytmetyczne

    2. operatory przypisania

    3. operatory logiczne

    4. operator sizeof

    5. operator przecinek

    6. operatory binarne

    7. łączność operatorów

  1. Przekształcanie typów

1. Instrukcje skoku

Do tej grupy instrukcji należą:

break;

continue;

return wyrażenie;

goto etykieta;

1.1. Instrukcja break

Służy do przerwania działania pętli for, while, do...while oraz instrukcji switch. Instrukcja ta, przenosi sterowanie do instrukcji bezpośrednio występującej po pętli lub po instrukcji switch. Jeśli mamy do czynienia z pętlami zagnieżdżonymi break przerywa tylko tą petlę lub instrukcję switch w której zostało użyte. Instrukcja break przerywa pętlę zanim wyrażenie testujące pętlę osiągnie wartość 0.

Program

#include <stdlib.h> //random(),

#include <stdio.h>

void main (){

int licz, i, los;

los = 7;

randomize();

licz=0;

do {

licz++;

if (random (30) = = los) break;

} while (1);

printf ("7 wylosowano za %d \

razem″ ,licz);

}

Program

#include <stdlib.h>

#include <iostream.h>

void main(){

int licz, i, los;

randomize();

licz=0; // czy poprawnie?

for (i=1; i<10; i++) {

do {

licz++;

if (random (30) = = i) break;

} while (1);

cout<<" i wylosowano za "<<licz

<<" razem";

}

}

1.2. Instrukcja continue

Instrukcja ta może być używana tylko w pętli for, while, do...while. Powoduje przeniesienie sterowania na koniec pętli.

Program

#include <stdio.h>

#include <conio.h>

void main (){

int i;

float iloczyn;

clrscr ();

iloczyn =1;

for (i=1; i<30; i++ {

if ( (i % 3) = = 0) continue; //skok na koniec pętli,

iloczyn = iloczyn * i;

//koniec pętli: continue przenosi sterowanie w to miejsce.

}

}

1.3. Instrukcja return

Return pozwala funkcji na natychmiastowe przeniesienie sterowania do miejsca wywołania funkcji i przekazania wartości stojącej po słowie return (w przypadku funkcji main do systemu operacyjnego).

int main (){

..............

return 1;

}

1.4. Instrukcja goto

Instrukcja ta, wykonuje bezwarunkowe przeniesienie sterowania do miejsca gdzie występuje dana etykieta. Etykieta musi być umieszczona w tej samej funkcji. Poniższy program ilustruje użycie goto do przerwania pętli:

float w, i;

i=0;

while (1) {

i++;

w=1/(i+1);

if (w<0.001) goto wyraz;

}

wyraz: w=sgrt (w);

printf (″w=%f”, w);

i=0;

do {

i++;

w=1/(i+1);

} while (w>0.001);

w=sgrt (w);

printf (″w=%f”, w);

Instrukcja ta, wykonuje bezwarunkowe przeniesienie sterowania do miejsca gdzie występuje dana etykieta. Poniższy program ilustruje użycie goto do przerwania zagnieżdżonej pętli:

for(i=0; i<n; ++i)

for(j=0; j<m; ++j)

if (tab[i][j] = = a) goto znaleziono;

znaleziono: cout<<znaleziono element;

0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic
0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic

0x08 graphic
0x08 graphic

  1. Modyfikator const (stałe nazwane)

float pi = 3.14; wartość pi może zostać zmieniona w programie

Obiekt, którego wartość nie ulega zmianie, nazywa się obiektem stałym. Deklaracja obiektu stałego.

const float pi = 3.14;

Inicjacjalizacja obiektu wartością musi sie odbyć w miejscu jego deklaracji. Potem nie jest to możliwe.

Deklaracja const float pi;

jest błędna, ponieważ deklarujemy obiekt stały więc jego wartość musi być inicjalizowana.

Poprawna:

const float pi = 3.14;

Grupa poniższych linii jest błędna, ponieważ stała nie może uzyskać wartości w instrukcji przypisania.

pi = 2.00; //błąd

pi = 3.14; //mimo, że próbujemy przypisać obiektowi const taką samą wartość będzie sygnalizowany błąd.

Dyrektywa preprocesora.

#define ESC 27

if (znak = = ESC) {...};

do {

.....

}

while (znak != ESC);

3. Operatory języka C/C++

a = i++ + j;

x*=(a!=0)?a:b++;

Operatory należą do jednej z dwu grup:

- operatory jednoargumentowe (unarne) wiązane z jednym argumentem.

- operatory dwuargumentowe (binarne) wiązane z dwoma argumentami.

3.1. Operatory arytmetyczne

- operatory : + - * /

Należą do grupy operatorów binarnych (ponieważ operują na dwóch obiektach - argumentach).

- operator % czyli modulo

Jest operatorem binarnym. W wyniki działania tego operatora otrzymujemy resztę z dzielenia argumentów stojących po obu stronach operatora:

45 % 6 -> 3

Argumenty tego operatora muszą być typu całkowitego. Argumenty tego operatora muszą być typu całkowitego. Jeśli argumenty operatora są nieujemne to , to reszta z dzielenia jest nieujemna w przeciwnym razie znak reszty zależy od implementacji.

Dla Borland 3.1, znak wyniku op1 % op2 jest zgodny ze znakiem oprandu op1.

z = - 45 % 6; z = - 45 % -6; z = 45 % -6;

z = -3 z = -3 z = 3

Priorytet operatorów *, /, % jest wyższy niż operatorów +, -.

- operatory jednoargumentowe + , -

Operator - zmienia wartość danego wyrażenia na przeciwną :

-a - (2*a + b)

- operatory inkrementacji i dekrementacji

++; --;

Realizują operacje zwiększania i zmniejszania o jeden.

Operatory dekrementacji i inkrementacji mogą mieć dwie formy:

- przedrostkową ( prefix): ++i; --i;

- przyrostkową (postfix): i++; i--;

W obu przypadkach wynikiem jest zmiana wartości i, ale wyrażenie ++i zwiększa i przed użyciem jej wartości, natomiast wyrażenie i++ zwiększa zmienną i dopiero po użyciu jej poprzedniej wartości. Jest to istotne w kontekście, w którym ważna jest wartość zmiennej i, a nie tylko jej zmiana np:

i = 10;

x = i++;

cout<<" x = "<<x;

daje w rezultacie x = 10, ale

i = 10;

x = ++i;

cout<<" x = "<<x;

daje w rezultacie x = 11.

int m=3, n=1, r;

r = (m++) + (++n); //r=3+2=5

Ponieważ są to operatory unarne (jednoargumentowe) to wyrażenie :

(i + j)++ jest błędne;

W przypadku, gdy chodzi tylko o sam efekt zwiększania o jeden, operatory post i prefiks-owe są równoważne.

for (i=11; i<34; i++) {...}

for (i=11; i<34; ++i) {...}

int i=1;

s[i] = i++; porządek wartościowania jest niezdefiniowany, może być wartościowane jako s[1]=1 lub jako s[2]=1.

3.2. Operatory przypisania

operatory: = += -= *= /= %=

float b = 15; float w,a = 5.2;

w=a+b;

Jeżeli, argumenty nie mają takiego samego typu, to o ile jest to możliwe wykonana zostaje niejawna konwersja typów.

int i=1.2; float b= 5/2; float b= 5.0/2;

Jeśli oba argumenty sa typu arytmetycznego to przed wykonaniem przypisania prawy argument jest przekształcany do typu lewego argumentu.

i = i + 2; bardziej zwięzły zapis: i += 2;

Uwaga!!!
x*= y + 1;

jest odpowiednikiem wyrażenia:

x = x * (y+1); NIE : x = x * y + 1;

Działa tu bowiem zasada:

wyr1 operator= wyr2 to samo co wyr1 = (wyr1) operator (wyr2)

3.3. Operatory logiczne

- operatory relacji

Są to operatory: > >= < <=

W wyniku działania tych operatorów otrzymujemy odpowiedź: prawda (true 1) lub fałsz (false 0) Priorytet tych operatorów jest taki sam .

- operatory przyrównania

Są to operatory = = !=.

Ich priorytet jest niższy niż priorytet operatorów relacji

Program 1

#include<iostream.h>

void main() {

int x = 10, x1 = 10;

if (x = 3) //błąd - przypisanie, zamiast porównanie. Kompilator generuje ostrzeżenie

x= 2*x1;

else

x= 2 - x1;

cout<<"x=*<<x};

- operatory sumy i iloczynu logicznego

Są to operatory:

| | - realizujący sumę logiczną (LUB - alternatywa)

&& - realizujący iloczyn logiczny (I - koniunkcja)

Argumenty mogą być typu arytmetycznego lub wskaźnikowego. Wynik jest typu int.

Przykład 1

#include<iostream.h>

void main(){

int ch;

ch = getche();

if ((ch >= 'a') && (ch <= 'z')) | | ((ch >= 'A') && (ch <= 'Z'))

cout<<"wprowadzony znak jest literą";

else if((ch >= '0') && (ch <= '9'))

cout<<"wprowadzony znak jest cyfrą";

else

cout<<"Wprowadzony znak nie jest cyfrą i nie jest literą";

}

Weźmy np. fragment kodu:

if ((x1 = = 0) && (x1 = = 15) && (z>10))

Operatory && i | | gwarantują wartościowanie argumentów od lewej do prawej.

Dla operatora && drugi argument nie będzie obliczony, jeśli pierwszy ma wartość zero.

Dla operatora | | drugi argument nie będzie obliczony, jeśli pierwszy ma wartość niezerową.

int i = -6, d = 4; //i=6, d=4

if ((i>0) && (d++)) {

...............

}

W instrukcji tej nie tylko wykonywana jest operacja logiczna , ale także chcemy zwiększyć wartość zmiennej d. Jeżeli, wyrażenie i>0 nie będzie prawdziwe to nie dojdzie do zwiększenia d.

int i = -6, d = 4; //i=6, d=4

if ((i>0) | | (d++)) {

...............

}

Priorytet operatora && jest większy niż operatora ||, ale oba są niższe niż operatorów przyrównania i relacji, więc w wyrażeniu:

i < gr - 1 && (c = getchar()) != '\n' | | c!= EOF

nie potrzeba dodatkowych nawiasów.

Ponieważ jednak priorytet operatora != jest wyższy niż przypisania, więc w wyrażeniu ( c=getchar() ) != '\n' potrzebne są nawiasy. Najpierw bowiem ma zostać przypisana wartość zmiennej c, a potem dopiero przyrównana do '\n'.

czytelnie: (i < (gr - 1)) && ((c = getchar()) != '\n' ) | | (c!= EOF)

- operator negacji !

Operator jest jednoargumentowy i stoi zawsze po lewej stronie operandu:

!n

Jeśli n = 0, to wartością wyrażenia jest PRAWDA.

Jeśli n różne od 0, to wartością wyrażenia jest FAŁSZ.

Instrukcja: if (!n) jest równoważna instrukcji: if (n = = 0)

Przykład 1

int x;

x= !(-12); -> x=0

x= !(120); -> x=0

x= !(0); -> x=1

int i = 0;

if (!i) cout<<"Wartość i jest zerowa";

while (i-2)

while ((2*x) && y)

while ((2*x) && (!y))

3.4. Operator sizeof ()

Operator: sizeof(), podaje rozmiary:

a) typów zmiennych sizeof (nazwa_typu)

b) obiektów sizeof(nazwa_obiektu)

Przykład 9

#include<iostream.h>

void main(){

int i;

cout <<"rozmiar typu integer w bajtach " << sizeof(int);

cout<<" \n rozmiar zmiennej i w bajtach " << sizeof(i);

}

3.5. Operator przecinkowy

Kilka wyrażeń oddzielonych przecinkiem wartościuje się od lewej do prawej, przy czym wartość lewego wyrażenia przepada.

i = 5;

b = (a = i, a=a+1);

Jeśli kilka wyrażeń stoi obok siebie i są oddzielone przecinkami, to wartością zmiennej b jest wartość prawego argumentu, czyli

b = 6 a = 6

Operator przecinkowy może wystąpić wyłącznie w nawiasie.

Jeżeli pominiemy nawiasy to:

b = a = i, a=a+1;

b = 5; a=6;

int x, a, c;

a=5; c=7;

c = (x=a, a=c, x);

czyli: x=5, a=7, c=5

Wyrażenie jest wartościowane od lewej do prawej.

3.6. Operatory bitowe

Operatory bitowe:

<< - przesunięcie w lewo

>> - przesunięcie w prawo

& - bitowy iloczyn logiczny

| - bitowa suma logiczna

^ - bitowa różnica symetryczna (bitowe exclusive OR)

~ - bitowa negacja

- operator przesunięcia w lewo <<

Jest to operator unarny, operujący na argumentach całkowitych: zmienna << ile miejsc

Służy do przesuwania bitów argumentu stojącego po lewej stronie operatora o liczbę pozycji określoną przez drugi argument (jego wartość musi być dodatnia). Zwolnione bity zostają uzupełnione zerami:

int x = 0x0010;

int wynik;

wynik = x << 2;

Powyższy fragment programu przesunie bity liczby x o 2 miejsca w lewo:

x = 0000 0000 0001 0000 //16 0x0010

wynik = 0000 0000 0100 0000 //64 0x0040

można:

x = x << 2.

Operacja ta ( x<<2) jest równoważna pomnożeniu zmiennej przez cztery:

x 0x0001 = 1

x<<2 0x0100 = 4

- operator przesunięcia w prawo >>

zmienna >> ile miejsc

Działa na operandach całkowitych. Przesuwa bity operandu stojącego polewej stronie operatora o ilość bitów wskazaną przez operand prawy.

Bity z prawej strony są gubione.

Jeśli operator pracuje na danej unsigned czyli bez znaku, to bity z lewego brzegu są uzupełnione zerami , jeśli jest to liczba ze znakiem, to bity z lewego brzegu są uzupełnione zerami lub jedynkami zależnie od implementacji, w pakiecie Borland 3.3 najbardziej znaczące bity uzupełniane są bitem znaku.

unsigned int x = 0x0ff0;

unsigned int wynik;

wynik = x >>2;

x 0000 1111 1111 0000

wynik 0000 0011 1111 1100

signed int f = 0xff00; //-256

signed int wynik;

wynik = x>>2; //-64

x 1111 1111 0000 0000

wynik 0011 1111 1100 0000 //uzupełnienie zerami

wynik1 1111 1111 1100 0000 //uzupełnienie bitem znaku

Implementacja Borland C++ daje wynik1.

- operatory negacji , iloczynu, sumy, różnicy symetrycznej

Operatory te działają na operandach całkowitych.

b1

b2

~ b1 (not)

b1 & b2 (and)

b1 | b2 (or)

b1 ^ b2 (xor)

0

0

1

0

0

0

0

1

1

0

1

1

1

0

0

0

1

1

1

1

0

1

1

0

int x1 = 0x0f0f;

int x2 = 0x0ff0;

x1 0000 1111 0000 1111

x2 0000 1111 1111 0000

x1 & x2 0000 1111 0000 0000 zasłania pewną grupę bitów

x1 | x2 0000 1111 1111 1111 służy do ustawiania bitów

x1 ^ x2 0000 0000 1111 1111 tam gdzie bity operandów są

takie same ustawia 0, a gdzie różne 1

~ x1 1111 0000 1111 0000 zamienia bit 1 na 0 i odwrotnie.

#include<stdio.h>

void main(){

unsigned char upr=0;

char pisz, czyt, kas;

pisz=1;

upr = pisz<<2;

printf ("%d ",upr);

czyt=2;

upr = upr | czyt;

printf ("%d ",upr);

kas=0;

upr = upr | kas;

printf ("%d ",upr);

char maska=4;

pisz = (upr & maska)>>2;

printf ("\n%d ",pisz);

maska=2;

czyt = (upr & maska)>>1;

printf ("\n%d ",czyt);

maska=1;

kas = upr & maska;

printf ("\n%d ",kas);

getch()

};

3.7. Priorytet i łączność operatorów

Priorytety operatorów (od najwyższego) podaje zestawienie:

15. () [] -> L

14. ! ~ ++ -- + - * & sizeof P // adres i wskaźnik

13. * / % L

12. + - L

11. << >> L

10. < <= > >= L

9. == != L

8. & L

7. ^ L

6. | L

5. && L

4. || L

3. ? : P

2. = += -= *= /= %= ^= |= <<= >>= P

1. , L

Litery L i P określają w jaki sposób grupowane jest wykonywanie wyrażenia i tak np:

dla wyrażenia z operatorem + (L)

a + b + c + d + e

lewostronna łączność oznacza:

((((a + b) + c) + d) + e)

natomiast dla wyrażenia z operatorem = (P)

a = b = c = d = e

oznacza:

(a = ( b = (c = (d = e))))

5. Przekształcanie typów

Konwersja wykonywana jest w następujący sposób, zasady powinny być stosowane wg kolejności wymieniania:

- jeśli jeden argument jest long double drugi przekształcany jest do long double.

- jeśli nie to jeśli jeden argument jest double drugi przekształcany jest do double.

- jeśli nie to jeśli jeden argument jest float drugi przekształcany jest do float.

- jeśli nie to jeśli jeden argument jest unsigned long drugi przekształcany jest do unsigned long

- jeśli nie to jeśli jeden argument jest signed long drugi przekształcany jest do signed long

- jeśli nie to jeśli jeden argument jest unsigned int drugi przekształcany jest do unsigned int

- w przeciwnym przypadku oba operandy są typu int

Sposoby wykonywania konwersji

- char na int

powielanie bitu znaku dla signed char lub wypełnienie zerami dla unsigned char

-short na int

ta sama wartość

- unsigned short na unsigned int

ta sama wartość

-konwersja dłuższego typu całkowitego do mniejszego

Odrzucenie bardziej znaczących bitów i w razie ich ustawienia utrata informacji

- konwersja między typami calkowitymi o tych samych dlugościach

bezpośrednie skopiowanie wartości jednej zmiennej do drugiej. Warto wiedzieć, że można uzyskać ciekawe wyniki np.:

int -1000 po konwersji do unsigned int 64536

( bit znaku traktowany jako bit o wadze 2 do 15)

- konwersja rzeczywiste na całkowite

odrzucenie części ułamkowej liczby rzeczywistej

- konwersja całkowite na rzeczywiste

nadanie odpowiedniej liczbie rzeczywistej wartości liczby całkowitej

- konwersje między typami rzeczywistymi o różnych rozmiarach

zaokrąglenie do najbliższej wartości docelowego typu.

Oprócz automatycznego przekształcania typów, w dowolnym wyrażeniu można jawnie wymusić przekształcenie typów za pomocą:

- jednoargumentowego operatora rzutowania (casting)

Operator ten może mieć dwie formy:

(nazwa_typu) zmienna //forma języka C/C++ - notacja rzutowa

nazwa_typu (zmienna) //forma C++ - notacja funkcyjna

Notacja funkcyjna stosowana tylko do typów które mają prostą nazwę.

int i; float f;

i = (int) f; f = (float) i;

i = int (f); f = float (i);

f = i/2; f = float (i/2); f=float (i) /2;

Programowanie w języku C/C++

6

wykład 3

1 wykład 3

INSTRUKCJE

Instrukcje iteracyjne (pętle)

Instrukcje skoku

Instrukcje wyboru

break

while

if...else

continue

if

do..while

goto

switch

for

return



Wyszukiwarka

Podobne podstrony:
M 5433 Dress
5433
5433
5433
5433
5433
5433
5433
5433, W5- elektryczny
5433
L 5433 Dress
5433
5433
M 5433 Dress

więcej podobnych podstron