Usput, vrijedi while(x) = for(;x;)...
Da, tako da for petlju mogu postaviti ovako:
for(int i = 0; i = (uneseniBroj != slucajniBroj);)
uz izostavljanje inkrementa
Usput, vrijedi while(x) = for(;x;)...
Da, tako da for petlju mogu postaviti ovako:
for(int i = 0; i = (uneseniBroj != slucajniBroj);)
uz izostavljanje inkrementa
onda možda bolje ovako:
for(int pokusaj = 0; (uneseniBroj != slucajniBroj); pokusaj++)
Dovoljno je čak for(; uneseniBroj != slucajniBroj; )
(postah prije no što vidjeh Tracerov post, ovo "dovoljno je" se odnosi na funkcionalnost koja se postiže u Flokijevoj verziji..)
To je gore i napisano. Samo što je usput dodana varijabla koja broji pokušaje tako da se ne mora posebno pisati ispod petlje. Slično kao:
for(i = 1, fakt = 1; i < n; fakt *= i++); // računanje faktorijela
Dovoljno je čak for(; uneseniBroj != slucajniBroj; )
(postah prije no što vidjeh Tracerov post, ovo "dovoljno je" se odnosi na funkcionalnost koja se postiže u Flokijevoj verziji..)
drugim riječima rečeno - geneza petlje while - iz petlje for uzet uvjet nastavka - a indexi ne trebaju
/* Napišite program koji učitava proizvoljan broj znakova, te ispisuje koliko ima slova, brojeva i ostalih znakova.
Kraj učitavanja niza određen je oznakom za prijelaz u novi red('\n').
Za unos znakova koristite funkciju getchar(),isdigit(),isupper() i islower, uključite biblioteku <ctype.h>*/
#include<stdio.h>
#include<ctype.h>
void main()
{
int slova=0;
int brojevi=0;
int ostaliZnakovi=0;
int znak;
puts("Unesite neki niz znakova:");
while((znak=getchar())!='\n')
{
if((islower(znak))||(isupper(znak)))
slova++;
else if(isdigit(znak))
brojevi++;
else
ostaliZnakovi++;
}
printf("Slova: &d\n",slova);
printf("Brojevi: %d\n",brojevi);
printf("Ostali znakovi: %d\n",ostaliZnakovi);
getchar();
}
Prepisao sam kod iz knjige i kada ga kompajliram ne javlja nikakvu gresku a kada unesem u program samo napise da je ostalih znakova 1 dok su ostali 0 ?
Ne znam gdje je greska.
void main()
int main()
if((islower(znak))||(isupper(znak)))
Ove zagrade su visak
printf("Slova: &d\n",slova);
Umjesto '&' treba ici '%', pretpostavljam da je ovo pogreska pri tipkanju.
getchar();
}
Ovdje izmedu getchar() i zatvorene viticaste zagrade nedostaje:
return 0;
sukladno sa main funkcijom koja bi trebala biti deklarirana da vraca int
Osim ovoga sto sam nabrojao, program ti je lose uvucen, moras poraditi na tome. Kad sam popravio ove greske program ti radi normalno.
/* Napišite program koji učitava niz od deset cijelih brojeva, te ispisuje samo one koji su parni. Ako u nizu ne postoji nijedan
parni broj,program treba ispisati odgovarajuću poruku.*/ Kako ovo boldano da ostvarim napisao sam da mi izbaci iz niza parne brojeve, kako da mi izbaci samo jednu poruku da u nizu nije paran broj uvijek mi izbaci vise poruka jer mi to nude po petljom for.
#include<stdio.h>
void upisi(int x[10])
{
int i;
for(i=0;i<10;i++)
{
scanf("%d",&x[i]);
}
}
void trazi(int x[10])
{
int i;
for(i=0;i<10;i++)
{
if(x[i]%2==0)
printf("%d\n",x[i]);
}
}
void main()
{
int i,a[10];
printf("Unesite 10 cijeli brojeva:\n");
upisi(a);
printf("Parni brojevi su:\n");
trazi(a);
getchar();
getchar();
}
Najjednostavnija modifikacija bi bila u funkciji trazi dodati novu varijablu, npr. sa int parnih = 0;, te potom unutar if-a u istoj funkciji dodati parnih++;. Pritom ne zaboravi dodati vitičaste zagrade za if-blok, jer su sad u njemu 2 naredbe. Zatim, u istoj funkciji a ispod petlje dodaj if (parnih == 0) printf("Nema parnih brojeva.");.
Jednostavno, u funkciji koja ti ispisuje parne brojeve samo u petlju dodas da broji koliko je parnih brojeva pronadeno. Ako na zavrsetku petlje imas nula parnih brojeva, tada ispisujes poruku da niti jedan paran broj nije pronaden.
Ovako:
void trazi(int x[10])
{
int i, parni=0;
for (i=0;i<10;i++)
{
if (x[i]%2==0)
{
printf("%d\n",x[i]);
parni++;
}
}
if (!parni)
printf("Nije pronaden ni jedan paran broj\n");
}
EDIT: preduhitren
/*Napišite program koji učitava dva niza znakova i ispisuje jesu li ta dva niza jednaka.
Kraj učitavanja niza određen je oznakom za prijelaz u novi redak ('\n').*/ Napisao sam ovaj zadatak na osnovi jednog primjera u knjiz, program mi radi ali kada se izvrsi i lupnem enter ispisuje mi ono sto je vec ispisano. Neznam puno zadataka ovog tipa, sljedeci mi je zadatak sa toupper funkcijom mozete li mi malo objasniti o toj funkciji da znam kako cu rjesiti zadatak, btw hvala na pomoci iz prethodnog zadatka.
#include<stdio.h>
void main()
{
char znak1,znak2;
printf("Upisite prvi znak: ");
scanf("%s",&znak1);
printf("Upisite drugi znak: ");
scanf("%s",&znak2);
while(getchar()=='\n')
{
if(znak1==znak2)
printf("Uneseni znakovi su jednaki.\n");
else
printf("Uneseni znakovi nisu jednaki.\n");
}
getchar();
getchar();
}
1. znakovni niz je znakovno polje.
2. znakovni nizovi se ne uspoređuju pomoću operatora == već znak po znak ili funkcijom strcmp(i).
Može li mi itko objasniti ovaj dio koda ne sto kod radi nego njegov princip rada, u vezi ovih pokazivača najvise ako moze.
#include<stdio.h>
#include<stdlib.h>
#define N 5
void getMinMax(double *niz, int nelem, double *pMin, double *pMax)
{
int i=0;
*pMin=*pMax=niz[0];
for(i=1;i<N;i++)
{
if(niz[i]>*pMax) *pMax=niz[i];
if(niz[i]<*pMin) *pMin=niz[i];
}
}
int main()
{
int i;
double min,max,data [N];
printf("Otkucaj %d realnih brojeva:\n",N);
for(i=0;i<N;i++)
scanf("%lg",&data[i]);
getMinMax(data,N,&min,&max);
printf("min=%lf max=%lf\n",min,max);
system("pause");
return 0;
}
Program učitava polje brojeva a zatim ga predaje funkciji getMinMax koja preko pokazivača (call by reference) vraća najmanji i najveći broj broj u tom polju.
Pošto sam tek počeo s pokazivačima neke mi stvari nisu jasne ne zelim ovo nauciti preko noći mislim da bi mi trebala 2-3 dana da barem pohvatam neke osnove što bi mi bilo dovoljno, sad na nekom osnovnom primjeru ako mi mozete objasniti:
Neka imam nesto ovakvo:
#include<stdio.h>
void main()
{
int x; /*(deklariram varijablu x tipa int, ok sada me zanima kada sam ja deklarirao tu varijablu jel ona ima svoju adresu u memoriji?)*/
int *p; /*(inicijaliziram pokazivač p koji pokazuje na objekt tipa int, jel i pokazivač ima svoju adresu?)*/
x=55; /* ( dao sam varijabli x vrijednost 55, jel se ta vrijednost sprema na adresu na kojoj je varijabla x?)*/
p=&x; /* (sada ono najbitnije na šta ovaj pokazivač p pokazuje na adresu na kojoj se nalazi x ili vrijednost koja se nalazi u varijabli x ili moze pokazivati oboje ako stavim da mi je ispis ( printf("%d", *p) i printf ("%d", p)) sta mi daje jedan ispis a sta drugi?)*/
}
Ako mi mozete odgovoriti na pitanja u komentarima koda, pa da pređem šta mi nije jasno u prethodnom zadatku.
Da, varijabla x ima svoju adresu u memoriji. Tu adresu je moguće dobiti sa &x.
Da, i pokazivač ima svoju adresu (pokazivač je ustvari brojevna varijabla, a broj koji sadrži je memorijska adresa). Njegovu adresu možeš dobiti sa &p, adresu koja je pohranjena u njemu sa p, a ono što se nalazi na adresi koja je u njemu pohranjena sa *p.
Da, ta se vrijednost tamo sprema.
Sa naredbom "p = &x;" u pokazivač p smještaš adresu varijable x. Pokazivač tada "pokazuje" na varijablu x. Reći da pokazivač pokazuje na neku varijablu je isto što i reći da je adresa te varijable spremljena u pokazivaču. Možda se pitaš možeš li broj 55 shvatiti kao adresu i natjerati pokazivač da pokazuje na adresu 55? Možeš, to radiš sa "p = x" (iako bi takvo što stvarno jako rijetko imalo smisla, jer u praksi ne znaš što će se nalaziti na kojoj adresi u memoriji).
Prvi ispis će dati 55 ("*p" znači "ono što se nalazi na adresi koja je spremljena u pokazivaču p; ili vrijednost varijable na koju pokazuje pokazivač p"). Drugi ispis će dati adresu koja je spremljena u pokazivaču (0xblablabl).
Pošto sam tek počeo s pokazivačima neke mi stvari nisu jasne ne zelim ovo nauciti preko noći mislim da bi mi trebala 2-3 dana da barem pohvatam neke osnove što bi mi bilo dovoljno, sad na nekom osnovnom primjeru ako mi mozete objasniti:
Neka imam nesto ovakvo:
#include<stdio.h>
void main()
{
int x; /*(deklariram varijablu x tipa int, ok sada me zanima kada sam ja deklarirao tu varijablu jel ona ima svoju adresu u memoriji?)*/
Naravno. Gdje bi se inače spremio podatak (vrijednost) koju predstavlja varijabla x?
int *p; /*(inicijaliziram pokazivač p koji pokazuje na objekt tipa int, jel i pokazivač ima svoju adresu?)*/
Pokazivači su također varijable pa i same svoju adresu. Na njihovoj adresi se spremaju adrese drugih varijabli.
x=55; /* ( dao sam varijabli x vrijednost 55, jel se ta vrijednost sprema na adresu na kojoj je varijabla x?)*/
Da.
p=&x; /* (sada ono najbitnije na šta ovaj pokazivač p pokazuje na adresu na kojoj se nalazi x ili vrijednost koja se nalazi u varijabli x ili moze pokazivati oboje ako stavim da mi je ispis ( printf("%d", *p) i printf ("%d", p)) sta mi daje jedan ispis a sta drugi?)*/
Pokazivači pokazuju na adrese, no dereferenciranjem pokazivača se može doznati vrijednost na adresi na koju pokazivač pokazuje. Npr.
int *p, n = 5;
p = &n; // p pokazuje na adresu od n
p - adresa na koju pokazivač pokazuje
*p - vrijednost koja se nalazi na adresi na koju pokazivač pokazuje
Sada možeš npr. napisati
*p= 10; // isto kao da si napisao i n = 10
}
Ako mi mozete odgovoriti na pitanja u komentarima koda, pa da pređem šta mi nije jasno u prethodnom zadatku.
Hvala na objasnjenju, možeš li još samo ovo pojasniti "deferenciranjem pokazivača" jel to ovaj izraz p=&n;.
Rekao si ovo:
Pokazivači su također varijable pa i same svoju adresu. Na njihovoj adresi se spremaju adrese drugih varijabli. Pokazivači pokazuju na adrese, no deferenciranjem pokazivača se može doznati vrijednost na adresi na koju pokazivač pokazuje.
Sad me zanima kada napisem u kodu p=&x sada p pokazuje samo adresu od varijable n, a da saznam vrijednost koja se nalazi u varijabli n kod ispisa samo mogu staviti
printf("%d",*p) da bi mi pokazalo vrijednost koja se nalazi u varijabli n, mogu li ikako saznati vrijednost na varijabli n pomoću ovog izraza npr neka mi kod ovako izgleda.
#include<stdio.h>
void main()
{
int suma; /*Deklarirana je varijabla suma i njena adresa je 1245024*/
int *p; /* Inicijaliziran je pokazivač neka znam njegovu adresu neka je 1345668*/
suma=77;/*Dao sam varijabli suma vrijednost 77*/
p=&suma;/*Ovaj izraz p=&suma (tj. pokazivač) samo pokazuje adresu od varijable suma 1245024*/
printf("%d",*p);/* Dok izraz pod printf("...") i uz *p pokazuje koja se vrijednost nalazi na adresi koju pokazivač pokazuje.*/
}
Jesam li dobro shvatio ovo?
Hvala na objasnjenju, možeš li još samo ovo pojasniti "deferenciranjem pokazivača" jel to ovaj izraz p=&n;.
Rekao si ovo:
Pokazivači su također varijable pa i same svoju adresu. Na njihovoj adresi se spremaju adrese drugih varijabli. Pokazivači pokazuju na adrese, no deferenciranjem pokazivača se može doznati vrijednost na adresi na koju pokazivač pokazuje.
Sad me zanima kada napisem u kodu p=&x sada p pokazuje samo adresu od varijable n, a da saznam vrijednost koja se nalazi u varijabli n kod ispisa samo mogu staviti
printf("%d",*p) da bi mi pokazalo vrijednost koja se nalazi u varijabli n, mogu li ikako saznati vrijednost na varijabli n pomoću ovog izraza npr neka mi kod ovako izgleda.
#include<stdio.h>
void main()
{
int suma; /*Deklarirana je varijabla suma i njena adresa je 1245024*/
int *p; /* Inicijaliziran je pokazivač neka znam njegovu adresu neka je 1345668*/
suma=77;/*Dao sam varijabli suma vrijednost 77*/
p=&suma;/*Ovaj izraz p=&suma (tj. pokazivač) samo pokazuje adresu od varijable suma 1245024*/
printf("%d",*p);/* Dok izraz pod printf("...") i uz *p pokazuje koja se vrijednost nalazi na adresi koju pokazivač pokazuje.*/
}
Jesam li dobro shvatio ovo?
Dereferencirenje pokazivača je ustvari postupak kojim pristupaš vrijednosti na adresi zapisanoj u tom pokazivaču!
To je npr. kako je Tracer napisao:
int *p;
int n=5;
p=&n;
*p=10 //ovo ti je dereferenciranje pokazivača, time ustvari mjenjaš vrijednost n-a na 10;
* Dereferenciranje
Može još objasnjena kod ovog zadatka:
#include<stdio.h>
#include<stdlib.h>
#define N 5
void getMinMax(double *niz, int nelem, double *pMin, double *pMax)
{
int i=0;
*pMin=*pMax=niz[0]; /*Jel ovaj izraz znači pokazivači *pMin i *pMax poprimaju/pokazuju na pocetnu vrijednost niza?*/
for(i=1;i<N;i++)
{
if(niz[i]>*pMax) *pMax=niz[i];
if(niz[i]<*pMin) *pMin=niz[i];
}
}
int main()
{
int i;
double min,max,data [N];
printf("Otkucaj %d realnih brojeva:\n",N);
for(i=0;i<N;i++)
scanf("%lg",&data[i]);
getMinMax(data,N,&min,&max); /*Ovi izrazi &min i &max znači da njima pristupam pomoću njhove adrese jer su argumenti funkcije pokazivači?*/
printf("min=%lf max=%lf\n",min,max);
system("pause");
return 0;
}
Prvo pitanje: ne. "*p = niz[0]" znači "na adresu na koju pokazuje p postavi vrijednost (ne adresu) prvog elementa polja".
Drugo pitanje: nisam siguran jesam li dobro shvatio što misliš sa "pristupati". Ugl., toj funkciji šalješ adresu min i max varijabli jer te funkcija traži pokazivače (dakle adrese) (na brojevne varijable), a ne same brojevne varijable.
Dobra je ideja razmišljati o pokazivačima kao o običnim brojevnim varijablama koje u sebi sadrže adresu, jednostavno zaboravi da se one nazivaju "pokazivači".
Prvo pitanje: ne. "*p = niz[0]" znači "na adresu na koju pokazuje p postavi vrijednost (ne adresu) prvog elementa polja".
Drugo pitanje: nisam siguran jesam li dobro shvatio što misliš sa "pristupati". Ugl., toj funkciji šalješ adresu min i max varijabli jer te funkcija traži pokazivače (dakle adrese) (na brojevne varijable), a ne same brojevne varijable.
Dobra je ideja razmišljati o pokazivačima kao o običnim brojevnim varijablama koje u sebi sadrže adresu, jednostavno zaboravi da se one nazivaju "pokazivači".
Ovo pod prvo na to sam i mislio samo sam se krivo izrazio.
A pod drugo uvijek kada mi je u argumentu funckije pokazivač ja moram poslati adresu varijable da bi njoj pokazivač mogao pristupiti?
I samo kod ovoga:
if(niz[i]>*pMax) *pMax=niz[i];
Jel ovo ovako čitam ako je niz[i] veći od vrijednosti koja se nalazi na pokazivaču p onda je vrijednost pokazivača jednaka niz[i]?
Pokazivač nije ništa drugo doli adresa.
Za ovo drugo, da, barem ako si pod "vrijednost pokazivača" mislio na "vrijednost na adresi u pokazivaču" (i radi se o operatoru pridruživanja, ne jednakosti, no to valjda znaš).
Hvala
if(niz[i]>*pMax) *pMax=niz[i];
Ovako pročitaš:
ako je niz[i]>*pMax - *pMax varijabli dodjeli vrijednost varijable niz[i]
Varijablu funkciji u obliku pokazivača predaješ tako da kao argument funkcije predaš adresu te varijable.
Što time dobijaš? - Promjena varijable koju si predao funkciji preko pokazivača je vidljiva u kodu iz kojeg si predao varijablu ako si u funkciji napravio izmjene varijable.
#include <stdio.h>
void PromjenaVarijable(int *pokazivac)
{
int broj = 10;
*pokazivac = broj;
}
int main ()
{
int a = 5;
printf("Varijabla prije poziva funkcije: %d", a);
PromjenaVarijable(&a); //predajemo adresu varijable funkciji
printf("\nVarijabla poslije poziva funkcije: %d", a); // a = 10 - promjena vrijednosti varijabe koja je
return 0; // napravljena u zasebnoj fukciji preko pokazivača je vidljiva
} // u main funkciji
Pozivom funkcije sa argumentom adrese varijable smo u stvari napravili ovo: int *pokazivac = &a - deklaracija i inicijalizacija pokazivača.
Ima li razlike u ovakvom zapisu npr. char* p i char *p?
Jel jedno te isto napraviti ovo:
int *p=&x[1]
i
int *p;
p=&x[1]; ?
Nema razlike u ta 2 zapisa. Inače, malo vezano uz zapise, C++ ima čudno pravilo da se deklaracija oblika "int* a, b;" ne shvaća kao "int* a; int* b;" već kao "int* a; int b;" (dakle zvjezdica se odnosi samo na neposrednu iduću varijablu)
Za drugo pitanje, isti je rezultat u obje verzije.
To je sve isto:
int* a ili int *a;
međutim - kako je @itf4n naglasio - kod višestruke deklaracije treba biti pažljiv.
Također možeš istovremeno izvršiti deklaraciju i inicijalizaciju pokazivača kao i svake druge varijable;
int *pokazivac = &varijabla;
Ovdje si razdvojio deklaraciju od inicijalizacije:
int *pokazivac;
*pokazivac = &varijabla;
Ovisi što ti i kad treba - deklaraciju i inicijalizaciju možeš provesti skupa - a ne moraš.
Napisao sam ovaj program da malo bolje shvatim stvari:
Program radi ja sam jos sebi uvalio ova dva printf-a da vidim adresu najvećeg u nizu i početnog u nizu, i dobivam isti rezultat da se početni i najveći nalaze u istoj adresi zašto?
Ispis je:
Najveca vrijednost u nizu je:27
Adresa najveceg u nizu je: 0012FF38
Adresa pocetnog u nizu je: 0012FF38
#include<stdio.h>
#include<stdlib.h>
void main()
{
int x[10]={3,4,17,-1,-13,24,27,9,21,14};
int i;
int *pMax;
pMax=&x[0];
for(i=0;i<10;i++)
{
if(x[i]>*pMax)
*pMax=x[i];
}
printf("Najveca vrijednost u nizu je: %d\n",*pMax);
printf("Adresa najveceg u nizu je: %p\n", pMax);
printf("Adresa pocetnog u nizu je: %p\n", &x[0]);
system("pause");
}