108. NCP koji izracunava obim i povrsinu trougla i kvadrata.
/* Program uvodi strukture - geometrijske figure */
#include <stdio.h>
/* Zbog funkcije sqrt. */
#include <math.h>
/* Podsecanje : pod linux-om je potrebno program prevoditi sa
gcc -lm primer.c
kada god se koristi <math.h>
*/
/* Tacke su predstavljene sa dve koordinate. Strukturom gradimo novi tip podataka. */
struct point
{
int x;
int y;
};
/* Izracunava duzinu duzi zadatu sa dve tacke */
float segment_length(struct point A, struct point B)
{
int dx = A.x - B.x;
int dy = A.y - B.y;
return sqrt(dx*dx + dy*dy);
}
/* Izracunava povrsinu trougla Heronovim obrascem.
Argumenti funkcije su tri tacke koje predstavljaju temena trougla */
float Heron(struct point A, struct point B, struct point C)
{
/* Duzine stranica BC, AC, AB*/
float a = segment_length(B, C);
float b = segment_length(A, C);
float c = segment_length(A, B);
/* Poluobim */
float s = (a+b+c)/2;
/*Heronov obrazac */
return sqrt(s*(s-a)*(s-b)*(s-c));
}
/* Izracunava obim poligona. Argumenti funkcije su niz tacaka(niz struktura point)
koje predstavljaju temena poligona kao i njihov broj */
float circumference(struct point polygon[], int num)
{
int i; /*brojac u ciklusu */
float o = 0.0; /*obim */
/* Dodajemo duzine stranica koje spajaju susedna temena */
for (i = 0; i<num-1; i++)
o += segment_length(polygon[i], polygon[i+1]);
/* Dodajemo duzinu stranice koja spaja prvo i poslednje teme */
o += segment_length(polygon[num-1], polygon[0]);
return o;
}
/* Izracunava povsinu konveksnog poligona. Argumenti funkcije su niz tacaka koje predstavljaju temena poligona kao i njihov broj */
float area(struct point polygon[], int num)
{
float a = 0.0; /* Povrsina */
int i; /* brojacka promenljiva */
/* Poligon delimo na trouglove i posebno izracunavamo povrsinu svakoga od njih */
for (i = 1; i < num -1; i++)
a += Heron(polygon[0], polygon[i], polygon[i+1]);
return a;
}
main()
{
/* Definisemo dve promenljive tipa tacke */
struct point a;
/* Inicijalizujemo tacku b na (1,2) */
struct point b = {1, 2};
/* triangle je niz od tri tacke - trougao (0,0), (0,1), (1,0) */
struct point triangle[3];
/* square je niz od cetiri tacke - jedinicni kvadrat.
Obratiti paznju na nacin inicijalizacije niza struktura */
struct point square[4] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
/* Postavljamo vrednosti koordinata tacke a*/
a.x = 0; a.y = 0;
/* Gradimo trougao (0,0), (0,1), (1,0) */
triangle[0].x = 0; triangle[0].y = 0;
triangle[1].x = 0; triangle[1].y = 1;
triangle[2].x = 1; triangle[2].y = 0;
/* Ispisujemo velicinu strukture tacka */
printf("sizeof(struct point) = %d\n", sizeof(struct point));
/* Ispisujemo vrednosti koordinata tacaka */
printf("x koordinata tacke a je %d\n", a.x);
printf("y koordinata tacke a je %d\n", a.y);
printf("x koordinata tacke b je %d\n", b.x);
printf("y koordinata tacke b je %d\n", b.y);
printf("Obim trougla je %f\n",
circumference(triangle, 3));
printf("Obim kvadrata je %f\n",
circumference(square, 4));
printf("Povrsina trougla je %f\n",
Heron(triangle[0], triangle[1], triangle[2]));
/* Broj tacaka je moguce odrediti i putem sizeof */
printf("Povrsina kvadrata je %f\n",
area(square, sizeof(square)/sizeof(struct point)));
}
Izlaz:
sizeof(struct point) = 8
x koordinata tacke a je 0
y koordinata tacke a je 0
x koordinata tacke b je 1
y koordinata tacke b je 2
Obim trougla je 3.414214
Obim kvadrata je 4.000000
Povrsina trougla je 0.500000
Povrsina kvadrata je 1.000000
109. NCP koji postavlja vrednosti koordinata tacke u 2-dimenzionoj ravni i ispisuje te koordinate. (Ilustracija koriscenja typedef.)
/* Koriscenje typedef radi lakseg rada */
#include <stdio.h>
#include <math.h>
/* Ovim se omogucava da se nadalje u programu umesto int moze koristiti ceo_broj */
typedef int ceo_broj ;
/* Ovim se omogucuje da se nadalje u programu umesto struct point moze koristiti POINT */
typedef struct point POINT;
struct point
{
int x;
int y;
};
main()
{
/* Umesto int mozemo koristiti ceo_broj */
ceo_broj x = 3;
/* Definisemo promenljivu tipa tacke. Umesto struct point mozemo koristiti POINT */
POINT a;
printf("x = %d\n", x);
/* Postavljamo vrednosti koordinata tacke a*/
a.x = 1; a.y = 2;
/* Ispisujemo velicinu strukture tacka */
printf("sizeof(struct point) = %d\n", sizeof(POINT));
/* Ispisujemo vrednosti koordinata tacaka */
printf("x koordinata tacke a je %d\n", a.x);
printf("y koordinata tacke a je %d\n", a.y);
}
Izlaz:
x = 3
sizeof(struct point) = 8
x koordinata tacke a je 1
y koordinata tacke a je 2
110. NCP koji unosi sa standardnog ulaza unosi dva kompleksna broja (Realni, Imaginarni deo) i ispisuje na standardni izlaz njihov zbir, razliku, proizvod, kolicnik. Ako je drugi broj 0, onda prekinuti dalje ucitavanje i ispis (deljenje nulom!!!) i ispisati vrednost imaginarne jedinice(0+i).
/* STRUKTURE */ #include <math.h> /*zbog pow(x,2) */ #include <stdio.h> typedef struct { double re, im; } Kompl; /* Struktura kompleksnog broja. */ /*alternativa: struct KB { double re, im; }; typedef struct KB Kompl ; */ Kompl zbir (Kompl a, Kompl b); /*funkcija racuna a+b, kao rezultat vraca strukturu, tj. kompleksan broj */ Kompl razlika (Kompl a, Kompl b); /* a-b */ Kompl proizvod (Kompl a, Kompl b); /* funkcija racuna a*b, kao rezultat vraca strukturu, tj. kompleksan broj */ Kompl kolicnik (Kompl a, Kompl b) ; /* a/b */ main () { Kompl x, y, z; Kompl j = {0, 1}; /*primer eksplicitnog zadavanja polja strukture Kompl: prvo polje re=0, drugo polje im=1 */ /*ucitavanje dva kompleksna broja - brojevi sa tastature se unose u polja strukture */ while (1) { printf ("\nUnesite prvi broj x- Re, Im: "); scanf ("%lf%lf", &x.re, &x.im); printf ( "Unesite drugi broj y- Re, Im: "); scanf ("%lf%lf", &y.re, &y.im); if (y.re==0 && y.im==0) break; /*bez deljenja nulom */ printf ("x = (%f,%f)\n", x.re, x.im); printf ("y = (%f,%f)\n", y.re, y.im); z = zbir (x, y); printf ("x+y = (%f,%f)\n", z.re, z.im); z = razlika (x, y); printf ("x-y = (%f,%f)\n", z.re, z.im); z = proizvod (x, y); printf ("x*y = (%f,%f)\n", z.re, z.im); z = kolicnik (x, y); printf ("x/y = (%f,%f)\n", z.re, z.im); } z = proizvod (j, j); printf ("\nj^2 = (%f,%f)\n", z.re, z.im); } Kompl zbir (Kompl a, Kompl b) { a.re += b.re; a.im += b.im; return a; } Kompl razlika (Kompl a, Kompl b) { a.re -= b.re; a.im -= b.im; return a; } Kompl proizvod (Kompl a, Kompl b) { Kompl c; c.re = a.re * b.re - a.im * b.im; c.im = a.im * b.re + a.re * b.im; return c; } Kompl kolicnik (Kompl a, Kompl b) { Kompl c; double d = pow(b.re, 2) + pow(b.im, 2); c.re = (a.re*b.re + a.im*b.im)/d; c.im = (a.im*b.re - a.re*b.im)/d; return c; }
111. Strukture
se u funkcije cesto prenose po referenci. Moguce je koristiti
pokazivace na strukture.
Sta
je rezultat rada sledeceg programa?
#include <stdio.h>
typedef struct point
{
int x, y;
} POINT;
/* Zbog prenosa po vrednosti tacka ne moze biti ucitana */
void get_point_wrong(POINT p)
{
printf("x = ");
scanf("%d", &p.x);
printf("y = ");
scanf("%d", &p.y);
}
/* Koriscenjem prenosa preko pokazivaca, uspevamo */
void get_point(POINT* p)
{
/* p->x je skraceni zapis za (*p).x */
printf("x = ");
scanf("%d", &p->x);
printf("y = ");
scanf("%d", &p->y);
}
main()
{
POINT a = {0, 0};
printf("get_point_wrong\n");
get_point_wrong(a);
printf("a: x = %d, y = %d\n", a.x, a.y);
printf("get_point\n");
get_point(&a);
printf("a: x = %d, y = %d\n", a.x, a.y);
}
112. NCP koji sa standardnog ulaza ucitava dva pravougaonika u ravni A, B i na standardni izlaz ispisuje povrsinu preseka pravougaonika, povrsinu unije pravougaonika, povrsinu razlike pravougaonika(A\B). Pravougaonik se zadaje preko x,y koordinata donjeg levog i gornjeg desnog temena pravougaonika. Stranice pravougaonika su paralelne koordinatnim osama. Ucitavanje paravougaonika, nalazenje preseka dva pravougaonika i izracunavanje povrsine pravougaonika izdvojiti u posebne funkcije!!!
#include <stdio.h> #include <stdlib.h> typedef struct _rect { float x,y; /*koordinate donjeg levog ugla */ float x1,y1; /*koordinate gornjeg desnog ugla */ } Pravougaonik ; void ucitavanje (Pravougaonik *P); /*ucitavanje donjeg levog i gornjeg desnog temena pravougaonika */ Pravougaonik Presek(Pravougaonik *A, Pravougaonik *B); /*presek pravougaonika A i pravougaonika B */ float Povrsina (Pravougaonik *A); /*izracunavanje povrsine datog pravougaonika */ main() { Pravougaonik A,B ; /*zadati pravougaonici */ Pravougaonik presekAB ; /*presek zadata dva pravougaonika */ float povrsinaA; /*povrsina pravougaonika A*/ float povrsinaB; /*povrsina pravougaonika B*/ float povrsAB; /*povrsina preseka pravougaonika A i pravougaonika B*/ /*ucitavanja pravougaonika sa standardnog ulaza */ ucitavanje(&A); ucitavanje(&B); /*odredjivanje A*B */ presekAB = Presek (&A , &B); /*izracunavanje povrsine datih pravougaonika i njihovog preseka */ povrsinaA=Povrsina(&A); povrsinaB=Povrsina(&B); povrsAB= Povrsina (&presekAB); /*ispis rezultata */ printf( "Povrsina unije : %g\n", povrsinaA+povrsinaB-povrsAB); printf( "Povrsina preseka : %g\n", povrsAB); printf( "Povrsina prve razlike : %g\n", povrsinaA - povrsAB); return 0; } void ucitavanje (Pravougaonik * P) { /*ucitavanje koordinata za odgovarajuca dva temena */ scanf("%f%f%f%f", &P->x, &P->y, &P->x1, &P->y1); } Pravougaonik Presek (Pravougaonik *A, Pravougaonik *B) { /*Racuna se i vraca presek pravougaonika A i B. Ako se A i B ne seku , funkcija vraca pravougaonik cije su sve koordinate jednake 0 */ Pravougaonik rezultat; /*presek zadata dva pravougaonika */ /*odredjivanje koordinata donjeg levog ugla preseka-uociti tacka i strelica notaciju kod rezultat i kod A, B */ rezultat.x = (A->x > B->x) ? A->x : B->x; rezultat.y = (A->y > B->y) ? A->y : B->y; /*odredjivanje koordinata gornjeg desnog ugla preseka => relacijski operator manje */ rezultat.x1 = (A->x1 < B->x1) ? A->x1 : B->x1; rezultat.y1 = (A->y1 < B->y1) ? A->y1 : B->y1; /*pravljenje korekcije u slucaju da je rezultat preseka prazan */ if (rezultat.x >= rezultat. x1 || rezultat.y >= rezultat.y1 ) rezultat.x=rezultat.y = rezultat.x1 = rezultat.y1 = 0; return rezultat; } float Povrsina (Pravougaonik *P ) { /*vraca se rezultat mnozenja duzina dveju susednih stranica znajuci za paralelnost sa koordinatnim osama */ return (P->x1 -P->x) * (P->y1 - P->y ); }
113. Sa standardnog ulaza se ucitava niz od n (n<100) tacaka u ravni takvih da nikoje tri tacke nisu kolinearne. Tacke se zadaju parom svojih koordinata (celi brojevi). Ispitati da li taj niz tacaka odredjuje konveksni mnogougao i rezultat ispisati na standardni izlaz.
#include<stdio.h>
typedef struct tacka
{
int x;
int y;
} TACKA;
/* F-ja ispituje da li se tacke T3 i T4 nalaze sa iste strane prave odredjene tackama T1 i T2.*/
int SaIsteStranePrave(TACKA T1,TACKA T2, TACKA T3, TACKA T4)
{
int t3 = (T3.y - T1.y)*(T2.x - T1.x) - (T2.y - T1.y) * (T3.x - T1.x);
int t4 = (T4.y - T1.y)*(T2.x - T1.x) - (T2.y - T1.y) * (T4.x - T1.x);
return (t3 * t4 > 0);
}
main()
{
TACKA mnogougao[100];
int j,i;
int n;
int konveksan = 1;
do
{
printf("Unesite broj temena mnogougla:\n");
scanf("%d",&n);
if(n<3) printf("Greska! Suvise malo tacaka! Pokusajte ponovo!\n");
}
while(n<3);
printf("Unesite koordinate temena mnogougla takve da nikoja tri temena nisu kolinearna!\n");
for(i=0;i<n;i++) scanf("%d %d", &mnogougao[i].x, &mnogougao[i].y);
/* Da bi mnogougao bio konveksan potrebno (i dovoljno) je da kada se
povuce prava kroz bilo koja dva susedna temena mnogougla sva ostala
temena budu sa iste strane te prave.*/
for(i=0;konveksan&&i<n-1;i++)
{
for(j=0;konveksan&&j<i-1;j++) konveksan=konveksan && SaIsteStranePrave(mnogougao[i], mnogougao[i+1],mnogougao[j],mnogougao[j+1]);
for(j=i+2;konveksan&&j<n-1;j++) konveksan=konveksan && SaIsteStranePrave(mnogougao[i],mnogougao[i+1],mnogougao[j],mnogougao[j+1]);
if(i!=0&&i!=n-1&&i+1!=0&&i+1!=n-1) konveksan=konveksan && SaIsteStranePrave(mnogougao[i], mnogougao[i+1],mnogougao[0],mnogougao[n-1]);
}
for(j=1;konveksan&&j<n-2;j++) konveksan=konveksan && SaIsteStranePrave(mnogougao[0], mnogougao[n-1],mnogougao[j],mnogougao[j+1]);
if(konveksan) printf("Uneti mnogougao jeste konveksan!\n");
else printf("Uneti mnogougao nije konveksan!\n");
}
114. Sa standardnog ulaza se unose koordinate četiri tačke A, B, C i D (realni brojevi) koje pripadaju istoj ravni. Proveriti da li tačka D pripada ili ne pripada unutrasnjosti trougla ABC (tačke A, B, C nisu kolinearne) i dobijeni rezultat ispisati na standardni izlaz.
#include<stdio.h>
typedef struct tacka
{
float x;
float y;
} TACKA;
/* F-ja ispituje da li se tacke T3 i T4 nalaze sa iste strane prave odredjene tackama T1 i T2. Pri tom, ukoliko neka od tacaka T3 i T4 lezi na odgovarajucoj pravoj smatra se da tacke nisu sa iste strane te prave. */
int SaIsteStranePrave(TACKA T1,TACKA T2, TACKA T3, TACKA T4)
{
int t3 = (T3.y - T1.y)*(T2.x - T1.x) - (T2.y - T1.y) * (T3.x - T1.x);
int t4 = (T4.y - T1.y)*(T2.x - T1.x) - (T2.y - T1.y) * (T4.x - T1.x);
return (t3 * t4 > 0);
}
main()
{
TACKA A, B, C, D;
printf("Unesite koordinate temena trougla:\n");
printf("Unesite koordinate temena A:\n");
scanf("%f %f", &A.x, &A.y);
printf("Unesite koordinate temena B:\n");
scanf("%f %f", &B.x, &B.y);
printf("Unesite koordinate temena C:\n");
scanf("%f %f", &C.x, &C.y);
printf("Unesite koordinate tacke D za koju se ispituje da li pripada trouglu ABC:\n");
scanf("%f %f", &D.x, &D.y);
if(SaIsteStranePrave(A,B,C,D) && SaIsteStranePrave(B,C,A,D) && SaIsteStranePrave(A,C,B,D))
printf("Tacka D pripada trouglu ABC!\n");
else printf("Tacka D ne pripada trouglu ABC!\n");
}
Zadaci za vezbu:
Zadatak 1. NCP koji unosi sa standardnog ulaza unosi kompleksan broj (Realni, Imaginarni deo) i ispisuje na standardni izlaz njemu konjugovan kompleksan broj i moduo.
Zadatak 2. Opisati sve greške u sledećem C programu.
include <stdio.h>
define OFFSET 3;
define
greska(msg) fprintf(stderr,#msg" %s\n",argv);
int
length, width;
long area;
struct coord_p
{ int x,
int y
}mypt
void f(void);
struct rectangle
{ coord_p
topleft,
coord_p bottomrt } mybox
main(int argc, char argv**) {
if(
argv = 3 ) /korektan broj argumenata /
{greska(Ne moze da se
otvori)
exit(1)
} else
{ f();
}
return 3;
}
void f(void);
{boolean
coord_test;
scanf("%d", mybox.topleft.x,
mybox.topleft.y);
scanf("%d", mybox.bottomrt.x);
fscanf("%d",
mybox.bottomrt.y);
coord_test=(bottomrt.x -
topleft.x)*(bottomrt.y - topleft.y) > 0;
if (coord_test){ /
izracunavanje duzine, visine i povrsine /
width = OFFSET+
bottomrt.x - topleft.x; length = OFFSET + bottomrt.y - topleft.y;
Area = width * length;
printf("\nPovrsina je %l\n",
area); }
}
Zadatak 3. Napisati program koji za dva polinoma stepena ne većeg od 20 unosi koeficijente (realni brojevi), a na standardni izlaz ispisuje:
a) zbir ta dva polinoma b) vrednost oba polinoma u tački x, koja se zadaje kao argument komandne linije
Pretpostaviti da polinom je zadat strukturom
typedef struct polinom pol; /*definicija polinoma - svaki polinom karakterisu stepen i koeficijenti */ struct polinom { int stepen; double koef[MAXEL]; };
Zadatak 4. Data je struktura
struct tacka{
int a;
int b;
char naziv[5];}
Ovom strukturom opisana je tacka sa koordinatama (a,b) u ravni kojoj je dodeljeno ima naziv. NCP koji ucitava dve tacke sa standardnog ulaza (ucitavaju se koordinate svake tacke i naziv) i ispisuje da li su date dve tacke jednake. Dve tacke su jednake ako su im iste obe koordinate.
Zadatak 5. Data je struktura
struct tacka{
int a;
int b;
char naziv[5];}
Ovom strukturom opisana je tacka sa koordinatama (a,b) u ravni kojoj je dodeljeno ima naziv. Napisati funkciju koja za dve promenljive tipa tacka kopira opis prve tacke u drugu promenljivu. NCP koji ucitava tacku sa standardnog ulaza (ucitavaju se koordinate tacke i naziv) i kopira je u drugu tacku.