98. Šta je rezultat rada sledećeg programa? Primer koji ilustruje operator &
/* broj
karaktera u nizu */
#define MAX 10
char niz[MAX] = "012345678";
/* niska znakova*/
main()
{
int index; /* brojac u
petlji */
/* stampanje
clanova niza prema zahtevu */
for
(index = 0; index < MAX; index++)
{
printf( "&niz[index]=0x%x (niz+index)=0x%x
niz[index]=0x%x\n", &niz[index], (niz+index), niz[index]);
}
return
(0);
}
99. Sta je rezultat rada sledećeg
programa?
Primer koji ilustruje rad sa pokazivacima
#include <stdio.h>
main()
{
int x = 3;
/* Adresu promenjive x zapamticemo u novoj promenljivoj.
Nova promenljiva je tipa pokazivaca na int (int*) */
int* px;
printf("Adresa promenljive x je : %p\n", &x);
printf("Vrednost promenljive x je : %d\n", x);
px = &x;
printf("Vrednost promenljive px je (tj. px) : %p\n", px);
printf("Vrednost promenljive na koju ukazuje px (tj. *px) je : %d\n", *px);
/* Menjamo vrednost promenljive na koju ukazuje px */
*px = 6;
printf("Vrednost promenljive na koju ukazuje px (tj. *px) je : %d\n", *px);
/* Posto px sadrzi adresu promenljive x, ona ukazuje na x tako da je
posredno promenjena i vrednost promenljive x */
printf("Vrednost promenljive x je : %d\n", x);
}
Izlaz (u konkretnom slucaju):
Adresa promenljive x je : 0012FF88
Vrednost promenljive x je : 3
Vrednost promenljive px je (tj. px) : 0012FF88
Vrednost promenljive na koju ukazuje px (tj. *px) je : 3
Vrednost promenljive na koju ukazuje px (tj. *px) je : 6
Vrednost promenljive x je : 6
100. Sta je
rezultat rada sledećeg programa?
Primer koji ilustruje
prenos argumenata preko pokazivaca – funkcija koja vrsi trampu
vrednosti dva cela broja.
Podsetimo se:
U programskom jeziku C parametri se mogu predati
funkciji po _______________ i po ______________.
Kada god je
potrebno da funkcija menja vrednost svojih stvarnih parametara i tako
izmenjene ih vrati pozivajucoj jedinici, onda se ti parametri predaju
funkciji po ____________________.
Kada god je potrebno da
funkcija svoje stvarne parametre vrati pozivajucoj jedinici
nepromenjene, onda se ti parametri predaju funkciji po
____________________.
Kada god je potrebno da funkcija vrati
pozivajucoj jedinici vise rezultata, onda se ti rezultati prenose kao
parametri funkcije i predaju funkciji po ____________________.
#include <stdio.h>
/* Pogresna verzija funkcije swap. Zbog prenosa po vrednosti, funkcija
razmenjuje kopije promenljivih iz main-a, a ne samih promenljivih */
void swap_sa_greskom(int x, int y)
{
int tmp;
printf("swap_sa_greskom: ");
printf("Funkcija menja vrednosti promenljivim na adresama : \n");
printf("x : %p\n", &x);
printf("y : %p\n", &y);
tmp = x;
x = y;
y = tmp;
}
/* Resenje je prenos argumenata preko pokazivaca */
void swap(int* px, int* py)
{
int tmp;
printf("swap : Funkcija menja vrednosti promenljivim na adresama : \n");
printf("px = %p\n", px);
printf("py = %p\n", py);
tmp = *px;
*px = *py;
*py = tmp;
}
main()
{
int x = 3, y = 5;
printf("Adresa promenljive x je %p\n", &x);
printf("Vrednost promenljive x je %d\n", x);
printf("Adresa promenljive y je %p\n", &y);
printf("Vrednost promenljive y je %d\n", y);
/* Pokusavamo zamenu koristeci pogresnu verziju funkcije */
swap_sa_greskom(x, y);
printf("Posle swap_sa_greskom:\n");
printf("Vrednost promenljive x je %d\n", x);
printf("Vrednost promenljive y je %d\n", y);
/* Vrsimo ispravnu zamenu. Funkciji swap saljemo adrese promenljvih x i y, a ne njihove vrednosti */
swap(&x, &y);
printf("Posle swap:\n");
printf("Vrednost promenljive x je %d\n", x);
printf("Vrednost promenljive y je %d\n", y);
}
Izlaz u konkretnom slucaju:
Adresa promenljive x je 0012FF88
Vrednost promenljive x je 3
Adresa promenljive y je 0012FF84
Vrednost promenljive y je 5
swap_sa_greskom: Funkcija menja vrednosti promenljivim na adresama :
x : 0012FF78
y : 0012FF7C
Posle swap_wrong:
Vrednost promenljive x je 3
Vrednost promenljive y je 5
swap : Funkcija menja vrednosti promenljivim na adresama :
px = 0012FF88
py = 0012FF84
Posle swap:
Vrednost promenljive x je 5
Vrednost promenljive y je 3
101. Šta je rezultat rada sledećeg programa? Primer koji ilustruje visestruko referenciranje.
#include
<stdio.h>
char *
c[]={"html","\\a","HEAD","a\thref","\\body"};
char **cp[]={c+3,c+4,c,c+1,c+2};
char
***cpp=cp;
main()
{
printf("1 %s\n", **++cpp);
printf("2 %s\n", **++cpp+1);
printf("3 %s\n", *((--cpp)[-1]) );
printf("4 %s\n", **cpp+1);
printf("5 %s\n", **++cpp);
return 0;
}
102. Napisati C potprogram div_and_mod koji kao rezultat vraca celobrojni deo kolicnika i ostatak pri deljenju dva cela broja x i y. NCP koji ilustruje rad sa potprogramom.
Primer koji ilustruje rad sa vise povratnih vrednosti funkcije koristeci prenos argumenata preko adrese (tj. pokazivace).
/* Funkcija istovremeno vraca dve vrednosti - kolicnik i ostatak dva data broja.
Ovo se postize tako sto se funkciji predaju vrednosti dva broja (x i y) koji se dele
i adrese dve promenljive na koje ce se smestiti rezultati */
void div_and_mod(int x, int y, int* div, int* mod)
{
printf("Kolicnik postavljam na adresu : %p\n", div);
printf("Ostatak postavljam na adresu : %p\n", mod);
*div = x / y;
*mod = x % y;
}
main()
{
int div, mod;
printf("Adresa promenljive div je %p\n", &div);
printf("Adresa promenljive mod je %p\n", &mod);
/* Pozivamo funkciju tako sto joj saljemo vrednosti dva broja (5 i 2)
i adrese promenljvih div i mod na koje ce se postaviti rezultati */
div_and_mod(5, 2, &div, &mod);
printf("Vrednost promenljive div je %d\n", div);
printf("Vrednost promenljive mod je %d\n", mod);
}
Izlaz u konkretnom slucaju:
Adresa promenljive div je 0012FF88
Adresa promenljive mod je 0012FF84
Kolicnik postavljam na adresu : 0012FF88
Ostatak postavljam na adresu : 0012FF84
Vrednost promenljive div je 2
Vrednost promenljive mod je 1
103. NCP koji ispisuje broj argumenata komandne linije i parametre komandne linije.
#include
<stdio.h>
/*argumenti
komandne linije */
main(int argc, char
*argv[] )
{ int i; /*brojac u
petlji */
printf("Broj
argumenata je %d\n", argc);
/*stampanje
svakog argumenta u zasebnom redu */
for(i=0;i<argc;i++)
printf( "argv[%d] = %s\n", i , argv[i] );
}
104.
NCP koji na izracunava i na standardni izlaz ispisuje sumu
brojeva koji se zadaju u komandnoj liniji. Celi brojevi se zadaju
posle imena programa i opcije -d. Realni brojevi se zadaju
posle imena programa i opcije -f.
RESENJE:
Dakle, program
mora da radi sa sledecom vrstom poziva iz komandne linije:
naziv (izvrsive verzije) programa
znak horizontalna crta
opcija d ili f (bez razmaka izmedđu horizontalne crte i opcije)
niz stringova koji sadrze cele brojeva ako je uneta opcija -d ili niz stringova koji sadrze realne brojeve ako je uneta opcija -f
U slucaju da korisnik u komandnoj liniji zada samo naziv programa,
dobro bi bilo da program obavestiti korisnika da nije uneo dovoljno
argumenata za pokretanje programa i da program prekine dalji rad.
U
slucaju da korisnik u komandnoj liniji izostavi znak horizontalne
crte, dobro bi bilo da program program prekine dalji rad i obavestiti
korisnika da nije uneo opcije na korektan nacin.
U slucaju da
korisnik u komandnoj liniji nakon znaka horizontalne crte unese znak
koji nije slovo d ili f, dobro bi bilo da program program prekine
dalji rad i obavestiti korisnika da nije uneo opcije na korektan
nacin.
U slucaju da korisnik u komandnoj liniji unese opciju -d,
onda konvertovati argumente komandne linije u cele brojeve f-jom
atoi.
U slucaju da korisnik u komandnoj liniji unese opciju -f,
onda konvertovati argumente komandne linije u realne brojeve f-jom
atof.
#include <stdio.h>
#include <stdlib.h>
typedef enum {GR1, GR2, GR3} kodGreske;
char *greske[]=
{ "Nekorektno pokretanje programa. Morate navesti i opcije i konkretne brojeve\n",
"Nekorektno zadavanje opcija -d ili -f\n",
"Nekorektno slovo u opciji. MORATE uneti -d ili -f\n"
};
void ispisGreske(kodGreske broj);
main(int argc, char*argv[])
{
int i; /*brojac u ciklusu*/
int s1=0; /*suma celih brojeva */
double s2=0; /*suma realnih brojeva*/
if (argc<2) ispisGreske(GR1);
if(*argv[1]!='-') ispisGreske(GR2);
/*analiza opcije, tj. slova iza - */
switch(*(argv[1]+1))
{
case 'd': for (i=2;i<argc;i++) s1+=atoi(argv[i]);
printf("\n Suma CELIH brojeva iz komandne linije: %d\n ", s1);
break;
case 'f': for (i=2;i<argc;i++) s2+=atof(argv[i]);
printf("\n Suma REALNIH brojeva iz komandne linije: %f\n ", s2);
break;
default: ispisGreske(GR3); break;
}
}
void ispisGreske(kodGreske j)
{ fprintf(stderr, greske[j]);
exit(EXIT_FAILURE);
}
105.
NCP koji u datoteku prosti.txt upisuje
proste brojeve zadatog intervala kojima je zbir cifara složen broj.
Interval se zadaje učitavanjem gornje i donje granice (dva
prirodna broja) u komandnoj liniji. Brojeve upisivati u datoteku u
opadajućem poretku. U programu nije potrebno predvideti obradu
greski nastalih usled nekorektnog pozivanja programa u komandnoj
liniji ili greske u otvaranju datoteke... Program treba da radi sa
preusmeravanjem standardnog izlaza.
gcc zad105.c -o zad105
POKRETANJE PROGRAMA: zad105 10 40
daje u izlaznoj datoteci
prosti.txt IZLAZ
37 31 19 17 13
jer broj 37 je prost, a zbir cifara 3+7=10 je
slozen broj
...
#include <stdio.h> #include <stdlib.h> int prost (int n); /*testira da li je broj n prost broj */ /*Prirodni brojevi (sem 1) imaju najmanje dva delioca:jedinicu i samog sebe. Brojevi koji nemaju drugih delioca,sem ova dva, nazivaju se prostim */ int zbirCifara (int n); /*vraca zbir cifara broja n */ main(int argc, char **argv) { int donja,gornja; /*granice intervala */ int i; /*brojac u petlji */ int pom; /*posrednik u eventualnoj trampi granica intervala*/ /* "ucitavanje" granica intervala iz niski argv[1], argv[2] u komandnoj liniji i konverzija u cele brojeve*/ sscanf(argv[1], "%d", &donja); /*donja=atoi(argv[1]) */ sscanf(argv[2], "%d", &gornja); /*gornja=atoi(argv[2]) */ if (donja > gornja) /*obezbedjivanje relacije: donja <=gornja */ { pom=donja; donja=gornja; gornja=pom; } /*brojevi ce se upisivati u datoteku u opadajucem poretku gornja - > donja*/ for(i=gornja;i>=donja; i--) if (prost (i) && !prost(zbirCifara(i) ) ) printf("%d ",i); } int prost(int n) /*Ispituje se da li je broj n prost tako to se proverava da li ima delioce medju brojevima od 2 do n/2. Pri implementaciji se koristi tvrdjenje da je broj prost ako je jednak 2, ili ako je neparan i ako nema delitelja medju neparnim brojevima od 3 do n/2 */ { int prost; /*indikator slozenosti broja n */ int i; /*potencijalni delitelj broja n */ if (n==1) return 0; prost= (n%2!=0) || (n==2); /*parni brojevi razliciti od od dva nisu prosti brojevi */ i=3; /*najmanji potencijalni kandidat za delitelje medju neparnim brojevima razlicitim od jedan */ while ( (prost) && (i<=n/2) ) { prost=n%i != 0; i=i+2; /*proveravamo kandidate za delitelje samo medju neparnim brojevma */ } return prost; } int zbirCifara (int n) { int Suma=0; while (n>0) { Suma+= n%10; /*dodavanje cifre tekuceg razreda,pocev od razreda jedinica , a iduci ka visim razredima cifara */ n=n/10; /*prelaz ka visem razredu */ } return Suma; }
106. NCP koji sa standardnog ulaza učitava 3x3 matricu i ispisuje je na standardni izlaz tako da centralno polje a[1][1] bude jednako sumi gornjeg levog (a[0][0]) i donjeg desnog polja (a[2][2]). Pre ucitavanja popuniti matricu proizvoljnim vrednostima.
#include <stdio.h>
main()
{
int a[3][3] = {{0, 1, 2}, {10, 11, 12}, {20, 21, 22}}; /* deklaracija i inicijalizacija matrice a */
int i, j; /*brojaci u ciklusu */
/* unos elemenata matrice */
for(i=0; i<3; i++)
for(j=0; j<3; j++)
{
printf("\na[%d][%d] = ", i, j);
scanf("%d", &a[i][j]);
}
printf("\n*************\n");
a[1][1] = a[0][0] + a[2][2]; /* 0 + 22 = 22 */
/*ispis matrice */
for(i=0; i<3; i++)
{
for(j=0; j<3; j++) printf("%d\t", a[i][j]);
printf("\n");
}
}
#include
<stdio.h>
#include
<stdlib.h>
main()
{ int tabla[8][8]; /*matrica nula i
jedinica cuva raspored 8 topova na tabli */
int suma;
/* pamti se suma reda/kolone kao test osobina iz zahteva zadatka */
int i,j;
/*brojaci u petljama */
/*ucitavanje
podataka o rasporedu topova uz sumiranje broja topova i u
slucaju greske
stampa se
odgovarajuca poruka i okoncava programa */
suma=0;
for (i=0; i<8; i++ )
for (j=0; j<8; j++)
{ scanf("%d", &tabla[i][j]);
/*test korektnosti ulaza */
if (tabla[i][j] !=0 && tabla[i][j] !=1 )
{ printf ("\nNekorektni ulazni podaci o
rasporedu topova\n");
exit(EXIT_FAILURE);
}
suma=suma + tabla[i][j];
}
/*greska je ako
je broj topova na tabli razlicit od 8 */
if
(suma !=8)
{ printf
("\nNekorektni ulazni podaci o broju topova\n");
exit(EXIT_FAILURE);
}
/*proveravanje
da li se dva topa nalaze u istom redu , tj. da li je suma
clanova nekog reda veca od 1
*/
for(i=0;i<8;i++)
{
suma=0;
for (j=0;j<8;j++) suma+=tabla[i][j];
if (suma >1
)
{
printf ("\nTopovi se tuku\n");
exit(EXIT_SUCCESS);
}
}
/*proveravanje
da li se dva topa nalaze u istoj koloni , tj. da li je suma
clanova neke kolone
veca od 1 */
for(j=0;j<8;j++)
{
suma=0;
for (i=0;i<8;i++) suma+=tabla[i][j];
if (suma >1
)
{
printf ("\nTopovi se tuku\n");
exit(EXIT_SUCCESS);
}
}
/*inace se
topovi ne tuku */
printf ("\nTopovi
se ne tuku\n");
exit(EXIT_SUCCESS);
}
Zadaci za vezbu:
Zadatak 1. Šta ispisuje sledeći kod:
#include
<stdio.h>
main() {
int a[] = { 1, 2, 3, 4, 5, 6};
int * z=&a[2];
z-=3;
z+=2;
printf("%d\n",*z); }
2
|
Zadatak 2. Šta ispisuje sledeći kod
#include <stdio.h>
main() {
int x=1,y=2,z=3,*p;
p=&x;
*p=y;
p=&y;
*p=x+z;
printf("x:%d y:%d z:%d\n",x,y,z);
}
x:2 y:5 z:3
|
Zadatak 3. (prenos parametara funkcije po adresi) Napisati funkciju void minimax3 (int a, int b, int c, int *min, int *max) koja za date brojeve a,b,c odredjuje njihov max i njihov min. Napisati C program koji ucitava 3 cela broja i pozivajuci funkciju minimax3 ispisuje max i min za unete brojeve.
POMOC: *min=minimum(minimum(a,b), c); gde minimum(x,y) je f-ja koja racuna minimum dva broja
ili pomocu operatora ?:
*min= (a)<(b) ? ((a)<(c) ? (a) : (c)) : ((b)<(c) ? (b) : (c))
Zadatak 4. Napisati funkciju koja za dati celobrojni niz a[] vraca srednju vrednost i zbir niza i to srednju vrednost kao povratnu vrednost funkcije, a zbir kroz listu argumenata.
Zadatak 5. Napisati f-ju compare koja poredi dve niske a, i b i vraca 1 ako jesu jednake, vraca 0 ako nisu jednake. NCP koji unosi sa standardnog ulaza dve niske sa do 20 karaktera i koristeci funkciju compare ispisuje na standardni izlaz da li su date niske razlicite.
Zadatak 6. Napisati f-ju compare koja poredi dve niske a, i b i vraca 1 ako jesu jednake, vraca 0 ako nisu jednake. NCP koji koristeci funkciju compare ispisuje na standardni izlaz da li su razlicite dve niske koje se zadaju kao parametri (argumenti) komandne linije.
Zadatak
7. Popuniti sledecu tabelu: