W katalogu domowym utworzyć podkatalog znaki2. Utworzyć w nim pliki Makefile i znaki.c postaci:
/* * znaki.c * * Zliczanie znakow z pliku. */ #include <stdio.h> #include <stdlib.h> int main(void) { FILE *plik1; char *nazwa = "p1.txt"; /* plik, ktorego znaki zliczamy */ int nc = 0; /* liczba znakow w pliku */ plik1 = fopen(nazwa, "r"); if (plik1 == NULL) { fprintf(stderr, "znaki: nie mozna otworzyc pliku %s\n", nazwa); exit(1); } while (fgetc(plik1) != EOF) ++nc; printf("Liczba znakow w pliku %s wynosi %d\n", nazwa, nc); if (fclose(plik1) != 0) { fprintf(stderr, "znaki: blad przy zamykaniu pliku %s\n", nazwa); exit(1); } return 0; }
Stworzyć plik tekstowy p1.txt, skompilować i uruchomić program.
Poprawić program, aby nazwa pliku była podawana jako argument programu.
Poprawić program z katalogu dzialania, aby operacje wykonywane przez użytkownika były zapisywane do pliku dzialania.log (wstawić argument "a" w funkcji fopen()).
Stworzyć program wczytujący dwie kolumny posortowanych liczb z dwóch plików i zapisujący jedną posortowaną kolumnę liczb (liczby z obu kolumn) do trzeciego pliku. Program powinien prawidłowo reagować również w przypadku pustych plików.
W katalogu domowym utworzyć podkatalog skrzynia. Utworzyć w nim pliki Makefile i skrzynia.c postaci:
/* * skrzynia.c * * Program ze strukturami. */ #include <stdio.h> int main(void) { struct skrzynia { char nazwa[30]; /* nazwa czesci */ int ilosc; /* ilosc czesci w skrzyni */ int cena; /* cena jednej czesci w groszach */ }; struct skrzynia skrzynia_zabawek = { /* inicjalizacja */ "zabawka", /* nazwa produktu */ 4, /* liczba zabawek w skrzyni */ 599 /* cena zabawki w groszach */ }; int wartosc; wartosc = skrzynia_zabawek.ilosc*skrzynia_zabawek.cena; printf("Ilosc zabawek w skrzyni: %d\n", skrzynia_zabawek.ilosc); printf("Cena zabawki w groszach: %d\n", skrzynia_zabawek.cena); printf("Wartosc zabawek w skrzyni w groszach: %d\n", wartosc); return 0; }
Skompilować i uruchomić program. Dopisać struktury dla innych produktów i wypisać o nich raport.
W katalogu domowym utworzyć podkatalog complex. Utworzyć w nim pliki Makefile i complex.c postaci:
/* * complex.c * * Program z liczbami zespolonymi. */ #include <stdio.h> struct complex_struct { double re; double im; }; typedef struct complex_struct Complex; /* wygodniejsza nazwa typu */ /* wg konwencji K i R piszemy z dużej litery */ Complex dodaj(Complex a, Complex b); int main(void) { Complex z1 = { 3.4, 1.2 }; Complex z2 = { 5.1, 5.5 }; Complex suma; suma = dodaj(z1, z2); printf("(%f, %f) + (%f, %f) = (%f, %f)\n", z1.re, z1.im, z2.re, z2.im, suma.re, suma.im); return 0; } Complex dodaj(Complex a, Complex b) { /* przekazywanie przez wartosc */ Complex s; s.re = a.re + b.re; s.im = a.im + b.im; return s; /* przekazywanie calej struktury */ }
Skompilować i uruchomić program. Dopisać funkcje realizujące odejmowanie, mnożenie i dzielenie liczb zespolonych.
W katalogu domowym utworzyć podkatalog screen. Utworzyć w nim pliki Makefile, main.c, main.h, oraz pozostałe dla każdej funkcji:
/* * main.h * * Plik naglowkowy. */ #include <stdio.h> #define max(a,b) ((a) < (b) ? (b) : (a)) #define min(a,b) ((a) < (b) ? (a) : (b)) struct point { /* struktura pojedynczego punktu */ int x; int y; }; struct rect { /* struktura prostokata */ struct point pt1; /* lewy dolny wierzcholek */ struct point pt2; /* prawy gorny wierzcholek */ }; struct point make_point(int x, int y); /* Tworzenie punktu */ struct rect canon_rect(struct rect r); /* Sprowadzanie prostokata do postaci "kanonicznej" */ void print_point(struct point pt); /* Rysowanie punktu */ void print_rect(struct rect r); /* Rysowanie prostokata */ int pt_in_rect(struct point p, struct rect r); /* Sprawdzanie, czy punkt nalezy do prostokata */
/* * make_point.c */ #include "main.h" struct point make_point(int x, int y) { struct point tmp; tmp.x = x; tmp.y = y; return tmp; /* przekazanie calej struktury */ }
/* * canon_rect.c * * Sprowadzanie prostokata do postaci "kanonicznej" - * trzymamy lewy dolny i prawy gorny punkt. */ #include "main.h" struct rect canon_rect(struct rect r) { /* przekazanie przez wartosc */ struct rect tmp; tmp.pt1.x = min(r.pt1.x, r.pt2.x); tmp.pt1.y = min(r.pt1.y, r.pt2.y); tmp.pt2.x = max(r.pt1.x, r.pt2.x); tmp.pt2.y = max(r.pt1.y, r.pt2.y); return tmp; /* przekazanie calej struktury */ }
/* * pt_in_rect.c * * Sprawdzanie, czy punkt nalezy do prostokata. * Gorna i prawa krawedz nie nalezy do prostokata. */ #include "main.h" int pt_in_rect(struct point p, struct rect r) { /* przekazanie przez wartosc */ if ( (p.x >= r.pt1.x) && (p.x < r.pt2.x) && (p.y >= r.pt1.y) && (p.y < r.pt2.y) ) return 1; /* punkt lezy wewnatrz protokata */ else return 0; /* punkt lezy na zewnatrz prostokata */ }
/* * main.c */ #include "main.h" int main(void) { const int XMAX = 80; const int YMAX = 20; struct rect screen; struct point middle, second; screen.pt1 = make_point(0, 0); screen.pt2 = make_point(XMAX, YMAX); middle = make_point((screen.pt1.x + screen.pt2.x)/2, (screen.pt1.y + screen.pt2.y)/2); print_rect(screen); print_point(middle); second = make_point(10, 20); print_point(second); if (pt_in_rect(second, screen) == 1) printf("Punkt wewnatrz prostokata\n"); else printf("Punkt na zewnatrz prostokata\n"); return 0; }
Dopisać brakujące funkcje. Skompilować i uruchomić program. Dopisać nowe funkcje, przykłady podane niżej.
int cmp_point(struct point a, struct point b); /* por. punktow */ int cmp_rect(struct rect r1, struct rect r2); /* porownywanie prostokatow */ int cmp_area(struct rect r1, struct rect r2); /* por. powierzchni -1|0|+1 */ int rect_area(struct rect r); /* pole pow. */ int is_empty(struct rect r); /* pole pow. 0 */ int is_subset(struct rect r1, struct rect r2); /* zawieranie */ struct rect intersection(struct rect r1, struct rect r2); /* przecięcie */ struct rect cover(struct rect r1, struct rect r2); /* prostokąt, który oba pokryje */
W katalogu kwadratowe poprawić program, aby wykorzystywał funkcję zwracającą strukturę
struct solution { int kod; /* kod rodzaju rozwiazania */ double p1, p2; /* dwa pierwiastki */ }; struct solution kwadratowe(double a, double b, double c); /* * Funkcja obliczająca pierwiastki równania kwadratowego * a * x * x + b * x + c = 0 * Wynik zapisywany jest do struktury. * Kody zwracane przez funkcję: * -1 - równanie sprzeczne * 0 - brak rozwiazań rzeczywistych * 1 - jeden pojedyńczy pierwiastek * 2 - jeden podwójny pierwiastek * 3 - dwa różne pierwiastki * 4 - nieskończona liczba rozwiązań */
Zapoznać się z programami z książki S. Oualline: COPY, FUN-FILE (znaleźć błąd - problem z \n), P_ARRAY (znaleźć błąd - tablice).