Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Proceduralne Języki Programowania Patryk Jasik Katedra Fizyki Teoretycznej i Informatyki Kwantowej Wydział Fizyki Technicznej i Matematyki Stosowanej Politechnika.

Podobne prezentacje


Prezentacja na temat: "Proceduralne Języki Programowania Patryk Jasik Katedra Fizyki Teoretycznej i Informatyki Kwantowej Wydział Fizyki Technicznej i Matematyki Stosowanej Politechnika."— Zapis prezentacji:

1 Proceduralne Języki Programowania Patryk Jasik Katedra Fizyki Teoretycznej i Informatyki Kwantowej Wydział Fizyki Technicznej i Matematyki Stosowanej Politechnika Gdańska Pokój 415GB Strona domowa: Konsultacje: poniedziałek 15-16, środa 16-17

2 Warunki zaliczenia przedmiotu Pisemny sprawdzian wiedzy z wykładu (10 pkt) 3 sprawdziany z programowania podczas zajęć laboratoryjnych (30 pkt) Uzyskanie 50% punktów spośród wszystkich możliwych do zdobycia Termin zaliczenia wykładu: ostatnie zajęcia w semestrze, 10.VI.2009 Terminy sprawdzianów z programowania: -23.III V VI.2009

3 Literatura I. Sommerville – „Inżynieria oprogramowania”, WNT, Warszawa 2003 B.W. Kernighan, D.M. Ritchie – „Język ANSI C”, WNT, Warszawa 2003 C.L. Tondo, S.E. Gimpel – „Język ANSI C – ćwiczenia i rozwiązania”, WNT, Warszawa 2004 N. Wirth – „Algorytmy + struktury danych = programy”, WNT – Proceduralne i obiektowe języki programowania S. Prata – „Język C. Szkoła programowania”, Helion S. Oaulline – „Język C. Programowanie”, Helion

4 Historia BCPL, Richards, 1967 – prototyp języka C Język B, Thompson, 1969 – prototyp języka C Simula 67, Dahl, 1970 – pojęcie klasy wraz z klasami pochodnymi i funkcjami wirtualnymi Algol 68, Woodward, 1974 – przeciążanie operatorów i możliwość umieszczania deklaracji wszędzie tam, gdzie są dozwolone instrukcje Język C, Kernighan, Ritchie, 1978 – prototyp języka C++ Język ANSI C, Kernighan, Ritchie, 1988 ADA, Ichbiah, 1979 – obsługa wyjątków CLU, Liskov, 1979 – obsługa wyjątków C z klasami, Stroustrup, 1980 – rozszerzenie języka C C++, Stroustrup, lipiec 1983 – pierwsze zastosowanie poza pracownią badawczą Standard ISO C++, Stroustrup, 1998, poprawki do standardu 2003, nowy standard 2009 Java, Gosling, 1994 C#, Hejlsberg, początek XXI wieku

5 Pierwszy program #include int main() { printf ("Witajcie! To jest wyklad z proceduralnych jezykow programowania."); }

6 Drugi program #include int main() { int x, y, liczba; printf(„Podaj pierwsza liczbe: \n"); scanf(„%i”, &x); printf(„Podaj druga liczbe: \n"); scanf(„%i”, &y); liczba = x+y; printf("To jest nasz wynik: x+y=%i\n", liczba); }

7 Kompilacja GCC (GNU Compiler Collection), Cygwin, MinGW, DJGPP, EMX 0.9, RSX tools for GNU C/C++, Borland C++ Compiler 5.5, Borland Kylix 3 Open Edition, Borland C++Builder 6 Personal, Borland C++BuilderX Personal, Microsoft Visual C++ Toolkit 2003, LCC-Win32, lcc 4.1, Digital Mars, Macintosh Programmer's Workshop (MPW), Turbo C 2.01, Turbo C , Pacific C MS- DOS Compiler, Compaq C Version 6.4 for Linux Alpha, Open Watcom 11C, Intel(R) C++ Compiler 6.0 for Linux, ACC, LadSoft CC , Small C Compiler 2.2, Tiny C Compiler, Digital Research C for PC-DOS, LSI C-86, Cyclone, Pelles C for Windows

8 Preprocesor To program interpretujący, którego zadaniem jest przetworzenie tekstu wejściowego w sposób określony za pomocą poleceń preprocesora przez programistę na tekst wyjściowy. Dopiero tak przetworzony tekst poddawany jest analizie składniowej i kompilacji. Wynikiem działania preprocesora jest więc tekst wyjściowy po przetworzeniu podlegający następnie kompilacji. Dyrektywy preprocesora mogą występować w ogólności w dowolnym miejscu programu, a rozróżnienie ich od tekstu kodu źródłowego w językach C i C++ dokonywane jest poprzez poprzedzenie dyrektywy znakiem hash #.

9 Preprocesor Do najważniejszych dyrektyw należą: #include … - dyrektywa włączająca tekst innego pliku źródłowego w miejscu jej wystąpienia w pliku podlegającym aktualnie przetwarzaniu, przy czym możliwe jest zagłębione występowanie dyrektywy include, #define … - definiuje stałe i makroinstrukcje (pseudofunkcje) #undef … - usuwa definicje stałej lub makra #if … - dyrektywy kompilacji warunkowej #elif … - działa podobnie jak else if w języku C #endif … - oznacza koniec bloku kompilacji warunkowej #ifdef … - znaczy to samo co #if defined(…) #ifndef … - znaczy to samo co #if !defined(…)

10 Biblioteki podstawowe assert.h - deniuje makro assert, używane do diagnostyki programu. complex.h – zestaw funkcji opisujących działania na liczbach zespolonych. ctype.h - deklaruje funkcje do klasykacji i konwersji znaków (kody ASCII). errno.h - deniuje makra dla warunków błędu, EDOM i ERANGE, oraz zmienną całkowitą errno, poprzez którą funkcje biblioteczne zwracają kod błędu.

11 Biblioteki podstawowe float.h - definiuje zakres wartości, które mogą być zapamiętywane w typach zmiennoprzecinkowych. fenv.h – kontrola środowiska zmiennoprzecinkowego. inttypes.h – funkcje precyzyjnej konwersji między typami całkowitymi (integer). iso646.h – definiuje makra w standardzie iso646 (and = &&, or = ||, not_eq = !=) limits.h - definiuje wartości ograniczające dla wszystkich danych typu całkowitego (_MIN, _MAX). locale.h - deklaruje strukturę lconv i funkcje niezbędne do przystosowania programu w C do poszczególnych środowisk lokalnych. math.h - deklaruje funkcje matematyczne oraz makro HUGE_VAL.

12 Biblioteki podstawowe setjmp.h - definiuje funkcje setjmp oraz longjmp, które mogą przekazywać kontrole z jednej funkcji do drugiej bez opierania się na wywołaniach i powrotach z funkcji. Definiuje również typ danych jmp_buf używany przez setjmp i longjmp. signal.h - definiuje symbole i procedury niezbędne dla obsługi zdarzeń wyjątkowych. stdarg.h - definiuje makra, które umożliwiają dostęp do nienazwanych argumentów w funkcji, która akceptuje zmienną liczbę argumentów. stdbool.h – obsługa typów logicznych. stdint.h – obsługa różnych typów w zakresie liczb całkowitym. stddef.h - deniuje standardowe typy danych ptrdi_t, size_t, wchar_t oraz symbol NULL.

13 Biblioteki podstawowe stdio.h - deklaruje funkcje i typy danych niezbędne do obsługi operacji we/wy (operacje na plikach, formatowane wyjście/wejście, f. realizujące we/wy znakowe, f. wyznaczające pozycję w pliku, obsługa błędów). stdlib.h - deklaruje wiele funkcji użyteczności takich, jak procedury konwersji łańcuchów, generator liczb losowych, procedury alokacji pamięci i procedury kontroli procesów (takie, jak abort, exit i system), wyszukiwanie, sortowanie. string.h - deklaruje funkcje do manipulowania łańcuchami takie, jak strcmp i strcpy. time.h - deklaruje typy daty i definiuje funkcje do manipulowania czasem. Definiuje typy clock_t i time_t oraz strukturę danych tm. wchar.h – manipulacje znakami regionalnymi (różne języki) wctype.h – klasyfikacja znaków regionalnych.

14 Słowa kluczowe auto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, int, long, register, return, short, signed, sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, while

15 Stałe znakowe nowy wiersz tabulacja pozioma tabulacja pionowa cofanie powrót karetki nowa strona alarm kreska ukośna w lewo znak zapytania apostrof cudzysłów liczba ósemkowa liczba szesnastkowa \n \t \v \b \r \f \a \\ \? \’ \” \ooo \xhh

16 Przekształcenia funkcji printf/scanf ZnakTyp argumentuPrzekształcany do postaci d, iintliczby dziesiętnej ze znakiem. ointliczby ósemkowej bez znaku (bez wiodącego zera) x, Xintliczby szesnastkowej bez znaku (bez wiodącego 0x) z użyciem liter abcdef dla 0x i ABCDEF dla 0X. uintliczby dziesiętnej bez znaku. cintpojedynczego znaku po przekształceniu do typu unsigned char. schar *Znaki tekstu są wypisywane aż do napotkania znaku ‘\0’ lub liczba wypisanych znaków osiągnie wskazaną precyzję. fdoubleliczby dziesiętnej [-]mmm.ddd, gdzie liczbę cyfr d określa precyzja. Domyślną precyzją jest 6; przy precyzji 0 opuszcza się kropkę dziesiętną. e, Edoubleliczby dziesiętnej [-]m.dddddde±xx lub [-]m.ddddddE±xx, gdzie liczbę cyfr d określa precyzja. g, GdoubleJeśli wykładnik potęgi jest mniejszy niż -4, większy lub równy precyzji, to stosuje się specyfikację %e lub %E; w przeciwnym przypadku %f. Nie wypisuje się nie znaczących zer i zbędnej kropki dziesiętnej. pvoid *wskaźnika (reprezentacja zalży od reprezentacji). nint *Liczbę dotychczas wypisanych znaków zapisuje się do odpowiedniego argumentu. Nie ma żadnego przekształcenia argumentu. %Nie ma żadnego przekształcenia argumentu-zostanie wypisany znak %.

17 Specyfikatory typu void char – jeden bajt, zdolny pomieścić jeden znak z lokalnego zbioru znaków (u 0-255, s ); short – 16 bitów ( ) int – typ całkowity (16 lub 32 bity), odzwierciedla naturalny rozmiar liczb całkowitych komputera ( lub to ) long – 32 bity − ( to ) float – typ zmiennopozycyjny pojedynczej precyzji ( ) double – typ zmiennopozycyjny pojedynczej precyzji signed – typ ze znakiem unsigned – typ bez znaku

18 Rodzina operatorów Operatory arytmetyczne +-*/% Relacje i operatory logiczne >>=<<===!=&&|| Operatory zwiększania i zmniejszania ++-- Operatory i wyrażenia przypisania +=-=*=/=%= >=&=^=|= Operator warunkowy wyr1 ? wyr2 : wyr3

19 Rodzina operatorów Przykład if((year % 4 ==0 && year % 100 != 0) || year % 400 == 0) printf(„%d jest rokiem przestępnym \n”, year); else printf(„%d nie jest rokiem przestępnym \n”, year);

20 Bloki sterujące if else else if switch case for while do while break continue goto

21 if else Przykład if (wyrażenie) { instrukcja1; instrukcja2; … } else { instrukcja3; instrukcja4; … }

22 else if Przykład if (wyrażenie) { instrukcja1; instrukcja2; … } else if (wyrażenie) { instrukcja3; instrukcja4; … } … else { instrukcja5; instrukcja6; … }

23 switch case Przykład switch (wyrażenie) { case wyrażenie-stałe1: instrukcje break; case wyrażenie-stałe2: instrukcje break; … default: instrukcje break; }

24 for Przykład for(wyr1; wyr2; wyr3) { instrukcja1; instrukcja2; … } for(i = 0; i < n; i++) { … }

25 while Przykład while(wyrażenie) { instrukcja1; instrukcja2; … }

26 do while Przykład do { instrukcja1; instrukcja2; … } while(wyrażenie)

27 Break i continue Przykład /* trim: usuń z s końcowe znaki odstępu, tabulacji, nowego wiersza */ int trim(char s[]) { int n; for(n = strlen(s)-1; n>=0; n--) if(s[n] != ‘ ’ && s[n] != ‘\t’ && s[n] != ‘\n’) break; s[n+1] = ‘\0’; return n; }

28 Break i continue Przykład for(i =0; i < n; i++) { if(a[i] < 0) /*pomiń element ujemny*/ continue; … /*przetwarzaj element nieujemny*/ }

29 Goto Przykład for (…) for (…) { … if (niepowodzenie) goto error; /*skocz do obsługi błedów*/ } … error: /*napraw sytuację lub wypisz komunikat*/

30 funkcje = moduły Przykład nazwa_funkcji(typ_argumentu argument1, typ_argumentu argument2, …) Typy zmiennych przekazywane do funkcji muszą być zgodne z typami argumentów funkcji. Typ funkcji również powinien być określony. funkcja = moduł Plik, w którym została zapisana funkcja powinien być dołączony do programu głównego w preprocesorze #include „nazwa_funkcji.h”

31 wskaźniki Wskaźnik jest zmienną, która zawiera adres innej zmiennej. ……… p:c: Wskaźnik jest grupą komórek, które mogą pomieścić adres. Jeśli c jest obiektem typu char, a p jest wskaźnikiem, który wskazuje na c, to taką sytuację zilustrowano na obrazku. Jednoargumentowy operator & podaje adres obiektu p = &c; powyższa instrukcja przypisuje zmiennej p adres zmiennej c, zmienna p wskazuje na zmienną c

32 wskaźniki Jednoargumentowy operator * oznacza adresowanie pośrednie lub odwołanie pośrednie, a zastosowany do wskaźnika daje zawartość obiektu wskazywanego przez ten wskaźnik Przykład int x=1, y=2, z[10]; int *ip;//ip jest wskaźnikiem do obiektów typu int ip = &x;//teraz ip wskazuje na x y = *ip;//y ma teraz wartość 1 *ip = 0;//x ma teraz wartość 0 ip = &z[0];//teraz ip wskazuje na element z[0] Od wskaźnika wymaga się wskazywania obiektów określonego rodzaju. (Z jednym wyjątkiem – wskaźnik do void, czyli „wskaźnik do niczego”, może przechowywać wskaźnik do obiektów dowolnego typu, ale nie można go stosować do adresowania pośredniego.)

33 wskaźniki Jeżeli wskaźnik ip wskazuje na zmienną całkowitą x, to *ip może wystąpić wszędzie tam, gdzie może wystąpić x y = *ip + 5 *ip = *ip + 10 *ip += 1 ++*ip (*ip)++ iq = ip

34 wskaźniki źródło: Wskaźnik (ang. pointer) to specjalny rodzaj zmiennej, w której zapisany jest adres w pamięci komputera, tzn. wskaźnik wskazuje miejsce, gdzie zapisana jest jakaś informacja. Oczywiście nic nie stoi na przeszkodzie aby wskazywaną daną był inny wskaźnik do kolejnego miejsca w pamięci. Obrazowo możemy wyobrazić sobie pamięć komputera jako bibliotekę a zmienne jako książki. Zamiast brać książkę z półki samemu (analogicznie do korzystania wprost ze zwykłych zmiennych) możemy podać bibliotekarzowi wypisany rewers z numerem katalogowym książki a on znajdzie ją za nas. Analogia ta nie jest doskonała, ale pozwala wyobrazić sobie niektóre cechy wskaźników: kilka rewersów może dotyczyć tej samej książki, numer w rewersie możemy skreślić i użyć go do zamówienia innej książki, jeśli wpiszemy nieprawidłowy numer katalogowy to możemy dostać nie tą książkę, którą chcemy, albo też nie dostać nic. Warto też poznać w tym miejscu definicję adresu pamięci. Możemy powiedzieć, że adres to pewna liczba całkowita, jednoznacznie definiująca położenie pewnego obiektu (czyli np. znaku czy liczby) w pamięci komputera.

35 wskaźniki Wskaźnik a wskazujący na zmienną b. Zauważmy, że b przechowuje liczbę, podczas gdy a przechowuje adres b w pamięci (1462)

36 wskaźniki Przykład #include int main() { int liczba = 80; printf("Zmienna znajduje sie pod adresem: %p, i przechowuje wartosc: %d\n", &liczba, liczba); }

37 wskaźniki Przykład #include int main() { int liczba = 80; int *wskaznik = &liczba; printf("Wartosc zmiennej: %d; jej adres: %p.\n", liczba, &liczba); printf("Adres zapisany we wskazniku: %p, wskazywana wartosc: %d.\n", wskaznik, *wskaznik); *wskaznik = 42; printf("Wartosc zmiennej: %d, wartosc wskazywana przez wskaznik: %d\n", liczba, *wskaznik); liczba = 55; printf("Wartosc zmiennej: %d, wartosc wskazywana przez wskaznik: %d\n", liczba, *wskaznik); }

38 wskaźniki a tablice W języku C występuje ścisła zależność między wskaźnikami i tablicami. Każdą operację, którą można przeprowadzić za pomocą indeksowania tablicy, można również wykonać za pomocą wskaźników. Wersja wskaźnikowa będzie na ogół szybsza. Przykład: int a[10]; - a[0], a[1], a[2], …, a[9] a[i] oznacza i-ty element tablicy a int *pa; - wskaźnik do obiektów całkowitych pa = &a[0]; - przypisanie ustawi pa tak, aby wskazywał na 0 element tablicy, wskaźnik pa zawiera adres elementu a[0] x = *pa – przypisanie skopiuje zawartość a[0] do x Jeśli pa wskazuje na pewien element tablicy, to pa+1 wskazuje na element następny, pa+i odnosi się do i-tego elementu po pa, pa-i do i- tego elementu przed pa. Jeśli pa wskazuje na a[0], to *(pa+1) – odnosi się do zawartości a[1]; pa+i jest adresem a[i], a *(pa+i) jest zawartością a[i].

39 wskaźniki a funkcje Czasami zdarza się, że argumentem (lub argumentami) funkcji są wskaźniki. W przypadku "normalnych" zmiennych nasza funkcja działa tylko na lokalnych kopiach tychże argumentów, natomiast nie zmienia zmiennych, które zostały podane jako argument. Natomiast w przypadku wskaźnika, każda operacja na wartości wskazywanej powoduje zmianę wartości zmiennej zewnętrznej. Przykład: #include void func (int *zmienna) { *zmienna = 5; } int main() { int z=3; printf ("z=%d\n", z); // wypisze 3 func(&z); printf ("z=%d\n", z); // wypisze 5 } Funkcje w języku C nie tylko potrafią zwracać określoną wartość, lecz także zmieniać dane, podane im jako argumenty. Ten sposób przekazywania argumentów do funkcji jest nazywany przekazywaniem przez wskaźnik (w przeciwieństwie do normalnego przekazywania przez wartość).

40 Argumenty wywołania programu Działania każdego programu rozpoczyna się wywołaniem funkcji main z dwoma argumentami. Pierwszy, umownie nazywany argc (ang. argument count), jest liczbą argumentów, z jakimi program został wywołany; drugi argv (ang. argument vector), jest wskaźnikiem do tablicy zawierającej argumenty, każdy argument jako osobny tekst. Zgodnie z przyjętą konwencją: argv[0] – jest nazwą z jaką program został wywołany, licznik argc jest więc co najmniej równy 1. Wartość argc równa 1 oznacza, że w wierszu polecenia po nazwie programu nie było argumentów. Przykład:./nazwa_programu aaa bbb argc = 3, argv[0] = nazwa_programu, argv[1] = aaa, argv[2] = bbb Dodatkowo standard wymaga, aby element argv[argc] = argv[3] był wskaźnikiem pustym, czyli równym NULL.

41 Argumenty wywołania programu Przykład: #include main(int argc, char* argv[]) { int i; printf("argc = %d\n", argc); for (i = 0; i < argc; i++) printf("argv[%d] = \"%s\"\n", i, argv[i]); }

42 #include #include int main(int argc, char** argv) { /* Set defaults for all parameters: */ int a_value = 0; float b_value = 0.0; char* c_value = NULL; int d1_value = 0, d2_value = 0;int i; /* Start at i = 1 to skip the command name. */ for (i = 1; i < argc; i++) { /* Check for a switch (leading "-"). */ if (argv[i][0] == '-') { /* Use the next character to decide what to do. */ switch (argv[i][1]) { case 'a': a_value = atoi(argv[++i]); break; case 'b': b_value = atof(argv[++i]); break; case 'c': c_value = argv[++i]; break; case 'd': d1_value = atoi(argv[++i]); d2_value = atoi(argv[++i]); break; } printf("a = %d\n", a_value); printf("b = %f\n", b_value); if (c_value != NULL) printf("c = \"%s\"\n", c_value); printf("d1 = %d, d2 = %d\n", d1_value, d2_value); }

43 Operacje na plikach Istnieją dwie metody obsługi czytania i pisania do plików: wysokopoziomowa i niskopoziomowa. Nazwy funkcji z pierwszej grupy zaczynają się od litery "f" (np. fopen(), fread(), fclose()), a identyfikatorem pliku jest wskaźnik na strukturę typu FILE. Owa struktura to pewna grupa zmiennych, która przechowuje dane o danym pliku - jak na przykład aktualną pozycję w nim. Szczegółami nie należy się przejmować, funkcje biblioteki standardowej same zajmują się wykorzystaniem struktury FILE, programista może więc zapomnieć, czym tak naprawdę jest struktura FILE i traktować taką zmienną jako "uchwyt", identyfikator pliku. Druga grupa to funkcje typu read(), open(), write() i close(). Podstawowym identyfikatorem pliku jest liczba całkowita, która jednoznacznie identyfikuje dany plik w systemie operacyjnym. Liczba ta w systemach typu UNIX jest nazywana deskryptorem pliku. Należy pamiętać, że nie wolno nam używać funkcji z obu tych grup jednocześnie w stosunku do jednego, otwartego pliku, tzn. nie można najpierw otworzyć pliku za pomocą fopen(), a następnie odczytywać danych z tego samego pliku za pomocą read(). Czym różnią się oba podejścia do obsługi plików? Otóż metoda wysokopoziomowa ma swój własny bufor, w którym znajdują się dane po odczytaniu z dysku a przed wysłaniem ich do programu użytkownika. W przypadku funkcji niskopoziomowych dane kopiowane są bezpośrednio z pliku do pamięci programu. W praktyce używanie funkcji wysokopoziomowych jest prostsze a przy czytaniu danych małymi porcjami również często szybsze.

44 Operacje na plikach Można zauważyć, że do zapisu do pliku używamy funkcji fprintf, która wygląda bardzo podobnie do printf - jedyną różnicą jest to, że w fprintf musimy jako pierwszy argument podać identyfikator pliku. Nie jest to przypadek - obie funkcje tak naprawdę robią tak samo. Używana do wczytywania danych z klawiatury funkcja scanf też ma swój odpowiednik wśród funkcji operujących na plikach - jak nietrudno zgadnąć, nosi ona nazwę fscanf. W rzeczywistości język C traktuje tak samo klawiaturę i plik - są to źródła danych, podobnie jak ekran i plik, do których można dane kierować. Jest to myślenie typowe dla systemów typu UNIX, jednak dla użytkowników przyzwyczajonych do systemu Windows albo języków typu Pascal może być to co najmniej dziwne. Nie da się ukryć, że między klawiaturą i plikiem na dysku zachodzą podstawowe różnice i dostęp do nich odbywa się inaczej - jednak funkcje języka C pozwalają nam o tym zapomnieć i same zajmują się szczegółami technicznymi. Z punktu widzenia programisty, urządzenia te sprowadzają się do nadanego im identyfikatora. Uogólnione pliki nazywa się w C strumieniami. Każdy program w momencie uruchomienia "otrzymuje" od razu trzy otwarte strumienie (aby z nich korzystać należy dołączyć plik nagłówkowy stdio.h): stdin (wejście) stdout (wyjście) stderr (wyjście błędów) Pierwszy z tych plików umożliwia odczytywanie danych wpisywanych przez użytkownika, natomiast pozostałe dwa służą do wyprowadzania informacji dla użytkownika oraz powiadamiania o błędach.

45 Operacje na plikach Przykład: #include int main() { FILE *fp; /* używamy metody wysokopoziomowej - musimy mieć zatem identyfikator pliku, uwaga na gwiazdkę! */ char tekst[] = "Hello world"; if ((fp=fopen("test.txt", "w"))==NULL) { printf ("Nie mogę otworzyć pliku test.txt do zapisu!\n"); exit(1); } fprintf (fp, "%s", tekst); /* zapisz nasz łańcuch w pliku */ fclose (fp); /* zamknij plik */ return 0; }

46 Operacje na plikach FILE *fopen(const char *filename, const char *mode); Funkcja fopen() otwiera plik, którego nazwa podana jest w pierwszym argumencie. Drugim jest łańcuch znaków zwierający litery oznaczające sposób otwarcia pliku: "r" - otwiera plik do czytania "w" - otwiera plik do nadpisywania (zamazuje starą treść) "a" - otwiera plik do dopisywania (jeśli plik nie istnieje, to jest tworzony) "t" - otwiera plik w trybie tekstowym "b" - otwiera plik w trybie binarnym Litery można ze sobą łączyć, np. "rwb" albo "wt".

47 Operacje na plikach #include int main(int argc, char *argv[]) { FILE *fp; int c; if (argc < 2) { fprintf (stderr, "Uzycie: %s nazwa_pliku\n", argv[0]); exit (-1); } fp = fopen (argv[1], "w"); if (!fp) { fprintf (stderr, "Nie moge otworzyc pliku %s\n", argv[1]); exit (-1); } printf("Wcisnij Ctrl+D lub Ctrl+Z aby zakonczyc\n"); while ( (c = fgetc(stdin)) != EOF) { fputc(c, stdout); fputc(c, fp); } fclose(fp); return 0; }

48 Operacje na plikach Dzięki standardowym funkcjom języka C możemy m.in. określić długość pliku. Do tego celu służą funkcje fsetpos, fgetpos oraz fseek. Ponieważ przy każdym odczycie/zapisie z/do pliku wskaźnik niejako "przesuwa" się o liczbę przeczytanych/zapisanych bajtów. Możemy jednak ustawić wskaźnik w dowolnie wybranym miejscu. Do tego właśnie służą wyżej wymienione funkcje. Aby odczytać rozmiar pliku powinniśmy ustawić nasz wskaźnik na koniec pliku, po czym odczytać ile bajtów od początku pliku się znajdujemy. Procedura ta działa wyjątkowo prosto i skutecznie. Użyjemy do tego tylko dwóch funkcji: fseek oraz fgetpos. Pierwsza służy do ustawiania wskaźnika na odpowiedniej pozycji w pliku, a druga do odczytywania na którym bajcie pliku znajduje się wskaźnik.

49 Operacje na plikach #include int main (int argc, char **argv) { FILE *fp = NULL; fpos_t dlugosc; if (argc != 2) { printf ("Użycie: %s \n", argv[0]); return 1; } if ((fp=fopen(argv[1], "rb"))==NULL) { printf ("Błąd otwarcia pliku: %s!\n", argv[1]); return 1; } fseek (fp, 0, SEEK_END); /* ustawiamy wskaźnik na koniec pliku fgetpos (fp, &dlugosc); printf ("Rozmiar pliku: %d\n", dlugosc); fclose (fp); return 0; }


Pobierz ppt "Proceduralne Języki Programowania Patryk Jasik Katedra Fizyki Teoretycznej i Informatyki Kwantowej Wydział Fizyki Technicznej i Matematyki Stosowanej Politechnika."

Podobne prezentacje


Reklamy Google