Programowanie strukturalne w C , pętle, instrukcje

background image

Programowanie strukturalne w

C++, pętle, instrukcje if, switch,

background image

Podstawowa budowa programu;
strumienie

Najprostszy program w C++, jaki jest, każdy

widzi:

#include <iostream>

using namespace

std;

int main()
{ // pierwszy program

cout

<<

"Hello, I'm Jan B.\n"

;

return

0;

}

// pierwszy program – pierwszy program w C++

to komentarz, czyli dowolny opis słowny. Jest on całkowicie

ignorowany przez kompilator, natomiast może być pomocny dla

piszącego i czytającego kod.

background image

Komentarze

piszemy w celu wyjaśnienia pewnych fragmentów kodu

programu, oddzielenia jednej jego części od drugiej, oznaczania funkcji
i modułów itp. Odpowiednia ilość komentarzy ułatwia zrozumienie
kodu, więc stosuj je często

W C++ komentarze zaczynamy od

//

(dwóch slashy), lub umieszczamy

je między /*

i */, na przykład:

/* Ten komentarz może być bardzo długi i składać się z kilku
linijek. */

background image

Rys.1. Translacja programu C++

background image

Funkcja

main()

Kiedy uruchamiamy nasz program, zaczyna on wykonywać kod

zawarty w funkcji main(). Od niej więc rozpoczyna się działanie aplikacji

– a nawet więcej: na niej też to działanie się kończy. Zatem program

(konsolowy) to przede wszystkim kod zawarty w funkcji main()

determinuje on bezpośrednio jego zachowanie.

Rys.2. Struktura funkcji main()

background image

W przypadku rozważanej aplikacji funkcja ta nie jest zbyt

obszerna, niemniej zawiera wszystkie niezbędne elementy.

Najważniejszym z nich jest nagłówek, który u nas prezentuje

się następująco:

W C++ Builder ta sama funkcja może mieć postać:

#include <iostream>
#include <conio.h>

//using namespace

std;

//int

main() // standard

void main()
{ // pierwszy program
std::

cout

<<

"Hello, I'm Jan B.\n"

;

getch();
// return 0; //standard
}

std::cout oznacza tak zwany strumień wyjścia. Jego

zadaniem jest wyświetlanie na ekranie konsoli wszystkiego, co doń

wyślemy – a wysyłać możemy oczywiście tekst.

background image

Korzystanie z tego strumienia umożliwia zatem pokazywanie nam w oknie

konsoli wszelkiego rodzaju komunikatów i innych informacji. Będziemy go

używać bardzo często, dlatego musisz koniecznie zaznajomić się ze

sposobem wysyłania doń tekstu.

Dołączanie plików nagłówkowych

#include

<iostream>

#include

<conio.h>

Linijki które wcale nie są tak straszne, jak wyglądają na pierwszy rzut

oka. Przede wszystkim zauważmy, że zaczynają się one od znaku

#

,

czym niewątpliwie różnią się od innych instrukcji języka C++. Są to

bowiem specjalne polecenia wykonywane jeszcze przed kompilacją - tak

zwane dyrektywy. Przekazują one różne informacje i komendy,

pozwalają więc sterować przebiegiem kompilacji programu.

background image

Pliki nagłówkowe

umożliwiają korzystanie z pewnych funkcji, technik,

bibliotek itp. wszystkim programom, które dołączają je do swojego kodu
źródłowego.

Preprocesor 

"Chiałbym się kiedyś dowiedzieć, że preprocesor został usunięty.

Jednak jedyny realny i odpowiedzialny sposób, który może do tego

doprowadzić, polega na tym, żeby najpierw sprawić, że stanie się zbędny,

po czym zachęcić ludzi do używania jego lepszych odpowiedników."

Bjarne Stroustrup

Preprocesor

to specjalny mechanizm języka, który przetwarza tekst

programu jeszcze przed jego kompilacją

.

background image
background image

Rys. Linkowanie (łączenie) tworzy wolny od luki kod
wykonywalny

background image

Zwyczajowy przebieg budowania programu

W

języku

programowania

nieposiadającym

preprocesora

generowanie docelowego pliku z programem przebiega, jak wiemy, w

dwóch etapach.

Pierwszym jest kompilacja, w trakcie której kompilator przetwarza

kod źródłowy aplikacji i produkuje skompilowany kod maszynowy,

zapisany w osobnych plikach. Każdy taki plik - wynik pracy

kompilatora - odpowiada jednemu modułowi kodu źródłowego.

W drugim etapie następuje linkowanie (łączenie) skompilowanych

wcześniej modułów oraz ewentualnych innych kodów, niezbędnych do

działania programu. W wyniku tego procesu powstaje gotowy

program.

background image

Rys. Najprostszy proces budowania programu z kodu

źródłowego

background image

Przy takim modelu kompilacji zawartość każdego modułu musi

wystarczać do jego samodzielnej kompilacji, niezależnej od innych

modułów. W przypadku języków z rodziny C oznacza to, że każdy moduł

musi zawierać deklaracje używanych funkcji oraz definicje klas, których

obiekty tworzy i z których korzysta.

Gdyby zadanie dołączania tych wszystkich deklaracji spoczywało na

programiście, to byłoby to dla niego niezmiernie uciążliwe. Pliki z kodem

zostały ponadto rozdęte do nieprzyzwoitych rozmiarów, a i tak

większość zawartych weń informacji przydawałyby się tylko przez

chwilę. Przez tą chwilę, którą zajmuje kompilacja modułu.

Nic więc dziwnego, że aby zapobiec podobnym irracjonalnym

wymaganiom wprowadzono mechanizm preprocesora.

background image

Dodajemy preprocesor

Ujawnił się nam pierwszy cel istnienia preprocesora: w języku C(+

+) służy on do łączenia w jedną całość modułów kodu wraz z
deklaracjami, które są niezbędne do działania tegoż kodu. A skąd
brane są te deklaracje?… Oczywiście - z plików nagłówkowych.
Zawierają one przecież prototypy funkcji i definicje klas, z jakich
można korzystać, jeżeli dołączy się dany nagłówek do swojego
modułu.

Jednak kompilator

nic nie wie

o plikach nagłówkowych. On tylko

oczekuje, że zostaną mu podane pliki z kodem źródłowym, do którego
będą się zaliczały także deklaracje pewnych zewnętrznych elementów
- nieobecnych w danym module.

Kompilator potrzebuje tylko ich

określenia „z wierzchu”, bez wnikania w implementację, gdyż ta może
znajdować się w innych modułach lub nawet innych bibliotekach i staje
się ważna dopiero przy linkowaniu

. Nie jest już ona sprawą kompilatora

- on żąda tylko tych informacji, które są mu potrzebne do kompilacji.

Niezbędne deklaracje powinny się znaleźć na początku każdego

modułu

. Trudno jednak oczekiwać, żebyśmy wpisywali je ręcznie w

każdym module, który ich wymaga. Byłoby to niezmiernie uciążliwe,
więc wymyślono w tym celu pliki nagłówkowe… i preprocesor. Jego
zadaniem jest tutaj połączenie napisanych przez nas modułów oraz
plików nagłówkowych w pliki z kodem, które mogą być bez przeszkód
przetworzone przez kompilator.

background image

Rys. Budowanie programu C++ z udziałem preprocesora

background image

Skąd preprocesor wie, jak ma to zrobić?… Otóż, mówimy o tym

wyraźnie, stosując dyrektywę

#include

. W miejscu jej pojawienia się

zostaje po prostu wstawiona treść odpowiedniego pliku nagłówkowego.

Włączanie nagłówków nie jest jednak jedynym działaniem

podejmowanym przez preprocesor. Gdyby tak było, to przecież nie

poświęcalibyśmy mu całego rozdziału. Jest wręcz przeciwnie:

dołączanie plików to tylko jedna z czynności, jaką możemy zlecić temu

mechanizmowi - jedna z wielu czynności…

Wszystkie zadania preprocesora są różnorodne, ale mają też kilka

cech wspólnych. Przyjrzyjmy się im w tym momencie.

background image

Dyrektywy

Polecenie dla preprocesora nazywamy jego dyrektywą (ang.

directive). Jest to specjalna linijka kodu źródłowego, rozpoczynająca się

od znaku

#

(hash), zwanego płotkiem:

#.

Na nim też może się zakończyć

- wtedy mamy do czynienia z dyrektywą pustą. Jest ona ignorowana

przez preprocesor i nie wykonuje żadnych czynności.

Przed hashem mogą znajdować się wyłącznie tzw. białe znaki, czyli

spacje lub tabulatory. Zwykle nie znajduje się nic.

 

Bardziej praktyczne są inne dyrektywy, których nazwy piszemy zaraz

za znakiem

#

. Nie oddzielamy ich zwykle żadnymi spacjami (choć można

to robić), więc w praktyce płotek staje się częścią ich nazw. Mówi się więc

o instrukcjach

#include

,

#define

,

#pragma

i innych, gdyż w takiej

formie zapisujemy je w kodzie.

Dalsza część dyrektywy zależy już od jej rodzaju. Różne „parametry”

dyrektyw poznamy, gdy zajmiemy się szczegółowo każdą z nich.

background image

Dyrektywy preprocesora kończą się zawsze przejściem do następnego
wiersza.

Zapamiętaj!

Nie kończ dyrektyw preprocesora średnikiem. Nie są to przecież
instrukcje

języka

programowania,

lecz

polecenia

dla

modułu

wspomagającego kompilator

.

background image

Oto pliki należące do standardowej biblioteki C (włącznie z ISO C 9X).
assert.h - makra do asercji
ctype.h -klasyfikacje znaków typu char (isspace, isalpha itd.)
errno.h - deklaracja errno
fenv.h - środowisko dla liczb zmiennoprzecinkowych (ISO C 9X)
float.h - definicje specjalne dla liczb zmiennoprzecinkowych
limits.h - makra określające granice dla typów ścisłych
locale.h - definicje lokali
math.h - funkcje matematyczne
setjmp.h - funkcje setjmp i longjmp
signal.h
- sygnały
stdarg.h - narzędzia dla funkcji o zmiennej liście parametrów
stddef.h - standardowe definicje (ptrdiff_t i size_t głównie)
stdio.h - operacje wejścia/wyjścia
stdlib.h - zespół funkcji użytkowych
string.h - funkcje operujące na tablicach znaków
time.h - narzędzia do odczytywania, interpretacji i prezentacji czasu
wchar.h - obsługa "szerokiego" (wide-char) zestawu znaków
wctype.h - wersja `ctype.h' dla szerokich znaków

background image
background image

Dyrektywa #define

Dyrektywa ta pozwala tworzyć makrodefinicje. Pozwala ona zastąpić
dowolny ciąg znaków (również pusty) identyfikatorem. Może służyć
np. do definiowania stałych:

#define przyciaganie_ziemskie 9.81
Taka makrodefinicja może również posiadać argumenty, np.
#define ctg( x ) 1/tan( x )
Znajomość tej dyrektywy raczej nie będzie Ci potrzebna; najwyżej

do tego, żeby wiedzieć, co to jest. Jest to uniwersalne dosyć
narzędzie, ale bardzo niebezpieczne i dające mnóstwo okazji do
popełniania błędów.

Kompilator nie stwierdzi błędu w definicji makra (jeśli np. zdefiniujesz
jako desygnat makra jakąś konstrukcję, która jest niepoprawna
składniowo w C++), a ewentualnie dopiero w miejscu, gdzie zostało ono
użyte (kompilator nie widzi makr ani ich używania; preprocesor jest
właśnie od tego, żeby je usuwać).

W przypadku zastępowania nimi

wyrażeń arytmetyczno-logicznych należy używać dla pewności jak
najwięcej nawiasów, oraz - o czym też wielu zapomina - NIE WOLNO
używać

żadnych

operatorów

modyfikujących

na

zmiennych

przekazywanych jako parametry makra

(tzn. jako argumenty makra

należy podawać wartości lub zmienne raczej, niż wyrażenia).

Jednym też

z typowych błędów jest zakończenie tej dyrektywy średnikiem

.

background image

Kompilacja warunkowa

Podstawową dyrektywą warunkową jest

#if

. Jako argument przyjmuje

ona warunek, który ma być spełniony (pamiętaj jednak, że interpretuje
go preprocesor, a nie kompilator!). Najczęściej jednak do kompilacji
warunkowej stosuje się makrowartowniki. Są to puste makra,
definiowane w plikach nagłówkowych, dla np. zabezpieczenia przed
kilkakrotnym wstawianiem tego samego pliku. Sprawdzenia tego
dokonujemy dyrektywami #ifdef i #ifndef, czasem używa się też #if
i funkcji preprocesora defined():
#ifndef __STDLIB_H
lub
#if !defined( __STDLIB_H )
i dalej:
#define __STDLIB_H ... (tutaj deklaracje) #endif

background image

Inne dyrektywy

Znacznie rzadziej są w programach używane dyrektywy takie, jak:

1. #error

- powoduje wyrzucenie błędu kompilacji z podanym jako

argument komunikatem (używane tylko wespół z dyrektywami

warunkowymi),

2. #pragma

- zmienia ustawienia kompilatora (użycie tej dyrektywy

zależy wyłącznie od implementacji)

3. #line

- udaje, że następna linia jest inną linią z innego pliku

Dyrektywa pusta (składająca się tylko ze znaku `#') jest dopuszczalna i

nie daje żadnego efektu

background image

Instrukcje i bloki

Instrukcja prosta jest to wyrażenie występujące w przeznaczonym dla

niego miejscu i zakończone średnikiem. Instrukcja złożona zaś, zwana też

blokiem, jest to jedna lub więcej instrukcji prostych, ujętych w

{ }.

Blok

taki -

proszę pamiętać

-

posiada już osobny, lokalny zasięg

;

toteż

identyfikatory w nim definiowane mają zasięg tylko wewnątrz tego bloku i

mogą "przysłaniać

" (ang. hide)

identyfikatory znajdujące się w wyższym

zasięgu.

No to może tak mały przykład:

Zauważ, że zadeklarowano zmienną w wyrażeniu będącym

argumentem instrukcji

if.

W C++ jest to dopuszczalne, ale proszę się

jednak starać tego nie nadużywać. Zmienna ‘a' jak widać jednak, ma
zasięg tylko dla instrukcji podporządkowanej

if

(jest podana instrukcja

prosta, ale można też podać złożoną, tak jak w każdym przypadku).
Podobnie jest ze wszystkimi tego typu instrukcjami.

Jak widać, mamy trzy różne zmienne x o różnych zasięgach.

Ponieważ zdarza się deklarować zmienne lokalne o takich samych
nazwach, jak globalne, dlatego istnieje operator ::, zwany operatorem
zasięgu. Jego jednoargumentowa (przedrostkowa) postać nakazuje
uzyskać identyfikator z najwyższego zasięgu.

background image

#include <iostream>
using namespace std;
int x = 5;int main()
{ //
blok funkcji main
int x = 0; //
zmienna lokalna dla bloku funkcji main
{ // lokalny blok
int x = 2; cout << "Wewnętrzna: " << x << endl;
}
cout << "Lokalna: " << x << endl;
cout << "Globalna: " << ::x << endl;
if ( int a = x + 2 > 0 ) cout << a << endl; //
instrukcja

podporządkowana if ( ) return 0;}

Operator ::

ten istniał już w

C

, ale tylko jako operator

jednoargumentowy, czyli o takim znaczeniu, jakie tu zostało podane.
Później poznamy ten operator w wersji dwuargumentowej. W
przeciwieństwie do swojego jednoargumentowego przodka, ten
dwuargumentowy jest operatorem jednym z częściej używanych w

C+

+.

Nadal zresztą nazywa się operatorem zasięgu

background image

Instrukcje sterujące

Słowa
kluczowe C++

background image

Program byłby „głupi”, gdyby przebiegał krokowo od początku do

końca. Dlatego też w programie praktycznie zawsze używa się instrukcji

sterujących, na które składają się:

 instrukcje odgałęzienia warunkowego: if, else ;
 pętle: while, do-while, for
 instrukcje przełączające: switch/case;
 instrukcje skoku: goto, break, continue;
 instrukcja powrotu z funkcji, return.

if

( <warunek> )

{nstr}

else

{instr}

Oczywiście

else

z całą resztą jest opcjonalne.

if

background image

Przejdźmy zatem do pętli. Najprostszą pętlą z wyrażeniem

warunkowym jest pętla

`while

':

while ( <warunek> )
<instr>

Instrukcja ta nakazuje powtarzać <instr> dopóki spełniony jest

<warunek>. Zwraca się uwagę, że <warunek> sprawdzany jest na
początku, a więc przed pierwszym wejściem i każdym następnym
powtórzeniem. Nieco inne możliwości prezentuje nam pętla do-while:

Pętla

while

może nie wykonać się ani razu, jeżeli jej warunek będzie od

początku nieprawdziwy.

do
{
<instr>
}while ( warunek );
Tu <warunek> sprawdzany jest na końcu pętli, toteż pętla wykona się

bezwzględnie co najmniej raz.

background image

Rysunek Działanie przykładowej pętli

do

for

( int i = 0; i < 5; i++ )

{
//instrukcje
….
…..
}

background image

for (;;)

{ // tu coś robimy...
// tu trzeba sprawdzić warunek
// i przerwać... tylko jak? // (dalej)
}

Pętla nieskończona

Do przerywania wykonywania pętli służy instrukcja

break

. Może

być ona używana w dowolnej pętli i powoduje wykonanie skoku do

pierwszej instrukcji za pętlą. Jeśli zależy nam z kolei na skoku na

początek bieżącej pętli, służy do tego celu słowo

continue

. Proszę

pamiętać jednak że słowo

continue

ma zupełnie inne znaczenie dla

pętli

while

i

do-while

, niż dla pętli for! W przypadku tych pierwszych

powoduje normalny skok na początek pętli, podczas gdy w ‘for'

powoduje przejście do następnej iteracji. W praktyce więc skacze do

wyrażenia <next> i dopiero potem jest sprawdzany <warunek>.

background image

switch

( <wartość> )

{
case <jedna_możliwość>: <instr> <instr> ...
case <druga_możliwość>: <instr> <instr> ...
default: <instr> <instr> ...
}

W większości przypadków należy zatem kończyć fragment kodu
rozpoczęty przez

case

instrukcją

break

- gwarantuje to, iż tylko jedna z

możliwości ustalonych w

switch

zostanie wykonana.

Pytanie?, co się stanie, kiedy umieszczę

continue

wewnątrz

switch

(pytanie sugeruje, że switch rozpocznie sprawdzanie od

początku). Najlepsza odpowiedź: po prostu, continue może się

pojawić tylko wewnątrz pętli ;*).

Instrukcja continue w ogóle nie ma związku ze switch

.

background image

Instrukcja przełączająca

switch

porównuje po kolei <wartość> z

kolejnymi wariantami. Etykieta default - jak się zapewne można

domyślać - jest miejscem skoku w przypadku gdy <wartość> nie pasuje

do żadnego wariantu.

Dlaczego radzę się jej wystrzegać? Dlatego, że jest bardzo prosta i

zachęcająca w stosowaniu do tego stopnia, że

większość programujących

zapomina o tym, że bywa powolna

.

Postawowe operacje wejścia/wyjścia; biblioteka
stdio

Ta biblioteka zawiera operacje na plikach, w tym również na konsoli.
Typem danej, na którym się tutaj operuje jest

FILE

. Jest to struktura,

do której nie warto zaglądać (może być na każdym systemie
zdefiniowana inaczej, aczkolwiek nie ma problemu; w C NIE DA się
niczego ukryć). Wiemy tylko tyle, że na niej operuje większość
podanych tu funkcji. Oczywiście należy pamiętać, że ową strukturę
otrzymujemy od funkcji f

open

przy otwieraniu pliku i przekazać

musimy do

fclose

chcąc go zamknąć (oczywiście przez wskaźnik).

background image

Język C/C++ nie ma wbudowanych żadnych instrukcji
umożliwiających wykonywanie operacji wejścia-wyjścia ! Służą
do tego funkcje biblioteczne

.

Funkcje zawarte w bibliotece < io.h >

Dostęp do pliku za pomocą uchwytu (ang. Handle) - operacje niskiego
poziomu
1

. Funkcje otwierania (zwraca uchwyt pliku) oraz zamknięcia pliku

int open

( const char ∗nazwa_pliku, int tryb_dostepu )

int close

( int handle )

2

. Funkcje zapisu i odczytu z pliku

int write

( int handle, void ∗adres_bufora, unsigned ilosc_bajtow )

int read

( int handle, void ∗adres_bufora, unsigned ilosc_bajtow );

3.

Funkcje pomocnicze

int eof

( int handle ) // zwraca 1 gdy „END OF FiILE”

wskaźnika pliku

long tell

( int handle ) // zwraca pozycję

long filelength

( int handle ) // zwraca długosć pliku w bajtach

long lseek

( int handle, long przesuniecie, int względem_czego )

// przesuwa wskaźnik względem zadanego miejsca: pliku o
zadaną ilość
//bajtów

background image

SEEK_SET

- względem początku pliku

SEEK_CUR

- względem aktualnej pozycji

SEEK_END

- względem końca pliku

Przykład
int plik;
char tekst[ ] = ”To jest tekst zapisywany i odczytywany z pliku”;
char znak;
plik = open( ”test.dat”, O_CREAT | O_RDWR );
write( plik, tekst, strlen( tekst ) ); // zapis zawartosci tekstu do
pliku
lseek( plik, 0L, SEEK_SET ); // przesuniecie wskaźnika na
poczatek

do
{ // odczyt po jednym znaku aż do napotkania eof
read( plik, &znak, 1);
printf( ”%c”, znak ); // wydruk odczytanego znaku na ekranie
} while ( !eof( plik ) );
close( plik );

background image

Przede wszystkim, na razie skorzystamy z trzech

podstawowych strumieni plikowych, które są predefiniowane
(jako stałe typu FILE*):

stdin

- "standardowe wejście; //konsola klawiatura

stdout

- "standardowe wyjście„;//konsola -monitor

stderr

- "standardowe wyjście diagnostyczne

"

stdprn

− strumień drukarki

Przy uruchamianiu programów na konsoli, stdin to

wejście z klawiatury, a stdout i stderr są kierowane na
ekran. Oczywiście przy uruchamianiu programu można
dokonać przekierowania, jeśli wywołujemy program przez
polecenie w linii komend ( < dla stdin i > dla stdout;
unixowe powłoki pozwalają też na przekierowanie stderr, np.
w sh i pochodnych jest to 2>).

background image

Funkcje otwarcia (zwraca wskaźnik na FILE) oraz zamknięcia pliku

FILE ∗ fopen

( char ∗nazwa_pliku, char ∗rodzaj_operacji )


rodzaj operacji:--

− r

- tylko do odczytu

w

- tylko do zapisu (utworzenie nowego)

a

- dopisywanie na końcu

+

- z możliwością aktualizacji

b

− otwarcie jako plik binarny

t

−otwarcie jako plik tekstowy

background image

Przykład

FILE ∗plik

; // utworzenie pliku binarnego z możliwoscia

aktualizacji

plik = fopen

( ”a:\\wyniki.dat”, ”w+b” );

if( plik == NULL ) // kontrola błędów we/wy
{
printf( ”Blad otwarcia pliku wyników” );
return -1
}

int fclose

( FILE ∗strumien ) // zamknięcie wskazanego

strumienia

int fcloseall

(void ) // zamknięcie wszystkich strumieni

background image

Zapis danych do strumienia

int fputc

( int znak, FILE∗ strumien ) // wysłanie

pojedynczego znaku

fputs

( char tekst, FILE strumien ) // int wysłanie

łańcucha znaków

int fprintf

( FILE ∗ strumien, char format, . . . )

// funkcja sformatowanego wyjscia analogiczna do
printf( )
i

nt fwrite

( void adres_w_pamieci,

size_t

rozmiar_bloku,

size_t

ilosc_blokow,

FILE ∗ strumien)
// funkcja kopiujca (ilosc_blokow*rozmiar_bloku)
bajtów
spod wskazanego obszaru pamięci do strumienia
(pliku)

background image

Przykład

#include <stdio.h>
struct T_student
{
char nazwisko[31];
char imie[16];
int wiek;
};
//--------------------------------------------------------
void main( void )
{
FILE *strumien;
T_student baza_danych[10];
int ilosc;
if ( (strumien = fopen( ”test.bin” , ”wb” ) ) != NULL )
{ // zapis zawartości zawartosci bazy ( tablicy struktur) do pliku
binarnego
fwrite( baza_danych, sizeof(T_student), 10 , strumien);
ilosc++;
fclose( strumien );
}

background image

if ( (strumien = fopen( ”test.txt” , ”wt” ) ) != NULL )
{ // zapis zawartości calej bazy ( tablicy struktur) do pliku
tekstowego
for( int i = 0; i < 10; i++ )
fprintf ( strumien, ”%s %s %d \n”, baza_danych[ i ].nazwisko,
baza_danych[ i ].imie, baza_danych [ i ].wiek );
fclose( strumien );
}
}

Ciąg dalszy programu

background image

Funkcje pomocnicze

int feof

( FILE ∗strumien ) // testowanie osiągnięcia końca

pliku

int fseek

( FILE ∗strumien, long przesuniecie, int wzgledem) //

przesuwa
//wskaźnik względem zadanego miejsca:

SEEK_SET

- względem początku pliku

SEEK_CUR

- względem aktualnej pozycji

SEEK_END

- względem końca pliku

long ftell

( FILE ∗strumien ) // zwraca aktualną pozycję

wskaźnika pliku

int fflush

( FILE ∗strumien ) // „wymiata” bufor wskazanego

strumienia

int flushall

( void ) // j.w.dla wszystkich buforowanych

strumieni

Przykład

// funkcja wyznaczająca pozycję maksymalnej liczby double w pliku
binarnym

background image

#include <stdio.h>
long Maksimum( char *nazwa_pliku )
{
FILE *plik_danych;
long pozycja=0, poz_max = -1;
double liczba, maksimum;
if ( (plik_danych = fopen( nazwa_pliku , ”rb” ) ) != NULL )
{
while( fread( &liczba, sizeof(double), 1, plik_danych) == 1)
{
if( pozycja == 0 )
{
maksimum = liczba; poz_max = 0; }
else
if( liczba > maksimum )
{
maksimum = liczba; poz_max = pozycja;
}
pozycja++;
}
fclose( strumien );
}
return poz_max ;
}

background image

Document Outline


Wyszukiwarka

Podobne podstrony:
Kopia Programowanie strukturalne w C , pętle, instrukcje
Programowanie strukturalne w C
plikus pl Programowanie strukturalne, Wyklad z C
petle, Instrukcja for
Programowanie strukturalne i obiektowe Podręcznik do nauki zawodu technik informatyk
key pro m8 auto key programmer update token instruction
dokumentacja, Zasady Programowania Strukturalnego (ZAP)
Zmienne tablicowe, INFORMATYKA, INFORMATYKA sem. III, 2.Prograowanie strukturalne i obiektowe
Programowanie strukturalne i obiektowe Podrecznik do nauki zawodu technik informatyk prstko
BLOKI, Programowanie strukturalne i obiektowe, C ++, Ćwiczenia C++ (skan)
Programowanie opracowanie, Informatyka, Informatyka semestr II, 3.Programowanie strukturalne i obiek
ALGORYTMY-PREZENTACJA, SZKOLNE PLIKI-mega zbiory (od podstawówki do magisterki), Programowanie struk
Programowanie strukturalne i obiektowe Podrecznik do nauki zawodu technik informatyk prstko 2

więcej podobnych podstron