DEFINIOWANIE ZMIENNYCH, C.D.

23
IENNYCH, C.D. ieją „podtypy” liczb całkowitych: int, short, long, ” zmiennoprzecinkowych: float i doube, zmienne znakowe tych zmiennych nych może być również zadeklarowana jako np.: przechowywane są w procesorze, dostęp do nich jest ęściej nie stosujemy powyższych deklaracji. Kompilator cji „sam” to robi z nas. (odpowiednik rekordów) katalog brzech

description

DEFINIOWANIE ZMIENNYCH, C.D. Pamiętamy, że istnieją „podtypy” liczb całkowitych: int, short, long, unsigned; „podtypy” zmiennoprzecinkowych: float i doube, zmienne znakowe char oraz tablice tych zmiennych Każda z tych zmiennych może być również zadeklarowana jako zmienna rejestrowa np.: - PowerPoint PPT Presentation

Transcript of DEFINIOWANIE ZMIENNYCH, C.D.

Page 1: DEFINIOWANIE ZMIENNYCH, C.D.

DEFINIOWANIE ZMIENNYCH, C.D.Pamiętamy, że istnieją „podtypy” liczb całkowitych: int, short, long,unsigned; „podtypy” zmiennoprzecinkowych: float i doube, zmienne znakowechar oraz tablice tych zmiennych

Każda z tych zmiennych może być również zadeklarowana jako zmienna rejestrowa np.:register int n;register char c;Zmienne rejestrowe przechowywane są w procesorze, dostęp do nich jest szybki. ALE: najczęściej nie stosujemy powyższych deklaracji. Kompilatorpodczas optymalizacji „sam” to robi z nas.

DANE STRUKTURALNE (odpowiednik rekordów)struc katalog { katalog brzechwa[50], lenin[100];int numer;char opis[40];float cena;int polka;} ksiazki[1000];

Page 2: DEFINIOWANIE ZMIENNYCH, C.D.

INICJOWANIE STRUKTURY:struct data {int dzien;int miesiac;int rok;char nazwa_miesiac[4];} d; struc data d={4,7,2003,``Lipi”}ODWOŁANIE SIĘ DO ELEMENTU STRUKTURY:nazwa_struktury.skladowad.dzien=4; d.miesiac=7; d.rok=2003; d.nazwa_miesiac[0]=``L’’;Struktury mogą być zagnieżdżone:struct osoba{char imie[10];char nazwisko[20];struct data data_urodzenia;} baba;baba.data_urodzenia.rok=2003; itp.

Page 3: DEFINIOWANIE ZMIENNYCH, C.D.

DEFINIOWANIE WŁASNYCH TYPÓW ZMIENNYCH:typedef int miesiac;typedef osoba chlop;DODATKOWE PRE-DEFINIOWANE STAŁE:\b - „backspace”; \r - powrót kursora, \f - nowa strona,\\ - „backslash”; \’ - pojedynczy apostrof, DALEJ: TRUE to 1, FALSE to 0, \xxx (xxx -liczba), liczba wpostaci ósemkowej, w szczególności \7 to „brzęczyk”printf (``\7 \7 \7”) - trzy razy zabrzęczy, NULL to \0******O DEFINIOWANIU TZW. UNII - PÓŹNIEJ ***********

INSTRUKCJA INCLUDE# include “nazwa_pliku” lub #include <nazwa_pliku>ZASTOSOWANIE apostrofu lub <...> WSKAZUJE gdziesystem będzie szukał pliku. Apostrof - aktualny katalog,<...> - tam, gdzie są biblioteki. W szczególności każdy programpowinien zaczynać się odinclude <stdio.h> (porównaj: uses Crt w PASCALU)

Page 4: DEFINIOWANIE ZMIENNYCH, C.D.

UZUPEŁNIENIE NT. OPERATORÓWOperatory << oraz >> służą do przesuwania BITÓW w lewo lub prawo, np.x<<2 to przesunięcie x w lewo o dwie pozycje, zwolnione bity uzupełniane są zerami.Podobnie x>>2 to przesunięcie w prawo o dwie pozycje, zwolnione bity dla wielkościunsigned „dopełniane” są (na początku) zerami; natomiast w przypadku zmiennych ze znakiem uzupełniane są bitami znaku. UWAGA: OSTATNIE TO STANDARD, NIE KAŻDY KOMPILATOR TAK ROBI!zatem mnożenie liczby przez 2 to x>>1, przez 8 to x>>3, itp.. (A DZIELENIE?)

Operator (negacja, nazywany także „uzupełnieniejedynkowe”) ~ zamienia 0 na 1 i odwrotnie

Mówiliśmy o wyrażeniach i++ (++i), teraz przez analogie:zamiast pisać i=i+2; możemy pisać i+=2DLA OPERATORÓW DWUARGUMENTOWYCH: +,-,*,/,<<,>>,&,^,|

zamiast pisać a=a (operator) b możemy pisać a (operator) = b

Page 5: DEFINIOWANIE ZMIENNYCH, C.D.

WYRAŻENIA WARUNKOWEif (warunek){ ... instrukcje ...} E1 ? E2 :E3 - to „skrócone” wyrażenie warunkowe else{instrukcje...}

Chcemy by zmienna z była największą liczbą z liczb a i bif (a>b)z=a; z=(a>b)? a:b;elsez=b;

Wypisać chcemy N elementów tablicy po 10 w każdym wierszuoddzielając każdą kolumnę odstępem( ‘ ‘) oraz kończąc każdy wiersz (wraz z ostatnim) znakiem nowego wiersza (‘\n’) for (i=0; i<N; i++)printf(``%6d%c”, a[i], (i%10==9 || i=N-1)? ‘\n’:’ ‘);

Page 6: DEFINIOWANIE ZMIENNYCH, C.D.

W instrukcjach warunkowych i logicznych często wygodniej jeststosować notację binarną, ósemkową lub szestnastkową. Należy samodzielnie przećwiczyć te notacje. Wiemy (zapewne) jak inter-pretować zapisy binarne, np.

192*12*02*12*02*110101 01234 A w jaki sposób odwrotnie, z liczby dziesiętnej otrzymać liczbę wpostaci binarnej? Mamy np. liczbę dziesiętną 501, jaka jest jej reprezen-tacja binarna? Możemy to rozwiązać np. w taki sposób:1) jeśli liczba jest nieparzysta, to ostatni (najniższy) bit jest na pewno 1, w przeciwnym wypadku - 02) szukamy największej potęgi 2, takiej, że 2n <=501 (od danej liczby); w naszym przypadku to 8, bo 28 = 256 a 29=512. Zatem na pozycji n+1=9 mamy 13) odejmujemy od liczby 2n, u nas 501-256=2454) powtarzamy 2) dla różnicy - 245, mamy 27= 128, 245-128=117. Zatem na pozycji n+1=7+1=8 jest jedynka, powtarzamy 2)26=64, 117-64=53, pozycja 6+1 - to jedynka, 25=32, 53-32=21, pozycja 5+1- jedynka;24=16, 21-16=5, pozycja 4+1- jedynka; 22=4, 5-4=1, pozycja 2+1 - jedynka, 20=1, pozycja pierwsza - jedynka. Pozostałe pozycje to zera. Zapiszmy wynik:111110101 to binarnie 501

Page 7: DEFINIOWANIE ZMIENNYCH, C.D.

Aby zapisywać liczby w postaci ósemkowej najwygodniej najpierwokreślić ich postać binarną, a później posługując się relacją binarna-ósemkowa:binarna ósemkowa000 0001 1010 2011 3100 4101 5110 6111 7 „przepisać” liczbę binarną jako ósemkową. Np. mamy: 10000001zapisujemy „ w grupach to trzy”10 000 001 binarna2 0 1 ósemkowa : 201SAMODZIELNIE: szestnastkowe, wówczas grupujemy po 4 bity (pobajcie). Cyfry szersnastkowe to 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,FOczywiście, możemy liczbę dziesiętną zamienic na ósemkowa (16-tkową) w tensam sposób jak na binarną - ale podstawa potęg będzie 8 (lub 16)

Page 8: DEFINIOWANIE ZMIENNYCH, C.D.

Program „musi wiedzieć” czy nadając wartość danej zmiennej,liczba zapisanajest dziesiętnie, ósemkowo czy szestnastkowoi=129 - dziesiętniei=0201 - ósemkowo, wyróżnik to ZERO NA POCZĄTKUi=0x81 (lub 0X81) - szestnastkowo, wróżnik to 0x lub 0X (ZERO x; ZERO X)ZADNIE 6Stosując przedstawiony algorytm napisać program przekształcający liczbędziesiętną w binarną && (ósemkową || szetsnastkową)Binarne operatory: koniunkcji (&), alternatywy (I) często służą do„zasłaniania” bitów liczby (por. przykład na przekształcanie małych literw duże litery). Jeśli chcemy wyzerować wszystkie bity, prócz okrslonych to wystarczy wykonać operację:nowa_liczba=stara_liczba& maskaNp. chcemy wyzerować wszystkie bity, prócz bitów 1,2,3 to nasza maska powinna mieć postać binarną ..000 111, liczba ósemkowa to maska=07, operacja liczba&maska wyzeruje wszystkie bity, poza ostatnimi trzema, które pozostawi niezmienione. OERATOR ~TO TZW. „UZUPEŁNIENIE JEDYNKOWE (zmienia 0 na jedeni odwrotnie. Liczba ~maska (~to ) zastosowana w wyrażeniu nowa_liczba=stara_liczba&(~maska) wyzeruje trzy ostatnie bity, pozostałych nie zmieni! (ROZWAŻ CO SIĘ STANIE jeśli liczba|maska oraz liczba|(~maska).

Page 9: DEFINIOWANIE ZMIENNYCH, C.D.

ZADANIE 7. napisz program, któren będzie a) „zasłaniać”b) zerować określoną liczbę bitów (dana wprowadzana do programu w postaci ósemkowej)Czytaną liczbę oraz wynik wyprowadź na ekran w postacia) dziesiętnejb) ósemkowejc) binarnej

TEMAT DO SAMODZIELNEGO OPRACOWANIA: priorytetyobliczeń ( JAK W PASCALU!). Pamiętaj: jeśli nie jesteś pewien, STOSUJ NAWIASY!! a/b*c to a dzielone przez b i WYNIK dzieleniamnożony przez c, jeśli chciałeś, aby a było dzielone przez iloczyn b i c,to powinieneś napisać a/b/c, albo, Z NAWIASAMI: a/(b*c), itd.

Page 10: DEFINIOWANIE ZMIENNYCH, C.D.

STEROWANIE1) Konstrukcja if-else (if-else-if-else-.....) Przykład: Dana jest tablica n liczb int uporządkowana rosnąco oraz liczba int x. Jeśli wartośc x wystepuje w tablicy, to funkcja zwrócijej pozycję (z przedziału 0,..,n-1), w przeciwnym wypadku zwróci -1szukaj(x,v,n) /* szukaj x wśród v[0],...,v[n-1] */int x,v[],n;{int low,high,mid; return(-1);low=0; } high=n-1;while(low<=high){ mid=(low+high)/2;if(x<v[mid])high=mid-1;elseif(x>v[mid])low=mid+1;else /* znaleziono x */return(mid); }

Page 11: DEFINIOWANIE ZMIENNYCH, C.D.

2) Instrukcja wielokrotnego wyboru - switch (analog instrukcji w PASCALU case). Jeśli zmienna c może przybierać wartości a,b,c,d lub inne (tzn. poza a,b,c,d) i w zależności od jej wartości wykonywane są instrukcje ia,ib,ic,id, inne, to struktura taka ma postać:switch( c) { case a: {ia}; case b: {ib}; case c: {ic}; case d: {id}; default: {inne};break;}Instrukcja break służy do opuszczenia danej istrukcjiZADANIE 8: przy użyciu instrukcji switch napisz program zliczający ilerazy w danych wejściowych pojawiły się cyfry 0,1,2,3,4,5,6,7,8,9 oraz pozostałeznaki. Czytaj dane wejściowe przy pomocy getchar(). Staraj się napisać program przy pomocy jak najmniejszej liczby instrukcji.

Page 12: DEFINIOWANIE ZMIENNYCH, C.D.

3) Pętle for i while while(wyrażenie){instrukcje}Instrukcja while wykonywana jeśli wyrażenie !=0 („prawda”; pamiętaj: fałsz to0!)W instrukcji while NAJPIERW obliczane jest wyrażenie, jeśli 0 toinstrukcja NIE JEST WYKONANA

for(wyr1; wyr2; wyr3} {instrukcje} jest równoważne instrukcjomwyr1;while(wyr2){{instrukcje}; wyr3;}

„Nietypowa” pętla: for(;;) {instrukcje}jest to przykład pętli NIESKOŃCZONEJ; zakończyć ją może umieszczeniew {instrukcje} „wyjscia” (return, break, goto)

Page 13: DEFINIOWANIE ZMIENNYCH, C.D.

Zastosowanie operatora , (przecinek) w instrukcji for

Para wyrażeń oddzielonych przecinkiem jest obliczana od lewej do prawej. w instrukcji for można umieścić kilka takich wyrażeń, np. do sterowania kilkoma indeksamichar s[]; /* odwracamy ciag znakow s */for(i=0;j=strlen(s)-1; i<j;i++, j--) /* funkcja standardowa strlen(s) */ {c=s[i]; /* oblicza slugosc lancucha s */s[i]=s[j];s[j]=c]}

ZADANIE 9Napisz program, który przepisuje łańcuch s1 do s2 a nastepniew łańcuchu s1 podwaja każdy znak, np.. jeśli s1 to asadlx, tootrzymać mamy aassaaddllxx

Page 14: DEFINIOWANIE ZMIENNYCH, C.D.

4) Pętla do-while (PASCAL: repeat-until)W poprzednich pętlach (while, for) warunek sprawdzany był na początkuw pętli do-while sprawdzany jest na końcu. Pętla ta ma postać:do{instrukcje};while(wyrażenie)Pętla jest zatrzymywana, gdy wyrażenie stanie się FAŁSZYWE (wartość 0)5) Instrukcje break i continueinstrukcja break powoduje wyjście z bloku {..} w pętliinstrukcja continue powoduje przerwanie w danym miejscu iponowne wykonanie następnego kroku pętli „od początku”, tzn.powoduje natychmiastowe wykonanie sprawdzenia warunku pętli. 6) instrukcja goto i etykiety. Jak w PASCALU. Różnica to brak deklaracjietykiet (w PASCALU: label), tzn. deklaracją jest sama etykietagoto ala;..........ala: instrukcja; /*to jest DEKLARACJA */Skok/etykieta obowiązują wewnątrz danej funkcji, użycie goto z „wyjściem” poza funkcje jest błędem

Page 15: DEFINIOWANIE ZMIENNYCH, C.D.

UZUPEŁNIENIE FUNKCJIWiemy, że funkcje mają postać:nazwa(lista_argumentów)deklaracje_argumetów{ deklaracje zmiennych lokalnychoraz instrukcjereturn(wyrażenie)}wszystkie elementy funkcji mogą być pominięte. W szczególności funkcja dummy() {} jest ATRAPĄ funkcji (stosowaną np.. w celu „zarezerwowaniamiejsca”. Nic ona nie robi. Komunikacja miedzy main a funkcjami oraz pomiędzy kolejnymifunkcjami odbywa się poprzez argumenty i wartości zwracane pod nazwąfunkcji. Przekazywanie argumentów odbywa się przez WARTOŚĆ. Nadawanie wartości nazwie funkcji odbywa się instrukcjąreturn(wyrażenie). Instrukcja return NIE MUSI zawierać wyrażenia,wówczas pod nazwą funkcji „nie ma nic” (tzn. mogą być „śmieci”)

Wszystko wyżej to podsumowanie naszych wiadomości

Page 16: DEFINIOWANIE ZMIENNYCH, C.D.

Nowe wiadomości:Program główny i funkcje niekoniecznie muszą być w jednym pliku. Jeśliprogram główny jest w pliku main.c, a funkcje w plikach fun1.c, fun2.cto możemy kompilować te pliki oddzielnie i łączyć je w jeden moduł wykonywalny: gcc main.c fun1.c fun2.c ..... lub też:gcc main.c fun1.o fun2.o ..... UWAGA: NAĆWICZENIACH PRZEROBIĆ systemową instrukcjemake Jeśli funkcje zwracają wartości niecałkowite to jej nagłówek mapostać: typ_funkcji nazwa_funkcji(argumenty), np.double fun2(x)double x{....return(...) }W PROGRAMIE GŁÓWNYM musimy „potwierdzić” typ funkcji, tzn.musi być deklaracja: double fun2();Ważna jest ZGODNOŚĆ typów w instrukcji return(...) itypu funkcji. Gdyby funkcja nie została zadeklarowana w programie głównymto wówczas kompilator założyłby, że zwraca ona wartość int! (podobniejest w FORTRANIE)

Page 17: DEFINIOWANIE ZMIENNYCH, C.D.

ZADANIE 10:Oto przykład funkcji, która przekształca tekst na liczbę zmiennoprzecinkową :double tekst_na_float(s)char s[];{double val,power;int i,sign;for(i=0;s[i]==‘ ‘||s[i]==‘\n’||s[i]==‘\t’;i++); /* trick, tekst może zaczynac się „bialymi” znakami, pomin je *//* srednik wyzej jest konieczny, petla ma nic nie robic tylko pomijac znaki */ sign=1;if(s[i]==‘+’||s[i]==‘-’) /*ustalamy znak liczby*/sign=(s[i++]==‘+’)? 1:-1; /*PYTANIE: DLACZEGO i++ a nie ++i ? */for(val=0, s[i]>=‘0’&& s[i]<=‘9’; i++)val=10*val+s[i]-’0’; /*PYTANIE: Dlaczego -’0’ ? */if(s[i]==‘.’)i++;for (power=1;s[i]>=‘0’&&s[i]<=‘9’;i++){ val=10*val+s[i]-’0’;power*=p10;return(sign*val/power); }

Page 18: DEFINIOWANIE ZMIENNYCH, C.D.

Wytłumacz dokładnie kolejne instrukcje programu. Napisz program główny,który wywołuje tą funkcję. Program główny ma czytać daneoraz wypisywać wynik

Page 19: DEFINIOWANIE ZMIENNYCH, C.D.

Posługiwanie się funkcjami ze zmienną liczbą argumentów nie jest naogół bezpieczne, napisanie takiej funkcji wymaga specjalnych procedur(przykładem funkcji o zmiennej liczbie argumentów jest printf)

Mówiliśmy, że argumenty przekazywane są przez wartość, tzn. ich elementy są KOPIOWANE i „lokalnie” zmieniane w funkcji. ALE:Jeśli argumentem funkcji jest nazwa tablicy, to przekazywaną wartościąjest POŁOŻENIE (adsres) początku tej tablicy i jej elementy NIE SĄKOPIOWANE. Tak więc funkcja MOŻE zmienić elementy tablicy. TABLICE SĄ PRZEKAZYWANE PRZEZ REFERENCJĘ (ADRESY)!!

W dalszej części mówić będziemy o wskaźnikach, które umożliwią funkcjomdostęp do danych innych niż tablice w funkcjach wywołujących

Page 20: DEFINIOWANIE ZMIENNYCH, C.D.

ZMIENNE STATYCZNEMówiliśmy, że zmienne lokalne w danej funkcji „pojawiają się” w momenciejej wywołania i „znikają” po wyjściu z funkcji. Przy ponownym wywołaniu funkcji program „nie pamięta” ich wartości obliczonych w poprzednimwywołaniu - chyba, że zadeklarujemy je w specjalny sposób. Tego typu zmiennedeklarujemy jako STATYCZNEstatic char[100];static double x; itp.Zmienne statyczne „znane są” TYLKO wewnątrz funkcji, w której jezadeklarowano, żadna inna funkcja nie ma do nich dostępu. Są one rodzajem„pamięci wewnętrznej” funkcji, są zmiennymi „prywatnymi” danej funkcji.

NADAWANIE WARTOŚCI POCZĄTKOWYCHMożemy to robić w deklaracjach, np. int i=0; zamiast int i; ...,i=0; Możemy inicjować tablice, np. int x[5]={0,0,0,0,0} (UWAGA: w standardzie cwszystkie zmienne powinny być inicjowane zerami; jednak należy to sprawdzićdla danego kompilatora). Tablice znakowe możemy inicjować w rozmaity sposóbchar wyraz[]=“ala”; albo char wyraz[]={‘a’,’l’,’a’,’\0’}

Page 21: DEFINIOWANIE ZMIENNYCH, C.D.

REKURENCJAPodobnie jak PASCAL, c pozwala na rekurencję, tzn. dana funkcja może wywoływać samą siebie. W PASCALU pisaliśmy funkcję silnia(n), obliczjącąn!. ZADANIE 11Napisz funkcję obliczającą n!a) bez rekurencjib) z rekurencjąwskazówka: w PASCALU rekurencja miała postać:function silnia(n:integer): extended;beginif n=0 then silnia:=1 else silnia:=n*silnia(n-1) end;

Page 22: DEFINIOWANIE ZMIENNYCH, C.D.

MAKRA (MAKRODEFINICJE)# define tak 1

# define begin { wówczas możemy pisac: if (i>0) then# define end ;} begin ....... end;# define then

INNE PRZYKŁADY

#define max(a,b) ((a)>(b)?(a):(b)) UWAGA NAWIASY - aby a i b mogły być wyrażeniami#define square(x) x*x

FUNKCJE MATEMATYCZNE#include <math.h>NAZWY ANALOGICZNE JAK W PASCALU (Prawie)ZADANIE 12Napisz program tablicujący funkcje |(a+sin(x))/cos(x)| w przedziale [min,max]z krokiem delta. Wszystkie dane czytane z klawiatury. Uważaj na komplikacjezwiązane z dziedziną funkcji.

Page 23: DEFINIOWANIE ZMIENNYCH, C.D.

WSKAŹNIKI I TABLICE