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).