C programski jezik Zbirka zadataka sa vezbi sa pojedinih fakulteta 2009 strana Nedostaju vezbe sa FTN Novi Sad i El Fak Nis (kad nabavim prosiricu zb...
ZBIRKA ZADATAKA IZ PROGRAMSKOG JEZIKA C V 1.0 05/08/2015 _________________________________________________________ ETF Beograd ETF Podgorica ETF Sarajevo FER Zagreb FSB Split FTN Kosovska Mitrovica MAT FAK Beograd PMF Niš PMF Srbsko Sarajevo FTN Čačak UN Singidunum Beograd VTŠ Čačak VTŠ Niš _____________________________________________________________
SADRŽAJ _________________________________________________________________ C reference card ANSI Službeni podsetnik FER Zagreb 1.ETF Beograd 2.ETF Podgorica 3.ETF Sarajevo 4.FER Zagreb 5.FSB Split 6.FTN Kosovska Mitrovica 7.MAT FAK Beograd 8.PMF Niš 9.PMF Srbsko Sarajevo 10.FTN Čačak 11.UN Singidunum Beograd 12.VTŠ Čačak 13.VTŠ Niš _________________________________________________________________ Napomena: Zbirka predstavlja skup vežbi iz programskog jezika C Nedostaju vežbe sa FTN NS i ELFAK Niš Za brži pristup pojedinoj stavki u sadržaju kliknuti na bukmark Za bolje razumevanje pogledati predavanja na odgovarajućem fakultetu tj. školi
C Reference Card (ANSI) Program Structure/Functions type fnc(type 1 ,. . . ) type name main() { declarations statements } type fnc(arg 1 ,. . . ) { declarations statements return value; } /* */ main(int argc, char *argv[]) exit(arg )
function declarations external variable declarations main routine local variable declarations function definition local variable declarations
Flow of Control
Constants long (suffix) float (suffix) exponential form octal (prefix zero) hexadecimal (prefix zero-ex) character constant (char, octal, hex) newline, cr, tab, backspace special characters string constant (ends with '\0')
L or l F or f e 0 0x or 0X 'a', '\ooo', '\xhh' \n, \r, \t, \b \\, \?, \', \" "abc. . . de"
Pointers, Arrays & Structures
include library file #include include user file #include "filename" replacement text #define name text replacement macro #define name(var ) text Example. #define max(A,B) ((A)>(B) ? (A) : (B)) undefine #undef name quoted string in replace # concatenate args and rescan ## conditional execution #if, #else, #elif, #endif is name defined, not defined? #ifdef, #ifndef name defined? defined(name ) line continuation char \
declare pointer to type type *name declare function returning pointer to type type *f() declare pointer to function returning type type (*pf)() generic pointer type void * null pointer NULL object pointed to by pointer *pointer address of object name &name array name[dim] multi-dim array name[dim 1 ][dim 2 ]. . . Structures struct tag { structure template declarations declaration of members }; create structure struct tag name member of structure from template name.member member of pointed to structure pointer -> member Example. (*p).x and p->x are the same single value, multiple type structure union bit field with b bits member : b
Data Types/Declarations
Operators (grouped by precedence)
comments main with args terminate execution
C Preprocessor
character (1 byte) integer float (single precision) float (double precision) short (16 bit integer) long (32 bit integer) positive and negative only positive pointer to int, float,. . . enumeration constant constant (unchanging) value declare external variable register variable local to source file no value structure create name by data type size of an object (type is size_t) size of a data type (type is size_t)
char int float double short long signed unsigned *int, *float,. . . enum const extern register static void struct typedef typename sizeof object sizeof(type name)
type name=value type name[]={value 1 ,. . . } char name[]="string "
structure member operator structure pointer increment, decrement plus, minus, logical not, bitwise not indirection via pointer, address of object cast expression to type size of an object
comparisons comparisons bitwise and bitwise exclusive or bitwise or (incl)
>, >=, <, <= ==, != & ^ |
logical and && logical or || conditional expression expr 1 ? expr 2 : expr 3 assignment operators +=, -=, *=, . . . expression evaluation separator , Unary operators, conditional expression and assignment operators group right to left; all others group left to right.
statement terminator ; block delimeters { } exit from switch, while, do, for break next iteration of while, do, for continue go to goto label label label : return value from function return expr Flow Constructions if statement if (expr ) statement else if (expr ) statement else statement while statement while (expr ) statement for statement for (expr 1 ; expr 2 ; expr 3 ) statement do statement do statement while(expr ); switch statement switch (expr ) { case const 1 : statement 1 break; case const 2 : statement 2 break; default: statement }
ANSI Standard Libraries
2
Character Class Tests alphanumeric? alphabetic? control character? decimal digit? printing character (not incl space)? lower case letter? printing character (incl space)? printing char except space, letter, digit? space, formfeed, newline, cr, tab, vtab? upper case letter? hexadecimal digit? convert to lower case? convert to upper case?
String Operations s,t are strings, cs,ct are constant strings length of s strlen(s) copy ct to s strcpy(s,ct) up to n chars strncpy(s,ct,n) concatenate ct after s strcat(s,ct) up to n chars strncat(s,ct,n) compare cs to ct strcmp(cs,ct) only first n chars strncmp(cs,ct,n) pointer to first c in cs strchr(cs,c) pointer to last c in cs strrchr(cs,c) copy n chars from ct to s memcpy(s,ct,n) copy n chars from ct to s (may overlap) memmove(s,ct,n) compare n chars of cs with ct memcmp(cs,ct,n) pointer to first c in first n chars of cs memchr(cs,c,n) put c into first n chars of cs memset(s,c,n)
c 1999 Joseph H. Silverman Permissions on back. v1.3
1
3
C Reference Card (ANSI) Input/Output Standard I/O standard input stream stdin standard output stream stdout standard error stream stderr end of file EOF get a character getchar() print a character putchar(chr ) print formatted data printf("format ",arg 1 ,. . . ) print to string s sprintf(s,"format ",arg 1 ,. . . ) read formatted data scanf("format ",&name 1 ,. . . ) read from string s sscanf(s,"format ",&name 1 ,. . . ) read line to string s (< max chars) gets(s,max) print string s puts(s) File I/O declare file pointer FILE *fp pointer to named file fopen("name ","mode ") modes: r (read), w (write), a (append) get a character getc(fp) write a character putc(chr ,fp) write to file fprintf(fp,"format ",arg 1 ,. . . ) read from file fscanf(fp,"format ",arg 1 ,. . . ) close file fclose(fp) non-zero if error ferror(fp) non-zero if EOF feof(fp) read line to string s (< max chars) fgets(s,max,fp ) write string s fputs(s,fp) Codes for Formatted I/O: "%-+ 0w.pmc" - left justify + print with sign space print space if no sign 0 pad with leading zeros w min field width p precision m conversion character: h short, l long, L long double c conversion character: d,i integer u unsigned c single char s char string f double e,E exponential o octal x,X hexadecimal p pointer n number of chars written g,G same as f or e,E depending on exponent
Variable Argument Lists declaration of pointer to arguments va_list name; initialization of argument pointer va_start(name ,lastarg ) lastarg is last named parameter of the function access next unamed arg, update pointer va_arg(name ,type) call before exiting function va_end(name )
4
Standard Utility Functions
Integer Type Limits
absolute value of int n abs(n) absolute value of long n labs(n) quotient and remainder of ints n,d div(n,d) retursn structure with div_t.quot and div_t.rem quotient and remainder of longs n,d ldiv(n,d) returns structure with ldiv_t.quot and ldiv_t.rem pseudo-random integer [0,RAND_MAX] rand() set random seed to n srand(n) terminate program execution exit(status) pass string s to system for execution system(s) Conversions convert string s to double atof(s) convert string s to integer atoi(s) convert string s to long atol(s) convert prefix of s to double strtod(s,endp) convert prefix of s (base b) to long strtol(s,endp,b) same, but unsigned long strtoul(s,endp,b) Storage Allocation allocate storage malloc(size), calloc(nobj,size) change size of object realloc(pts,size) deallocate space free(ptr) Array Functions search array for key bsearch(key,array,n,size,cmp()) sort array ascending order qsort(array,n,size,cmp())
The numbers given in parentheses are typical values for the constants on a 32-bit Unix system. CHAR_BIT bits in char (8) CHAR_MAX max value of char (127 or 255) CHAR_MIN min value of char (−128 or 0) INT_MAX max value of int (+32,767) INT_MIN min value of int (−32,768) LONG_MAX max value of long (+2,147,483,647) LONG_MIN min value of long (−2,147,483,648) SCHAR_MAX max value of signed char (+127) SCHAR_MIN min value of signed char (−128) SHRT_MAX max value of short (+32,767) SHRT_MIN min value of short (−32,768) UCHAR_MAX max value of unsigned char (255) UINT_MAX max value of unsigned int (65,535) ULONG_MAX max value of unsigned long (4,294,967,295) USHRT_MAX max value of unsigned short (65,536)
Time and Date Functions processor time used by program clock() Example. clock()/CLOCKS_PER_SEC is time in seconds current calendar time time() time2 -time1 in seconds (double) difftime(time2 ,time1 ) arithmetic types representing times clock_t,time_t structure type for calendar time comps tm tm_sec seconds after minute tm_min minutes after hour tm_hour hours since midnight tm_mday day of month tm_mon months since January tm_year years since 1900 tm_wday days since Sunday tm_yday days since January 1 tm_isdst Daylight Savings Time flag convert local time to calendar time mktime(tp) convert time in tp to string asctime(tp) convert calendar time in tp to local time ctime(tp) convert calendar time to GMT gmtime(tp) convert calendar time to local time localtime(tp) format date and time info strftime(s,smax,"format ",tp) tp is a pointer to a structure of type tm
radix of exponent rep floating point rounding mode decimal digits of precision smallest x so 1.0 + x 6= 1.0 number of digits in mantissa maximum floating point number maximum exponent minimum floating point number minimum exponent decimal digits of precision smallest x so 1.0 + x 6= 1.0 number of digits in mantissa max double floating point number maximum exponent min double floating point number minimum exponent
Send comments and corrections to J.H. Silverman, Math. Dept., Brown Univ., Providence, RI 02912 USA. [email protected]
5
6
c 1999 Joseph H. Silverman May 1999 v1.3. Copyright Permission is granted to make and distribute copies of this card provided the copyright notice and this permission notice are preserved on all copies.
Programiranje i programsko inženjerstvo – službeni podsjetnik Prioritet operatora
Izvadak iz ASCII tablice Opis
LF Space 0 A a
sljedeći red, novi red blank, praznina znamenka nula veliko slovo A malo slovo a
poziv funkcije()
[]
IEEE 754 dvostruka preciznost K = BE + 1023 denormalizirani broj: K = 0 ± ∞ili NaN: K = 2047 najveći pozitivan broj 1.8 × 10308 najmanji pozitivan broj 4.9 × 10-324
ρ 2-53 1.1 × 10-16
math.h double double double double
fabs (double x); sin (double x); cos (double x); tan (double x);
Prikaz realnih brojeva IEEE 754 jednostruka preciznost K = BE + 127 denormalizirani broj: K = 0 ± ∞ ili NaN: K = 255 najveći pozitivan broj 3.4 × 1038 najmanji pozitivan broj 1.4 × 10-45
Izgled konverzijskih specifikacija kod funkcije printf %[znak][širina][.preciznost]tip
x
e ln x log x xy x
x mod y
x x
stdlib.h int abs (int x); x long labs (long x); x void exit (int status); void srand (unsigned int seed); int rand (void); void *malloc (size_t size); void free (void *block); void *realloc(void *block, size_t size);
[znak]
Objašnjenje
ništa
desno pozicioniranje tiska - predznak, a umjesto + predznaka je praznina lijevo pozicioniranje rezultat uvijek počinje s + ili ispisuje vodeće nule konverzija na alternativan način: ne utječe na c s d i u ispisuje vodeću 0 za o ispisuje vodeće 0x ili 0X za x ili X ispisuje dec. točku i kad nema decimala za e E F ispisuje prateće 0 za g G
praznina + 0 #
vraća broj iz intervala [0, RAND_MAX] vraća NULL u slučaju pogreške vraća NULL u slučaju pogreške
Programiranje i programsko inženjerstvo – službeni podsjetnik
verzija 2013.b
char *strrchr(const char *s, int c); char *strstr(const char *string, const char *substring); char *strpbrk(const char *string, const char *setofcharacters); ctype.h int toupper(int int tolower(int int isdigit(int int isalpha(int int isalnum(int int isprint(int int iscntrl(int int isspace(int int islower(int int isupper(int
ch); ch); c); c); c); c); c); c); c); c);
provjerava je li znak znamenka (0-9) provjerava je li znak slovo (A-Z ili a-z) provjerava je li znak slovo (A-Z ili a-z) ili znamenka (0-9) provjerava može li se znak ispisati (0x20-0x7E) provjerava je li znak kontrolni (0x7F ili 0x00-0x1F) provjerava je li znak praznina provjerava je li znak malo slovo (a-z) provjerava je li znak veliko slovo (A-Z)
stdio.h int getchar(void); vraća učitani znak ili EOF int putchar(int ch); vraća ispisani znak ili EOF (kod pogreške) int scanf(const char *format, arg1, arg2, ...,arg n); vraća broj učitanih argumenata (0…n) ili EOF (kraj datoteke) Tipovi formatskih specifikacije za scanf: %d,%i,%o,%u,%x,%c,%s,%e,%f,%g,%p,%[…],%[^…]. Prefiksi: h(za short) l(long, double) L(long double), npr. %hd, %ld, %lf, %Lf int printf(const char *format, arg1, arg2, ...,arg n);
vraća broj ispisanih znakova
Tipovi formatskih specifikacije za printf: %d,%i,%o,%u,%x,%X,%c,%s,%e,%f,%g,%G,%e,%E,%p. int puts(const char *s); char *gets(char *string);
vraća EOF u slučaju pogreške vraća NULL ako kao prvi znak pročita kraj datoteke (CTRL+Z (windows) ili CTRL+D(unix)) ili ako je nastupila pogreška
FILE *fopen(const char *filename, const char *mode); mode: "w","a","r","w+","a+","r+" Napomena: U Windows op. sustavu za binarne datoteke treba na kraj dodati b vraća 0 ako je operacija uspjela ili EOF u slučaju pogreške vraća pročitani znak ili EOF (pogreška ili kraj datoteke) const char *format, arg1, arg2, ..., arg n); vraća broj učitanih argumenata ili EOF(pogreška ili kraj datoteke) char *fgets(char *s, int n, FILE *stream); vraća NULL u slučaju pogreške ili kraja datoteke int fputc(int c, FILE *stream); vraća ispisani znak ili EOF u slučaju pogreške int fprintf (FILE *stream, const char *format, arg1, arg2, ..., arg n); vraća broj ispisanih znakova ili EOF u slučaju pogreške int fputs(char *s, FILE *stream); vraća nenegativni broj ili EOF u slučaju pogreške size_t fread(void *ptr, size_t size, size_t n, FILE *stream); vraća broj učitanih objekata. (0..n) size_t fwrite(void *ptr, size_t size, size_t n, FILE *stream); vraća broj ispisanih objekata. U slučaju pogreške taj je broj < n. int fseek(FILE *stream, long offset, int whence); vraća 0 ako je pozicioniranje uspjelo ili broj različit od 0 u slučaju pogreške whence: SEEK_SET – pozicioniranje u odnosu na početak datoteke SEEK_CUR - pozicioniranje u odnosu na trenutnu poziciju u datoteci SEEK_END - pozicioniranje u odnosu na kraj datoteke int fclose(FILE *fp); int fgetc(FILE *stream); int fscanf (FILE *stream,
long ftell(FILE *stream);
vraća trenutnu poziciju u datoteci ili -1 u slučaju pogreške
ELEKTROTEHNIČKI FAKULTET UNIVERZITETA U BEOGRADU PROGRAMIRANJE 2 MATERIJAL ZA VEŽBE NA TABLI I PRIPREMU ISPITA verzija: 26.06.2008. Detaljna objašnjenja vezana za bilo koji deo gradiva vezanog za teoriju dostupna su u beleškama sa predavanja, kao i u knjizi koja opisuje jezik C dovoljno precizno: • Laslo Kraus – Programski jezik C. Više zadataka se može pronaći u odgovarajućoj zbirci prof. Krausa: • Laslo Kraus, Zbirka zadataka iz programskog jezika C. Sve ove knjige su dostupne u skriptarnici ili u biblioteci fakulteta. Zadaci koji su tipa ispitnih pitanja su priloženi u celosti, uključujući i obrazloženje rešenja tamo gde je to potrebno. U materijal je uključeno i nekoliko ispitnih zadataka, koji su rešeni u potpunosti i komentarisani do odgovarajućeg stepena opširnosti. Materijal će biti stalno dorađivan. Nove verzije će redovno biti dodavane na Internet stranicu predmeta: http://rti.etf.rs/ir1p2 Sugestije, primedbe i uočene greške poslati putem elektronske pošte na adresu [email protected].
Ove materijale treba koristiti isključivo kao podsetnik a nipošto kao jedini izvor znanja. Nemojte NIKAD učiti programski kod napamet. Svako ponavljanje bez razumevanja programskog koda je štetno i na ispitu će biti kažnjavano oduzimanjem poena.
Elektrotehnički fakultet Univerziteta u Beogradu
Predstavljanje realnih brojeva
SADRŽAJ
Standard za aritmetiku realnih brojeva Zaokruživanje Zadatak Z12 Zadatak IZ3 Zadatak IZ4 Zadatak IZ5 Zadatak IZ34A (integralni ispit, 09.10.1998. godine) Zadatak Z14
Programski jezik C
Zadatak C5 Zadatak C10 Operatori: prioritet i redosled primene Zadatak C15 Zadatak C20 Zadatak C25 Zadatak C30 Zadatak C35 Zadatak C40 Zadatak C45 Zadatak C47 Zadatak C48 Zadatak C50 Zadatak C55 Zadatak C57 Zadatak C60 Zadatak C65 Zadatak C70 Zadatak C75 Zadatak C80b Zadatak C90 Zadatak C95 Zadatak C100 Zadatak C104 Zadatak C110 Zadatak C115 Zadatak C120 Zadatak C122 Zadatak C125 Zadatak CI-2007-Jan-2 Zadatak CI-2006-Okt-1 Zadatak CI-2007-Okt-2 Zadatak CI-2006-Sep-2 Zadatak CI-2006-Jan-1 Zadatak CI-2006-Jan-2 Zadatak CI-2006-Sep-1 Zadatak C2008-A1 Zadatak C2008-S11 Zadatak C2008-S12 Zadatak C2008-S21 Zadatak C2008-S22
PREDSTAVLJANJE REALNIH BROJEVA Standard za aritmetiku realnih brojeva – – –
Raznolikost predstavljanja realnih brojeva u računarima. Problem portabilnosti numeričkog softvera. Standard za binarnu aritmetiku realnih brojeva u pokretnom zarezu: ANSI/IEEE Std 754-1985. (IEEE – The Institute of Electrical and Electronics Engeneers ANSI – American National Standard Institute)
Standard specificira: 1. Osnovni i prošireni format realnih brojeva 2. Operacije +, –, *, /, ostatka (rem), kvadratnog korena( 3. 4. 5. 6.
) i komparaciju realnih brojeva
Konverzije: celi brojevi ⇔ realni brojevi Konverzije: realni brojevi ⇔ realni brojevi (različiti formati brojeva) Konverzije: osnovni format realnih brojeva ⇔ decimalni niz znakova Rukovanje kodovima grešaka
Osnovna osobina standarda: niz bitova, generisan kao rezultat aritmetičke operacije, može nositi dvojaku informaciju: 1. ispravno obavljena operacija ⇒ niz bitova je rezultat operacije 2. detektovana je neka greška ⇒ niz bitova je binarno kodirani signal greške (tzv. NaN = Not a Number) Postoje dva tipa NaN–a: 1. signalni NaN (signal NaN) – signalizira neispravnu operaciju kad god se pojavi u ulozi operanda 2. tihi (mirni) NaN (quiet NaN) – za skoro sve aritmetičke operacije ne signalizira neispravnost U skladu sa IEEE standardom, realni brojevi se u memorijske reči smeštaju na sledeći način: memorijska reč broj bita u datom polju smisao polja
s eeeeeee mmmmmmmmmmm 1 k p znak eksponent mantisa
Ukupan broj bita: n = 1 + k + p Vrednost tako predstavljenog realnog broja se računa na sledeći način:
R = (–1)s⋅2E⋅M gde vrednosti s, E i M imaju sledeća tumačenja: • s predstavlja znak datog broja (s=0 ⇒ broj je pozitivan; s=1 ⇒ broj je negativan) • E predstavlja celobrojni eksponent, čija se vrednost računa u kôdu sa viškom, kao E = e-v, gde je o e vrednost neoznačenog celog broja čija se vrednost dobija na osnovu bita eee...e, polja eksponent o v se naziva višak, a predstavlja celobrojnu vrednost koja se računa: v=2k-1-1, gde je k broj bita polja eksponent • M predstavlja vrednost mantise sa skrivenim bitom (videti objašnjenje u nastavku) Materijal za vežbe na tabli i pripremu ispita
Strana 3/52
Elektrotehnički fakultet Univerziteta u Beogradu
Programiranje 2
U zavisnosti vrednosti bita polja eksponent, postoje četiri različita načina tumačenja sadržaja memorijske reči u kojoj je smešten realan broj. 1. Kada biti polja eksponent nisu sve 0 ili sve 1 (e≠0000...0 i e≠1111...1), vrednost eksponenta E se nalazi u opsegu [Emin, Emax] i tada memorijska reč sadrži uobičajen realni broj sa normalizovanom mantisom. Vrednost mantise M se računa dodavanjem skrivenog bita vrednosti 1 i decimalnog zareza ispred niza bita polja mantisa: M=1.mmmmm...m. Skriveni bit se podrazumeva pa zbog toga nije potrebno posebno ga skladištiti u memorijskoj reči. 2. Kada su biti polja eksponent sve 0 (e=0000...0), ali biti polja mantisa nisu sve 0 (m≠0000...0), tada memorijska reč sadrži realan broj sa nenormalizovanom mantisom. Vrednost eksponenta E se u ovom specijalnom slučaju računa kao E=e-v+1. Vrednost mantise M se računa dodavanjem skrivenog bita vrednosti 0 i decimalnog zareza ispred niza bita polja mantisa: M=0.mmmm...m. Kao i u prethodnom slučaju, ovaj skriveni bit se podrazumeva. Smisao realnih brojeva sa nenormalizovanom mantisom je proširenje opsega za realne brojeve veoma male apsolutne vrednosti. 3. Kada su biti polja eksponent i mantisa sve 0 (e=0000...0, m=0000...0), tada memorijska reč sadrži realan broj čija je vrednost 0. Treba primetiti da zbog znaka (bit s), standard dozvoljava postojanje pozitivne i negativne nule (+0 i -0) ali između njih ne pravi razliku (tj. imaju istu vrednost). 4. Kada su biti polja eksponent sve 1 (e=1111...1), vrednost eksponenta E je veća od Emax i razlikuju se dva slučaja: a. vrednosti bita polja mantisa su sve 0 (m=0000...0) : realni broj ima vrednost ±∞ (u zavisnosti od vrednosti bita s) b. vrednosti bita polja mantisa nisu sve 0 (m≠0000...0) : radi se o NaN-u, koji označava matematički nedefinisanu vrednost Pozitivni realni brojevi, manji od najmanjeg realnog broja (minREALl) koji je moguće predstaviti sa zadatim brojem bita se zaokružuju na vrednost 0 (tzv. potkoračenje, eng. underflow), dok se pozitivni realni brojevi veći od najvećeg realnog broja (maxREAL) zaokružuju na vrednost +∞ (tzv. prekoračenje, eng. overflow). Slično važi za negativne realne brojeve. -∞ [ -maxREAL
]
0 |
-minREAL
[
] +∞
minREAL
maxREAL
Standardni formati realnih brojeva IEEE Standard uvodi 4 formata realnih brojeva (format se odnosi na broj bitova pojedinih polja): (1) jednostruki (2) jednostruki prošireni (3) dvostruki (4) dvostruki prošireni FORMAT jednostruki jednostruki prošireni dvostruki dvostruki prošireni
w 32 ≥ 43 64 ≥ 79
Materijal za vežbe na tabli i pripremu ispita
k 8 ≥ 11 11 ≥ 15
p 23 ≥ 32 52 ≥ 64
v +127 nedef. +1023 nedef.
Emax +127 ≥ +1023 +1023 ≥ +16383
Emin -126 ≤ -1022 -1022 ≤ -16382
Strana 4/52
Elektrotehnički fakultet Univerziteta u Beogradu
Programiranje 2
Jednostruki format 1 k=8 p = 23 s e e e e e e e e mmmmmmmmmmmmmmmmmmmmmmm 31 30 23 22 0 Opseg brojeva: 1. Najmanji nenormalizovani: e=0 ⇒ 2. Najveći nenormalizovani: e=0 ⇒ 3. Najmanji normalizovani: e=1 ⇒ 4. Najveći realan broj: e=254 ⇒
Zaokruživanje Zbog ograničenog broja bita polja mantisa, najčešće nije moguće prezicno smeštanje realnog broja u memorijsku reč, već se pristupa zaokruživanju. Podrazumeva se da je posmatrani broj, pre smeštanja u memorijsku reč, beskonačno precizan, pa se zaokruživanje vrši sa ciljem da se uklopi u odredišni format. Skoro sve operacije nad realnim brojevima daju najpre “beskonačno precizan” rezultat koji se potom zaokružuje prema odredišnom formatu. 1. Osnovni način zaokruživanja: prema najbližoj vrednosti. 2. Ako su dve zaokružene vrednosti podjednako udaljene od “beskonačno precizne” vrednosti – bira se ona vrednost kod koje je bit najmanjeg značaja 0. 3. Ako je apsolutna vrednost “beskonačno precizne” vrednosti: |R| ≥ 2Emax⋅(2–2–p), vrši se zaokruživanje na (–1)s⋅(∞) p i Emax se određuju iz odredišnog formata. U praksi, ovo znači sledeće (desno od vertikalne crte se nalaze biti koji se odbacuju): 1 binarna x.xx | 0zzz...zzz predstava broja vrednost na koju x.xx se zaokružuje
2 x.xx | 1yyy...yyy (makar jedan y je 1) x.xx + 0.01
3 x.x0 | 100...00
4 x.x1 | 100...00
x.x0
x.x1 + 0.01
Ako se pažljivije pogleda, ovakav način zaokruživanja odgovara uobičajenom načinu zaokruživanja realnih brojeva. Gubitak tačnosti ima za posledicu da kod računarskog sabiranja realnih brojeva ne važi uvek zakon asocijativnosti. Primer1: decimalni računar sa 4 značajne cifre: R=123.4, r=0.049 ⇒ R+r=123.449 ≈ 123.4 Z1 = ((R+r)+r)+r = 123.4 Z2 = ((r+r)+r)+R = 123.4+0.147 = 123.547 ≈ 123.5 ≠ Z1 Opšte pravilo: početi sumiranje od brojeva manje apsolutne vrednosti.
Materijal za vežbe na tabli i pripremu ispita
Strana 5/52
Elektrotehnički fakultet Univerziteta u Beogradu
Programiranje 2
Zadatak Z12 Za smeštanje realnih brojeva koriste se 8 bitova od kojih 3 bita predstavljaju eksponent u kodu sa viškom. Mantisa se smešta sa skrivenim bitom. Za brojeve veće od nule odrediti najmanju i najveću vrednost koja se može predstaviti na gornji način.
Zadatak IZ3 Napomena: ovaj zadatak ilustruje razliku između savremenog IEEE standarda za reprezentaciju realnih brojeva i standarda VAX koji mu je prethodio. Format predstave realnih brojeva je seeeemmmmm – s je bit za znak broja, eeee su bitovi za eksponent broja (kôd sa viškom), a mmmmm su bitovi normalizovane mantise (sa skrivenim bitom). U računaru A – predstava realnih brojeva je sa viškom 8, a u računaru B – sa viškom 7. U računaru A – mantisa je 0.5≤MA<1, a u računaru B – mantisa je 1≤MB<2. Izgled jednog broja u računaru B, u skladu sa opisanim formatom, je 3DF16. Kako je predstavljen realan broj iste vrednosti u računaru A? A) 3DF16 B) 3FF16 C) 3FE16 Rešenje Prvi način: Moguće je reći, da je predstava realnih brojeva u računaru B u skladu sa duhom IEEE standarda, imajući u vidu da je višak 7 = 24-1 -1, a mantisa je oblika MB = 1.mmmmm. Zbog toga, broj 3DF16 = 1|1110|111112 predstavlja maxREAL, kad je računar B u pitanju. Moguće je zaključiti, da je predstava realnih brojeva u računaru A – u skladu sa starom (VAX) predstavom brojeva (8 = 24-1, MA = 0.1mmmmm). Kako je maxREALIEEE = 2⋅maxREALVAX, može se zaključiti da ovaj broj nije moguće predstaviti u računaru A, jer je maxREALVAX dva puta manji od posmatranog broja. Drugi način: B: 3DF16 = 1|1110|111112 XB = –1.111112⋅27 = –111111002 MA = 0.1mA
EB = eeeeB – 7 = 7
MB = 1.mmmmmB = 1.111112
XA = XB = –0.1111112⋅28
mA = 111112
EA = eA + 8 = 1610 = 100002
a to nije moguće predstaviti u polju eA koje je širine 4 bita.
Odgovor: N
Materijal za vežbe na tabli i pripremu ispita
Strana 6/52
Elektrotehnički fakultet Univerziteta u Beogradu
Programiranje 2
Zadatak IZ4 Format predstave realnih brojeva pomoću reči širine 10 bita je: bit najveće težine za znak broja, četiri bita za eksponent u kôdu sa viškom 7, i pet bitova najmanje težine za normalizovanu mantisu sa skrivenim bitom (1≤M<2). Rezultat sabiranja brojeva čiji je izgled A=16068 i B=05158 je: A) 16338 B) 15668 C) 17668 Rešenje A: 1|1100|00110 SA=1 ⇒ A <0 EA=12–7=5 MA=1.00110
|MA| > |MB’| ⇒ A + B = – (MA – MB’)⋅2EA = –MA+B⋅2EA
MA = 1.00110 –MB’ = 0.01011 –––––––––––––––––– MA+B = 0.11011
ovde se mora izvršiti normalizacija.
MA+B = 1.10110⋅2–1 A + B = –MA+B⋅2EA = –1.10110⋅2–1⋅2EA = –1.10110⋅2EA-1 = –MA+B’⋅2EA+B’ SA+B = 1
MA+B’ = 1.10110
EA+B’ = EA – 1 = 4
eA+B = 4 + 7 = 11
s = 1, eeee = 1011, mmmmm = 10110 (A + B) : 1|1011|10110 = 1|101|110|110 =15668 Odgovor: B
Materijal za vežbe na tabli i pripremu ispita
Strana 7/52
Elektrotehnički fakultet Univerziteta u Beogradu
Programiranje 2
Zadatak IZ5 U nekom računaru, celi brojevi su predstavljeni u drugom komplementu pomoću reči širine 10 bita, a za predstavljanje realnih brojeva je takođe predviđeno 10 bita, i to tako da bit najveće težine određuje znak broja, sledeća 4 bita su za eksponent broja u kôdu sa viškom 7, a preostalih 5 za normalizovanu mantisu sa skrivenim bitom (1≤M<2). Ako je izgled realnog broja na lokaciji X: 39716, a izgled celog broja na lokaciji J: 31016, koji će biti izgled lokacije realne promenljive Y nakon izvršene operacije Y=X+J? Računanje obavljati upotrebljavajući realne brojeve. A) 3FA16 B) 3E516 C) 3BA16 Rešenje X: 1|1100|10111 SX = 1, X<0 MX = 1.10111 EX = 12 – 7 = 5
EJ > EX X = – MX⋅2-2⋅27 MX’ = 0.01101|11 ≈ 0.01110 Y = – (MJ + MX’) ⋅ 2Ej MJ= 1.11100 +MX’= 0.01110 ––––––––––––– MY =10.01010 = 1.00101 ⋅ 21 Y = – MY’ ⋅ 2EY+1 = -1.00101 ⋅ 28 s = 1, e = 8 + 7= 1510 = 11112, eeee = 1111, mmmmm = 00101 Y: 1|1111|00101 = 3E516 Odgovor: B
Materijal za vežbe na tabli i pripremu ispita
Strana 8/52
Elektrotehnički fakultet Univerziteta u Beogradu
Programiranje 2
Zadatak IZ34A (integralni ispit, 09.10.1998. godine) Realni brojevi se predstavljaju sa 11 bita formatom seeeeemmmmm gde je s bit za predznak broja, eeeee (5) biti eksponenta u kodu sa viškom 8, a mmmmm (5) biti normalizovane mantise sa skrivenim bitom 0.5<=M<1. Celi brojevi predstavljaju se sa 10 bita u drugom komplementu. Ceo broj I ima izgled 17716 a ceo broj J ima izgled 32516. Najpre se izvrši celobrojno sabiranje N=I+J. Zatim se izvrši konverzija brojeva I i J u realne brojeve, i sabiranjem tih realnih brojeva dobije broj B. Kolika će biti apsolutna vrednost razlike brojeva N i B? (Napomena: Sva zaokruživanja vrše se prema pravilima IEEE standarda, a svi koraci u sabiranju realnih brojeva vrše se na širini određenoj formatom mantise.) A) 4 B) 8 C) 2.125 Rešenje Prvo ćemo izvršiti celobrojno sabiranje. I = 17716 = 01 0111 0111 J = 32516 = 11 0010 0101 I+J= 100 1001 1100 Pošto u memoriji imamo samo 10 bita sa predstavljanje celih brojeva, jedanaesti bit koji je generisan u procesu sabiranja otpada i dobijamo 00100111002 = 9C16 = 15610 kao rešenje. Realno sabiranje se vrši tako što prvo celobrojne vrednosti konvertujemo u realne, uz potrebna zaokruživanja, a potom dobijene realne vrednosti saberemo. J: 11 0010 0101, što znači da je J<0. I: 9 9 0101110111 = 0.101110111∙2 ≈ 0.101111∙2 s -J: 00 1101 1011 = 0.11011011∙28 ≈ 0.110111∙28 Sada je potrebno svesti ova dva broja na isti eksponent i pri tome izvršiti zaokruživanja, ako se za tim ukaže potreba: J = (-1)∙0.110111∙28 = (-1)∙0.0110111∙28 ≈ (-1)∙0.011100∙28. Pošto su brojevi različitog znaka, oduzimamo mantisu manjeg od mantise većeg broja: MI: 0.101111 -MJ: - 0.011100 MI-MJ: 0.100110 Traženi broj izgleda ovako: 0.100110∙28, što je jednako pozitivnom celom broju 00100110002 = 9816 = 15210. Odavde se može zaključiti da je apsolutna razlika ova dva zbira jednaka 4. Napomena: Kada se vrši konverzija iz celobrojnog u realni broj, vrši se zaokruživanje na po vrednosti najbliži realni broj koji se može predstaviti u memoriji datog računara. Konverzija u obrnutom smeru podrazumeva ili zaokruživanje početnog realnog broja na po vrednosti najbliži celi broj ili prosto odsecanje razlomljenog dela realnog broja. Ako nije posebno naglašeno, podrazumeva se prvi pristup. Odgovor: A
Zadatak Z14 Brojevi sa pokretnom tačkom u računaru imaju binarni oblik seeeeeemmmmmmmmm, gde je s bit za znak broja, m su bitovi normalizovane mantise sa skrivenim bitom (0.5≤M<1), e su bitovi eksponenta u kodu sa viškom 25. Naći zbir brojeva x i y čiji su oblici u računaru zadati u brojnom sistemu sa osnovom q. Rezultate proveriti pretvaranjem zadatih vrednosti i rezultata u decimalni brojni sistem.
Materijal za vežbe na tabli i pripremu ispita
Strana 9/52
Elektrotehnički fakultet Univerziteta u Beogradu
Programiranje 2
PROGRAMSKI JEZIK C Zadatak C5 Sledeći program za određivanje rešenja linearne jednačine Ax+B=0, za A<>0, napisan na programskom jeziku C, sadrži više grešaka. Ispraviti sve greške! main Float _x,a,b
main predstavlja funkciju – treba da stoji main() C je CaseSensitive jezik (razlikuje mala i velika slova) deklaracija treba da stoji unutar programskog bloka
{ scanf('%f %f',a,b);
_x=-b/a; printf('%f',_X)
niz znakova u jeziku C se ogranicava parom znakova " scanf zahteva adresu, a ne vrednost; Prevodilac za jezik C ne prijavljuje ovo kao gresku. _X nije dobro, jer smo deklarisali _x
}
Rešenje: Ispravljeni program izgleda ovako: #include main() { float _x,a,b; scanf("%f %f",&a,&b); _x=-b/a; printf("%f",_x); }
/* na početku svakog programa dolaze direktive */
/* _x ne smeta (Promenljiva moze sadrzati znak _ ) */
/* svaka naredba jeziku C završava se znakom tacka-zarez; */
Komentar: Neispravno napisan program je testiran i kompajliran u programskom paketu Visual Studio.net. Poruke kompajlera su sledeće: Compiling... c5.c c5.c(5) : error C2061: syntax error : identifier 'Float' c5.c(5) : error C2059: syntax error : ';' c5.c(7) : error C2143: syntax error : missing ';' before '{' c5.c(7) : error C2449: found '{' at file scope (missing function header?) c5.c(8) : error C2015: too many characters in constant c5.c(14) : error C2059: syntax error : '}'
Na početku svakog programa koji nešto učitava ili ispisuje mora postojati direktiva include sa parametrom . Ovo predstavlja uputstvo prevodiocu da iz datoteke stdio.h treba da pročita osobine bibliotečkih funkcija za ulaz i izlaz podataka.
Materijal za vežbe na tabli i pripremu ispita
Strana 10/52
Elektrotehnički fakultet Univerziteta u Beogradu
Programiranje 2
Zadatak C10 Sastaviti program na programskom jeziku C za ispisivanje tablice ASCII kodova za sve štampajuće znake. Rešenje ASCII kod sa brojem 32 je blanko simbol ili razmak. Prva 32 ASCII koda (od 0 do 31) i svi ASCII kodovi veći ili jednaki 127 predstavljaju specijalne simbole koji se koriste u različite svrhe i najčešće nemaju neko jasno slovno značenje. Koristili su se za iscrtavanje DOS prozora, i na taj način simulirali grafiku u tekstualnom režimu rada. Konkretno, prozori razvojnog okruženja Turbo C su napravljeni na ovaj način! ASCII kodovi između 32 i 126 su štampajući znaci, i ima ih ukupno 95. Znaci se prikazuju po kolonama. U jednoj koloni se prikazuje po 19 znakova, a u jednom redu se prikazuje po 5 znakova (5x19=95). Prikazaćemo sve ASCII kodove od 32 do 126. Program za prikazivanje tablice ASCII kodova može se realizovati na više načina. I način #include main() { char c; int i; printf ("\t\tTablica ASCII kodova \n \n"); for(c = ' '; c < ' ' + 19; c++) { for(i = 0; i < 95; i += 19) printf("%3d%c ", c+i, c+i); putchar('\n'); } }
II način – ovako NE TREBA raditi!!! #include main() { char c=' '; int i; printf ("\t\tTablica ASCII kodova \n \n"); linija: i=0; znak: printf("%3d %c ", c+i, c+i); i=i+19; if (i<95) goto znak; printf("\n"); c=c+1; if (c<' '+19) goto linija; }
Komentar: U drugom rešenju se koristi skok sa proizvoljnim odredištem: goto. Korišćenje naredbe goto treba izbegavati (bilo koji algoritam koji sadrži goto može se ostvariti na neki drugi način, što i pokazuje prvo rešenje). Glavni razlog za izbegavanje naredbe goto je taj što ta naredba ima veliki stepen slobode u izboru odredišta skoka tako da omogućava sastavljanje nestrukturiranih, vrlo nepreglednih programa, koji jako često sadrže mnogo grešaka uzrokovanih upravo lošom strukturom.
Materijal za vežbe na tabli i pripremu ispita
Strana 11/52
Elektrotehnički fakultet Univerziteta u Beogradu
Programiranje 2
Operatori: prioritet i redosled primene SMER GRUPISANJA
PRIORITET
BROJ OPERANADA
OPERATORI
15
2
[] () . ->
→
14
1
! - ++ -- + - * & (tip) sizeof
←
13
2
* / %
→
12
2
+ -
→
11
2
<< >>
→
10
2
< <= > >=
→
9
2
== !=
→
8
2
&
→
7
2
^
→
6
2
|
→
5
2
&&
→
4
2
||
→
3
3
?:
←
2
2
= += -= *= /= %= &= ^= |= <<= >>=
←
1
2
,
→
Primeri Relacijski operatori
Operatori za dodelu vrednosti
Izraz 5 > 7 10 <= 20 8 == 13 > 5 14 > 5 < 3 a < b < 5 a+5 >= c-1.0/e
Izraz y = a * x + b d *= e + f d = d * e + f a=b=c=d+5 a = b++ + 3*(c=d<<3) a = b++ + 3*c = d<<3
Objašnjenje d = (d*(e+f)) d = ((d*e)+f) c=d+5,b=c,a=b c=d<<3,u=b,b=b+1,a=u+(3*c) greška !
Redosled računanja i bočni efekti ((a<<5)+4/b)*(d-=c-2)
* ++e
Standard garantuje da će se pre množenja izračunati vrednosti operanada u zagradama. Standard ne precizira kojim će se redom računati (prvo levi ili prvo desni operand) – implementaciona zavisnost. Ako rezultat zavisi od redosleda izračunavanja operanada - loš stil pisanja izraza. Bočni efekti: uzgredna promena vrednosti jedne ili više promenljivih. Rezultat zavisi od redosleda izračunavanja operanada ako se bar jedna promenljiva, koja podleže uticaju nekog bočnog efekta, koristi na više od jednog mesta u izrazu. Operatori koji proizvode bočne efekte su ++, -- i svi operatori dodele vrednosti. Izraz Objašnjenje a=b*c + b++ a=b*c+(b=d/e) a[i] = ++i
Zadatak C15 Odrediti čemu su ekvivalentni sledeći izrazi (koristiti zagrade da bi se eksplicitno odredio redosled izračunavanja) 1. 2. 3. 4. 5.
x+=y-=m n%=y+m m++ - --j x=j * j++ ++j==m!=y*2
Odgovor: 1. 2. 3. 4.
x=(x+(y=(y-m)) n=(n % (y+m)) m-(j-1); m=m+1; j=j-1 x=j * j++ ; ovo zavisi od toga kojim se redom racuna, sa leva na desno ili obrnuto Odgovor: implementaciono zavisno 5. ((j+1)==m)!=(y*2); j=j+1
Primer – Bočni efekti (autor: Jelica Protić) Sledeći primer ilustruje manifestovanje bočnih efekata u 8 različitih izraza, za različite prevodioce jezika C. Inicijalna vrednost promenljive j je 5. 1. 2. 3. 4. 5. 6. 7. 8.
Pitanje: zašto VS dobija 16 kao rezultat u primeru 6?
GNU GCC 25 25 36 36 9 12 9 9
ARM C 30 30 36 36 9 12 15 18
Elektrotehnički fakultet Univerziteta u Beogradu
Programski jezik C
Zadatak C20 Sastaviti program na programskom jeziku C koji učitava srednje temperature po mesecima za 12 meseci i na osnovu njih izračuna i ispiše srednju temperaturu za celu godinu. Rešenje: #include #define BROJ_MESECI 12 main() { enum meseci {JAN=1,FEB,NAR,APR,MAJ,JUN,JUL,AVG,SEP,OKT,NOV,DEC}; enum meseci mesec=JAN; /* Moguce je umesto gornje dve linije napisati samo jednu: enum meseci {JAN=1,FEB,NAR,APR,MAJ,JUN,JUL,AVG,SEP,OKT,NOV,DEC} mesec=JAN; */ float temperature[BROJ_MESECI]; float srednja_temp=0; while (1) { printf("Temperatura za mesec %2d: ",mesec); scanf("%f",&temperature[mesec - 1]); /* niz u C-u uvek ide od 0 */ srednja_temp+=temperature[mesec - 1]; if (mesec==DEC) break; mesec++; } srednja_temp/=BROJ_MESECI; printf("Srednja temperatura je %.2f\n",srednja_temp); } /* Jasno je da nam niz nije potreban za racunanje srednje vrednosti dovoljno je da mesecnu temperaturu ucitavamo u neku pomocnu (float) promenljivu i da nju dodajemo na srednja_temp */
Komentar Prikaz nekih vrednosti adresa i niza temperature: &temperature,p: 22FC(SS):0FCC &temperature[0],p: 22FC(SS):0FCC
- adresa clana 0
&temperature[1],p: 22FC(SS):0FD0
- adresa clana 1
temperature: { 3.0,8.0,12.0,15.0,20.0,26.0,29.0,30.0,26.0,20.0,13.0,7.0 } - prikaz celog niza temperature[0]: 3.0
- vrednost clana sa indeksom 0
Ovakav prikaz se može dobiti pomoću Watch prozora razvojnog okruženja Turbo C. Najpre se navodi izraz čija se vrednost posmatra, a onda način kako ona treba da bude ispisana. Uz pomoć ovog dodatka, može se isti izraz posmatrati na više načina. izraz,d – kao broj izraz,c – kao karakter izraz,p – kao pokazivač (adresa)
Materijal za vežbe na tabli i pripremu ispita
Strana 14 od 52
Elektrotehnički fakultet Univerziteta u Beogradu
Programski jezik C
Zadatak C25 Sastaviti program na programskom jeziku C za određivanje broja velikih slova, malih slova i cifara u tekstu koji se iz proizvoljnog broja redova učitava preko glavne ulazne jedinice. Tekst se završava znakom za kraj datoteke. Rešenje #include #include /* treba za funkcije vezane za ispitivanje slova */ main() { int znak, vel_sl=0, mal_sl=0,cifra=0; printf("Unesite zeljeni tekst \n"); while ((znak=getchar())!=EOF) { vel_sl += isupper(znak) != 0; /* ctype.h */ mal_sl += islower(znak) != 0; /* ctype.h */ cifra += isdigit(znak) != 0; /* ctype.h */ } printf("Velikih slova ima %d\n",vel_sl); printf("Malih slova ima %d\n",mal_sl); printf("Cifara ima %d\n",cifra); }
Komentar U zaglavlju ctype.h se nalaze prototipovi funkcija za ispitivanje znakova. U ovom programu su upotrebljene sledeće funkcije: - isupper(znak): ispituje da li je zadovoljen uslov (znak>='A') && (znak<='Z') - islower(znak) : ispituje da li je zadovoljen uslov (znak>='a') && (znak<='a') - isdigit(znak) : ispituje da li je zadovoljen uslov (znak>='0')&&(znak<='9') Sve is_ funkcije vraćaju 0 za logičku neistinu, a različito od 0 (ne obavezno 1) za logičku istinu
Materijal za vežbe na tabli i pripremu ispita
Strana 15 od 52
Elektrotehnički fakultet Univerziteta u Beogradu
Programski jezik C
Zadatak C30 Sastaviti program na programskom jeziku C koji učitava decimalan pozitivan celi broj u obliku niza znakova i ispisuje njegovu vrednost u binarnom obliku. Pretpostaviti da se za interno predstavljanje celih brojeva koristi 16 bitova. Rešenje #include #include #include main() { char dec[10]; short int bin, i; printf("Unesite decimalan broj: "); scanf("%s",dec); /* ucitava string sa standardnog ulaza (dec=&dec[0]) */ /* atoi vraca 0 ukoliko nije uspela konverzija. Ukoliko je strlen(dec)=0 onda se drugi deo USLOVA (iza && operatora) nece ni proveravati. Po postavci zadatka ocekuje se pozitivan broj, i takav uslov se jednostavno, ovim putem, moze proveriti. */ if (strlen(dec) && (bin=atoi(dec))) { printf("Binarni broj: "); i=-1; while (++i<16) { putchar((bin & 0x8000) ? '1' : '0'); /* 0x8000 ima jedinicu na najvisem 15-om bitu Gornja naredba ce ispisati 15-i bit broja bin! Najpre ispisujemo najvise bitove, jer takav prikaz zelimo na ekranu bit15 bit14 ... bit2 bit1 bit0 */ bin <<= 1 ; /* bin = bin shl 1 ; pomeramo bin ulevo za 1 bit */ if (i%4 == 3) putchar(' '); /* prikaz razmaka izmedju svake polovine bajta */ } printf("\n"); } else printf("Neispravan broj ili nula\n"); }
Komentar 16-bitni binarni broj može da ima najveću vrednost 65535, ukoliko se tretira kao unsigned, odnosno 32767, ukoliko se tretira kao signed. To konkretno znači da je za ovaj 16-bitni prikaz dovoljno koristiti niz brojeva char dec[6] (5 za cifre i 1 za terminator). Sa druge strane, ako se u ovom zadatku unese neki broj veći od 65535/32767 rezultat neće biti ispravan (biće prikazano samo najnižih 16-bitova zadatog broja ako je short int na datom računaru duži od 16 bita). Funkcija atoi se može koristiti i za konverziju negativnih vrednosti. Treba imati na umu i sledeću činjenicu: ako se unese više od 10 znakova nepredvidiv je ishod izvršavanja ovog programa, jer niz 'dec' ima dodeljeno svega 10 znakova (bajtova) u memoriji i ništa preko toga! Ostatak memorije pripada drugim podacima ili drugom programskom kodu, tako da se upisivanjem van granica niza može izazvati nepredvidivo ponašanje.
Materijal za vežbe na tabli i pripremu ispita
Strana 16 od 52
Elektrotehnički fakultet Univerziteta u Beogradu
Programski jezik C
Zadatak C35 Koja od datih konstrukcija na programskom jeziku C predstavlja ekvivalent iskaza na programskom jeziku Pascal: if (a>b) then begin a:=1; b:=1 end A) if (a>b) { a=1; b=1; } B) if (a>b) a=1, b=1; C) if (a>b) a=1; b=1; Komentar Odgovor će biti A ili V (A i B), zavisno od toga kako se definiše ekvivalentnost dva iskaza. A) Ovo je upravo prepisana selekcija sa Pascala na C. B) Ukoliko je ispunjen uslov biće izvršena jedna instrukcija u then grani, pri čemu se ona sastoji od 2 izraza. Efekat izvršavanja ova dva izraza je u ovom slučaju identičan slučaju pod A). C) b=1 se izvršava u svakom slučaju, što ne važi za originalni segment.
Zadatak C40 Šta ispisuju sledeći programi? a)
b)
#include main() { int x; for (x=0;x<100;x++) { /* ako x nije deljivo sa dva vrati se na pocetak tela ciklusa */ if (x%2) continue; /* do ovde dolazi samo ako je x deljivo sa 2 (x mod 2 = 0) */ printf("%d\n",x); } }
#include main() { int x=0,i; for (i=0;i<5;i++) switch (i) { case 1: x+=1; /* ukoliko je i=1 izvrsava se deo iza case 1: i case 2: */ case 2: x+=2; break; /* Ako je i=2 izvrsava se samo deo iza case 2: (zbog break;) */ case 4: x+=3; /* Ako je i=4 izvrsava se samo deo iza case 4: */ } printf("d=%d\n",x); }
A) Sve cele brojeve od 0 .. 99 B) Sve parne brojeve od 0 .. 99 C) Sve neparne brojeve od 0 .. 99 Odgovor B
A) 5 B) 6 C) 9 Odgovor N Komentar Najpre je x=0; Za i=0, x se ne menja (x=0); Za i=1, x+=1; x+=2; => x=3; Za i=2, x+=2; => x=5; Za i=3, x se ne menja; Za i=4, x+=3; => x=8;
Materijal za vežbe na tabli i pripremu ispita
Strana 17 od 52
Elektrotehnički fakultet Univerziteta u Beogradu
Programski jezik C
Zadatak C45 Sastaviti program na programskim jeziku C koji formira slučajan celobrojni niz sastavljen od jednocifrenih brojeva i izvrši uređivanje niza po neopadajućem redosledu vrednosti brojeva. Rešenje: Za sortiranje brojeva postoji niz algoritama. Više detalja o ovoj oblasti se može pronaći u knjizi “Strukture podataka” profesora Tomaševića. Ovde je predstavljen najjednostavniji algoritam pod nazivom Selection sort, odnosno sortiranje metodom izbora. Ideja je sledeća: u i-tom prolazu se odabere i-ti (u ovom slučaju) najmanji broj, pa se smesti na i-to mesto. #include #include #define DIM 50 main() { int n,a[DIM],i,j,b; for (;;) { printf("\n\n Duzina niza (max %d): ",DIM); scanf("%d", &n); if ((n <= 0) || (n > DIM)) break; /* break prekida for ciklus. Ovo je ciklus sa izlazom u sredini */ printf("\nPocetni niz: \n\n"); for (i=0;i a[j]) b = a[i],a[i] = a[j],a[j] = b;
/* zamena 2 promenljive */
printf("\nSortirani niz:\n\n"); for (i = 0; i < n; i++) printf("%d%c", a[i], (i % 30 == 29 || i == n-1) ? ('\n') : (' ')); /* Deo (i%30==29 || i==n-1) ? ('\n') : (' ') predstavlja karakter koji treba da se napise iza broja (Clana) niza. Ukoliko se nalazimo na kraju niza (poslednji element i==n-1), ispisujemo znak za novi red. Takodje, radi jasnijeg prikaza posle svakog 30-tog clana niza ispisujemo isto znak za novi red. U svakom drugom slucaju ispisuje se blanko (razmak).*/ } }
Zadatak C47 Koji od programskih segmenata na programskom jeziku C daju isti izlaz kao dati programski segment na programskom jeziku Pascal? j:= -2; for i:= -2 to j*j do begin write(j:3); j:=j+1 end;
A) for (i=j=-1;i<=j*j;i++,j++) printf(" %3d ",j); B) i=-2; while (printf(" %3d ",i),i++ -4); C) i=j=-2; while (i++ == 4 ? 0 : 4) printf(" %3d ",j++); Obrazloženje: U programskom jeziku Pascal se interval for ciklusa određuje neposredno po ulasku u ciklus i ne menja se u toku izvršavanja ciklusa, dok se u programskom jeziku C uslov kod for ciklusa računa pre svakog ponavljanja. Ovaj programski segment na programskom jeziku Pascal ispisuje -2,-1,0,1,2,3,4. Programski segment (A) na programskom jeziku C je logički neispravan, jer i nikada neće prestići vrednost j*j. Dodirna tačka im je za i==0,j==0 i i==1,j==1, ali posle toga zbog obostranog inkrementiranja i će biti uvek manje od j*j. U realnosti, u nekom trenutku će doći do prekoračenja opsega celih brojeva, i j*j će postati manje od i, za vrednost j takvu da vrednost izraza j*j prekoračuje maksimalni celi broj. Programski segment (B) na programskom jeziku C je logički ispravan i ispisuje iste vrednosti kao i dati programski segment na programskom jeziku Pascal. Zadnji ispisani broj je 4, tada se ne postiže uslov za ulaz u petlju (i-4 == 0, što predstavlja logičku neistinu), a kao bočni efekat i=5. Programski segment (C) na programskom jeziku C je logički ispravan. Međutim, on ne ispisuje iste vrednosti kao i programski segment na programskom jeziku Pascal. Ispisuje jedan broj manje (tj. sve od -2 do 3). Iz ciklusa se izlazi kada je i==4. Broj koji se ispisao pre toga je bio 3, a bočni efekat je bio j=4.
Zadatak C48 Data su tri segmenta programa na programskom jeziku C: I for (i=x=y=0; ; ++i) {x++; if (i==n) break; y++; } printf(“%ld %ld”,x,y);
II x=0, y=0; for (i=0; i<=n; i++) {x=x+1; if (i
III x=i=0; while (i<=n) { i++; ++x; y=x>n;} printf(“%ld %ld”,x,y);
Ako su sve promenljive celi brojevi koja dva segmenta daju isti izlaz za n>0? A) I i II B) II i III C) I i III Obrazloženje: I uvek ispisuje x=n+1, y=n,a II i III uvek ispisuju x=n+1, y=1 (n ne utiče na vrednost y).
Materijal za vežbe na tabli i pripremu ispita
Strana 19 od 52
Elektrotehnički fakultet Univerziteta u Beogradu
Programski jezik C
Zadatak C50 Napisati na programskom jeziku C program koji analizira tekst koji se unosi sa standardnog ulaza, prepoznaje realne brojeve po formatu cc...c.ddd...d i ispisuje ih po formatu c.ddE+ee, a sve ostale učitane znake ispisuje bez izmene. Rešenje #include #include #define DECIMALNA_TACKA '.' #define ZNAK_ZA_KRAJ '!' main() { int c, j, broj_cifara; double vrednost, decimala; do { /* sve dok se ne pojavi neka cifra, ispisuju se karakteri sa ulaza */ while (! ( isdigit(c = getchar()) || (c==ZNAK_ZA_KRAJ) ) ) putchar(c); if (c == ZNAK_ZA_KRAJ) break; /* Ukoliko je nadjen znak ! onda se prekida glavna petlja */ vrednost = 0.; broj_cifara = 0; /* sve dok se ne naidje na tacku, dodaje se vrednosti pritisnuta cifra na kraj */ while ( isdigit(c) ) vrednost = vrednost * 10 + (c-'0'), c = getchar(); if (c == DECIMALNA_TACKA) /* sve dok se unose cifre, dodaju se na kraj decimalnog dela */ { c=getchar(); while ( isdigit(c) ) { broj_cifara++; decimala = c - '0'; for (j=0; j < broj_cifara; j++) decimala/=10; vrednost += decimala; c = getchar(); } } ungetc(c,stdin); printf("%1.2E",vrednost); } while (c != ZNAK_ZA_KRAJ); /* '!' je trenutno znak za kraj */ }
Obrazloženje Iz programa se izlazi ukoliko se bilo gde u liniji upiše znak '!' Od unete cifre, broj koji ona predstavlja dobija se kada se od njenog ASCII koda oduzme ASCII kod znaka '0'. Pitanje Šta će se dobiti na izlazu za sledeći red? 123.123.123 Odgovor: 1.23E+02.1.23E+02
Materijal za vežbe na tabli i pripremu ispita
Strana 20 od 52
Elektrotehnički fakultet Univerziteta u Beogradu
Programski jezik C
Zadatak C55 Šta ispisuje sledeći program? a) /*C55a*/ #include main() { int a[]={1,0}, *p; p=a; printf("%d, ", *p++); printf("%d\n", *p); }
A) 1, 2
B) 1, 0
C) 0, 0
Komentar Odgovor je B. Prioritet * i ++ je isti, ali je asocijativnost ove grupe operatora sdesna ulevo. b) /*C55b, J.Protic*/ #include main() { int a[]={0, 1, 2, 3, 4}; int i, *p; for (p=a, i=0; p<=&a[4]; p++) printf("%d", *p);
Napraviti program koji ucitava koordinate trodimenzionalnom prostoru: Tacke t i t su definirane kao trojke: 1
dvije
tacke
u
2
- t =(x , y , z ) , 1
1
1
1
- t =(x , y , z ). 2
2
2
2
Kao izlaz program daje udaljenost izmedju tih tacki. NAPOMENA: Za drugi korijen koristiti funkciju sqrt() koja je definirana u datoteci math.h. Na primjer, naredba a=sqrt(9); ce izracunati drugi korijen iz 9 i pridruziti izracunatu vrijednost varijabli a. RJEŠENJE: // Ukljucujemo datoteke u kojima se nalaze funkcije koje cemo koristiti. # include # include // Definisanje glavne funkcije main() int main () { // Definisanje potrebnih varijabli float x1,y1,z1,x2,y2,z2,d; // Unos kordinata x1,y1,z1 (printf - ispis poruke; scanf - unos varijabli) printf("Unesi tacku a(x1,y1,z1): "); scanf("%f,%f,%f", &x1, &y1, &z1); // Unos kordinata x2,y2,z2 printf("Unesi tacku b(x2,y2,z2): "); scanf("%f,%f,%f", &x2, &y2, &z2); // Racunanje udaljenosti po formuli (sqrt - funkcija koja racuna drugi korjen) d=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1)); // Ispis udaljenosti d printf("Udaljenost izmedju tacki a i b je: %f", d); // Kraj programa (getch() - stavljamo da bi zadrzali poruku u kojoj je // rezultat. U suprotnom nam se nece prikazati poruka na ekranu, iako je // program uspjesno izvrsen getch(); // Return 0; - (umjesto 0 mozemo staviti bilo koji cio broj, jednostavno // nekako je potrebno zavrsiti funkciju main() pa se obicno stavlja return 0; return 0; }
Napravite C-program koji ucitava potrošnju elektricne energije u KWh (velika tarifa(VT) i mala tarifa(MT)) i pripadajuce cijene po KWh (cijena za malu tarifu i cijena za veliku tarifu). Kao izlaz program daje: - ukupnu potrošnju u KWh; - novcani iznos racuna; - udio velike tarife i male tarife u ukupnoj potrošnji. Na primjer, izlaz iz programa treba biti sljedeceg formata: Ukupna potrosnja je 234.25 KWh. Udio velike tarife u ukupnoj potrosnji je 25 %. Udio male tarife u ukupnoj potrosnji je 75%. Iznos racuna je 25.45 KM. RJEŠENJE: # include int main () { // Definisanje potrebnih varijabli float VT,MT,CV,CM,UKUPNO,RACUN,UDIOM,UDIOV; // Unos male tarife, velike tarife, cijene male tarife i cijene velike tarife printf("\n Unesi potrosnju po velikoj tarifi (KWh): "); scanf("%f", &VT); printf("\n Unesi potrosnju po maloj tarifi (KWh): "); scanf("%f", &MT); printf("\n Cijena za veliku tarifu po jednom Kwh: "); scanf("%f", &CV); printf("\n Cijena za malu tarifu po jednom Kwh: "); scanf("%f", &CM); // Racunanje ukupne potrosnje UKUPNO=VT+MT; // Racunanje cijene ukupne potrosnje (cijena po maloj tarifi + cijena po // velikoj tarifi) RACUN=VT*CV+MT*CM; // Izracunava udio velike i male tarife u ukupnoj potrosnji (procenat) UDIOM=(MT/UKUPNO)*100; UDIOV=(VT/UKUPNO)*100; // Ispis rezultata printf ("\n Ukupna potrosnja elektricne energije je: %.f KWh", UKUPNO); printf ("\n Ukupna cijena elektricne energije je: %.f KM", RACUN); printf ("\n Udio velike tarife u potrosnji je: %.f procenata", UDIOV); printf ("\n Udio male tarife u potrosnji je: %.f procenata", UDIOM); // Kraj programa getch(); return 0; }
Napisati program koji ce izracunati presjek skupova S1 i S2. Skupovi S1 i S2 definirani su intervalima realnih brojeva: S1=[A, S2=[C, Na primjer, program kao
B] D]. za slijedeci ulaz: izlaz treba dati:
A=3, B=9, C=7, D=11
Rezultantni interval je REZ=[7, 9]. RJEŠENJE: #include main() { // Definisanje varijabli float A,B,C,D,MAX,MIN; // Unos skupova printf("\n Unesi prvi skup X[A,B] A>B: "); scanf("%f,%f", &A,&B); printf("\n Unesi drugi skup Y[C,D] C>D: "); scanf("%f,%f", &C,&D); /* Logika zadatka je sljedeca: Prvo moramo pretpostaviti da je prvi broj intervala veci ili jednak drugom, A>=B i C>=D, jer ako ovo ne vrijedi interval nije matematicki ispravan (taj uslov nismo ispitivali da nebi komplikovali zadatak). Presjek skupa ce biti neki interval [MIN,MAX]. Uslov da zadatak ima RJEŠENJE je da je B < C kao i D < A sto je i logicno jer u suprotnom presjeka nema! Broj MIN je ustvari jedan od brojeva A ili C (manji broj od ova 2 broja), a MAX je manji broj od brojeva B i D. Ako je A=C ili B=D uzima se vrijednost pod ELSE ali tada nam je svakako svejedno koja ce se uzeti vrijednost kao MIN ili MAX jer je tada A=C odnosno B=D */ if (A>C) MAX=A; else MAX=C; if (BD)) printf("\n Nema presjeka!"); else { printf ("\n Presjek je: [%.f,%.f]", MAX, MIN); } // Kraj programa getch(); return 0; }
Napisati program koji ucitava koeficijente a, b i c realnog tipa. Ti koeficijenti definiraju funkciju f(x): 2
f(x)=ax +bx+c Program zatim provjerava da li su ti keficijenti u rasponu -10 do 10. Ako nisu, program ispisuje poruku: Koeficijenti a, b i c nisu u zadanom rasponu. Ako koeficijenti a, b i c jesu u zadanom rasponu, program kao izlaz daje vrijednost prve derivacije u tacki x. Tacka x se takodjer unosi sa standardnog ulaza. Na primjer, ako je ulaz a=1, b=2, c=1, x=1 program kao izlaz daje: Prva derivacija u tacki x=1 je 4. RJEŠENJE: # include int main () { // Definisanje varijabli float a,b,c,x,izvod; // Unos koeficijenata a,b,c printf ("Unesi koef. (a,b,c) funkcije f(x)=ax2+bx+c (-10<(a,b,c)<10):"); scanf("%f,%f,%f", &a,&b,&c); // Unos vrijednosti x printf ("Unesi vrijednost x"); scanf("%f", &x); // Ispit uslova if (a>-10&&a<10&&b>-10&&b<10&&c>-10&&c<10){ // Izracunavanje izvoda po odredjenoj matematickoj formuli izvod=2*a*x+b; // Ispis izvoda printf("Prva derivacija u tacki x=%.f je %.f", x, izvod); // Ispis odgovarajuce poruke ukoliko uslov nije zadovoljen } else printf ("Koeficijenti nisu iz odgovarajuceg intervala!"); // Kraj programa getch(); return 0; }
Napisati program koji ucitava tri cijela broja iz intervala od 50 do 200. Ako svi uneseni brojevi nisu iz tog intervala, program treba ispisati poruku "Svi brojevi nisu iz intervala 50 do 200” i završiti program. Ako su brojevi unutar tog intervala program treba ispisati ucitane brojeve po velicini od najmanjeg prema najvecem. RJEŠENJE: #include main() { // Definisanje varijabli int x[3], i, j, p; // Unos brojeva printf("\n Unesi tri broja u rasponu od 50 do 200 (U formatu: a, b, c): "); scanf("%d, %d, %d", &x[0], &x[1], &x[2]); // Provjera jesu li brojevi iz odgovarajuceg intervala if (x[0]>50&&x[1]>50&&x[2]>50&&x[0]<200&&x[1]<200&&x[2]<200) { /* Sortiranje brojeva Potrebne su nam dvije for petlje koje ce „listati“ brojeve koji se nalaze u nekom nizu. Ovaj tip sortiranja se uglavnom svodi na provjeru da li je prvi broj manji od drugog ili treceg, i ako jeste, onda mijenja mjesto sa tim brojem. Medjutim nakon ovoga nije zavrseno sortiranje. Ako npr. Unesemo brojeve 3, 2, 1, nakon prvog prolaska imamo 2, 3, 1 nakon drugog 2, 1, 3 ali jos uvijek nije zavrseno sortiranje, i zbog toga i postoji prva for petlja koja ce to ponoviti jos jednom i dobivamo 1, 2, 3 i niz je sortiran, i sada ga samo jos treba ispisati na ekran. */ for (i=0;i<2;i++) for (j=0;j<2;j++) if (x[j]>x[i]) { p=x[i]; x[i]=x[j]; x[j]=p; } // Ispis sortiranih brojeva printf("\n Sortirani brojevi: %d, %d, %d ", x[0], x[1], x[2]); // Ako brojevi nisu iz intervala, ispis odgovarajuce poruke } else { printf("\n Svi brojevi nisu iz intervala 50 do 200!!!"); } // Kraj programa getch(); return 0; }
Napisati program koji ce ispisati brojeve djeljive sa 5, 7 ili 11, a manje ili jednake od nekog ucitanog broja n sa tastature. Brojeve treba ispisati od najveceg prema najmanjem. Obavezno koristiti for petlju. Na primjer, ako je korisnik za n unio broj 20 onda program treba ispisati: 20 15 14 11 10 7 5 RJEŠENJE: #include int main() { // Definisanje varijabli int n, i; // Unos nekog prirodnog broja printf("Unesite broj: "); scanf("%d", &n); /* For petlja postavlja brojac „i“ na vrijednost unesenog broja, i provjerava se da li je taj broj djeljiv sa 5, 7 ili 11, i ako jeste printa ga na ekran i umanjuje brojac za jedan, ako broj nije djeljiv sa ovim brojevima, onda se samo brojac umanji na kraju for petlje bez printanja broja na ekranu. Isti se postupak ponavlja i za broj manji za jedan, kao i broj manji za dva... sve tako do broja 1 (mogli smo staviti i 4 jer brojevi ispod 5 svakako nisu djeljivi sa ovim brojevima! */ for(i=n;i>0;i--) { if ((i % 5 == 0)||(i % 7 == 0)||(i % 11 == 0)) printf("\n Broj: %d", i); } // Kraj programa getch(); return 0; }
Napisati program koji ce izracunavati sumu prema slijedecoj formuli: suma=1-1/2+1/3-1/4+...+1/n Broj n se unosi sa tastature(standardnog ulaza). Program treba ispisati vrijednost sume na standardnom izlazu (monitoru) koristeci slijedecu poruku: Koristeci clanova suma je . (Na mjestu se treba nalaziti konkretno uneseni broj n, a na mjestu se treba nalaziti konkretno izracunata suma.) Zadatak riješite koristeci while petlju. RJEŠENJE: #include int main() { // Definisanje varijabli float i=1,n,suma=0; // Unos prirodnog broja printf ("\n Unesi broj n:"); scanf("%f", &n); /* Racunanje sume While petlja vrti podprogam u okviru while petlje sve dok je brojac „i“ koji je na pocetku 1, manji od unesenog broja n. Ako je uneseni broj 1 ne ulazi se u petlju i na izlazu se ispisuje Suma je:1. Ako je broj veci od 1 onda se racuna suma prema matematickoj formuli. Grupisali smo formulu datu u zadatku tako da trazimo sume po dva broja (odnosno razlike), i zatim te razlike brojeva sabiramo, ali moramo paziti jer moramo brojac „i“ uvecati za 2 jer smo u formuli ukljucili odmah 2 broja. Ovaj nacin ima i dobru i losu stranu. Dobra strana je jer nemoramo uvoditi nikakvu pomocnu varijablu i citav kod za racunanje sume se sastoji od dva izraza, a losa strana je kad unesemo neparne brojeve sto necemo dobiti tacnu sumu i tako kad unesemo broj 3 program ce izracunati 1-1/2+1/3=0.5 sto nije tacno, a to smo dobili jer program nemoze grupisati clanove po 2 jer ih imamo tri i zadnji ostaje sam i ne racuna se. Ali ovaj mali nedostatak mozemo zanemariti jer se u ovakvim zadacima obicno unose veliki brojevi da se sve svodi na preciznost nalazenja broja 0.69 pa nam je svejedno da li je zadnji clan uracunat ili ne, ali eto ako zelimo ipak 100% precizno uraditi, zadatak moze se uraditi i bez grupisanja sa mijenjanjem predznaka sume, ali to uradite sami :) */ while ((i1)) { suma=suma+(1/i-1/(i+1)); i=i+2; } // Ispis sume if (n>1) printf ("\n Suma je: %f", suma); else if (n=1) printf ("Suma je: 1"); // Kraj programa getch(); return 0; }
Napraviti program koji sa standardnog ulaza ucitava cijeli broj m koji predstavlja redni broj mjeseca u godini, te ucitava i broj g koji predstavlja godinu, a na monitoru ispisuje naziv tog mjeseca i broj dana u tom mjesecu. Pretpostaviti da je prestupna svaka cetvrta godina, iako je pravilo o racunanju prestupnih godina nešto slozenije. Na primjer, ako su ulazne vrijednosti m=2, g=2000 program treba ispisati: februar, 2000. g., broj dana:29 Ili ako su ulazne vrijednosti m=5, g=2005 program treba ispisati: maj, 2005. g., broj dana: 31 RJEŠENJE: #include main() { /* Deklarisanje varijabli Definisanje dvodimenzionalne matrice 12 sa 9 (12 mjeseci, a broj 9 je ustvari broj slova od kojih se sastoje mjeseci, najvise ima semptembar (9 slova). */ int m,g,d,i; char mj[12][9]={{"Januar"},{"Februar"},{"Mart"},{"April"}, {"Maj"},{"Juni"},{"Juli"},{"August"},{"Septembar"}, {"Oktobar"},{"Novembar"},{"Decembar"}}; // U programu se uvodi i naredba „goto“ koja „skace“ sa linije na liniju // programa. pocetak: // Unos mjeseca i godine printf ("\n Unesi mjesec i godinu (m,g):"); scanf ("%d,%d", &m,&g); // Ako se unese 1,3,5,7,8,10 ili 12 mjesec onda ima d=31 dan if ((m==1)||(m==3)||(m==5)||(m==7)||(m==8)||(m==10)||(m==12)) d=31; else // Ako se ipak unese 4,6,9 ili 11 mjesec onda ima d=30 dana if ((m==4)||(m==6)||(m==9)||(m==11)) d=30; else /* Ili ako se ipak unese mjesec 2 onda se provjerava jos i prijestupna godina (svaka godina djeljiva sa 4), i u zavisnosti da li je prijestupna ili ne d=29 odnosno d=29 dana. Ako broj nije od 1 do 12 vraca se na pocetak programa*/ if ((m==2)) if ((g%4==0)) d=29; else d=28; else goto pocetak; // Ispis mjeseca koji se nalazi zapisan u mj[] (m-1 jer nam je januar pod brojem 0) printf("%s , %d. g., broj dana: %d", mj[m-1], g, d); // Kraj programa getch(); return 0; }
Napisati program koji ucitava realnu matricu dimenzija 10x10 te pronalazi najmanji element na glavnoj dijagonali. RJEŠENJE: #include main (){ // Deklarisanje varijabli float A[10][10], MIN; int i,j; /* Unos matrice (koristimo 2 for petlje pri unosu (i su redovi a j su kolone). Brojevi se unose po redovima. */ printf("\n Unesi matricu A[10][10]: \n"); for (i=0;i<10;i++) for (j=0;j<10;j++) { printf(" [%d,%d]:", i+1, j+1); scanf("%f", &A[i][j]); } /* Trazenje najmanjeg elementa na dijagonali! Postupak je sljedeci. Elementi na dijagonali su tipa [i,j] gdje su i,j jednaki. Tako dijagonalni elementi matrice 3x3 su [1,1], [2,2], [3,3]. Posto nam trebaju samo elementi kada su (i,j) jednaki koristimo jednu for petlju. Na pocetku stavimo da je najmanji element prvi element na poziciji [1,1], u C-u je pozicija (0,0) ustvari pozicija (1,1) u realnom svijetu. I ulazimo u for petlju. Ispituju se redom brojevi kod kojih su brojaci „i“ i „j“ jednaki. Ako je neki od brojeva koji se ispitaju manji od MIN onda se taj broj pridruzi varijabli MIN. */ MIN=A[0][0]; for (i=1,j=1;i<10;i++,j++) if (A[i][j]
Email: [email protected] ; MSN: [email protected]
LoVe dOts... ForEver... ETF - 2005/2006
Autor: Murtic Nirmel www.etf.ba
10.
Napišite funkciju faktor () koja izracunava n! pri cemu je prototip funkcije faktor (): double faktor (int n) Zatim, napisati glavni program koji ucitava neki prirodni broj n,1 main (){ // Deklarisanje varijabli int N; double F; // Deklarisanje prototipa funkcije double faktor (int n); //Unos prirodnog broja printf("\nUnesi prirodan broj N: "); scanf("%d", &N); /* Pozivanje funkcije faktor() i pridruzivanje izracuna varijabli F */ F=faktor(N); // Ispis faktorijele printf("Faktorijela od %d je: %g", N, F); // Kraj programa getch(); return 0; }
vrijednosti
koju
funkcija
/* Funkcija koja racuna vrijednost faktorijele. Funkcija prima prirodan broj N a vraca realan broj (double) kao rezultat. */ double faktor (int n) { int i; double fak=1; /* Racunanje faktorijele se vrsi tako da se broj od kojeg trazimo faktorijelu pomnozi sa svakim cijelim brojem manjim od sebe a koji je veci od 1. Na pocetku je fak=1 jer ako bi bilo 0 dobili bi uzastopno mnozenje sa 0 i nebi dobili ispravan rezultat */ for (i=n;i>1;i--) fak=fak*i; // Vracanje izracunate faktorijele return fak; }
Napisati program koji ucitava broj elemenata (n) nekog cjelobrojnog polja (Polje) a zatim i elemente tog polja (maksimalno 100). Program nakon toga pronalazi maksimalni element unesenog polja i ispisuje ga na standardni izlaz. Na primjer, ako su ulazni podaci: n=4, Polje=(2,5,20,4) program ce ispisati vrijednost broja 20. RJEŠENJE: # include main (){ // Definisanje varijabli int n, i, niz[100], max; // Unos broja elemenata printf("\nUnesi broj elemenata: "); scanf("%d", &n); // Unos niza od N elemenata (pomocu for petlje) for (i=0;i
Email: [email protected] ; MSN: [email protected]
LoVe dOts... ForEver... ETF - 2005/2006
Autor: Murtic Nirmel www.etf.ba
12.
Napisati program koji ucitava 5 realnih elemenata dva polja A i B a zatim izracunava elemente treceg polja C (koji takodjer ima 5 elemenata) pri cemu se i-ti element polja C dobiva prema slijedecoj formuli: C[i]=2*A[i]+B[i], i=1,2,…n Na kraju program na standardni izlaz ispisuje elemente sva tri polja: A, B i C. RJEŠENJE: # include main (){ // Definisanje varijabli float A[5], B[5], C[5]; int i; /* Unos elemenata prvog polja (pomocu for petlje, i+1 zbog realnosti, da nam ne ispisuje se na ekranu "Unesi element 0") */ for (i=0;i<5;i++){ printf("\nUnesi %d element prvog polja: ",i+1); scanf("%f", &A[i]); } // Unos elemenata drugog polja for (i=0;i<5;i++){ printf("\nUnesi %d element drugog polja: ",i+1); scanf("%f", &B[i]); } // Racunanje clanova matrice C po formuli C=2*A+B (pomocu jedne for petlje). for (i=0;i<5;i++) C[i]=2*A[i]+B[i]; // Ispis elemenata polja A printf("\nElementi prvog polja A: "); for (i=0;i<5;i++) printf("%.f ", A[i]); // Ispis elemenata polja B printf("\nElementi drugog polja B: "); for (i=0;i<5;i++) printf("%.f ", B[i]); // Ispis elemenata polja C printf("\nElementi treceg polja C: "); for (i=0;i<5;i++) printf("%.f ", C[i]); // Kraj programa getch(); return 0; }
Napisati program koji ucitava broj elemenata nekog polja (maksimalno 100) a zatim i elemente tog polja. Program zatim pronalazi najmanji element i na standardni izlaz ispisuje sve elemente koji su manji od dvostruke vrijednosti pronadjenog najmanjeg elementa. RJEŠENJE: # include main (){ // Definisanje varijabli int n, i, niz[100], min; // Unos broja elemenata printf("\nUnesi broj elemenata: "); scanf("%d", &n); // Unos niza od N elemenata (pomocu for petlje) for (i=0;iniz[i]) min=niz[i]; /* For petlja vrti sve brojeve i za svaki broj se vrsi provjera da li je manji od dvostruke vrijednosti nadjenog najmanjeg broja, i ako je taj broj zaista manji od 2*min ispisuje se na ekran, a ako nije ide se na iduci broj. */ for (i=0;i
Email: [email protected] ; MSN: [email protected]
LoVe dOts... ForEver... ETF - 2005/2006
Autor: Murtic Nirmel www.etf.ba
14.
Napisati funkciju koja kao argument prima cijeli broj a vraca broj koji se dobije tako da se iz argumenta izbace cifre 2,3,8 i 9. Prototip funkcije je: int izbaci2389(int x) Nakon toga, napišite glavni program koji ucitava neki cjeli broj, poziva funkciju izbaci2389 i ispisuje rezultat na standardnom izlazu. RJEŠENJE: # include main (){ // Definisanje prototipa funkcije int izbaci2389(int x); // Definisanje varijabli int N, X; // unos prirodnog broja printf("\nUnesi prirodan broj: "); scanf("%d", &N); // Poziv funkcije i pridruzivanje rezultata varijabli X X=izbaci2389(N); // Ispis prepravljenog broja printf("\nPrepravljeni broj: %d", X); // Kraj programa getch(); return 0; } // Funkcija za izbacivanje cifri 2,3,8,9 iz prirodnog broja int izbaci2389(int x) { int t=1, y=0, ost; /* While petlja se izvrsava dok je x>0. Uzima se ostatak dijeljenja broja sa 10 (npr. od broja 129, ostatak je 9), zatim se varijabli x odbije zadnja cifra dijeljenjem sa 10 (do odbijanja dolazi jer radimo sa int brojevima pa nema decimalnog zareza (npr 129/10=12). Zatim provjerimo dali je dobijeni ostatak ost jednak 2,3,8 ili 9 i ako jest vracamo se na pocetak petlje i vrsimo isti postupak za broj koji smo dobili odbijanjem zadnje cifre (i sve tako dok ne odbijemo sve cifre, tj. dok ne dobijemo broj 0). Ako varijabla ost ipak je razlicita od 2,4,8,9 onda se varijabli y doda vrijednost ost pomnozena sa t. U programu varijabla t nam ustvari broji koja je decimala u pitanju. Kad je t=1 radimo sa jedinicama, kad je t=10 radimo sa deseticama... Tako npr. broj 1234 mozemo rastaviti kao 4*1+3*10+2*100+1*1000 gdje su nam brojevi 1,10,100,1000 ustvari nase t. */ while (x>0){ ost=x%10; x=x/10; if ((ost==2)||(ost==3)||(ost==8)||(ost==9)) continue; y=y+ost*t; t=t*10; } return y; }
Napisati funkciju koja kao argument uzima potrošnju u KWh za veliku i malu tarifu te na standardnom izlazu ispisuje racun za utrošenu elektricnu energiju. Pretpostaviti da je cijena za veliku tarifu po utrošenom KWh 0.10 KM, a cijena za malu tarifu po utrošenom KWh je 0.05 KWh. Prototip funkcije je: void racun(float vt, float mt) gdje : * vt oznacava potrošnju za veliku tarifu * mt oznacava potrošnju za malu tarifu Nakon toga, napišite glavni program koji ucitava potrošnju za veliku tarifu i malu tarifu, te na standardnom izlazu ispisuje racun za tu potrošnju. RJEŠENJE: # include main (){ // Definisanje prototipa funkcije void racun(float vt, float mt); // Definisanje varijabli float vt, mt; // Unos potrosnje po velikoj i maloj tarifi printf("Unesi potrosnju za veliku tarifu: "); scanf("%f", &vt); printf("Unesi potrosnju za malu tarifu: "); scanf("%f", &mt); // Poziv void funkcije (funkcija ne vraca rezultat), sa argumentima vt i mt racun(vt, mt); // Kraj programa getch(); return 0; } // Funkcija koja kreira racun za utrosak energije na osnovu argumenata vt i mt void racun(float vt, float mt) { float cijena; // Racunanje ukupne cijene na osnovu argumenata vt i mt i zadatih cijena cijena=vt*0.10+mt*0.05; // Ispis rezultata printf("\n--------------RACUN ZA UTROSENU EL. ENERGIJU-------------------- "); printf("\nPotrosnja VT: %f KWh", vt); printf("\nPotrosnja MT: %f KWh", mt); printf("\n**************************************************************** "); printf("\nUkupno: %f KM", cijena); printf("\n**************************************************************** "); }
Napisati funkciju koja kao argument uzima tri cijela broja a, p i c. Funkcija vraca cijeli broj koji se dobije tako da se u broju a iza p-te cifre s desne strane umetne cifra c. Ako je p veci od ukupnog broja cifri izlaz iz funkcije treba biti jednak ulazu. Ako se broj c sastoji od više cifri onda se umece samo zadnja cifra iz tog broja. Prototip funkcije je: int umetni(int a, int p, int c) Nakon toga, napišite program koji ucitava neki pozitivan cijeli broj a, poziciju umetanja cifre p i broj koji definira cifru koja se umece c, te poziva funkciju umetni() i ispisuje na standardnom izlazu rezultirajuci broj. RJEŠENJE: # include main (){ // Definisanje prototipa funkcije int umetni(int a, int p, int c); // Definisanje varijabli int a, p, c, rez; // Unos brojeva a,p,c printf("Unesi brojeve a, p, c: "); scanf("%d,%d,%d", &a,&p,&c); // Poziv funkcije umetni() i pridruzivanje rezultata varijabli rez rez=umetni(a,p,c); // Ispis rezultata printf("Rezultat: %d", rez); // Kraj programa getch(); return 0; } // Funkcija koja umece broj c na p-tu poziciju u broju a s desna int umetni(int a, int p, int c) { int t=1, ost, x=0,br=0; // Broju c pridruzuje se samo njegova zadnja cifra c=c%10; /* Racuna se ostatak dijeljenja sa 10 (ost), broju a se "otkida" zadnja cifra. Ukoliko su brojevi p i br (brojac) identicni na to mjesto treba ubaciti broj c. t nam broji decimale (vidi 14. zadatak). Varijabli x se dodaje ostatak ost pomnozen sa t. X je trazeni broj koji funkcija vraca u glavni program. */ while (a>0){ ost=a%10; a=a/10; if (p==br) {x=x+c*t; t=t*10; p=1000;} x=x+ost*t; t=t*10; br++; } return x; }
Napraviti program koji ce na monitoru ispisati prvih N cijelih brojeva i njihove kvadrate u formatu: 1 na kvadrat je 1 2 na kvadrat je 4 3 na kvadrat je 9 .......................... Broj N se unosi sa tastature. Koristiti for petlju. RJEŠENJE: #include int main() { // Definisanje varijabli int n,i; /* Unos broja n sa tastature */ printf("\nUnesi broj n: "); scanf("%d", &n); /* Ispis prvih n brojeva i njihovih kvadrata, krenuvsi od broja 1, i znaci krece od 1 i ide sve do broja za jedan manji od unesenog */ for ( i = 1 ; i < n ; i++ ) printf("\n %d na kvadrat je %d \n", i, i*i); // Kraj programa getch(); return 0; }
Koeficijenti a , a , b , a , a , b se unose sa tastature. Ako 11
12
1
21
22
2
sistem jednadzbi nema rješenje program ispisuje poruku «RJEŠENJE ne postoji». RJEŠENJE: #include int main() { // Definisanje varijabli float a11,a21,a12,a22,x1,x2,b1,b2; /* Unos podataka (U dijelu %fx1%fx2=%f izmedju %fx1 i %fx2 nema plusa, u suprotnom bi morali pri unosu operacije - (minus) upisivati +-) */ printf("\n Unesite 1 linearnu jednacinu a11x1+a12x2=b1 (x1, x2 nepoznate): "); scanf("%fx1%fx2=%f", &a11, &a12, &b1); printf("\n Unesite 2 linearnu jednacinu a21x1+a22x2=b2 (x1, x2 nepoznate): "); scanf("%fx1%fx2=%f", &a21, &a22, &b2); /* Izracunavanje x2 metodom supstitucije */ x2=(b2 * a11 - a21 * b1) / (a22 * a11-a21 * a12); /* Izracunavanje x1 metodom uvrstavanja x2 u prvu jednacinu */ x1=(b1 - a12 * x2) / a11; /* Provjerava se da li je sistem odredjen */ /* Ukoliko je sistem odredjen ispisuju se rjesenja, u suprotnom se ispisuje poruka: RJEŠENJE ne postoji */ if ((a11*a22)==(a12*a21)) printf("\nRJEŠENJE ne postoji!!!"); else printf("\nRezultat je: x1=%.2f i x2=%.2f", x1, x2); // Kraj programa getch(); return 0; }
Napisati program koji ucitava 4 cijela broja, a kao izlaz daje dva najveca broja. Na primjer, ako korisnik kao ulaz unese slijedece cijele brojeve: 23 5 45 33 rezultat izvodjenja programa treba biti: Najveci broj je 45. Drugi broj po velicini je 33. Napomena: Tekstualne poruke vašeg programa trebaju biti iste kao gore navedene. RJEŠENJE: #include int main() { // Definisanje varijabli int i,j,p,niz[4]; /* Unos brojeva niza (4 broja), pomocu for petlje koja ide od 1 do 4. */ printf("\n Unesite 4 cijela broja!"); for(i=1;i<=4;i++){ printf("\n %d broj: ", i); scanf("%d",&niz[i]); } /* Proces sortiranja Koristena je metoda bubblesort (spomenuta u jednom od zadataka ranije), to je metoda „preljevanja“, provjerava se da li je j-ti clan manji od j+1-vog i ako jeste mijenjaju se mjesta. Npr. Unesemo 1,2,3,4. Nakon prvog prolaska imamo 2,1,3,4. Nakon drugog prolaska 2,3,1,4. Nakon treceg prolaska imamo 2,3,4,1. I onda prva for petlja proces ponavlja jos jednom. Pa imamo 3,2,4,1 zatim i 3,4,2,1 pa onda ostaje isto jer je 2 vec vece od 1. Ali niz nije sortiran! Prva for petlja jos jednom pokrece postupak i imamo 4,3,2,1. Proci ce se onako bezveze jos 2 puta kroz petlju „j“ i zatim se izlazi iz petlje, i ispisuju se rezultati*/ for(i=1;i<=3;i++) for(j=1;j<=3;j++) if (niz[j+1]>niz[j]) { p=niz[j]; niz[j]=niz[j+1]; niz[j+1]=p; } /*Ispis rjesenja zadatka*/ printf("\n Najveci broj je %d", niz[1]); printf("\n Drugi broj po velicini je %d", niz[2]); // Kraj programa getch(); return 0; }
Napisati program koji ce sa tastature ucitati prirodan broj, te ispitati da li je broj prost. Ako se unese broj koji nije prirodan (n<=0), program ispisuje poruku „Broj nije prirodan“ i završava. Ako je broj prost program ispisuje poruku „ Uneseni broj je prost“. Ako broj n nije prost program ispisuje poruku „Uneseni broj je slozen“. Ako je unesen broj n=1 program ispisuje poruku: „Broj 1 nije niti prost niti slozen“. Napomena:Pod prostim brojem podrazumijevamo prirodan broj koji se ne moze napisati kao umnozak dvaju prirodnih brojeva manjih od tog broja. Broj 1 nije niti prost niti slozen.
RJEŠENJE: #include main () { // Definisanje varijabli int i,br, ispit; // Unos jednog prirodnog broja printf ("\n Unesi prirodan broj: "); scanf ("%d", &br); // Provjera da li je broj prirodan, i ako nije ispisuje // se poruka da broj nije prirodan if (br<=0) printf("\n Broj nije prirodan"); else // Provjera da li je uneseni broj, broj 1, i ako jeste, // ispisuje se odgovarajuca poruka if (br==1) printf("\n Broj 1 nije ni prost ni slozen"); else /* Ako je unesen prirodan broj veci od 1, provjerava se da li je broj prost ili slozen, varijabla "ispit" kao rezultat. Djelimo broj „br“ sa svakim brojem manjim od polovine unesenog broja. Na pocetku je „ispit=0“ sto nam govori da je broj neparan. Ulazi se u petlju i pocinje dijeljenje sa brojevima 2,3,4... Ako se broj „br“ uspije podijeliti sa nekim od brojeva varijabla ispit ce automatski poprimiti vrijednost 1. U zavisnosti da li je broj „br“ uspio se podijeliti sa nekim brojem bez ostatka, zavisiti ce i cinjenica da li je broj prost ili slozen. */ { ispit=0; i=2; while (i
program koji izracunava n! (n faktorijela). Broj n se unosi sa tastature i treba biti u rasponu [1,20]. Ako broj n nije u datom rasponu, program ispisuje poruku „Uneseni broj nije u datom rasponu“ i završava se program. Napomena: n! je definirano kao n! = n⋅ (n-1) ⋅ (n-2) ⋅....3⋅2⋅1. RJEŠENJE: #include main () { // Definisanje varijabli int i; float n,f; // Unos prirodnog broja printf("\n Unesi broj N u rasponu od [1,20]: "); scanf("%f", &n); /* Racunanje faktorijele, ukoliko je broj u rasponu [1,20]. Faktorijela se racuna tako sto se uneseni broj pomnozi sa svakim brojem manjim od sebe, i sve se to pridruzuje varijabli „f“. */ f=1; if ((n>0) && (n<21)) { for (i=0;i
Email: [email protected] ; MSN: [email protected]
LoVe dOts... ForEver... ETF - 2005/2006
Autor: Murtic Nirmel www.etf.ba
22.
Napisati program koji ce izracunati sumu kvadrata prvih n prirodnih brojeva. Broj n se unosi sa tastature i treba biti u intervalu [2,100]. Ako broj n nije u tom intervalu program ispisuje poruku „Broj nije u zadanom intervalu“ i završava. Na primjer, ako se unese n=3, program ce izracunati sumu: suma=12+22+32=14. RJEŠENJE: #include main () { // Definisanje varijabli int i,broj,suma; // Unosenje prirodnog broja sa tastature u rasponu od [2,100] printf("\n ULAZ: Broj \"N\" u rasponu od [2,100]: "); scanf("%d", &broj); /* Ukoliko se unese broj u tacnom intervalu [1,100] racunanje sume kvadrata. Imamo varijablu suma (na pocetku 0), koja se krece sabirati redom sa: 1*1 + 2*2 + 3*3 + 4*4 ... I sve do unesenog broja.*/ suma=0; if ((broj>1) && (broj<101)) { for (i=1;i<=broj;i++) suma=suma+(i*i); // Ispis sume kvadrata prvih n brojeva printf("\n Suma kvadrata prvih %d brojeva: %d", broj, suma); // Ispis odgovarajuce poruke ukoliko broj n nije u odgovarajucem rasponu } else printf ("\n Uneseni broj nije u datom rasponu!"); // Kraj programa getch(); return 0; }
Napraviti program koji ce na ekranu ispisivati broj PI prema formuli PI=1-1/3+1/5-1/7...1/i, a vrijednost eps unosimo sa tastature i mora biti u intervalu 0.1 do 0.0001. Suma se racuna sve dok je 1/i vece od eps. RJEŠENJE: #include main () { // Definisanje varijabli float eps,pi,n; // Unos broja koji oznacava preciznost printf("\n Unesi broj eps u rasponu od [0.0001,0.1]: "); scanf("\n %f", &eps); /* Provjera da li je broj „eps“ iz odredjenog intervala, i ako jeste racunanje broja „pi“. Radi lakseg sastavljanja formule (jer imamo – i + naizmjenicno) grupisacemo clanove po 2. i onda sve svodimo na operaciju sabiranja razlika 2 broja. Na kraju se brojac uvecava za 4 jer smo odmah po dva clana u formuli koristili */ n=1; pi=0; if ((eps>0.0001) && (eps<0.1)) { while (1/n>eps) { pi=pi+(4/n-4/(n+2)); n=n+4; } // Ispis broja PI printf ("PI je: %f", pi); // Ispis poruke ukoliko broj eps nije u odgovarajucem rasponu } else printf ("\n Broj nije u trazenom rasponu!"); // Kraj programa getch(); return 0; }
Napisati C program koji ce ucitati dimenzije (RA x KA) realne matrice A (maksimalno 10 x 10) , dimenzije (RB x KB) realne matrice B (maksimalno 10 x 10), te ucitati elemente tih matrica. Program zatim treba izracunati matricu C koja je proizvod matrica A i B. Na kraju program treba ispisati sve tri matrice: A, B i C. * RA, RB oznacavaju broj redova matrica A i B, respektivno; * KA, KB oznacavaju broj kolona matrica A i B, respektivno. Prilikom unosa dimenzija matrica program treba provjeriti da li su unesene dimenzije u dozvoljenim granicama, tj. da li je RA<=10, RB<=10, KA<=10, KB<=10, te isto tako program treba provjeriti da li se matrice mogu mnoziti, tj. da li je ispunjeno: KA=RB RJEŠENJE: #include main(){ float A[10][10], B[10][10], C[10][10]; int RA, RB, KA, KB, i, j, k; // Unos dimenzija prve i druge matrice printf("\nUnos dim. matrica A[RA,KA], B[RB,KB], u obliku \"RA,KA,RB,KB\": "); scanf("%d,%d,%d,%d", &RA, &KA, &RB, &KB); // if // if
Ispit uslova: da li su dimenzije u intervalu od 1 do 10. ((RA<=10)&&(RA>0)&&(RB<=10)&&(RB>0)&&(KA<=10)&&(KA>0)&&(KB<=10)&&(KB>0)) { Ispit uslova: da li je broj kolona prve matrice i broj redova druge isti. (KA==RB){
/* Unos elemenata prve matrice A (pomocu 2 for petlje, objasnjeno u jednom od prethodnih zadataka. */ printf("\nUnesi elemente matrice A[%d,%d]: \n", RA, KA); for (i=0;i
/* Racunanje matrice C po formuli C=A*B. Dvije for petlje identicne for petljama pri unosu matrice ili ispisu, koje „setaju“ po redovima i kolonama matrica A,B,C. Prema matematickom postupku proizvod matrica A i B je: C[1][1]=A[0][0] * B[0][0] + A[0][1] * B[1][0] + ... + A[0][n] * B[n][0] sto je primjenjeno na formulu koja se nalazi unutar for petlje sa argumentom „k“. Argument „k“ se krece od 1 do broja kolona prve matrice, i predstavlja broj sabiraka u formuli iznad. C[i][j] = 0; je uvedeno jer vrijednost C[i][j] nije definisana, a moramo je koristiti u formuli unutar for petlje po „k“. */
Napisati C program koji sa standardnog ulaza ucitava elemente realne matrice dimenzija 5 x 5, te izracunava sumu elemenata svake kolone i sumu elemenata svakog reda. Za unos i pohranjivanje matrice koristite dvodimenzionalno polje, dok za pohranjivanje suma po redovima i kolonama trebate koristiti jednodimenzionalno polje. Program takodjer treba pronaci: * u kojoj koloni je najmanja suma, * u kojem redu je najveca suma, te ispisati na standardni izlaz unesenu matricu, redne brojeve i sume pronadjene kolone, odnosno, reda. RJEŠENJE: #include main(){ // Definisanje varijabli float MATRIX[5][5], SUMA[5], sumaR, sumaK; int i,j, Kolona, Red; // Unos elemenata matrice printf("\nUnesi elemente matrice MATRIX[5,5]: \n"); for (i=0;i<5;i++) for (j=0;j<5;j++){ printf("[%d,%d]: ", i+1, j+1); scanf("%f", &MATRIX[i][j]); } /* Postavljanje vrijednosti elemenata niza SUMA na 0 (jer vrijednosti niza SUMA[] nisu definisane. */ for (i=0;i<5;i++) SUMA[i]=0; /* Racunanje suma po redovima. Sabiramo sve brojeve prvog reda, znaci „i“ se ne mijenja, a „j“ se uvecava za 1 sve do 5. I kada se sabere tih 5 brojeva, to je suma prvog reda i zapisuje se u SUMA[0], zatim se isto ponavlja za ostale redove, tako sto se samo „i“ uvecava za 1 i prelazi time na iduci red. */ for (i=0;i<5;i++) for (j=0;j<5;j++) SUMA[i]=SUMA[i]+MATRIX[i][j]; /* Nalazenje najvece od izracunatih suma. Postavlja se da je prva suma najveca, i zatim se provjerava da li od preostalih ima neka koja je veca, i ako je veca, onda se ta suma postavlja da je najveca. Vrijednost „i+1“ nam predstavlja broj reda u kojem je ta suma (na pocetku stavili smo da je „i=1“ jer ispred stoji da je „sumaR=SUMA[0]“. */ sumaR=SUMA[0]; Red=1; for (i=1;i<5;i++) if (sumaR
Email: [email protected] ; MSN: [email protected]
LoVe dOts... ForEver... ETF - 2005/2006
Autor: Murtic Nirmel www.etf.ba
/* Racunanje suma po kolonama... ista procedura, samo smo zamijenili mjesta brojaca „i, j“ unutar „MATRIX[i][j]“. */ for (i=0;i<5;i++) for (j=0;j<5;j++) SUMA[i]=SUMA[i]+MATRIX[j][i]; // Pronalazenje najmanje od izracunatih suma sumaK=SUMA[0]; Kolona=1; for (i=1;i<5;i++) if (sumaK>SUMA[i]) {sumaK=SUMA[i]; Kolona=i+1;} // Ispis matrice MATRIX printf("\nMatrica MATRIX[5,5]: \n"); for (i=0;i<5;i++){ printf("\n"); for (j=0;j<5;j++) printf("%.f ", MATRIX[i][j]); } // Ispis rjesenja printf("\nU %d koloni je najmanja suma koja iznosi %.f", Kolona, sumaK); printf("\nU %d redu je najveca suma koja iznosi %.f", Red, sumaR); // Kraj programa getch(); return 0; }
Program ucitava jednu rijec a i znak c koji se treba prebrojati u toj rijeci. Nakon toga program poziva funkcije duzina() i izbroji () i samogl(), te ispisuje duzinu unesene rijeci a i broj pojavljivanja znaka c u toj rijeci, kao i broj samoglasnika u rijeci. RJEŠENJE: #include // Funkcije „duzina“, „izbroji“ i „samogl“ // Funkcija duzina prima pokazivac na prvo slovo nekog stringa, a zatim u while petlji provjerava se koliko znakova ima rijec, kada se dodje do nultog znaka, izlazi se iz petlje, rezultet je varijabla „d“ koja se vraca iz funkcije. int duzina(char *string) { int d=0; while (*string++!='\0') d++; return d; } /* Slicno prvoj funkciji, samo funkcija pored pokazivaca na prvi znak stringa prima i znak koji se broji. I umjesto da broji se broj clanova, umjesto d++ ide uslov (ako je slovo na koje pokazuje pokazivac nase slovo), „b“ se uveca za 1. Kada „dodje“ while petlja do nultog znaka, izlazi se iz petlje a varijabla „b“ se vraca kao rezultat. NAPOMENA: U gornjoj funkciji stoji u uslovu *string++ sto prebaca pokazivac na iduci clan nakon sto while petlja napravi jedan „krug“, dok u drugoj funkciji stoji u uslovu samo *string ali je poslije if petlje uvecan pokazivac za „1“, sto nam daje opet isti efekat. */ int izbroji(char *string, char c) { int b=0; while (*string!='\0') { if (*string==c) b++; string++; } return b; } /* Identicno funkciji izbroji() samo umjesto provjere „*string==c“ ide uslov da li je „*string“ neki od samoglasnika, a ne znak koji unosimo. Funkcija prima samo pokazivac bez znaka. */ int samogl (char *string) { int b=0; while(*string!='\0') { if (*string=='a'||*string=='A'||*string=='E'||*string=='e'||*string=='I'|| *string=='i'||*string=='O'||*string=='o'||*string=='U'||*string=='u') b++; string++; } return b; }
int main() { // Definisanje varijabli char a[80],c; // Unos rijeci bez razmaka i jednog slova koje ce se prebrojavati printf("\nUnesite jednu rijec do 20 znakova (bez razmaka):"); scanf("%s",a); printf("\nKoji znak treba prebrojati:"); scanf("\n%c",&c); // Ispis rjesenja printf("\nUnesena rijec sadrzi %d znakova!",duzina(a)); printf("\nBroj znakova %c je: %d",c,izbroji(a,c)); printf("\nBroj samoglasnika je: %d", samogl(a)); // Kraj programa getch(); return 0; }
Napisati program koji u realno polje temp ucitava 10 realnih vrijednosti koje predstavljaju temperature u 10 razlicitih dnevnih termina. Program zatim poziva funkcije maxtemp() i prtemp() koje izracunavaju maksimalnu dnevnu temperaturu i prosjecnu dnevnu temperaturu i ispisuje na standardnom izlazu te vrijednosti. RJEŠENJE: #include main () { // Definisanje varijabli float temp[10], *p; int i; // Definisanje prototipa funkcija float maxtemp(float *p); float prtemp(float *p); // Unos 10 temperatura u niz temp[]; for (i=0;i<10;i++) { printf("\nUnesi temperaturu br.%d: ",i+1); scanf("%f", &temp[i]); } // Postavljanje pokazivaca p na prvi clan niza temp[]; p=temp; // Isipis rezultata uz poziv funkcija printf("\nMaksimalna temperatura je: %.1f", maxtemp(p)); printf("\nProsjecna temperatura je: %.1f", prtemp(p)); // Kraj programa getch(); return 0; } /* Funkcija maxtemp() prima pokazivac na realan niz i pomocu for petlje (vidi 11. zadatak) pronalazi se najveci broj (temperatura i vraca se iz funkcije */ float maxtemp(float *p) { float max=*p; int i; for (i=0;i<10;i++) { if (max<*p) max=*p; p++; } return max; } /* Funkcija prtemp() prima pokazivac na realan niz i pomocu for petlje se saberu svi clanovi niza i na kraju (poslije for petlje) se podijeli sve sa 10 (broj temperatura), tj. vraca se vrijednost (pr/10) kao rezultat */ float prtemp(float *p) { float pr=0; int i; for (i=0;i<10;i++) { pr=pr+*p; p++; } return (pr/10); }
Modificirati prethodni program (27) tako da program ucitava cijeli broj n a zatim se sa tastature unosi n vrijednosti za temperature u polje temp. Pretpostaviti da je n<=10. U skladu s tim potrebno je modificirati funkcije maxtemp() i prtemp() tako da imaju slijedece prototipove: float maxtemp(int n, float *p); float prtemp(int n, float *p); RJEŠENJE: # include main () { // Definisanje varijabli float temp[10], *p; int i, n; // Definisanje prototipa funkcija float maxtemp(int n, float *p); float prtemp(int n, float *p); // Unos broja n printf("\nUnesi broj temperatura: "); scanf("%d", &n); // Unos n temperatura u niz temp[]; for (i=0;i
Email: [email protected] ; MSN: [email protected]
LoVe dOts... ForEver... ETF - 2005/2006
Autor: Murtic Nirmel www.etf.ba
29.
Napisati funkciju s imenom adresa() koja kao argument uzima dva stringa koji predstavljaju ime i prezime a kao rezultat vraca se novi string koji se dobije tako da se string koji predstavlja prezime promijeni u string koji predstavlja e-mail adresu slijedeceg oblika: [prezime].[ime]@etf.unsa.ba Prototip funkcije je: char *adresa(char *ime, char *prezime) Na primjer, ako su argumenti ime=“Marko“, prezime=“Markovic“ funkcija adresa() vraca pokazivac na rezultirajuci string prezime koji je promijenjen u novi string oblika: [email protected]. Nakon toga, napisati glavni program koji ucitava ime i prezime neke osobe i na standardnom izlazu ispisuje toj osobi pridruzenu e-mail adresu koja se dobije pozivom funkcije adresa(). RJEŠENJE: #include // Funkcija adresa() char *adresa(char *ime, char *prezime) { // Definisanje varijabli potrebnih za rad u funkciji char *p, POMOC[]="@etf.unsa.ba", *POM; /* Pointer „p“ pokazuje na pocetak prezimena, a „POM“ pokazuje na pomocni niz “POMOC“ u kojem se nalazi string „@etf.unsa.ba.“ */ p=prezime; POM=POMOC; // Generisanje email adrese // Ova while petlja pokazivac postavi iza zadnjeg znaka, tj. Na nulti znak. while (*p!='\0') p++; // Umjesto nultog znaka upise se „.“ i predje se na iduci znak *p='.'; p++; // Poslije tacke se ubacaju karakteri iz niza na koji pokazuje pokazivac „ime“ while (*ime!='\0') { *p=*ime; ime++; p++; } // Poslije imena se doda string na koji pokazuje pokazivac „POM“ while (*POM!='\0') { *p=*POM; POM++; p++; } // Vracanje pokazivaca iz funkcije return p; } // Glavni program int main(){ // Definisanje varijabli char *ime, *prezime, *c; char U1[100], U2[100]; // Unos podataka ime i prezime printf("\nUnesi ime:"); scanf("%s", &U1); printf("\nUnesi prezime:"); scanf("%s", &U2); // Postavljanje pokazivaca „c“ na pocetak prezimena c=U2; // Postavljanje pokazivaca ime i prezime na stringove U1 i U2
ime=U1; prezime=U2; // Poziv funkcije „adresa()“ i slanje pokazivaca „ime“ i „prezime“ u funkciju prezime=adresa(ime, prezime); // Ispis Email adrese printf("\nGenerirana korisnikova Email adresa: %s", c); // Kraj programa getch(); return 0; }
Napisati funkciju koja kao argument uzima znakovno polje jmbg (jedinstveni maticni broj gradjanina) a kao izlaz vraca strukturnu varijablu koja predstavlja datum rodjenja doticne osobe. Prototip funkcije je: struct datum fdatum(char *jmbg) gdje struct datum predstavlja strukturu definiranu kao: struct datum { int dan; int mjesec; int godina; }; Na primjer, ako je strukturna varijala drodj definirana kao: struct datum drodj; te ako je ulaz u funkciju jmbg=“2405978234567“ poziv funkcije drodj=fdatum(jmbg); treba vratiti strukturnu varijablu koja predstavlja datum 24.05.1978., tj. funkcija vraca slijedece podatke strukturne varijable tipa datum: drodj.dan=24; drodj.mjesec=5; drodj.godina=1978; Nakon toga napišite glavni program koji sa standardnog ulaza ucitava jmbg kao znakovno polje a nakon poziva funkcije fdatum() ispisuje datum rodjeja osobe sa doticnim jedinstvenim maticnim brojem. RJEŠENJE: # include // Definisanje strukture datum struct datum { int dan; int mjesec; int godina; }; /* Funkcija koja vraca datum kreiran od znakovnog polja u koje je upisan maticni broj */ struct datum fdatum(char *jmbg){ // Definisanje varijable drodj kao strukturne varijable od datum struct datum drodj; // Definisanje pokazivaca koji pokazuje na strukturnu varijablu struct datum *pd; int i;
// Racunanje varijabli strukturne varijable // Pretpostavka je da je korisnik ciji maticni broj unesete rodjen 1xxx godine drodj.dan=0; drodj.mjesec=0; drodj.godina=1000; // Racunanje jedinice dana for (i=0;i<10;i++) if (*jmbg==49+i) drodj.dan=10*(1+i); // Racunanje desetice dana i sabiranje sa jedinicom for (i=0;i<10;i++) if (*(jmbg+1)==49+i) drodj.dan+=(1+i); // Racunanje jedinice mjeseca for (i=0;i<10;i++) if (*(jmbg+2)==49+i) drodj.mjesec=10*(1+i); // Racunanje desetice mjeseca i sabiranje sa jedinicom for (i=0;i<10;i++) if (*(jmbg+3)==49+i) drodj.mjesec+=(1+i); // Racunanje stotice godine i sabiranje sa 1000 for (i=0;i<10;i++) if (*(jmbg+4)==49+i) drodj.godina+=100*(1+i); // Racunanje desetice godine i sabiranje sa stoticom for (i=0;i<10;i++) if (*(jmbg+5)==49+i) drodj.godina+=10*(1+i); // Racunanje jedinice godine i sabiranje sa deseticom for (i=0;i<10;i++) if (*(jmbg+6)==49+i) drodj.godina+=(1+i); // Postavljanje pokazivaca na prvi znak strukturne varijable „drodj“ pd=&drodj; // Funkcija vraca objekat koji se nalazi na adresi na koju pokazuje „pd“ return *pd; } // Glavni dio programa main () { struct datum drodj; char jmbg[40], *p; // Pretpostavka je da je uneseni maticni broj odgovarajuci printf("Unesi maticni broj: "); scanf("%s", &jmbg); // Poziv funkcije fdatum i pridruzivanje rezultata strukturnoj varijabli drodj drodj=fdatum(jmbg); // Ispis rjesenja printf("\nDatum rodjenja: %d.%d.%d", drodj.dan, drodj.mjesec, drodj.godina); // Kraj programa getch(); return 0; }
Napisati program koji broji rijeci koje imaju n znakova u tekstualnoj datoteci cije ime se unosi sa tastature. Na primjer, ako u direktoriju(folderu) T11 na disku C: postoji datoteka pismo.txt sa slijedecim sadrzajem: Lijep pozdrav! Sretnu i uspjesnu Novu godinu zeli Vam kompanija BHKOM. Isto tako se nadamo da ce se dosadasnja uspjesna saradnja nastaviti i u novoj 2006. godini. Direktor: IVIC IVICA program treba nakon unosa imena sa tastature i broja n: Unesite broj znakova: 5 Unesite ime datoteke: C:\T11\pismo.txt dati slijedeci izlaz: Datoteka pismo.txt sadrzi 4 rijeci sa 5 znakova. Napomene: Rijeci sa pet znakova za gore navedenu datoteku su: {Lijep, BHKOM, novoj, IVICA}. Prilikom brojanja znakova ne uzimaju se u obzir znakovi interpunkcije: tacka (.), zarez (,), usklicnik (!) i sl. Prilikom rješavanja zadatka obavezno napravite testnu datoteku pismo.txt i pohranite je u direktorij T11, te tu datoteku koristite za testiranje vašeg rješenja. RJEŠENJE: # include main() { // Definisanje varijabli FILE *datoteka; char dat[60], znak; int znakovi, br=0, rez=0; // Unos putanje do datoteke printf("Unesi putanju do datoteke: "); scanf("%s", &dat); // Ispituje se da li datoteka postoji, ako postoji, ide se dalje u program u // suprotnom se ispisuje error poruka i izlazi iz programa if ( (datoteka = fopen (dat, "r")) == NULL) { printf("Greska kod otvaranja datoteke %s !\n", dat); getch(); exit(1); } // Unos broja znakova printf("Unesi broj znakova: "); scanf("%d", &znakovi); /* While petlja vrti se i uzima se znak po znak iz datoteke sve dok ne dodje se do kraja datoteke i kada stignemo na kraj izlazi se iz programa. Ukoliko je uneseni karakter razlicit od znakova ? ! . \n , \t i blanko znaka onda se varijabla br uveca za jedan, u suprotnom se provjeri da li je broj br jednak broju znakova koji smo unjeli, i ako jeste varijabla rez se uveca za jedan, i onda se br postavi na 0. Kada stignemo do kraja datoteke izlazi se iz petlje.*/
while((znak=fgetc(datoteka))!=EOF){ if ((znak=='?')||(znak=='!')||(znak==' ') ||(znak=='.')||(znak=='\n')||(znak==',')||(znak=='\t')) { if (br==znakovi) rez++; br=0;} else br++; } /* Ukoliko zadnja rijec se sastoji od trazenog broja znakova, ona nece biti uracunata jer smo izasli iz petlje, pa je potrebno dodati ovaj uslov iza petlje da bi smo imali 100% tacan program*/ if (br==znakovi) rez++; //Zatvaranje datoteke fclose(datoteka); // Izlaz iz programa printf("Datoteka %s sadrzi %d rijeci sa %d znakova.", dat, rez, znakovi); getch(); return 0; }
Napravite tekstualnu datoteku “ORPodaci.txt“ (pomocu programa Notepad ili slicnog) slijedeceg formata: [prezime ]· · · · · ·[ime] · · · · ·[brbod1] · · · · · ·[brbod2] gdje : - kolona [prezime] zauzima 15 mjesta; - kolona [ime] zauzima 10 mjesta; - kolona [brbod1] zauzima 4 mjesta i predstavlja broj bodova na prvom parcijalnom ispitu - kolona [brbod2] zauzima 4 mjesta i predstavlja broj bodova na drugom parcijalnom ispitu - U datoteku “ORPodaci.txt“ unesite podatke za 15 studenata. - Spasite datoteku “ORPodaci.txt“ u direktorij C:\T12. - VAZNO: Prilikom kreiranja datoteke “ORPodaci.txt“ budite precizni u zauzimanju mjesta za pojedine kolone. Zatim, napisati program koji ucitava sadrzaj tekstualne datoteke “ORPodaci.txt” i na temelju te datoteke kreira novu datoteku pod imenom “Polozili.txt” u kojoj se treba nalaziti sortiran (od veceg prema manjem) spisak onih studenata koji su polozili oba parcijalna ispita (to su oni studenti koji imaju na oba parcijalna 10 ili više bodova). Datoteka “Polozili.txt” je slijedeceg formata: [prezime ]· · · · · · · ·[ime] · · · · · · ·[ukupno] gdje : - kolona [prezime] zauzima 15 mjesta; - kolona [ime] zauzima 10 mjesta; - kolona [ukupno] zauzima 4 mjesta i predstavlja ukupan broj bodova sa oba parcijalna ispita. RJEŠENJE: #include #include /* Definisanje strukture forma koja se sastoji iz varijabli prezime i ime tipa char i prvi i drugi tipa integer */ struct forma { char prezime[15]; char ime[10]; int prvi; int drugi; };
main(){ /* Definisanje varijabli: Neo - pokazivac na fajl koji se cita Trinity - pokazivac na fajl u koji se pise
podaci[15] - strukturni niz podaci u koji ce se upisati svi podaci koji se ucitaju iz fajla, maksimalno 15... Love - pomocna strukturna varijabla i,j,k - potrebni projaci za sortiranje, i jos ponesta :) */ FILE *Neo, *Trinity; struct forma podaci[15]; struct forma Love; int i=0, j=0, k=0; /* Otvaranje datoteke ORPodaci.txt i pridruzivanje pokazivacu Neo, ako ne postoji datoteka izlazi se iz programa */ if ((Neo=fopen("C:\\T12\\ORPodaci.txt","r"))==NULL) { printf("Greska pri otvaranju datoteke"); exit(1); } /* Datoteka polozili.txt se kreira i pridruzuje pokazivacu Trinity */ Trinity = fopen ("c:\\T12\\Polozili.txt", "w"); /* Citanje podataka iz datoteke i upisivanje istih u strukturu podaci. Varijabla i se vraca kao broj koji oznacava broj studenata koji su polozili obe parcijale. podaci[i].prvi se automatski sabira sa podaci[i].drugi i ukupna vrijednost postaje ustvari podaci[i].prvi!*/ while(fscanf(Neo,"%15s%10s%4d%4d",&podaci[i].prezime,&podaci[i].ime,&podaci[i] .prvi,&podaci[i].drugi) != EOF ) { if ((podaci[i].prvi>=10)&&(podaci[i].drugi>=10)) podaci[i].prvi+=podaci[i].drugi; else i--; i++; } // Proces sortiranja... objasnjen u jednom od zadataka ranije... for(j=0;jpodaci[j].prvi) { Love=podaci[j]; podaci[j]=podaci[k]; podaci[k]=Love; } // Upis podataka u datoteku na koju pokazuje pokazivac Trinity (Polozili.txt) for (j=0; j
Email: [email protected] ; MSN: [email protected]
LoVe dOts... ForEver... ETF - 2005/2006
Autor: Murtic Nirmel www.etf.ba
33.
Napisati funkciju okreni() koja kao argument uzima neki string i okrece sadrzaj tog stringa naopako. Prototip funkcije okreni() treba biti: void okreni(char* p) Zatim napravite glavni program koji sa standardnog ulaza ucitava neki string, te ga ispisuje naopako. Primjer: Unesite string: Sarajevo Naopako: ovejaraS RJEŠENJE: #include // Funkcija okreni void okreni(char *p){ // Definisanje pomocnih varijabli char pom; int i=0, j=0, br=0; // Brojanje slova rijeci, pointer „odlazi“ na kraj rijeci. while (*p!='\0') {br++; p++;} /* Pointer je „otisao“ na kraj rijeci, a nama treba u nastavku da je na pocetku, pa cemo ga vratiti na pocetak tako sto ga pomaknemo za isti broj mjesta nazad, za koji smo ga while petljom pomjerili naprijed! */ p=p-br; // Glavni dio programa, ALGORITAM. /* Recimo da smo unjeli rijec LOVE. Rijec koju trebamo dobiti kao rezultat je EVOL. Znaci potrebno je zamjeniti zadnje slovo sa prvim, i drugo sa predzadnjim. Brojac „i“ nam predstavlja znak do kojeg smo dosli sprijeda, a brojac „j“ straga. Na pocetku ce biti i=0, j=3 (jer je br=3, nemojte se zbuniti sto je 3 a ne 4, tu su ipak cetiri clana 0,1,2,3). Znaci nakon sto se for petlja jednom izvrsi „i“ se uveca za 1 i postaje 1, a j se umanji za 1 i postane 2. Znaci u prvom slucaju pomocu pomocne varijable „pom“ mijenjamo znakove na 0 i 3 poziciji, drugi put ce se zamjeniti znakovi na 1 i 2 poziciji. I dobili smo trazenu rijec. Mozda zbunjuje uslov i
// Postavljanje pokazivaca „t“ na „NIZ“ t=NIZ; // Pozivanje funkcije i slanje pokazivaca „t“ u funkciju okreni(t); /* Ispis stringa NIZ preuredjenog funkcijom (printa se „t“, a „t“ nam pokazuje na „NIZ“). */ printf("%s", t); // Kraj programa getch(); return 0; }
Napisati funkciju ubaci5() koja kao argument uzima neki prirodni broj n i dva broja a i b, a zatim vraca se broj koji bi nastao zamjenom cifri na mjestu a i b cifrom 5 (gledano s desne strane). Funkcija ne treba ništa ispisivati. Funkcija ubaci5() treba imati prototip: int ubaci5(int n,int a,int b); Pretpostaviti da su a i b valjano unesene vrijednosti koje imaju smisla. Primjeri ulaznih argumenata i vracenih vrijednosti: Primjer1: za ulazne argumente n=123321, a=2, b=3 funkcija vraca broj 123551. Primjer 2: za ulazne argumente n=23455, a=3, b=5 funkcija vraca broj 53555. RJEŠENJE: #include // Funkcija ubaci5(); int ubaci5(int n,int a,int b) { // Definisanje varijabli int c=0,t=1,o,i; /* Brojac „i“ krece od 1(prvi znak straga) i ide dok broj „n“ koji smo primili u funkciju ne postane 0. Svaki put kada for petlja se izvrsava ponovo, uzima se ostatak dijeljenja sa 10, odnosno uzima se zadnja cifra broja „n“, i pridruzuje varijabli „o“. Zatim se broj „n“ podijeli sa 10, cime mu se odbije zadnja cifra. Suma „c“ se uvecava za „t*o“ gdje t se mijenja kao 1,10,100,1000. Kada i bude jednako „a“ ili „b“ onda se umjesto „t*o“ doda „t*5“ i time se na „a-to/b-to“ mjesto doda broj 5 umjesto broja koji je bio na toj poziciji. Naredba „continue;“ ce vratiti na pocetak for petlje kako se nebi izvrsile i linije ispod, jer bi time dobili ubacivanje brojeva, a ne zamjenu!!! Savjet: Probajte napisati recimo petocifren broj, i skontajte malo na papiru prvo kako biste te zamjene uradili, skontajte ulogu varijabli „o“ i „t“!!! */ for (i=1;n>0;i++){ o=n%10; n=n/10; if (i==a) {c=c+t*5; t=t*10; continue;} if (i==b) {c=c+t*5; t=t*10; continue;} c=c+t*o; t=t*10;} return c;} main(){ // Definisanje varijabli a,b,n int n, a, b; // Unos brojeva a,b,n printf("Unesi prirodan bron n:"); scanf("%d", &n); printf("Unesi brojeve a,b:"); scanf("%d,%d", &a, &b); /* Poziv funkcije, slanje n,a,b u funkciju, a rezultat se pridruzuje varijabli n, koja se printa u iducoj liniji. */ n=ubaci5(n,a,b); printf("%d", n); // Kraj programa. getch(); return 0; }
Napisati program koji ucitava podatke iz ulazne formatirane tekstualne datoteke „gradovi.txt“ i kreira izlaznu datoteku „prosjeci.txt“ koja sadrzi spisak gradova s prosjecnom temperaturom za prva tri mjeseca. Datoteka „gradovi.txt“ je sljedeceg formata: [grad] [JAN] [FEB] [MAR] gdje je: [grad] kolona u kojoj su zapisani nazivi gradova i koja zauzima 15 mjesta; [JAN], [FEB], [MAR] kolona u kojoj su zapisane cjelobrojne prosjecne temperature za mjesec januar, februar i mart, respektivno. Ove kolone zauzimaju po 10 mjesta. Datoteka „prosjeci.txt“ je slijedeceg formata: [grad] [PRTEMP] gdje je: [grad] kolona u kojoj su zapisani nazivi gradova i koja zauzima 15 mjesta; [PRTEMP] kolona u kojoj su zapisane prosjecne temperature koristeci dva decimalna mjesta i maksimalno dva mjesta prije decimalne tacke. Primjer sadrzaja datoteke „gradovi.txt“: TRAVNIK 0 1 2 ZENICA 2 3 4 TUZLA 2 5 5 SARAJEVO 0 3 1 Primjer sadrzaja datoteke „prosjeci.txt“: TRAVNIK 1.00 ZENICA 3.00 TUZLA 4.00 SARAJEVO 1.33 RJEŠENJE: #include main(){ // Definisanje varijabli FILE *Neo, *Trinity; char grad[15]; float JAN, FEB, MAR, PRO; /* Provjera da li postoji datoteka gradovi.txt i ako ne postoji ispis greske, u suprotnom se nastavlja program */ if ((Neo=fopen("C:\\gradovi.txt","r"))==NULL) { printf("Greska pri otvaranju datoteke"); return 0; } // Otvaranje datoteke prosjeci.txt Trinity=fopen("C:\\prosjeci.txt","w"); /* Citanje podataka iz datoteke gradovi.txt izracunavanje prosjecne temperature PRO i printanje u datoteku prosjeci.txt */
Napisati funkciju izbacip() koja kao argument uzima neki prirodni broj n, a zatim vraca broj koji bi nastao izbacivanjem parnih cifri iz tog broja. Funkcija ne treba ništa ispisivati. Funkcija izbacip() treba imati prototip: int izbacip(int n); Na primjer, za argument 123420 funkcija treba vratiti broj 13. RJEŠENJE: // Funkcija izbacip() prima neki integer broj int izbacip(int n){ /* Definisanje varijabli, „t“ je tezisnica koja se svaki put kada dodajemo neku cifru pomnozi sa 10, „o“ je ostatak, „i“ je brojac, a „c“ je broj koji ce funkcija vratiti kao rezultat */ int c=0,t=1,o,i; /* „i“ se uvecava za 1 i for petlja se vrti sve dok broj „n“ bude jednak 0 */ for (i=1;n>0;i++){ /* Uzima se ostatak dijeljenja sa 10, odnosno zadnja cifra broja */ o=n%10; // „Odbije“ se zadnja cifra broja „n“ dijeljenjem sa 10 n=n/10; /* Ako je broj paran, vraca se na pocetak petlje i time se izbacaju parne cifre */ if (o%2==0) continue; // Dodavanje cifre na broj „c“ c=c+t*o; // Mnozenje tezisnice sa 10 t=t*10; } // Vracanje varijable c return c; }
Napisati funkciju ispis_preko_a() koja kao argment uzima neko cjelobrojno polje i dva prirodna broja a i d, a zatim ispisuje sve elemente polja koji su veci od broja a. Broj d predstavlja broj elemenata polja. Funkcija treba imati slijedeci prototip: void ispis_preko_a(int *polje, int a, int d) Na primjer, za ulazne argumente int polje[]={4,5,7,20,8,10,2,-2}, a=6, d=8 trebaju se ispisati brojevi: 7, 20, 8, 10 RJEŠENJE: // Funkcija prima pokazivac na polje, i dva cijela broja „a“,“d“ void ispis_preko_a(int *polje, int a, int d) { // Definisanje brojaca „i“ int i; /* For petlja se „vrti“ sve dok brojac i koji krece od 0 ne bude veci od broja „d“ koji je funkcija primila. */ for (i=0; i
Email: [email protected] ; MSN: [email protected]
LoVe dOts... ForEver... ETF - 2005/2006
Autor: Murtic Nirmel www.etf.ba
38.
Napisati funkciju zamijeni() koja ce u jednodimenzionalnom polju A velicine d zamijeniti i-ti element sa minimalnim elementom u polju A. Elementi polja A su vec definirani u glavnom programu. Funkcija treba imati prototip: void zamijeni(int *A, int i, int d) Na primjer, ako su elementi polja A: int A[]={3, 7, 10, 20, 18, 4,10, 2, 20], a argumenti i i d imaju slijedece vrijednosti i=3, d=9 funkcija zamijeni() promjeni polje A u polje sa slijedecim elementima: 3, 7, 2, 20, 18, 4, 10, 2, 20 (na trece mjesto se stavlja minimalni element iz polja a to je 2) RJEŠENJE: // U funkciju se prima niz brojeva „A“, broj „i“, broj „d“. void zamijeni(int *A, int i, int d) { // Definisanje brojaca „j“ i varijable „min“ int j,min; // Postavljanje vrijednosti „min“ na prvi clan niza min=A[0]; /* Trazenje najmanjeg elementa u nizu. Pretpostavili smo da je to prvi broj, i sada trebamo ispitati da li postoji neki broj krenuvsi od drugog (j=1 umjesto j=0 u for petlji) i ako postoji neki manji postavi se da je taj broj „min“. */ for (j=1; jA[j]) min=A[j]; /* Postavljanje na i-tu poziciju vrijednosti „min“ (i=1 ide jer nam je i-ti clan ustvari broj za jedan manje, jer nam je prvi clan nulti clan! */ A[i-1]=min; // Ispis niza for (j=0; j
Email: [email protected] ; MSN: [email protected]
LoVe dOts... ForEver... ETF - 2005/2006
Autor: Murtic Nirmel www.etf.ba
39.
Data je tekstualna datoteka c:\pismo.txt. Napisati funkcije za: a) ispis datoteke na standardni izlaz zadrzavajuci strukturu po redovima; b) prepis datoteke u novu mijenjajuci mala i velika slova; c) ispisati datoteku u obrnutom redosljedu na izlaz (prva postaje zadnja, druga postaje pretposljednja rijec...) d) ispitati da li je neka rijeè palindrom (isto znacenje kada se cita i u obrnutom smjeru) RJEŠENJE: # include // Ispis datoteke na standardni izlaz zadrzavajuci strukturu po redovima... void ispis(FILE *datoteka){ char znak; printf("\nSadrzaj datoteke je: \n\n"); while(fscanf(datoteka,"%c", &znak)!=EOF){ printf("%c", znak); } } /* Ispitati da li je neka rijec palindrom (isto znacenje kada se cita i u obrnutom smjeru) */ void palindrom(FILE *datoteka){ char znak[100]; char *p, *t; int i, br=0, ispit=0; printf("\n\nProvjera palindroma: \n"); while(fscanf(datoteka,"%s", &znak)!=EOF){ p=znak; t=znak; br=0; while(*p!='\0') {p++; br++;} p--; ispit=1; for(i=0;i<(br/2);i++) if (*(p-i)!=*(t+i)) {ispit=0; break;} if (ispit==1) {printf("\nPalindrom je: %s", znak); ispit=0;} } } // Prepis datoteke u novu mijenjajuci mala i velika slova void ispisunovu(FILE *datoteka){ FILE *datoteka1; char znak; datoteka1=fopen("c:\\pismo1.txt","w"); while(fscanf(datoteka,"%c", &znak)!=EOF){ if ((znak>64)&&(znak<91)) znak=znak+32; else if ((znak>96)&&(znak<122)) znak=znak-32; fprintf(datoteka1, "%c", znak); } fclose(datoteka1); }
/* Ispisati datoteku u obrnutom redosljedu na izlaz (prva postaje zadnja, druga postaje pretposljednja rijec...) */ void ispisobrnuto(FILE *datoteka){ char znak, matrix[1000][1000], pok[1000]; int i=0, j=0, br=0, k=0, niz[100]; printf("\n\nSadrzaj datoteke je (naopako): \n"); while(fscanf(datoteka,"%c", &znak)!=EOF){ if (znak==' ') {br++; j++; i=0; continue;} if (znak=='\n') {br++; niz[k]=j; j++; k++; i=0; continue;} matrix[j][i]=znak; i++; } niz[k]=j; j=0; for (i=br;i>=0;i--) { if((i==niz[k-j])&&(k-j!=-1)) { printf("\n"); j++;} printf("%s ", matrix[i]); } } main() { // Definisanje pokazivaca na datoteku FILE *datoteka; // Otvaranje datoteke za citanje datoteka=fopen("c:\\pismo.txt","r"); // Poziv funkcije za ispis datoteke na ekran... ispis(datoteka); fclose(datoteka); // Otvaranje datoteke za citanje datoteka=fopen("c:\\pismo.txt","r"); // Poziv funkcije za prepis datoteke u novu mijenjajuci mala i velika slova. ispisunovu(datoteka); fclose(datoteka); // Otvaranje datoteke za citanje datoteka=fopen("c:\\pismo.txt","r"); /* Poziv funkcije za ispis datoteke u obrnutom redosljedu na izlaz (prva postaje zadnja, druga postaje pretposljednja rijec...) */ ispisobrnuto(datoteka); fclose(datoteka); // Otvaranje datoteke za citanje datoteka=fopen("c:\\pismo.txt","r"); /* Poziv funkcije za ispitivanje da li je neka rijec palindrom (isto znacenje kada se cita i u obrnutom smjeru) */ palindrom(datoteka); fclose(datoteka); // Kraj programa... getch(); return 0; }
Napisati program koji cita više linija teksta sa ulaza i štampa koliko rijeci je duzine 2 3 4 i više slova. Štampu realizovati pomocu funkcije STAM_REZ u datoteku ili na ekranu. Iz datoteke rezultata dati izvještaj o ukupnom broju rijeci i prosjecnoj duzini rijeci. RJEŠENJE: #include // Funkcija koja kreira datoteku sa rezultatima void STAM_REZ(char *tekst, int br){ // Definisanje pokazivaca na fajl FILE *rezultati; // Definisanje varijabli int i,b=0,dva=0,tri=0,cetiri=0,vise=0, brojslova=0, prosjek=0; // Otvaranje datoteke u koju cemo pisati podatke rezultati=fopen("c:\\rezultati.txt","w"); // For petlja vrti se "br" puta... for (i=0;i 1 broj slova ce se sabrati sa brojem slova rijeci koja se trenutno obradjuje, ako je b=2 onda se varijabla dva koja broji rijeci sa 2 slova uveca za 1. Ako je tri onda se varijabla tri uveca za 1... ako je preko 4 onda se varijabla vise uveca za 1... primjetite da se brojac vraca na 0 izlaskom iz uslova, nebitno da li je bilo b=0 ili 1 ili 2 ili ... */ if (b>1) brojslova=brojslova+b; if (b==2) {dva++; b=0;} else if (b==3) {tri++; b=0;} else if (b==4) {cetiri++; b=0;} else if (b>4) {vise++; b=0;} else b=0; } else b++; } // Upis podataka u datoteku... fprintf(rezultati,"Rijeci sa 2 slova: %d\n", fprintf(rezultati,"Rijeci sa 3 slova: %d\n", fprintf(rezultati,"Rijeci sa 4 slova: %d\n", fprintf(rezultati,"Rijeci sa preko 4 slova: %d\n", prosjek=brojslova/(dva+tri+cetiri+vise); fprintf(rezultati,"PROSJEK: %d\n", prosjek);
/* Zatvaranje datoteke i izlaz iz funkcije... „void“ funkcija ne vraca nista!!! Izlaskom je sve sto se u njoj desavalo zaboravljeno, ali zato imamo sve rezultate pohranjene u datoteci iz koje cemo po povratku u program citati podatke.*/ fclose(rezultati); } // Glavni program main(){ // Definisanje varijabli int br=0, i=0, p=0, dva, tri, cetiri, vise, prosjek; char tekst[1000]; // Definisanje pokazivaca na fajl FILE *izvjestaj; /* Unos teksta (koristio sam while petlju koja upisuje znak po znak, a ne %s koja upisuje cijeli string odjednom, a zasto? pa jednostavno jos uvijek neznam drugi nacin da izbjegnem situaciju kad upisete prvi razmak, a program to shvati kao kraj stringa i racuna samo da je string prva rijec, a ostalo kao da niste unjeli. Ovako se ucita sve sto unesete sa tastature, sto nam i treba. U zadatku nije naznaceno sta ce biti prekid unosa, pa sam ja stavio tacku :) )*/ printf("Unesi tekst[i], (Tacka za kraj unosa!):"); while (tekst[i-1]!='.') { scanf("%c", &tekst[i]); i++; br++;} /* Poziv funkcije u koju saljemo tekst koji smo unijeli kao i brojac „br“ koji je prebrojao broj unesenih karaktera, mogli smo i bez njega, al eto ja nekako vise volim for petlje od while petlji :) */ STAM_REZ(tekst, br); // Otvaranje datoteke za citanje i pridruzivanje pokazivacu izvjestaj. izvjestaj=fopen("c:\\rezultati.txt","r"); // Citanje podataka iz datoteke... formati fscanf(izvjestaj,"Rijeci sa 2 slova: fscanf(izvjestaj,"Rijeci sa 3 slova: fscanf(izvjestaj,"Rijeci sa 4 slova: fscanf(izvjestaj,"Rijeci sa preko 4 slova: fscanf(izvjestaj,"PROSJEK: %d", &prosjek);
isti kao pri upisu :) %d\n", &dva); %d\n", &tri); %d\n", &cetiri); %d\n", &vise);
// Ispis izvjestaja na ekranu. printf("\n\nIZVJESTAJ: "); printf("\n\nUkupno rijeci: %d", dva+tri+cetiri+vise); printf("\nProsjecna duzina rijeci: %d", prosjek); // Zatvaranje datoteke i kraj programa fclose(izvjestaj); getch(); return 0; }
Program treba unjeti 2 broja i ispisati NZD... najveci zajednicki djeljilac... RJEŠENJE: #include main() { // Definicija varijabli int i,a,b,min,nzd=1; // Unos dva prirodna broja printf("Unesi dva broja: "); scanf("%d,%d", &a, &b); // Pridruzuje se varijabli min manji od unesena 2 broja if (a<=b) min=a; else min=b; // I se stavlja da je jednako min, i umanjuje se sve do 1... prvi broj // sa kojem uspiju podijeliti se oba broja je i NZD... izlazi se iz petlje kad // se oba broja uspiju bodijeliti... for (i=min;i>0;i--){ if (((a%i)==0)&&((b%i)==0)) {nzd=i; break;} } // Ispis NZD-a printf("\nNajveci zajednicki sadrzilac je: %d" , nzd); // Kraj programa getch(); return 0; }
Unesite broj clanova niza cijelih brojeva, a zatim i clanove niza a zatim ih sortirajte od najveceg ka najmanjem i ispisite sortirano na ekran. RJEŠENJE: # include main(){ // Definisanje varijabli int n,i,j,niz[100],pom; // Unos broja clanova niza printf("\n Unesite broj clanova: "); scanf("%d", &n); /* Unos niza */ for (i=0;i ... :) */ for (i=0;i<(n-1);i++) for (j=0;j<(n-1);j++) if (niz[j]
Email: [email protected] ; MSN: [email protected]
LoVe dOts... ForEver... ETF - 2005/2006
44.
Autor: Murtic Nirmel www.etf.ba
Zadatak br. 43. (prethodni) na drugi nacin...
RJEŠENJE: # include main(){ // Definisanje varijabli int n,i,j,niz[100],pom; // Unos broja clanova niza printf("\n Unesite broj clanova: "); scanf("%d", &n); /* Unos niza */ for (i=0;i
-
3 1 4 2 5
4 1 3 2 5
4 1 3 2 5
5 1 3 2 4
5 3 1 2 4
5 3 1 2 4
5 4 1 2 3
5 4 2 1 3
5 4 3 1 2
5 4 3 2 1
Vidite kako smo dosli do rezultata uz samo 11 permutacija, naspram onih 16 iz prvog primjera. Znaci u prvom dijelu ovog grafickog prikaza, nadjen je najveci broj niza i stavljen na vrh (broj 5). U drugom dijelu (primjetite da smo smanjili broj okretanja sa 4 na 3 jer nas vise broj na vrhu ne interesuje, i samo od preostalog niza od 4 clana trazimo najveci i stavljamo na vrh... i tako do kraja. */ for (i=0;i<(n-1);i++) for (j=i+1;jniz[i]) { pom=niz[i]; niz[i]=niz[j]; niz[j]=pom; } // Ispis niza i kraj programa... printf("\n Ispis niza: "); for (i=0;i
Email: [email protected] ; MSN: [email protected]
LoVe dOts... ForEver... ETF - 2005/2006
Autor: Murtic Nirmel www.etf.ba
45.
Unosi se sa ulaza broj clanova. Zatim se unese IME, PREZIME i broj bodova svakog clana. Na izlazu treba ispisati clanove sortirane po broju bodova. RJEŠENJE: # include // Definisanje strukture struct struktura { char ime[100]; char prezime[100]; int bodovi; }; main(){ // Definisanje varijabli int n,i,j; struct struktura spisak[100]; struct struktura pom; // Unos broja clanova niza printf("\n Unesite broj imena: "); scanf("%d", &n); /* Unos imena, prezimena, bodova i direktan upis u strukturu*/ for (i=0;i
Email: [email protected] ; MSN: [email protected]
Programiranje i programsko inženjerstvo, FER Upute za rad s razvojnom okolinom M S Visual Studio 2008 - Pisanje i pokretanje programa pisanih u programskom jeziku C
Upute za rad s razvojnom okolinom MS Visual Studio 2008 Pisanje i pokretanje programa pisanih u programskom jeziku C 1.Instalacija razvojne okoline: Preuzeti instalaciju razvojne okoline MS Visual Studio .NET 2008 Professional sa stranica http://msdnaa.fer.hr/ i instalirati ga na vlastito računalo. Dozvoljene su i verzije 2005 i 2010.
2.Pokretanje razvojne okoline: Start → Programs → Microsoft Visual Studio 2008 → Microsoft Visual Studio 2008 Prilikom pokretanja sučelja obično se pojavi tzv. Start Page na koje se vidi lista nekoliko zadnje kreiranih projekata, što se inače koristi za brzi pristup prethodno kreiranim projektima. 3. Stvaranje projekta (preduvjet za početak pisanja programa) Iz izbornika File, odaberite opciju New Project (slika 1).
Slika 1.
Odabirom opcije New Project pojavit će se dijalog kao na slici 2. U ovom dijalogu odaberite: tip projekta: Visual C++ → Win32 Console Application ime projekta: u polje Name umjesto upišite željeno ime
1
Programiranje i programsko inženjerstvo, FER Upute za rad s razvojnom okolinom M S Visual Studio 2008 - Pisanje i pokretanje programa pisanih u programskom jeziku C
lokaciju projekta: za polje Location odaberite kazalo u kojem će projekt biti smješten pritiskom na gumb Browse. Kazalo ispod kojeg će vaš novi projekt biti kreiran mora postojati. Ostale podatke nemojte mijenjati te pritisnite gumb OK.
Slika 2
Nakon toga pojavit će se dijalog kao na slici 3. Odaberite opciju Application Settings.
Slika 3
2
Programiranje i programsko inženjerstvo, FER Upute za rad s razvojnom okolinom M S Visual Studio 2008 - Pisanje i pokretanje programa pisanih u programskom jeziku C
Na dijalogu kao na slici 4 potrebno je uključiti opciju Empty project. Nakon toga odaberite gumb Finish i novi projekt će biti kreiran.
Slika 4
U ovom je trenutku stvoren projekt koji još uvijek ne sadrži niti jednu datoteku s programskim kodom.
4. Pisanje programa Dodavanje programske datoteke u projekt: pozicionirati se u tzv. Solution Explorera (u slučaju da nije vidljiv odabrati opciju izbornika View → Solution Explorer). Unutar Solution Explorera pod nazivom projekta (u ovo primjeru smo projekt nazvali Vjezba1) nalaze se 3 stavke: Source Files, Header Files i Resource Files. desnim klikom miša na Source Files pojavit će se dijalog kao na slici 5 čime nam je omogućeno dodavanje nove datoteke u projekt. Potrebno je odabrati opciju Add → New item.
3
Programiranje i programsko inženjerstvo, FER Upute za rad s razvojnom okolinom M S Visual Studio 2008 - Pisanje i pokretanje programa pisanih u programskom jeziku C
Slika 5
Nakon toga potrebno je odabrati da želite dodati C++ datoteku (slika 6) i dati joj ime koje mora završavati s ekstenzijom .c (u ovom primjeru tu ćemo datoteku nazvati vjezba.c). Pritisnite gumb Open i datoteka će se stvoriti i postati dijelom projekta.
Slika 6
U novodobiveni prostor za pisanje programa koji je dobiven dodavanjem datoteke vjezba.c potrebno je upisati program. Za vježbu upišite program sa slajda 21 prvog predavanja (02-UvodProgramiranje).
4
Programiranje i programsko inženjerstvo, FER Upute za rad s razvojnom okolinom M S Visual Studio 2008 - Pisanje i pokretanje programa pisanih u programskom jeziku C
Slika 7
5. Prevođenje programa Potrebno je izvesti izgradnju izvršne datoteke odabirom opcije izbornika Build → Build ImeVašegProjekta (na slici 7 to je opcija Build Vjezba1)
Slika 8
U slučaju da vaš program nema grešaka pojavit će se poruka kao na slici 8. U slučaju da se Output prozor ne vidi, pokrenite opciju izbornika View → Output.
5
Programiranje i programsko inženjerstvo, FER Upute za rad s razvojnom okolinom M S Visual Studio 2008 - Pisanje i pokretanje programa pisanih u programskom jeziku C
Ako je program imao grešaka na ovom prozoru će se pojaviti lista grešaka gdje se dvoklikom miša na pojedinu od njih možete pozicionirati na redak u kojem se ta pogreška nalazi.
Slika 9
6. Pokretanje programa Ako je program bio bez grešaka možete ga pokrenuti odabirom opcije Start Without Debugging iz izbornika Debug (slika 9).
Slika 10
7. Rad na drugom programu Želite li testirati neki drugi program, a da pri tome sačuvate već napisani program, možete koristiti jednu od ovih metoda: zatvorite projekt korištenjem opcije File → Close Solution, te cjelokupni opisani postupak ponoviti s nekim drugim imenom u već postojeće rješenje koje sadrži jedan projekt dodati još jedan tako da u Solution Exploreru desnom tipkom miša kliknete na Solution ImeRješenja (u ovom primjeru Solution 'Vjezba1') i odaberete opciju Add → New Project. Postupak dodavanja novog projekta je sličan već opisanom postupku. Ako imate više otvorenih projekata, odabir koji projekt (program) želite pokrenuti obavlja se tako da se na željeni projekt klikne desnom tipkom miša i odaberete Set as StartUpProject (slika 10).
6
Programiranje i programsko inženjerstvo, FER Upute za rad s razvojnom okolinom M S Visual Studio 2008 - Pisanje i pokretanje programa pisanih u programskom jeziku C
Slika 11
7
Programiranje i programsko inženjerstvo Sveučilište u Zagrebu - Fakultet elektrotehnike i računarstva -Zavod za primijenjeno računarstvo
Upute za instalaciju paketa MinGW i rad s prevodiocem GCC Pisanje i izvršavanje programa pisanih u programskom jeziku C
1. Instalacija paketa MinGW Preuzeti i instalirati MinGW Installer alat sa stranica http://sourceforge.net/projects/mingw/files/latest/download?source=files Pokrenuti MinGW Installer alat te putem njega instalirati osnovne komponente paketa MinGW. U lijevom polju potrebno je odabrati Basic Setup i zatim u desnom polju označiti stavku mingw32-base.
Nakon toga u izborniku odaberite Installation -> Apply Changes te u novootvorenom prozoru kliknite na gumb Apply.
Nakon provedene instalacije potrebno je podesiti sistemsku varijablu PATH dodavanjem putanje do direktorija bin paketa MinGW. Ako ste MinGW instalirali s inicijalnim (default) postavkama, direktorij bin paketa MinGW će biti C:\MinGW\bin. Sistemska varijabla PATH može se podesiti u Control Panel-u:
1
Control Panel -> System and Security -> System Potrebno je kliknuti na link koji se nalazi s lijeve strane -> Advanced system settings
U novootvorenom prozoru odabrati karticu (tab) Advanced te zatim kliknuti na gumb Environment Variables… kako je prikazano na slici:
2
Nakon toga potrebno je u listi System variables odabrati varijablu Path i kliknuti na gumb Edit
U novootvorenom prozoru, u polje Variable value, na kraj postojećeg teksta dodati ;C:\MinGW\bin\ 3
Obratite pažnju na znak ; na početku teksta koji se dodaje u varijablu Path.
Napomena: Ako ste MinGW instalirali u drugom direktoriju (umjesto u C:\MinGW) tada u tekstu kojim se dopunjava varijabla Path, zamijeniti C:\MinGW s putanjom do tog direktorija. Navedeni tekst dodajte na kraj postojećeg sadržaja varijable Path, vodeći računa o tome da postojeći sadržaj varijable ne obrišete! Alternativni način instalacije
Studenti koji imaju problema sa instalacijom najnovije inačice MinGW kolekcije na svoje Windows računalo mogu pokušati ovu alternativnu metodu: 1. Na računalu kreirati direktorij u koji će se smjestiti MinGW datoteke (npr. C:\MinGW\) 2. Iz repozitorija datoteka preuzeti arhivu MinGW.zip i raspakirati je u gore kreirani direktorij 3. Postaviti PATH sistemsku varijablu kao što piše u uputama (ako se MinGW nalazi u "C:\MinGW\" onda je u PATH potrebno nadodati ;C:\MinGW\bin\ )
4
2. Pisanje i pokretanje programa Nakon što ste instalirali paket MinGW, u direktoriju C:\PPI (ili neki drugi direktorij po vašem izboru) stvorite znakovnu datoteku (npr. koristeći uređivač teksta Notepad) „ppi.c“. U znakovnu datoteku upišite sljedeći kod: #include int main(void){ printf("Programiranje i programsko inzenjerstvo"); return 0; } Program ćete prevesti pomoću prevodioca GCC na sljedeći način: 1. Pokrenite command prompt (npr. Start menu -> Run pa upišite „cmd“) i pozicionirajte se u direktorij C:\PPI. 2. Pokrenite prevodilac GCC naredbom cc -ansi -pedantic-errors -Wall -o ppi.exe ppi.c Prvo se navodi naziv programa koji obavlja prevođenje – „cc“. Nakon toga navode se parametri: -ansi – parametar kojim osiguravamo prevođenje sukladno ANSI standardu -pedantic-errors – parametar kojime zahtijevamo detaljno ispisivanje grešaka u programu -Wall – parametar kojime zahtijevamo detaljan ispis upozorenja Zatim slijedi parametar „–o“ kojim se određuje kako će se zvati izvršna datoteka, u našem slučaju to je „ppi.exe“. Na kraju je naveden naziv datoteke s izvornim kodom, „ppi.c“. Nakon prevođenja programa ppi.c, pokrenite izvršnu datoteku „ppi.exe“. Na zaslonu će se ispisati tekst „Programiranje i programsko inzenjerstvo“.
5
Napomena: Ako vam prilikom pokretanja prevodioca GCC sustav javi sljedeću grešku 'cc' is not recognized as an internal or external command, operable program or batch file. znači da sistemska varijabla Path nije ispravno podešena. Ako niste u mogućnosti podesiti varijablu Path, možete napraviti sljedeće:s 1. Pozicionirajte se u direktorij bin unutar direktorija u kojeg ste instalirali MinGW. Ako ste ostavili inicijalne postavke tada se to direktorij nalazi u C:\MinGW\bin 2. Sada možete pokrenuti GCC prevodilac, ali za naziv datoteke s izvornim kodom morate unijeti cijelu putanju do te datoteke. Isto vrijedi i za naziv izvršne datoteke Ako se datoteka s izvornim kodom nalazi u C:\PPI\ppi.c te ako u istom direktoriju (C:\PPI) želimo stvoriti i datoteku s izvršnim kodom, GCC prevodilac treba pokrenuti : cc -ansi -pedantic-errors -Wall -o C:\PPI\ppi.exe C:\PPI\ppi.c Kao naziv datoteke s izvornim kodom naveden je C:\PPI\ppi.c, a kao naziv izlazne datoteke navedena je datoteka C:\PPI\ppi.exe. Program se pokreće navođenjem apsolutnog ili relativnog puta do datoteke s izvršnim kodom, u našem primjeru: C:\PPI\ppi.exe
6
Programiranje i programsko inženjerstvo Sveučilište u Zagrebu - Fakultet elektrotehnike i računarstva -Zavod za primijenjeno računarstvo
Korištenje znakovnog sučelja u operacijskom sustavu Windows Windows operacijski sustav za komunikaciju s korisnikom, osim grafičkog korisničkog sučelja (GUI graphical user interface), omogućava korištenje znakovnog (tekstualnog) korisničkog sučelja (CLI command-line interface, command-line user interface, console user interface, CUI-character user interface) u kojem se računalom upravlja upisivanjem naredbe u naredbenom retku (command line). Kod takvog načina komunikacije, računalo prvo korisniku ispisuje obavijest (prompt) da je spremno od njega prihvatiti naredbu, nakon čega korisnik koristeći tipkovnicu upisuje naredbu. Znakovno korisničko sučelje vrlo je često u upotrebi u znanosti, inženjerstvu i industriji, a podržano je od svih danas važnih operacijskih sustava, kao što su Unix, Linux, Windows, itd. U sklopu kolegija Programiranje i programsko inženjerstvo, znakovno sučelje koristit će se prilikom rada s datotekama u koje su pohranjeni izvorni i izvršni kodovi C programa, te radi prevođenja i izvršavanja C programa.
1
Pokretanje znakovnog sučelja
Postoji više mogućnosti za pokretanje znakovnog sučelja (tj. otvaranja prozora s znakovnim sučeljem). U nastavku je navedeno nekoliko mogućnosti: a)
nakon čega se otvara prikazani prozor u kojem je u okvir potrebno upisati naredbu cmd te pritisnuti gumb OK:
c)
Start u okvir za pretraživanje (Search) upisati cmd, nakon čega se otvara prozor prikazan pod b)
d)
istovremeni pritisak tipki Windows i R (Win+R), nakon čega se otvara prozor prikazan pod b)
Nakon toga otvara se prozor s znakovnim sučeljem:
1
2
Izvođenje programa i naredbi
Pokretanje naredbe ili programa obavlja se upisivanjem njegovog imena, argumenata (npr. naziv datoteke) i opcija (parametri koji modificiraju djelovanje naredbe, a navode se iza znaka /), te pritiskom na tipku Enter. Ne razlikuju se velika i mala slova u nazivima datoteka, naredbi i opcija. Dakle, sasvim je svejedno je li upisano npr. HELP ili help. Naredba se upisuje iza prompta, koji se pojavljuje kada je sučelje spremno od korisnika prihvatiti naredbu. Prompt obično završava znakom >. U nastavku su navedeni primjeri korištenja pojedinih naredbi u njihovom osnovnom obliku. Popis uobičajenih naredbi moguće je dobiti upisivanjem naredbe help. Za prikaz dodatnih informacija o pojedinoj naredbi, potrebno je upisati help naziv_naredbe. Program koji se izvodi može biti prekinut istovremenim pritiskom na tipke Ctrl i C (Ctrl+C). Izvođenje programa može biti privremeno zaustavljeno pritiskom na tipku Pause ili kombinacijom tipki Ctrl+S. Nastavak izvođenja na ovaj način zaustavljenog programa obavlja se pritiskom na bilo koju tipku, na primjer Enter. Naredbom exit završava se rad s znakovnim sučeljem i zatvara pripadni prozor. Primjer: help help
(dobivanje uputa o radu programa help)
help tree
(dobivanje uputa o radu programa tree; uz kratki opis naredbe dan je i opis dozvoljenih opcija: /F i /A, pa je moguće, na primjer, zadati naredbu: tree /f)
3
Rad s datotekama i direktorijima
3.1 Datotečni sustav operacijskog sustava Windows Podaci pohranjeni u vanjskoj (postojanoj) memoriji (npr. disk, CD, memory stick, ...) logički su organizirani u datoteke. Datoteka je imenovani skup podataka koji sačinjavaju logičku cjelinu. Datoteke su logički grupirane u direktorije (mape, kazala), koji mogu sadržavati proizvoljan broj datoteka i drugih direktorija (poddirektorija). Direktoriji su organizirani hijerarhijski, u strukturu nalik na stablo. Direktorij je zapravo datoteka koja sadrži popis i podatke o karakteristikama drugih datoteka.
2
Datotečni sustav računala je dio operacijskog sustava koji služi za organiziranje, upravljanje i pristup datotekama. Upravljanje datotekama jedna je od osnovnih zadaća operacijskog sustava. Operacijski sustav, između ostalog, vodi evidenciju o fizičkom smještaju datoteka na mediju za pohranu te nudi sučelje za otvaranje postojećih, stvaranje novih datoteka, čitanje iz datoteke, pisanje u datoteku, premještanje, preimenovanje te brisanje datoteka i direktorija. Datoteka je određena (identificirana) imenom i apsolutnim putem (path) do direktorija u koji je upisana. Ime datoteke/direktorija sastoji se od osnovnog dijela i nastavka, međusobno odvojenih točkom. Nastavak nije obavezan dio imena datoteke/direktorija, ali se obično navodi uz ime datoteke kako bi se njime sugerirao njezin tip i namjena. Na primjer, uobičajeno je datoteci koja sadrži samo tekst dodijeliti nastavak txt, datoteci koja sadrži izvorni kod napisan u programskom jeziku C dodijeliti nastavak c, a datoteci koja predstavlja izvršni program dodijeliti nastavak exe. Osim naziva, datoteka ima i ostala svojstva kao što je npr. veličina, vrijeme nastanka i izmjene itd. Datotečni sustav može uključivati više vanjskih jedinica za pohranu (najčešće tvrdih diskova). U operacijskom sustavu Windows one mogu biti podijeljene u više logičkih jedinica (particija), obično označenih slovima C:, D:, itd. U nastavku se pod pojmom disk misli na logičku jedinicu. Svaki disk sadrži jedan izvorni ili osnovni direktorij (root) koji je označen znakom \. Kako broj izvornih direktorija ovisi o broju diskova, da bi se znalo o kojem se izvornom direktoriju radi, ispred znaka \ navodi se i oznaka diska, npr. C:\, D:\, itd. U nekim operacijskim sustavima (npr. Unix), postoji samo jedan izvorni direktorij te se ne navodi oznaka diska. Na slici je, u grafičkom sučelju operacijskog sustava Windows (pomoću programa Windows Explorer), prikazana stablasta struktura direktorija na disku C te, na desnoj strani, sadržaj (direktoriji i datoteke) direktorija \cygwin\lib:
3
Prikaz stablaste strukture direktorija u znakovnom sučelju omogućava naredba tree. Ako je naredba zadana bez opcija, ispisuju se samo nazivi direktorija. Navođenjem opcije /f, biti će prikazane i datoteke (slika desno). Operacijski sustav prati trenutnu poziciju korisnika unutar datotečnog sustava za vrijeme dok koristi znakovno korisničko sučelje. Ta se trenutna pozicija naziva radni (working, current) disk i radni direktorij. Informacija o radnom disku i radnom direktoriju sastavni je dio prompta. Na slici desno prompt predstavlja tekst C:\cygwin\lib>, što znači da je radni disk C, a radni direktorij je direktorij lib, koji je poddirektorij direktorija cygwin smještenog u izvornom direktoriju. Datoteci/direktoriju moguće je pristupiti navođenjem puta do te datoteke/direktorija, tj. navođenjem naziva direktorija kroz koje je potrebno proći da bi se došlo do te datoteke/direktorija, odvojene znakom \. Put može biti apsolutan ili relativan. Apsolutni put započinje oznakom diska i izvornim direktorijem, nakon čega se navode svi direktoriji do direktorija u koji je smještena datoteka. Na primjer, ako se datoteka popis.txt nalazi u direktoriju \users\ana na disku C, apsolutni put do nje je C:\users\ana\popis.txt. Relativni put ovisi o radnom direktoriju. Prilikom navođenja relativnog puta do datoteke moguće je koristiti i posebne oznake: . ..
označava radni direktorij označava direktorij nadređen radnom direktoriju
Na primjer, ako je radni direktorij C:\users\hrvoje (apsolutni put do tog direktorija), oznaka . predstavlja oznaku za direktorij C:\users\hrvoje, oznaka .. predstavlja oznaku za direktorij C:\users, a ..\.. je oznaka za izvorni direktorij C:\. Relativni put do datoteke čije je ime popis.txt, a nalazi se u direktoriju C:\users\ana je ..\ana\zivotopis.txt. Većina naredbi kao argument prihvaća naziv jedne ili više datoteka, odnosno direktorija. Ako se kod navođenja naziva izostavi ime direktorija ili diska, podrazumijeva se da se radi o trenutno radnom direktoriju i disku. Kod nekih naredbi nije potrebno pisati puno ime datoteka ili direktorija, već je moguće koristiti i posebne znakove (tzv. metaznakove, wildcard): *
zamjenjuje neodređeni niz, bilo koju kombinaciju znakova
?
zamjenjuje samo jedan, bilo koji znak.
Na primjer, niz ?.txt određuje sve datoteke koje imaju ime duljine jednog znaka i nastavak txt. 4
Primjer: tree \
(prikaz stablaste strukture direktorija radnog diska, počevši od izvornog direktorija, bez prikaza datoteka)
3.2 Pregled sadržaja direktorija (dir) Naredbom dir ispisuje se sadržaj direktorija. Imena koja u ispisu imaju oznaku su direktoriji, a ostalo su datoteke. Primjer: (pregled svih datoteka i direktorija u radnom direktoriju)
dir
dir dir dir dir
ppi c:\tmp \tmp c:\t*.*
(pregled direktorija ppi koji se nalazi u radnom direktoriju) (pregled direktorija tmp na disku C:, navođenjem apsolutnog puta) (pregled direktorija tmp na radnom disku, navođenjem apsolutnog puta) (pregled svih datoteka čiji naziv počinje slovom t i imaju neki nastavak)
3.3 Promjena radnog direktorija (cd) Za promjenu radnog direktorija koristi se naredba cd. Izvođenjem naredbe cd, navedeni direktorij proglašava se radnim direktorijem. Direktorij čije je ime navedeno uz naredbu mora postojati. Ako se naziv direktorija iza naredbe cd izostavi, naredba ispisuje apsolutni put do radnog direktorija. Dozvoljeno je koristiti apsolutni i relativni put do direktorija. Naredbom cd nije moguće promijeniti radni disk. Promjena radnog diska obavlja se navođenjem naziva diska i dvotočke. Primjer: cd \users cd .. cd ..\ana cd users cd D:
(direktorij users na radnom disku postaje radni direktorij) (direktorij nadređen radnom postaje radni direktorij) (radni direktorij postaje direktorij ana, koji se nalazi u direktoriju nadređenom radnom) (direktorij users, koji se nalazi u radnom direktoriju, postaje radni direktorij) (ispis apsolutnog puta do radnog direktorija) (disk D postaje radni disk)
3.4 Kreiranje direktorija (mkdir) Naredbom mkdir stvara se novi direktorij, čiji je naziv obavezno navesti. Stvaranjem direktorija on ne postaje radnim. Da bi postao radni, potrebno je upotrijebiti naredbu cd. Primjer: 5
mkdir c:\tmp mkdir tmp
(stvaranje direktorija tmp u izvornom direktoriju na disku C) (stvaranje direktorija tmp u radnom direktoriju)
3.5 Kopiranje datoteka (copy) Naredbom copy obavlja se kopiranje datoteke (datoteka) u neku drugu datoteku unutar istog ili nekog drugog direktorija. Naredba copy u jednostavnijem obliku ima dva argumenta: prvi argument predstavlja ime datoteke čiji se sadržaj kopira (izvor), a drugi argument je ime kopije. U drugom obliku, copy naredbi se može predati više datoteka kao izvor, a kao zadnji argument navodi se ime jednog direktorija u koji se kopiraju sve navedene datoteke. Primjer: copy ppi.c ppi1.c (kopiranje datoteke ppi.c u datoteku ppi1.c u radnom direktoriju) copy ppi.c \tmp (kopiranje datoteke ppi.c iz radnog direktorija u direktorij tmp na radnom disku) copy C:\*.* . (kopiranje svih datoteka izvornog direktorija u radni direktorij)
3.6 Promjena imena i premještanje datoteka i direktorija (move) Naredbom move obavlja se promjena imena jedne datoteke ili direktorija, odnosno premještanje direktorija ili datoteka u druge direktorije. Ako se kao izvor navedu nazivi više datoteka ili koriste posebni znakovi, za ciljno ime treba navesti naziv direktorija (slično kao kod naredbe cp) u koji će biti premještene izvorne datoteke. Primjer: move ana hrvoje move ppi.c ppi.save move ppi* tmp
(promjena naziva direktorija ana u hrvoje) (promjena naziva datoteke ppi.c u ppi.save) (premještanje datoteka čije ime počinje s ppi.c u direktorij tmp)
3.7 Ispis sadržaja datoteke na zaslon (type) Naredba type prikazuje na zaslonu sadržaj datoteke (obično datoteke s nastavkom txt). Pokušaj ispisa sadržaja datoteke koja ne sadrži samo tekst (npr. datoteke s nastavkom exe), rezultira ispisom nerazumljivog niza znakova. Primjer: type ppi.c
(ispisivanje sadržaja datoteke ppi.c na zaslon)
3.8 Brisanje datoteke (del) Naredbom del moguće je obrisati jednu ili više datoteka (dozvoljena je upotreba posebnih znakova * i ?). Ako se kao argument naredbe navede ime direktorija, obrisat će se sve datoteke u tom direktoriju. Primjer: del ppi.exe del x.* del \tmp del .
(brisanje datoteke ppi.exe) (brisanje svih datoteka s imenom x i bilo kojim nastavkom u radnom direktoriju) (brisanje svih datoteka u direktoriju tmp) (brisanje svih datoteka u radnom direktoriju)
6
3.9
Brisanje direktorija (rmdir)
Naredbom rmdir briše se navedeni direktorij. Ako nisu navedene dodatne opcije, direktorij je moguće obrisati samo ako je prazan, tj. ako u njemu nema niti jedne datoteke ili direktorija. Korištenjem opcije /s moguće je obrisati i direktorij koja nije prazan. Primjer: rmdir C:\tmp rmdir /s vjezba
4
(brisanje praznog direktorija tmp u izvornom direktoriju) (brisanje direktorija vjezba koji se nalazi u radnom direktoriju, direktorij će biti obrisan i ako nije prazan)
Preusmjeravanje (redirekcija)
Prilikom izvođenja naredbi u znakovnom sučelju podrazumijeva se da se ulazni podaci prihvaćaju s tipkovnice, a izlazni ispisuju na zaslonu. Tipkovnica predstavlja standardni ulaz, a zaslon standardni izlaz. Međutim, ponekad je potrebno izlazne podatke preusmjeriti u datoteku, ili pak ulazne podatke, umjesto s tipkovnice, preuzeti iz datoteke. To se postiže korištenjem znakova za preusmjeravanje: > < >>
4.1
preusmjerava izlaz u datoteku; ako datoteka već postoji, briše se njen dotadašnji sadržaj preuzima ulazne podatke iz datoteke preusmjerava izlaz u datoteku; ako datoteka već postoji, podaci se dodaju na kraj datoteke
Preusmjeravanje izlaznih podataka u datoteku
Naredbom dir C:\tmp > dir_tmp.txt rezultat naredbe dir C:\tmp, koji bi se standardno pojavio na zaslonu, bit će zapisan u datoteku dir_tmp.txt u radnom direktoriju. Ako datoteka nije postojala prije izvođenja naredbe, naredbom će biti kreirana. Ako je datoteka postojala, njen stari sadržaj će se izgubiti. Naredbom dir . >> dir_tmp.txt rezultat naredbe dir . bit će nadodan na kraj datoteke dir_tmp.txt.
4.2
Preusmjeravanje ulaznih podataka iz datoteke
Preusmjeravanje ulaznih podataka naročito je korisno prilikom testiranja programa koji zahtijeva puno ulaznih podataka, jer je umjesto njihovog stalnog upisivanja pomoću tipkovnice moguće koristiti podatke koji su unaprijed pripremljeni i pohranjeni u datoteku. Naredbom izracunaj.exe < podaci.txt standardni ulaz usmjeren je iz datoteke podaci.txt, pa će program izracunaj.exe iz te datoteke, umjesto s tipkovnice, učitati potrebne podatke. Ako program ispisuje rezultate, oni će biti ispisani na zaslonu monitora.
4.3
Preusmjeravanje ulaznih i izlaznih podataka
Naredbom izracunaj.exe < podaci.txt > rezultati.txt postiže se da se ulaz u program izracunaj.exe preusmjeri iz datoteke podaci.txt, a izlaz se preusmjeri u datoteku rezultati.txt. 7
5
Editori teksta
Editori teksta su programi namijenjeni pisanju teksta u kojem nema posebnih znakova za formatiranje (tzv. kontrolnih kôdova). Za razliku od editora, programi za uređivanje teksta, osim slova i uobičajenih znakova, ubacuju posebne znakove koji služe za formatiranje konačnog teksta (određivanje rubova, određivanje tipa i veličine slova i sl.). Za pisanje programa koriste se isključivo editori. Na vježbama se koristi editor Notepad. Editor je moguće pokrenuti na dva načina: navođenjem samo naredbe notepad, navođenjem naredbe notepad iza koje slijedi ime datoteke koju je potrebno editirati (notepad ime_datoteke). Ako je editor pokrenut na prvi način, potrebno je naknadno navesti ime datoteke u koju se želi spremiti upisani tekst. Međutim, kako je txt ponuđeni nastavak za naziv datoteke, često se dogodi da datoteka dobije dodatni nastavak txt, a treba paziti i na direktorij u koji će biti smještena. Na primjer, ako je datoteku potrebno nazvati ppi.c, moguće je da zapravo bude nazvana ppi.c.txt. Zato je preporuka pokretati editor uz navođenje naziva datoteke (uz mogućnost navođenja apsolutnog ili relativnog puta): notepad ppi.c
(editorom se otvara datoteka ppi.c koja je smještena u radnom direktoriju)
notepad d:\vjezbe\p.c (editorom se otvara datoteka p.c koja je smještena u direktoriju \vjezbe na disku D)
8
Zadaci za vježbu 1) Obaviti sljedeće: 1. Izvorni direktorij na disku C proglasiti radnim direktorijem (u nastavku vježbe radni disk i direktorij promijeniti samo kada je to traženo u zadatku). 2. Na disku C u izvornom direktoriju kreirati direktorij vjezba. 3. Unutar direktorija vjezba, ne mijenjajući radni direktorij, kreirati direktorije osobno i ppi. 4. Uz korištenje relativnog puta proglasiti direktorij C:\vjezba\osobno radnim direktorijem, te unutar njega kreirati direktorije txt i slike. 5. Uz korištenje apsolutnog puta proglasiti direktorij slike radnim direktorijem, a zatim u taj direktorij kopirati nekoliko slika (možete ih prethodno potražiti korištenjem npr. programa Windows Explorer). Prilikom kopiranja slika navesti apsolutni put do direktorija u kojem se nalaze slike, a relativni put do direktorija u koji je potrebno kopirati slike. 6. Jednom naredbom proglasiti direktorij C:\vjezba\osobno\txt radnim direktorijem, uz korištenje relativnog puta. 7. Provjeriti postoji li u radnom direktoriju datoteka nema.me. 8. Editorom Notepad u datoteku zivot.txt upisati neki tekst. 9. Kopirati datoteku zivot.txt u datoteke pom.txt i pom1.txt u radnom direktoriju. 10. Ispisati stablastu strukturu direktorija (bez datoteka) na disku C počevši od izvornog direktorija. Privremeno zaustaviti te nakon toga nastaviti ispisivanje te strukture na zaslon. 11. Ispisati stablastu strukturu direktorija, uključujući datoteke, počevši od direktorija vjezba uz korištenje relativnog puta. Usporediti dobivenu strukturu sa strukturom prikazanom u grafičkom sučelju, koristeći program Windows Explorer. 12. Pozvati program help bez argumenata, a izlaz programa preusmjeriti u datoteku help.txt. 13. Ispisati sadržaj radnog direktorija. 14. Prebaciti datoteku help.txt u nadređeni direktorij. 15. Ispisom sadržaja radnog, a zatim i nadređenog direktorija, provjeriti je li kopiranje uspješno obavljeno. 16. Bez promjene radnog direktorija, na zaslon ispisati sadržaj datoteke help.txt. 17. U radnom direktoriju obrisati sve datoteke čije ime započinje slovom p. 18. Proglasiti izvorni direktorij radnim direktorijem navođenjem relativnog puta. 19. Obrisati direktorij C:\vjezba\osobno\txt (navesti apsolutni put do direktorija). 20. Obrisati sve datoteke u direktoriju C:\vjezba\osobno\slike (navesti relativni put do direktorija). 21. Obrisati direktorij osobno.
2) Napisati program koji će pročitati dva cijela broja i ispisati veći broj. Izvorni kod pohraniti u datoteci proba.c u direktoriju ppi kreiranom u 1. zadatku. Za editiranje koristiti editor Notepad (naziv datoteke navesti prilikom pokretanja editora). Prevesti program pomoću prevodioca GCC, a izvršnu datoteku nazvati proba.exe. Izvesti program tako da se: 1) brojevi čitaju s tipkovnice, a rezultat ispisuje na zaslon monitora 2) brojevi čitaju s tipkovnice, a rezultat ispisuje u datoteku izlaz.txt 3) brojevi čitaju iz datoteke ulaz.txt koja je prethodno pripremljena pomoću editora, a rezultat ispisuje na kraj datoteke izlaz.txt, bez uništavanja njenog prethodnog sadržaja
9
Rješenja 1) 1. cd c:\ 2. mkdir vjezba 3. mkdir vjezba\osobno mkdir vjezba\ppi 4. cd vjezba\osobno mkdir txt mkdir slike 5. cd c:\vjezba\osobno\slike npr: copy c:\users\hrvoje\slike\*2013*.jpg . 6. cd ..\txt 7. dir nema.me 8. notepad zivot.txt 9. copy zivot.txt pom.txt copy zivot.txt pom1.txt 10. tree \ privremeno zaustavljanje izvođenja: Pause (ili Ctrl+S) nastavak izvođenja: bilo koja tipka 11. tree /f ..\.. 12. help > help.txt 13. dir 14. move help.txt .. 15. dir . dir .. 16. type ..\help.txt 17. del p* 18. cd ..\..\.. 19. rmdir /s C:\vjezba\osobno\txt 20. del C:\vjezba\osobno\slike 21. rmdir /s C:\vjezba\osobno 2) cd c:\vjezba\ppi notepad proba.c U znakovnu datoteku proba.c upisati sljedeći kod: #include int main(void) { int x,y; printf("Upisite dva cijela broja: "); scanf("%d %d", &x, &y); if (x>y) { printf("%d\n", x); } else { printf("%d\n", y); } return 0; }
10
cc -ansi -pedantic-errors -Wall -o proba.exe proba.c 1) proba.exe 2) proba.exe > izlaz.txt type izlaz.txt 3) notepad ulaz.txt U znakovnu datoteku proba.c upisati dva cijela broja, npr: 10 5 proba.exe < ulaz.txt >> izlaz.txt type izlaz.txt
11
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 25
Napomene: - Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja - Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
1. vježbe uz predavanja 1. Napišite program koji na zaslon ispisuje poruku Upisite jedan pozitivni cijeli broj: i nakon toga preko tipkovnice učita jedan cijeli broj. Ako je broj ispravno upisan (tj. učitan je pozitivan broj), na zaslon treba ispisati: Zadnja znamenka broja xxxxx je x inače, ako je učitan negativan broj ili nula, na zaslon ispisati Broj xxxxx nije pozitivan broj Uputa: kojim brojem n treba podijeliti broj m da bi se kao ostatak dijeljenja dobila zadnja (krajnje desna) znamenka broja m? Postoji li u programskom jeziku C aritmetička operacija kojom se izračunava ostatak cjelobrojnog djeljenja? 2. S tipkovnice učitati polumjer kruga (realni broj). Ako je učitani broj pozitivan, izračunati opseg i površinu kruga, te na zaslon ispisati: zadani polumjer je: xxxxxx.xxxx opseg kruga je: xxxxxx.xxxx povrsina kruga je: xxxxxx.xxxx inače (ako učitani broj nije pozitivan) na zaslon treba ispisati: broj xxxxxx.xxxx nije ispravan polumjer kruga 3. S tipkovnice učitati cijeli broj i zatim na zaslon ispisati poruku: ucitan je broj xxxxx Ako je učitan negativan broj, ispisati: broj je negativan Nakon toga (bez obzira je li učitani broj negativan) ispitati parnost učitanog broja i ispisati odgovarajuću poruku: broj je paran ili broj je neparan
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 25
Rješenja 1. #include int main (void) { int broj, zadnjaZnamenka; printf("Upisite jedan pozitivan cijeli broj: "); scanf("%d", &broj); if (broj > 0) { zadnjaZnamenka = broj % 10; /* Druga mogucnost izracunavanja zadnje znamenke jest: zadnjaZnamenka = broj - broj / 10 * 10; U prethodnoj naredbi uocite cjelobrojno dijeljenje! */ printf("Zadnja znamenka broja %5d je %d\n", broj, zadnjaZnamenka); } else { printf("Broj %5d nije pozitivan broj\n", broj); } return 0; }
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 25
3. #include int main (void) { int broj, ostatak; scanf("%d", &broj); printf("ucitan je broj: %5d\n", broj); if (broj < 0) { printf("broj je negativan\n"); } ostatak = broj % 2; if (ostatak == 0) { printf("broj je paran\n"); } else { printf("broj je neparan\n"); } return 0; }
ili #include int main (void) { int broj; scanf("%d", &broj); printf("ucitan je broj: %5d\n", broj); if (broj < 0) { printf("broj je negativan\n"); } if (broj % 2 == 0) { printf("broj je paran\n"); } else { printf("broj je neparan\n"); } return 0; }
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 47
Napomene: - Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja - Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
2. vježbe uz predavanja 1. Pročitajte i zaključite što bi sljedeći program (kada bi bio ispravan) trebao raditi. #include ; int mein (void) { integer xa; ya; xb; yb; xc; yc; printf("Upisite koordinate vrha trokuta A >"); scan("%d %d", &xa, &ya); printf("Upisite koordinate vrha trokuta B >"); scan("%d %d", &xb, &yb); printf("Upisite koordinate vrha trokuta C >"); scan("%d %d", &xc, &yc); xTezista = xa + xb + xc / 3; yTezista = ya + yb + yc / 3; printf("Teziste trokuta A(%d, %d), B(%d, %d), C(%d, %d) jest T(%d, %d)" , xa, ya, xb, yb, xc, yc, xTezista, yTezista); return 0 }
Zatim pomoću copy-paste upišite program u datoteku na svom računalu i pokušajte ga prevesti. Prvo ispravite isključivo sintaktičke pogreške. Nakon toga ispravite pogreške povezivanja. Kada se program uspješno prevede, testirajte program s različitim ulaznim podacima: - za vrhove trokuta s koordinatama (0, 0), (3, 3) i (6, 0) - za vrhove trokuta s koordinatama (0, 0), (1, 1) i (2, 0) - za vrhove trokuta s koordinatama (0, 0), (1.5, 1.5) i (3, 0) Ispravite sve logičke pogreške. Uputa: pri rješavanju ovog zadatka korisno je poslužiti se C prevodiocem, koji će otkriti one sintaktičke pogreške i pogreške povezivanja koje sami možda ne uspijete uočiti. 2. Napisati C program kojim će se s tipkovnice učitati pozitivni cijeli broj koji ima 5 znamenaka. Nije potrebno provjeravati je li korisnik upisao ispravan broj. Program treba na zaslon ispisati prvu i posljednju znamenku učitanog broja. 3. Napisati C program kojim će se s tipkovnice učitati pozitivni cijeli broj koji ima 5 znamenaka. Nije potrebno provjeravati je li korisnik upisao ispravan broj. Program treba na zaslon ispisati drugu i četvrtu znamenku.
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 47
Rješenja 1. Sintaktičke pogreške: − točka-zarez se ne smije stavljati iza pretprocesorskih naredbi − definicija varijabli xa, ya, xb, yb, itd. je neispravna. Varijable koje se odjednom definiraju međusobno se odjeljuju zarezom, a ne točkom-zarezom. Tip integer ne postoji. − varijable xTezista i yTezista nisu definirane − nedostaje točka-zarez iza naredbe return. Pogreške povezivanja: − u stdio.h ne postoji funkcija scan (postoji scanf) − program mora sadržavati funkciju main (a ne mein) Logičke pogreške: − koordinate težišta se neispravno izračunavaju. X koordinate triju vrhova treba prvo zbrojiti, a tek tada podijeliti s 3 (trenutno se na kvocijent z/3 dodaje vrijednost za x i y. Isto vrijedi i za y koordinate. − nakon dodavanja zagrada program će ispravno raditi za koordinate vrhova (0, 0), (3, 3) i (6, 0), ali ne i za koordinate (0, 0), (1, 1) i (2, 0). Razlog je u cjelobrojnom dijeljenju i tipu rezultata: 0+1+0 cjelobrojno podijeljeno s 3 daje 0, a ne 0.33333. Potrebno je promijeniti tip svih varijabli: koordinate vrhova trokuta i težišta trebaju biti realni, a ne cijeli brojevi. Program nakon ispravljanja svih pogrešaka: #include int main (void) { float xa, ya, xb, yb, xc, yc; float xTezista, yTezista; printf("Upisite koordinate vrha trokuta A >"); scanf("%f %f", &xa, &ya); printf("Upisite koordinate vrha trokuta B >"); scanf("%f %f", &xb, &yb); printf("Upisite koordinate vrha trokuta C >"); scanf("%f %f", &xc, &yc); xTezista = (xa + xb + xc) / 3; yTezista = (ya + yb + yc) / 3; printf("Teziste trokuta A(%f, %f), B(%f, %f), C(%f, %f) jest T(%f, %f)" , xa, ya, xb, yb, xc, yc, xTezista, yTezista); return 0; }
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 47
2. #include int main (void) { int broj; printf("Upisite 5-znamenkasti pozitivni cijeli broj: "); scanf("%d", &broj); printf("Prva znamenka: %d\n", broj/10000); printf("Posljednja znamenka: %d\n", broj%10); return 0; }
3. #include int main (void) { int broj; printf("Upisite 5-znamenkasti pozitivni cijeli broj: "); scanf("%d", &broj); printf("Druga znamenka: %d\n", broj%10000/1000); printf("Cetvrta znamenka: %d\n", broj%100/10); return 0; }
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 84
Napomene: - Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja - Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
3. vježbe uz predavanja 1. Pročitajte i zaključite što bi sljedeći program (kada bi bio ispravan) trebao raditi. Napišite tekst programskog zadatka koji bi odgovarao programu. Nacrtajte dijagram toka. Zatim pomoću copy-paste upišite program u datoteku na svom računalu i pokušajte ga prevesti. Ispravite sve vrste pogrešaka i testirajte s različitim ulaznim podacima. #definiraj PI 3,1415926 float main (void) { int a; float b; printf("Upisite duljinu velike poluosi a>"); scanf("%f", &a); printf("Upisite duljinu male poluosi b>"); scanf("%f", &b); if (a > 0) { if (b > 0) { povrsina = A x B x pi; printf("Povrsina elipse s poluosima a=%f i b=%f je %f", povrsina); scanf("%f", &b); } else { printf("Duljina male poluosi mora biti veca od nule.\nKraj. "); } } else { printf("Duljina velike poluosi mora biti veca od nule.\nKraj. "); } return O; }
2. Napisati C program za pretvaranje vrijednosti temperature izražene u različitim mjernim jedinicama. Na početku program treba ispisati poruku: Program za konverziju Fahrenheit - Celsius i obrnuto. Za F u C upisite 1, a za C u F bilo koji drugi cijeli broj >
Ako korisnik upiše broj 1, tada ispisati poruku Upisite temperaturu izrazenu u stupnjevima Fahrenheit >
te s tipkovnice učitati realni broj koji predstavlja temperaturu izraženu u stupnjevima Fahrenheit, izračunati ekvivalentnu temperaturu izraženu u stupnjevima Celsius te ispisati temperaturu izraženu u obje jedinice xxxx.xxx st. F = xxxx.xxx st. C
Ako korisnik upiše bilo koji drugi cijeli broj, tada ispisati poruku Upisite temperaturu izrazenu u stupnjevima Celsius >
te s tipkovnice učitati jedan realni broj koji predstavlja temperaturu izraženu u stupnjevima Celsius, izračunati ekvivalentnu temperaturu izraženu u stupnjevima Fahrenheit te ispisati temperaturu izraženu u obje jedinice xxxx.xxx st. C = xxxx.xxx st. F
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 84
3. Nacrtati dijagram toka i napisati C program za zbrajanje ili množenje realnih brojeva. Na početku program treba ispisati poruku Program za zbrajanje ili mnozenje. Upisite dva realna broja >
i učitati dva realna broja koji predstavljaju operande. Nakon toga program treba ispisati poruku Upisite vrstu operacije (1-zbrajanje, 2-mnozenje) >
i učitati cijeli broj kojim se određuje vrsta operacije. Ako je korisnik upisao broj 1, tada treba izračunati i ispisati zbroj operanada, a ako je upisao broj 2, tada izračunati i ispisati umnožak operanada. Ako za odabir vrste operacije korisnik nije upisan niti broj 1 niti broj 2, tada treba ispisati poruku Neispravan odabir operacije.
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 84
Rješenja 1. Programski zadatak: napisati program kojim će se učitati duljine velike i male poluosi elipse. Nakon učitavanja duljina obje osi, ispitati ispravnost unesenih podataka. Ako je velika poluos neispravno zadana, ispisati poruku "Duljina velike poluosi mora biti veca od nule.", u sljedećem retku na zaslonu ispisati "Kraj", te završiti s izvršavanjem programa. Ako je mala poluos neispravno zadana, ispisati poruku "Duljina male poluosi mora biti veca od nule.", u sljedećem retku na zaslonu ispisati "Kraj", te završiti s izvršavanjem programa. Ako su duljine obje osi ispravno zadane, izračunati površinu elipse i ispisati poruku " Povrsina elipse s poluosima a=x.xxxxxx i b=x.xxxxxx je x.xxxxxx. Dijagram toka: učitaj a, b Da a>0 Ne ispiši "neispravna velika os, kraj"
Da b>0 Ne ispiši "neispravna mala os, kraj"
izračunaj i ispiši površinu elipse
Program nakon ispravljanja svih pogrešaka: #include #define PI 3.1415926 int main (void) { float a; float b; float povrsina; printf("Upisite duljinu velike poluosi a> "); scanf("%f", &a); printf("Upisite duljinu male poluosi b> "); scanf("%f", &b); if (a > 0) { if (b > 0) { povrsina = a * b * PI; printf("Povrsina elipse s poluosima a=%f i b=%f je %f", a, b, povrsina); } else { printf("Duljina male poluosi mora biti veca od nule.\nKraj"); } } else { printf("Duljina velike poluosi mora biti veca od nule.\nKraj"); } return 0; }
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 02-UvodProgramiranje.pdf - do stranice: 84
2. #include int main (void) { float cels, fahr; int izbor; printf("Program za konverziju Fahrenheit - Celsius i obrnuto.\n"); printf("Za F u C upisite 1, a za C u F bilo koji drugi cijeli broj >"); scanf("%d", &izbor); if (izbor == 1) { printf("Upisite temperaturu izrazenu u stupnjevima Fahrenheit >"); scanf("%f", &fahr); cels = (fahr - 32.) * 5. / 9.; printf("%8.3f st. F = %8.3f st. C\n", fahr, cels); } else { printf("Upisite temperaturu izrazenu u stupnjevima Celsius >"); scanf("%f", &cels); fahr = cels * 9. / 5. + 32.; printf("%8.3f st. C = %8.3f st. F\n", cels, fahr); } return 0; }
3. U ovom rješenju je prikazan samo dio dijagrama toka: Ne op = 1 Da ispiši zbroj
Ne op = 2 Da ispiši umnožak
ispiši "neispravna operacija"
#include int main (void) { float x, y; int operacija; printf("Program za zbrajanje ili mnozenje.\nUpisite dva realna broja >"); scanf("%f %f", &x, &y); printf("Upisite vrstu operacije (1-zbrajanje, 2-mnozenje) >"); scanf("%d", &operacija); if (operacija == 1) printf("Zbroj je %f\n", x + y); else if (operacija == 2) printf("Umnozak je %f\n", x * y); else printf("Neispravan odabir operacije.\n"); return 0; }
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 30
Napomene: - Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja - Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
4. vježbe uz predavanja 1. Dekadski broj 29 prikažite u obliku binarnog broja 2. Binarni broj 10011011 prikažite u obliku dekadskog broja (za prikaz ovog binarnog broja nije korištena tehnika dvojnog komplementa) 3. Registar od 8 bitova koristi se za prikaz brojeva tehnikom dvojnog komplementa. Koja dekadska vrijednost je prikazana u registru, ako je sadržaj registra 00011011. 4. Registar od 8 bitova koristi se za prikaz brojeva tehnikom dvojnog komplementa. Koja dekadska vrijednost je prikazana u registru, ako je sadržaj registra 10011011. 5. Dekadski broj -14 prikazati kao binarni broj u registru od 5 bitova, korištenjem tehnike dvojnog komplementa 6. Dekadski broj -14 prikazati kao binarni broj u registru od 10 bitova, korištenjem tehnike dvojnog komplementa 7. Koji se najveći i najmanji broj (izraziti u dekadskom obliku) može pohraniti u registru od 12 bita a. ako se ne koristi tehnika dvojnog komplementa b. ako se koristi tehnika dvojnog komplementa 8. Koliko najmanje bitova treba imati registar ako je u njega potrebno pohraniti dekadski broj 38 a. ako se ne koristi tehnika dvojnog komplementa b. ako se koristi tehnika dvojnog komplementa 9. U binarnom brojevnom sustavu, uz primjenu tehnike dvojnog komplementa, koristeći registre veličine 5 bitova, obavite operacije: a. 410 + 710 b. 1210 - 510 c. 710 + 1110 d. 1210 - 1610 Rezultate provjerite pretvorbom dobivenih binarnih rezultata u dekadske brojeve 10. Dekadski broj 110 pretvoriti u oktalni broj: a. direktno (uzastopnim dijeljenjem s 8) b. indirektno, grupiranjem znamenaka binarnog broja 11. Dekadski broj 94 pretvoriti u heksadekadski broj: a. direktno (uzastopnim dijeljenjem sa 16) b. indirektno, grupiranjem znamenaka binarnog broja 12. Heksadekadske brojeve F2C i 4E napisati u obliku binarnih i oktalnih brojeva 13. Oktalni broj 76431 napisati u obliku heksadekadskog broja
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 30
14. Dekadski broj -9 pohraniti u registar od 5 bitova (tehnikom dvojnog komplementa). Rezultat prikazati kao a. binarni broj b. heksadekadski broj c. oktalni broj
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 30
Rješenja 1.
29 14 7 3 1
: : : : :
2 2 2 2 2
= 14 = 7 = 3 = 1 = 0
ostatak ostatak ostatak ostatak ostatak
1 0 1 1 1
Broj 29 je pozitivan, stoga nije potrebno izračunavati dvojni komplement. Rješenje:
11101
Provjera:
1⋅24 + 1⋅23 + 1⋅22 + 0⋅21 + 1⋅20 = 29
2. Prva znamenka jest jedinica, ali u zadatku piše da nije korištena tehnika dvojnog komplementa. To znači da se radi o pozitivnom broju: 1⋅27 + 0⋅26 + 0⋅25 + 1⋅24 + 1⋅23 + 0⋅22 + 1⋅21 + 1⋅20 = 155 3. U zadatku piše da se za prikaz broja koristi tehnika dvojnog komplementa, ali prvi bit u registru nije jedinica. To znači da je u registru prikazan pozitivan broj. Vrijednost određujemo na isti način kao da se tehnika dvojnog komplementa uopće ne koristi: 1⋅24 + 1⋅23 + 0⋅22 + 1⋅21 + 1⋅20 = 27 4. Za prikaz broja se koristi tehnika dvojnog komplementa, a prvi bit u registru jest jedinica. To znači da je u registru prikazan neki negativan broj x. Izračunavanjem dvojnog komplementa dobit će se broj koji je jednak po apsolutnoj vrijednosti, ali suprotnog predznaka (dakle, pozitivan broj): 10011011
-> x
01100100
-> jedinični komplement
+ 1 = 01100101
dodaje se jedan kako bi se dobio dvojni komplement -> -x
Dobiveni broj -x je pozitivan broj (prvi bit mu nije jedinica), stoga se lako može odrediti o kojem se dekadskom broju radi: 1⋅26 + 1⋅25 + 0⋅24 + 0⋅23 + 1⋅22 + 0⋅21 + 1⋅20 = 10110 Ako je -x=10110, onda je x=-10110. Konačno rješenje jest: u registru je pohranjen dekadski broj -101 5. Negativni cijeli brojevi prikazuju se tehnikom dvojnog komplementa. Nije moguće direktno odrediti binarni prikaz broja -14, stoga se prvo određuje binarni prikaz pozitivnog broja 14 (uzastopnim dijeljenjem s 2). Voditi računa o tome da registar ima 5 bitova! +1410 = 011102 3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 30
Binarni broj iste apsolutne vrijednosti, ali suprotnog predznaka dobije se izračunavanjem dvojnog komplementa 01110 10001 +
1
= 10010
-> jedinični komplement dodaje se jedan kako bi se dobio dvojni komplement -> dvojni komplement
Konačno rješenje: -14 prikazan u tehnici dvojnog komplementa u registru od 5 bitova jest 10010 6. Slično kao u prethodnom zadatku. Treba voditi računa da se sada radi o 10-bitnom registru! +1410 = 00000011102 Negativna vrijednost dobije se izračunavanjem dvojnog komplementa 0000001110 1111110001 +
-> jedinični komplement dodaje se jedan kako bi se dobio dvojni komplement
1
= 1111110010
-> dvojni komplement
Konačno rješenje: -14 prikazan u tehnici dvojnog komplementa u registru od 10 bitova jest 1111110010 7. a) Ako se ne koristi tehnika dvojnog komplementa, raspon brojeva koji se može prikazati u registru od n bitova jest [0, 2n-1]. Najveći broj koji se može prikazati u 12-bitnom registru jest 212-1 = 4095. Najmanji broj koji se može prikazati jest 0. b) Ako se koristi tehnika dvojnog komplementa, raspon brojeva koji se može prikazati u registru od n bitova jest [-2n-1, 2n-1-1]. Najveći broj koji se može prikazati u 12-bitnom registru jest 211-1 = 2047. Najmanji broj koji se može prikazati jest -2048. 8. a) Ako se ne koristi tehnika dvojnog komplementa, raspon brojeva koji se može prikazati u registru od 5 bitova jest [0, 31], a u registru od 6 bitova [0, 63]. Potreban je registar od 6 bitova. b) Ako se koristi tehnika dvojnog komplementa, raspon brojeva koji se može prikazati u registru od 6 bitova jest [-32, 31], a u registru od 7 bitova [-64, 63]. Potreban je registar od 7 bitova.
9. a)
00100 + 00111 = 01011
-> 4 -> 7 -> 11
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 30
b)
01100 + 11011 = 00111
-> 12 -> -5 -> 7
c)
00111 + 01011 = 10010
-> 7 -> 11 -> -14
U ovom slučaju rezultat nije kakav bi se očekivao jer se u registru od 5 bitova, u tehnici dvojnog komplementa, broj 18 ne može prikazati. d)
01100 + 10000 = 11100
-> 12 -> -16 -> -4
10. a) 110 : 8 = 13 13 : 8 = 1 1 : 8 = 0
ostatak 6 ostatak 5 ostatak 1
Rješenje:
156
Provjera:
1⋅82 + 5⋅81 + 6⋅80
b) 11010 = 11011102 Binarne znamenke grupirati po tri. PAZITI da se grupiranje obavi "s desna na lijevo": 1 101 1102 = 1568 11. a)
94 : 16 = 5 5 : 16 = 0
ostatak 14 ostatak 5
Rješenje:
5E
Provjera:
5⋅161 + 14⋅160
b) 9410 = 10111102 Binarne znamenke grupirati po četiri. PAZITI da se grupiranje obavi "s desna na lijevo": 101 11102 = 5E16
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 30
12. Svaka heksadekadska znamenka pretvara se u četiri binarne: F 2 C16 = 1111 0010 11002 4 E16 = 0100 11102 Heksadekadski broj se lako pretvara u oktalni: heksadekadski broj treba napisati kao binarni broj, zatim binarne znamenke grupirati u grupe po tri. PAZITI da se grupiranje obavi "s desna na lijevo": F 2 C16 = 1111 0010 11002 = 111 100 101 1002 = 74548 4 E16 = 0100 11102 = 01 001 1102 = 1168 13. Oktalni broj se lako pretvara u heksadekadski: oktalni broj treba napisati kao binarni broj, zatim binarne znamenke grupirati u grupe po četiri. PAZITI da se grupiranje obavi "s desna na lijevo": 7 6 4 3 18 = 111 110 100 011 0012 = 111 1101 0001 10012 = 7D1916 14.
-910 = 101112 = 1716 = 278
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 67
Napomene: - Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja - Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
5. vježbe uz predavanja 1. Koje vrijednosti poprimaju varijable a, b nakon izvođenja sljedećeg programskog odsječka: char a; short int b; a = 120; b = 32000; a = a + 10; b = b + 1000;
Svoje rješenje provjerite tako da programski odsječak, dopunjen naredbom za ispis vrijednosti varijabli na zaslon i ostalim nužnim naredbama, izvedete na svom računalu. 2. Napisati sadržaj registra u kojem je, prema IEEE 754 standardu za prikaz brojeva u jednostrukoj preciznosti, pohranjen broj -17.7812510. Sadržaj registra napisati u oktalnom i heksadekadskom obliku. 3. U registru od 32 bita upisan je broj C2 B0 00 0016. Napisati koji je broj predstavljen u tom registru, ako registar služi za pohranu varijable tipa float. Rezultat napisati u dekadskom brojevnom sustavu. 4. U registru od 32 bita upisan je broj 43 00 20 0016. Napisati koji je broj predstavljen u tom registru, ako registar služi za pohranu varijable tipa float. Rezultat napisati u dekadskom brojevnom sustavu. 5. U registru od 32 bita upisan je broj 3 01 22 40 00 008. Napisati koji je broj predstavljen u tom registru, ako registar služi za pohranu varijable tipa float. Rezultat napisati u dekadskom brojevnom sustavu. 6. U registru od 32 bita upisan je broj 3 77 40 00 00 008. Napisati koji je broj predstavljen u tom registru, ako registar služi za pohranu varijable tipa float. 7. U registru od 32 bita upisan je broj 7F C0 00 0016. Napisati koji je broj predstavljen u tom registru, ako registar služi za pohranu varijable tipa float. 8. U registru od 32 bita upisan je broj 80 00 00 0016. Napisati koji je broj predstavljen u tom registru, ako registar služi za pohranu varijable tipa float. 9. U registru od 32 bita upisan je broj 00 68 00 0016. Napisati koji je broj predstavljen u tom registru, ako registar služi za pohranu varijable tipa float. 10. U registru od 32 bita upisan je broj 80 00 00 0116. Napisati koji je broj predstavljen u tom registru, ako registar služi za pohranu varijable: a. signed int i; b. unsigned int j; c. float x; Rezultate napisati u dekadskom brojevnom sustavu.
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 67
11. Napisati sadržaje registara u kojima je, prema IEEE 754 standardu za prikaz brojeva u jednostrukoj preciznosti, pohranjen sadržaj varijabli x i y nakon obavljanja sljedećih naredbi: float x, y; x = 0.f; y = -3.75f / x; Sadržaje registara napisati u heksadekadskom obliku. 12. Napisati sadržaj registra u kojem je, prema IEEE 754 standardu za prikaz brojeva u jednostrukoj preciznosti, pohranjen sadržaj varijable x nakon obavljanja sljedećih naredbi: float x; x = 0.f; x = x / x; Sadržaj registra napisati u heksadekadskom obliku. 13. Što će se ispisati uz pomoć sljedećih naredbi (napomena: u svim naredbama 0 predstavlja znamenku nula, a ne slovo O) char c; c = 'A' + '0'; printf("%d\n", c); printf("%c\n", c); printf("%c\n", 'D' - 'A' + '0'); printf("%d\n", 'D' - 'A' + '0'); printf("%d\n", '7' - '5'); printf("%d\n", '7' - 5); printf("%c\n", '7' - 5); printf("%d\n", '0' % 10);
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 67
Rješenja 1. Pri rješavanju ovakvih zadataka treba se sjetiti koji se najveći/najmanji brojevi mogu prikazati u varijablama određenih tipova podataka. 2. Prvi bit za predznak se postavlja na P=1. Time je pitanje predznaka riješeno (upamtiti: u IEEE 754 formatu se ne koristi ništa što podsjeća na tehniku dvojnog komplementa!) Sada treba odrediti karakteristiku i mantisu. Prvo pretvoriti broj u binarni oblik: 17.7812510 = 10001.110012 Normalizirati: 10001.110012 = 1.000111001 ⋅ 24 BE = 410 ⇒ K = 4 + 127 = 13110 = 100000112 M = 1.000111001 U 32-bitni registar prepisati P, K, te M (ali BEZ SKRIVENOG BITA!): 1 10000011 00011100100000000000000 Grupirati po tri znamenke s desna na lijevo 11 000 001 100 011 100 100 000 000 000 0002 = 301434400008 Grupirati po četiri znamenke s desna na lijevo 1100 0001 1000 1110 0100 0000 0000 00002 = C18E400016 3. Varijable tipa float pohranjuju se prema IEEE 754 formatu jednostruke preciznosti C2 B0 00 0016 = 1100 0010 1011 0000 0000 0000 0000 00002 Odrediti predznak: P = 1, stoga je broj negativan. Odrediti binarni eksponent: K = 100001012 = 13310 ⇒ BE = 133 - 127 = 6 Odrediti mantisu (vratiti joj skriveni bit!): "mantisa bez skrivenog bita" = .011000000000000000000002 M = 1.011000000000000000000002 Rezultat se dobije množenjem mantise s 2BE 1.011000000000000000000002 ⋅ 26 = 1011000.02 = 88.010 Ne zaboraviti negativni predznak (jer P=1) Konačni rezultat: -88.0 4.
128.12510
5.
-12.62510 3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 67
6. K = 255, u mantisi su svi bitovi postavljeni na nulu. Radi se o prikazu beskonačnosti. Budući da je predznak P=1, konačno rješenje jest: -∞. 7. K = 255, a u mantisi postoji jedan ili više bitova koji su postavljeni na jedinicu. U registru je prikazana vrijednost NaN (Not a Number). 8. K = 0, a u mantisi su svi bitovi postavljeni na 0. Radi se o prikazu broja 0. Budući da je predznak P=1, konačno rješenje jest: -0.0. 9. K = 0, a u mantisi postoje bitovi koji su postavljeni na jedan. Radi se o prikazu denormaliziranog broja. 00 68 00 0016 = 0000 0000 0110 1000 0000 0000 0000 00002 BE = -126 (kod denormaliziranog broja ne koristi se formula BE = K - 127) M = 0.1101 (kod denormaliziranog skriveni bit nije 1, nego 0) BE
o prikazu broja u tehnici dvojnog komplementa. Broj je negativan: 0000 0000 0000 0000 0000 0000 0001 1111 1111 1111 1111 1111 1111 1110 1 1111 1111 1111 1111 1111 1111 11112 = 214748364710
U registru je prikazan broj -2147483647 b) Radi se o prikazu broja u kojem se ne koristi tehnika dvojnog komplementa. Broj je pozitivan, unatoč tome što je prvi bit jedinica: 1000 0000 0000 0000 0000 0000 0000 00012 = 214748364910 c) Radi se o prikazu broja u IEEE 754 formatu: ≈ -1.4 ⋅ 10-45 11. Rezultat operacije je -∞. Rješenje jest: FF 80 00 0016 12.
Rezultat operacije je NaN. Rješenje jest (jedno od mogućih, jer na predavanjima nismo specificirali koje vrijednosti trebaju imati bitovi u mantisi kad se prikazuje NaN): 7F C0 00 0016
13.
Ispravnost vlastitog rješenja provjeriti izvođenjem programskog odsječka na računalu. 4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 102
Napomene: - Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja - Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
6. vježbe uz predavanja 1. Odredite najveću moguću relativnu i najveću moguću apsolutnu pogrešku koja se može očekivati pri pohrani broja 2⋅1022 u IEEE 754 formatu jednostruke preciznosti. 2. Gdje se (i zašto) u sljedećem odsječku programa nalaze sintaktičke pogreške: int thin, tall, short; float which, while, when, why, who; char single, double, triple; signed long a777, 7b, _19; 3. Pronađite koje su konstante ispravno, a koje neispravno napisane. Za ispravno napisane konstante odredite kojeg su tipa i koliko okteta zauzimaju u memoriji: 2 4u 7f 9.1 14.5U 0101u 12.1L 12.1e+22F 12.1e22 12.1Fe-22 12.1E11L 12.1E11u 0x22L 0xABC 0x2f 2F 0x2F.1F 021.1f 4. Napisati sadržaj registra u kojem je, prema IEEE 754 standardu za prikaz brojeva u dvostrukoj preciznosti pohranjen broj -0.2510. Sadržaj registra napisati u heksadekadskom obliku. 5. U registru od 64 bita upisan je broj C0 3D 80 00 00 00 00 0016. Napisati koji je broj predstavljen u tom registru, ako registar služi za pohranu varijable double x. Rezultat napisati u dekadskom brojevnom sustavu. 6. Napisati sadržaj registra u kojem je, prema IEEE 754 standardu za prikaz brojeva u dvostrukoj preciznosti pohranjen broj -∞. Sadržaj registra napisati u heksadekadskom obliku. 7. Napisati sadržaj registra u kojem je, prema IEEE 754 standardu za prikaz brojeva u dvostrukoj preciznosti pohranjena vrijednost NaN. Sadržaj registra napisati u heksadekadskom obliku. 8. Odredite najveću moguću relativnu i najveću moguću apsolutnu pogrešku koja se može očekivati pri pohrani broja 2⋅1022 u IEEE 754 formatu dvostruke preciznosti.
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 102
Rješenja 1. Najveća moguće relativna pogreška ovisi isključivo o broju bitova mantise m. Vodite računa o tome da parametar m uključuje i skriveni bit. Kod prikaza prema IEEE 754 standardu jednostruke preciznosti m = 24. Najveća moguća relativna pogreška iznosi 2-24 ≈ 6 ⋅ 10-8 Najveća moguća apsolutna pogreška ovisi o parametru m i konkretnom broju x koji se prikazuje: Najveća moguća apsolutna pogreška iznosi x ⋅ 2-24 ≈ 2 ⋅ 1022 ⋅ 6 ⋅ 10-8 = 1.2 ⋅ 1015
2. int thin, tall, short; float which, while, when, why, who; char single, double, triple; signed long a777, 7b, _19; U prvom retku se za ime varijable koristi ključna riječ short; U drugom retku se za ime varijable koristi ključna riječ while; U trećem retku se za ime varijable koristi ključna riječ double; U četvrtom retku ime varijable 7b započinje znamenkom (nije dopušteno) 3. 2 4u 7f 9.1 14.5U 0101u 12.1L 12.1e+22F 12.1e22 12.1Fe-22 12.1E11L 12.1E11u 0x22L 0xABC 0x2f 2F 0x2F.1F 021.1F
signed int - 4 okteta unsigned int - 4 okteta pogreška: nedostaje točka double - 8 okteta pogreška: ne postoji tip unsigned double unsigned int u oktalnom obliku - 4 okteta long double - 8 okteta float - 4 okteta double - 8 okteta pogreška: F na pogrešnom mjestu long double - 8 okteta pogreška: ne postoji tip unsigned double long int u heksadekadskom obliku - 4 okteta int u heksadekadskom obliku - 4 okteta int u heksadekadskom obliku - 4 okteta pogreška: nedostaje točka pogreška: ne može se realni broj zapisati u heksadekadskom obliku float, 0 na početku nema nikakvo značenje, ali nije pogreška - 4 okteta
4. BFD0000000000000 5. -29.5
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 102
6. FFF0000000000000 7. Prikazano je jedno od mogućih rješenja. Bitno je da su svi bitovi karakteristike postavljeni na 1, te da je barem jedan bit mantise postavljen na 1 FFF8000000000000 8. Najveća moguća relativna pogreška iznosi 2-53 ≈ 1.1 ⋅ 10-16 Najveća moguća apsolutna pogreška iznosi x ⋅ 2-53 ≈ 2.2 ⋅ 106
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 132
Napomene: - Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja - Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
7. vježbe uz predavanja 1. Napisati C program koji će s tipkovnice učitati cijeli broj x, a zatim na zaslon ispisati tekst Istina je ako je učitani broj u intervalu [1, 9] ili je u intervalu [80, 90]. 2. Napisati C program koji će s tipkovnice učitati cijeli broj m, a zatim na zaslon ispisati tekst Istina je ako je učitani broj neparan pozitivan broj. 3. Napisati C program koji će na zaslon ispisati tekst Istina je ako uvjet iz 1. zadatka nije zadovoljen (napisati jedno rješenje uz korištenje operatora negacije i jedno rješenje bez korištenja operatora negacije). 4. Napisati C program koji će na zaslon ispisati tekst Istina je ako uvjet iz 2. zadatka nije zadovoljen (napisati jedno rješenje uz korištenje operatora negacije i jedno rješenje bez korištenja operatora negacije). 5. Napisati C program koji će s tipkovnice učitati dva znaka u varijable c1 i c2 tipa char. Ako su oba učitana znaka velika slova abecede (A-Z) i pri tome su oba znaka samoglasnici, ispisati tekst Ucitani znakovi su "veliki" samoglasnici (primijetite da unutar teksta treba dva puta ispisati i dvostruke navodnike). 6. Ispisati tekst Barem jedan od znakova nije veliki samoglasnik ako uvjet iz 5. zadatka nije zadovoljen (napisati jedno rješenje uz korištenja operatora negacije i jedno rješenje bez korištenja operatora negacije). 7. Napisati C program koji će s tipkovnice učitati znak. Ako je učitani znak malo slovo abecede ili znamenka, ispisati tekst Istina je. 8. Napisati C program koji će s tipkovnice učitati dva znaka. Ako oba učitana znaka predstavljaju heksadekadske znamenke, ispisati poruku Upisan je ispravan dvoznamenkasti heksadekadski broj. 9. Što je rezultat evaluacije svakog od sljedećih izraza (treba odrediti tip podatka i vrijednost): 12 / 2*3 15 / 2*3 15. / 2*3 15.f / 2*3 15.f / 2*3. 15 / 2*3. 12 / (2*3) 2 * 2+3 2 * 5%2 2 * (5%2) (float)15/2/3
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 132
10. Što će biti sadržaj svake od definiranih varijabli nakon obavljanja sljedećeg programskog odsječka (za varijable tipa char treba navesti njihovu numeričku vrijednost): char c1, c2; float f1, f2; double f3, f4; c1 = 132.f - (double)2; f1 = -2147483648.0; f2 = -2147483645.0; f3 = -2147483645.0; f4 = -2147483645.0f; c2 = 126;
11. Što će se ispisati programskim odsječkom: int i; i = !0 <= 101 % 100; printf ("%d\n", i); i = !1 && !200 || !0 && !100; printf ("%d\n", i); i = (!1 && !0 || 100) + 'a' - 'A'; printf ("%d\n", i); i = 'a' - 'A' + 18; printf ("%c %d\n", i, i); i = 10; printf ("%d\n", i==15); printf ("%d\n", i);
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 03-TipoviPodataka.pdf - do stranice: 132
Rješenja
1.
#include int main (void) { int x; scanf("%d", &x); if (x >= 1 && x <= 9 || x >= 80 && x <= 90) { printf("Istina je"); } return 0; }
2.
#include int main (void) { int m; scanf("%d", &m); if (m > 0 && m % 2 != 0) { printf("Istina je"); } return 0; }
11. Svoje rješenje provjerite obavljanjem navedenih naredbi u vlastitom C programu. 5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 04-OstaliOperatori.pdf - do stranice: 37
Napomene: - Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja - Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
8. vježbe uz predavanja 1. Što će se ispisati sljedećim odsječkom programa: char c, c1; c = 'a' / 2*1.1; printf("%d\n", c); c1 = 1 + c++; printf("%d %d\n", c, c1); c1 = ++c + 12; printf("%d %c %d %c\n", c, c, c1, c1); 2. Što će se ispisati sljedećim odsječkom programa: int i1 = 5, i2, j1 = 5, j2, k1, k2; i2 = ++i1 + 3; printf("%d %d\n", i1, i2); j2 = j1++ + 3; printf("%d %d\n", j1, j2); k1 = i2++ * --j2; printf("%d %d %d\n", i2, j2, k1); i2++; ++j2; k2 = ++i2 * j2++; printf("%d %d %d\n", i2, j2, k2); 3. Što će se ispisati sljedećim programskim odsječkom: int i = 23, j = 13, k = 11, m; printf("%d\n", i || j && k); printf("%d\n", i | j & k); m = i == j && k; printf("%d %d\n", m, -!m < 0); m = i ^ (j=13); printf("%d %d\n", m, j); j = 7; m = 7; m = i & ~(j==7); printf("%d\n", m); m = ~(~k | k); printf("%d\n", m); 4. Što će se ispisati sljedećim programskim odsječkom: int i = 6; printf("%d\n", i << 3); printf("%d\n", i);
1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 04-OstaliOperatori.pdf - do stranice: 37
5. Što će se ispisati sljedećim odsječkom programa: int i = 7; if (i = 3 & 4) printf("ISTINA JE %d\n", i); else printf("NIJE ISTINA %d\n", i); if (i = 3 && 4) printf("ISTINA JE %d\n", i); else printf("NIJE ISTINA %d\n", i); printf("Jos jednom upozoravam, NIJE ISTINA\n"); printf("Program zavrsava\n"); 6. Što će se ispisati obavljanjem sljedećeg programskog odsječka: char x, y, z; x = 2; y = '1'; z = (y <= x) ? ( ++x ) : ( y += ++x ); printf("%d %c %d %c", x, y, y, z); 7. Što će se ispisati obavljanjem sljedećeg programskog odsječka: int a = 3, b = 5, c = 9, d; d = a + (b+=c); printf("%d %d %d %d", a, b, c, d);
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 04-OstaliOperatori.pdf - do stranice: 37
Rješenja
6. Prvo se izračunava y <= x → 0 Budući je rezultat "laž", izraz ( ++x ) se uopće ne izračunava! Izračunava se samo ( y+= ++x ), a zatim se rezultat tog izraza pridružuje varijabli z. Zbog prefiksnog oblika ++ operatora, varijabla x se prvo uvećava za 1, a zatim se njena vrijednost dalje koristi u izrazu. Uvećana vrijednost varijable x je 3. y += 3 je isto što i y = y + 3 Konačno, x = 3, y = '4' (odnosno 52), z = '4' (odnosno 52) Ispisat će se: 3 4 52 4
7. Prvo se izračunava (b+=c) → b=14, rezultat cijelog izraza (b+=c) je 14 d = a + 14, tj. d = 17 Ispisat će se: 3 14 9 17
Svoja rješenja ostalih zadataka provjerite izvođenjem programa na vlastitim računalima.
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
Napomene: - Savjetuje se navedene zadatke riješiti ubrzo nakon predavanja - Savjetuje se ne gledati rješenja prije nego se pokuša samostalno riješiti zadatke
9. vježbe uz predavanja 1. S tipkovnice u char varijablu c učitajte jedan znak. Ako je učitano veliko slovo, ispisati poruku "To je veliko slovo". Ako je učitano malo slovo, ispisati poruku "To je malo slovo". Ako je učitana znamenka (0-9), ispisati poruku "To je znamenka". Ako nije učitano ni slovo ni znamenka, ispisati poruku "To je neki drugi znak". 2. S tipkovnice u char varijablu z1 učitajte znak. Ako učitani znak nije heksadekadska znamenka (0-9, A-F, a-f), ispisati poruku "Nije dobra znamenka" i završiti program. Inače, ispisati dekadski ekvivalent učitane heksadekadske znamenke. Npr. ako je učitan znak e, treba ispisati 14. 3. Riješiti pomoću petlje s ispitivanjem uvjeta na početku. Izračunati i na zaslon ispisati sumu: 1 1
-
1 + 2
1 3
-
1 4
+ ...
+
1 999
-
1 1000
4. Riješiti pomoću petlje s ispitivanjem uvjeta na početku. S tipkovnice učitavati i sumirati cijele brojeve dok god su oni djeljivi s 3 ili 7. Na kraju ispisati sumu učitanih brojeva. Podrazumijeva se da se zadnji broj koji je učitan (onaj zbog kojeg se prekida učitavanje) ne dodaje u sumu. Vodite računa o tome da već i prvi učitani broj može biti "neispravan". 5. Riješiti pomoću petlje s ispitivanjem uvjeta na početku. S tipkovnice učitavati i sumirati cijele brojeve dok god su oni djeljivi s 3 ili 7. Na kraju ispisati sumu učitanih brojeva. Podrazumijeva se da se zadnji broj koji je učitan (onaj zbog kojeg se prekida učitavanje) također dodaje u sumu. Vodite računa o tome da već i prvi učitani broj može biti "neispravan". 6. Riješiti pomoću petlje s ispitivanjem uvjeta na početku. S tipkovnice učitati cijeli broj n koji mora biti između 0 i 16 (uključivo s granicama). Ako broj nije ispravan, ispisati odgovarajuću poruku. Ako je broj ispravno upisan, učitati n binarnih znamenki i ispisati dekadski ekvivalent učitanog binarnog broja (ne primjenjuje se tehnika dvojnog komplementa, pa je dekadski ekvivalent sigurno pozitivan broj). Npr., ako je korisnik upisao 4 1 1 0 1 program treba ispisati 13 (jer je 11012 = 1310). Npr., ako je korisnik upisao 0 program treba ispisati 0. 1
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
7. Riješiti pomoću petlje s ispitivanjem uvjeta na početku. Načinite program za izračunavanje n!. Vrijednost za n učitati s tipkovnice. Ako broj nije ispravan (mora biti cijeli broj veći ili jednak 0), ispisati odgovarajuću poruku. 8. Riješiti pomoću petlje s ispitivanjem uvjeta na početku. Načinite program za pretvaranje nenegativnog (to znači pozitivnog ili nule) cijelog dekadskog broja u heksadekadski oblik (uzastopnim dijeljenjem sa 16). Nije potrebno provjeravati je li učitani broj nenegativan. Znamenke heksadekadskog broja smijete ispisati "obrnutim" redoslijedom. Npr. za uneseni dekadski broj 725, program treba ispisati 5D2. Za uneseni broj 0, program treba ispisati 0. 9. Riješiti pomoću petlje s ispitivanjem uvjeta na početku. Isto kao prethodni zadatak, ali za učitani dekadski broj treba ispisati oktalni broj. 10. Riješiti pomoću petlje s ispitivanjem uvjeta na početku. U varijablu tipa int s tipkovnice učitati nenegativni cijeli broj (ne treba kontrola je li broj nenegativan). Na zaslon ispisati binarni sadržaj registra te varijable (binarne znamenke se moraju ispisati ispravnim redoslijedom). Za izdvajanje bitova koristiti bitovni operator & i operator za posmak bitova prema desno. Može se pretpostaviti da se za pohranu int tipa podatka koristi 32 bita. Uputa: •
•
•
•
ako se sadržaj registra 01000000000000000000000000010010 posmakne za 31 mjesto u desno, koja binarna znamenka originalnog broja će se pojaviti na krajnjoj desnoj poziciji? ako se sadržaj registra 01000000000000000000000000010010 posmakne za 30 mjesta u desno, koja binarna znamenka originalnog broja će se pojaviti na krajnjoj desnoj poziciji? ako se sadržaj registra 01000000000000000000000000010010 posmakne za 29 mjesta u desno, koja binarna znamenka originalnog broja će se pojaviti na krajnjoj desnoj poziciji? I tako dalje... vrijednost "krajnje desnog bita" varijable x može se dobiti operacijom x & 1
11. Riješiti pomoću petlje s ispitivanjem uvjeta na kraju (do-while). Usporediti s rješenjem u kojem se koristila petlja s ispitivanjem uvjeta na početku. Izračunati i na zaslon ispisati sumu: 1 1
-
1 + 2
1 3
-
1 4
+ ...
+
1 999
-
1 1000
2
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
12. Riješiti pomoću petlje s ispitivanjem uvjeta na kraju (do-while). Usporediti s rješenjem u kojem se koristila petlja s ispitivanjem uvjeta na početku. S tipkovnice učitavati i sumirati cijele brojeve dok god su oni djeljivi s 3 ili 7. Na kraju ispisati sumu učitanih brojeva. Podrazumijeva se da se zadnji broj koji je učitan (onaj zbog kojeg se prekida učitavanje) ne dodaje u sumu. Vodite računa o tome da već i prvi učitani broj može biti "neispravan".
13. Riješiti pomoću petlje s ispitivanjem uvjeta na kraju (do-while). Usporediti s rješenjem u kojem se koristila petlja s ispitivanjem uvjeta na početku. S tipkovnice učitavati i sumirati cijele brojeve dok god su oni djeljivi s 3 ili 7. Na kraju ispisati sumu učitanih brojeva. Podrazumijeva se da se zadnji broj koji je učitan (onaj zbog kojeg se prekida učitavanje) također dodaje u sumu. Vodite računa o tome da već i prvi učitani broj može biti "neispravan". 14. Napisati dva rješenja. Jedno rješenje pomoću petlje s ispitivanjem uvjeta na početku i jedno rješenje pomoću petlje s ispitivanjem uvjeta na kraju. Usporediti rješenja. S tipkovnice učitati nenegativan cijeli broj N (N može biti nula!). Na zaslon ispisati N kvocijenata (može biti niti jedan) u obliku realnih brojeva ukupne širine 7 znakova, s pet decimala iza decimalne točke): N 2 3 1 2
3
4
...
N+1
15. S tipkovnice učitavati cijele brojeve dok god ne bude upisan broj manji ili jednak nuli. Na zaslon ispisati sumu učitanih pozitivnih brojeva podijeljenu s najvećim do tada učitanim pozitivnim brojem i pomnoženu s najmanjim do tada učitanim pozitivnim brojem. Ako nije upisan niti jedan pozitivni broj, ispisati odgovarajuću poruku. Primjer: ako korisnik utipka brojeve 2 5 3 2 2 -22, program treba ispisati 5.600000
16. Napišite program koji s tipkovnice učitava dva znaka te ispisuje sve znakove ASCII tablice koji se nalaze između ta dva znaka. Npr., ako se učitaju znakovi d i k, program ispisuje defghijk.
3
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
17. Načinite program koji će ispisati sljedeću tablicu: A. a b B. b c C. c d D. d e ... itd. S. s t T. t u U. u v
c d e f
d e f g
e f g h
f g h i
.F .G .H .I
u v w x .X v w x y .Y w x y z .Z
Očekuje se da zadatak riješite pomoću dvije programske petlje, a ne npr. ovako: printf("A. printf("B. printf("C. printf("D. ... itd.
a b c d
b c d e
c d e f
d e f g
e f g h
f g h i
.F\n"); .G\n"); .H\n"); .I\n");
18. Načinite program kojim će se učitati član niza a1 koji mora biti cijeli broj veći od 1. Nije potrebno provjeravati ispravnost unesenog broja. Ispisati članove niza a1, a2, a3, ..., an i ukupan broj članova niza. Član niza ai (za i > 1) izračunava se na sljedeći način: ako je ai-1 paran, tada je ai = ai-1 / 2 ako je ai-1 neparan, tada je ai = 3 ai-1 + 1 Niz završava članom an = 2
4
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
Rješenja 1.
#include int main (void) { char c; scanf("%c", &c); if (c >= 'A' && c <= 'Z') printf("To je veliko slovo\n"); else if (c >= 'a' && c <= 'z') printf("To je malo slovo\n"); else if (c >= '0' && c <= '9') printf("To je znamenka\n"); else printf("To je neki drugi znak\n"); return 0; }
Uočite da je sljedeće rješenje loše (objasnite zašto), iako "program radi": Loše rješenje !!! #include int main (void) { char c; scanf("%c", &c); if (c >= 'A' && c <= 'Z') printf("To je veliko slovo\n"); if (c >= 'a' && c <= 'z') printf("To je malo slovo\n"); if (c >= '0' && c <= '9') printf("To je znamenka\n"); if (! (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9') ) printf("To je neki drugi znak\n"); return 0; }
5
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
#include int main (void) { int i; float suma, brojnik; i = 1; suma = 0.f; while (i <= 1000) { brojnik = i % 2 ? 1.f : -1.f; suma += brojnik / i; ++i; } printf("Suma je: %f\n", suma); return 0; }
6
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
4.
#include int main (void) { int suma = 0, x; scanf("%d", &x); while (x % 3 == 0 || x % 7 == 0) { suma += x; scanf("%d", &x); } printf("Suma ucitanih brojeva je %d\n", suma); return 0; }
5.
#include int main (void) { int suma = 0, x; scanf("%d", &x); suma += x; while (x % 3 == 0 || x % 7 == 0) { scanf("%d", &x); suma += x; } printf("Suma ucitanih brojeva je %d\n", suma); return 0; }
6.
#include int main (void) { int n, znamenka, dekadski = 0; scanf("%d", &n); if (n < 0 || n > 16) { printf("Upisali ste neispravan broj\n"); } else { while (n > 0) { scanf("%d", &znamenka); dekadski = dekadski*2 + znamenka; --n; } printf("%d\n", dekadski); } return 0; }
7.
#include int main (void) { int n, fakt = 1; scanf("%d", &n); if (n < 0) { printf("Upisali ste neispravan broj\n"); } else { while (n > 1) { fakt *= n; --n; } printf("%d\n", fakt); } return 0; }
7
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
8.
#include int main (void) { int n, ostatak; scanf("%d", &n); if (n == 0) { printf("0\n"); } else { while (n > 0) { ostatak = n % 16; if (ostatak < 10) printf("%d", ostatak); else printf("%c", 'A' + ostatak - 10); n = n / 16; } } return 0; }
9.
#include int main (void) { int n, ostatak; scanf("%d", &n); if (n == 0) printf("0\n"); else while (n > 0) { ostatak = n % 8; printf("%d", ostatak); n = n / 8; } return 0; }
10.
#include int main (void) { unsigned nt broj; int kolikoPosmaknutiDesno, pomocna; scanf("%u", &broj); printf("Upisali ste broj %d\n", broj); kolikoPosmaknutiDesno = 31; while (kolikoPosmaknutiDesno >= 0) { pomocna = broj >> kolikoPosmaknutiDesno; /* sada se u varijabli pomocna, na poziciji nultog bita (najmanje znacajnog bita) nalazi znamenka koja se u varijabli broj nalazi na poziciji kolikoPosmaknutiDesno. Vrijednost tog bita, 0 ili 1, moze se dobiti tako da se obavi operacija: pomocna & 000000000000000000000000000000012 */ printf("%d", pomocna & 1); /* u sljedecem koraku posmaknuti za 30 mjesta, u sljedecem za 29 mjesta itd. */ --kolikoPosmaknutiDesno; } printf("\n"); return 0; }
8
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
Rješenje 11. zadatka #include int main (void) { int i; float suma, brojnik; i = 1; suma = 0.f; do { brojnik = i % 2 ? 1.f : -1.f; suma += brojnik / i; ++i; } while (i <= 1000); printf("Suma je: %f\n", suma); return 0; }
s petljom s ispitivanjem uvjeta na početku #include int main (void) { int i; float suma, brojnik; i = 1; suma = 0.f; while (i <= 1000) { brojnik = i % 2 ? 1.f : -1.f; suma += brojnik / i; ++i; } printf("Suma je: %f\n", suma); return 0; }
Tijelo petlje će se sigurno izvršiti točno tisuću puta. Jednako je prikladno koristiti obje vrste petlji. Napomena: u ovom zadatku bi najprikladnija vrsta petlje bila petlja s poznatim brojem ponavljanja, koja za sada još nije obrađena na predavanjima i zato se ne koristi u rješenju.
Rješenje 12. zadatka #include int main (void) { int suma = 0, x; do { scanf("%d", &x); if (x % 3 == 0 || x % 7 == 0) suma += x; } while (x % 3 == 0 || x % 7 == 0); printf("Suma ucitanih brojeva je %d\n", suma); return 0; }
s petljom s ispitivanjem uvjeta na početku #include int main (void) { int suma = 0, x; scanf("%d", &x); while (x % 3 == 0 || x % 7 == 0) { suma += x; scanf("%d", &x); } printf("Suma ucitanih brojeva je %d\n", suma); return 0; }
Jedan dio tijela petlje se mora izvršiti barem jednom (scanf), a drugi dio tijela petlje (sumiranje) se možda neće trebati izvršiti niti jednom. Jednako je (ne)prikladno koristiti obje vrste petlji.
Rješenje 13. zadatka #include int main (void) { int suma = 0, x; do { scanf("%d", &x); suma += x; } while (x % 3 == 0 || x % 7 == 0); printf("Suma ucitanih brojeva je %d\n", suma); return 0; }
s petljom s ispitivanjem uvjeta na početku #include int main (void) { int suma = 0, x; scanf("%d", &x); suma += x; while (x % 3 == 0 || x % 7 == 0) { scanf("%d", &x); suma += x; } printf("Suma ucitanih brojeva je %d\n", suma); return 0;
}
9
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
Cijelo tijelo petlje se mora izvršiti barem jednom. U ovom zadatku očito je prikladnije koristiti petlju s ispitivanjem uvjeta na kraju.
Rješenje 14. zadatka #include int main (void) { int n, i = 1; scanf("%d", &n); while (i <= n) { printf("%7.5f\n", (float)i/(i+1)); ++i; } return 0; } #include int main (void) { int n, i = 1; scanf("%d", &n); do { if (i <= n) { printf("%7.5f\n", (float)i/(i+1)); ++i; } } while (i <= n); return 0; }
Moguće je da tijelo petlje neće trebati izvršiti niti jednom. U ovom zadatku očito je prikladnije koristiti petlju s ispitivanjem uvjeta na početku. Napomena: u ovom zadatku bi najprikladnija vrsta petlje bila petlja s poznatim brojem ponavljanja, koja za sada još nije obrađena na predavanjima i zato se ne koristi u rješenju.
Rješenje 15. zadatka #include int main (void) { int suma = 0, najmanji, najveci, ucitani; do { scanf("%d", &ucitani); if (ucitani > 0) { if (suma == 0) najmanji = najveci = ucitani; suma += ucitani; if (ucitani < najmanji) najmanji = ucitani; if (ucitani > najveci) najveci = ucitani; } } while (ucitani > 0); if (suma > 0) printf("Rezultat je: %f\n", (float)suma / najveci * najmanji); else printf("Nije ucitan niti jedan pozitivan broj\n"); return 0; }
10
Programiranje i programsko inženjerstvo, ZPR-FER-UNIZG Vježbe uz predavanja 05-KontrolneNaredbe.pdf - do stranice: 33
Rješenje 16. zadatka #include int main(void) { char c1, c2, c; scanf("%c %c", &c1, &c2); c = c1; while (c <= c2) printf("%c", c++);
Komentirajte: što će se dogoditi ako se umjesto znakova d i k s tipkovnice učitaju znakovi k i d ? Što će se dogoditi ako se umjesto znakova d i k s tipkovnice učitaju znakovi d i d ?
printf("\n"); return 0; }
Rješenje 17. zadatka #include int main(void) { char i = 'A', j; while (i <= 'U') { printf("%c. ", i); j = i + 'a' - 'A'; while (j < i + 'a' - 'A' + 6) { printf("%c ", j++); } printf(".%c\n", i++ + 5); } return 0; }
Vanjska petlja mijenja vrijednost varijable i od 'A' do 'U'. Na početku svakog retka se ispisuje vrijednost varijable i (u formatu %c), a na kraju retka ispisuje se slovo koje se u ASCII tablici nalazi "5 mjesta dalje" od slova koje se ispisalo na početku retka, te na samom kraju znak za skok u novi red. Unutarnja petlja mijenja vrijednost varijable j od "male verzije" slova koje je ispisano na početku retka, do slova koje se u ASCII tablici nalazi "6 mjesta dalje" od početnog malog slova.
Rješenje 18. zadatka #include int main(void) { int ai, brClanova = 0; printf("Upisite cijeli broj veci od 1: "); scanf("%d", &ai); while (ai >= 2) { brClanova = brClanova + 1; printf ("Clan a%d = %d\n", brClanova, ai); /* izracunaj sljedeci clan */ if (ai % 2 != 0) /* prethodni clan je neparan */ ai = 3 * ai + 1; else /* prethodni clan je paran */ ai = ai / 2; } printf ("Ukupno %d clanova.\n", brClanova); return 0; }