Programiranje

Programiranje u C-u - od svega pomalo

cerberus čet 24.2.2011 22:31

ide bez problema; Baš kao da varijabli pristupamo "preko reference". {#} Ili pak - pointer možeš preusmjeriti. Ali rečenicu u ovom slučaju ne možeš.

 

    char recenica1[30];
    char recenica2[30];
    char *recenica3;

    recenica2 = recenica1;  // ne prolazi
    recenica3 = recenica1;  // OK

 

Možda se doduše varam...

Kao da je netko pazio pointer predavanje {#}

rustweaver čet 24.2.2011 22:34
FiCoO kaže...

mozda ovako

Da, bas tako. I onda samo nanizes if blokove za svaku rijec posebno i to ti je to.

 

mozes cak ici i ovako (kad imas puno razlicitih slucajeva)

 

if (uvjet)

 

else if (uvjet)

 

else if (uvjet)

 

...

 

else

     printf("upisali ste pogresnu rijec");

cerberus čet 24.2.2011 22:35
FiCoO kaže...

ocu li ja danas mozda od nekoga saznat jel se moze to ikako napraviti..ako ne onda bar da za brzinu napisem b za vrijeme v itd.

Moze se uraditi. Ali jedino sta mi zasad pada na pamet, a da je vise manje trivijalno, je if - else provjera unosa. Dakle korisnik upise, npr. brzina, a ti u if - else if - else granama odradis sve moguce uvjete i pripadajuce akcije u slucaju podudaranja. Na onom kodu sa if si dobro poceo, sada samo nastaviti.

mbaksa čet 24.2.2011 22:57
cerberus kaže...

ide bez problema; Baš kao da varijabli pristupamo "preko reference". {#} Ili pak - pointer možeš preusmjeriti. Ali rečenicu u ovom slučaju ne možeš.

 

    char recenica1[30];
    char recenica2[30];
    char *recenica3;

    recenica2 = recenica1;  // ne prolazi
    recenica3 = recenica1;  // OK

 

Možda se doduše varam...

Kao da je netko pazio pointer predavanje {#}

Ma i ja se sjećam (a to je bilo otprije desetak godina) da je bilo riječi o pokazivačima na prvi član polja. I baš sad listam Demistificirani C++ (drugo izdanje) i pišu o vezi pokazivača i polja - npr. str. 127: Polja i pokazivači su slični, no valja biti svjestan njihove razlike. Ime polja je jednostavno sinonim za pokazivač na početnu vrijednost, no sam pokazivač nije nigdje alociran u memoriji.

 

A vidi što pišu za reference - str. 153.: Reference se u principu implementiraju kao pokazivači koji ne traže operator * za pristup sadržaju.

...što se njega tiče (C++ prevoditelja), referenca je samo sinonim za neki drugi objekt.

 

 

Tako da, iz moje perspektive, varijabla za polje je prije referenca na prvi član, nego pokazivač. {#} Da je pokazivač, onda bi u memoriji zauzeo memorijski prostor veličine adrese (u biti int) koji bi sadržavao adresu prvog člana polja, što nije slučaj. Polja se dovode u vezu s pokazivačima (možda bolje reći - s "pokazivačima u širem smislu") baš zato jer preko indeksa zapravo uvećavaš memorijsku adresu prvog člana da bi došao do ostalih članova. Dakle, nije riječ o pokazivačima nego o nečem što je slično pokazivačima.

 

Da, pokazivači i reference su slične stvari i možda inače ni ne bi trebalo ulaziti u ovu raspravu, no ne volim kad me netko "ispravlja" za nešto što sam ispravno rekao. {#} Da, shvaćam da je automatska reakcija reći da je varijabla za polje pokazivač na prvi član polja (vjerojatno to kažu i profesori na faksevima - mislim da su i meni tako rekli), no valja malo dublje razmisliti što to točno znači, odnosno što se misli reći tom rečenicom.

1domagoj1 čet 24.2.2011 22:57
mbaksa kaže...
Jesi 100% siguran? Možda se to tako inače govori, ali je li zaista riječ o pointeru? Naime, ako je u pitanju pointer, onda bi vrijednost dodjeljivao ovako:

 

*recenica = "abcd";

 

A to ne ide. Ali zato:

 

recenica = "abcd";

Naravno da ne ide jer ti fali tip.

 

char *recenica = "abcd";

 

ide. Te recimo ispis s printf("%s", proba); ispisat će, pogodi :D, "proba". :D

 

recenica = "abcd"; također ne ide. Dok recimo char recenica[20] = "abcd"; može.

 

Stvar je u tome kaj u C-u ne postoje reference. To si pobrkao C i C++ :P. Naime, naredba:

 

a = x[2] ekvivalentna je naredbi a = *(x + 2); jer se u C-u radi sve sa pointerima. Zapravo samo ime x ima smisao pointera na prvi član polja. Recimo sa &(x[2]) možeš saznati adresu člana x[2]. Ma kužiš dalje :P.

 

EDIT: Ah ne znam onda ni ja kad da velim sad. :D

mbaksa čet 24.2.2011 23:05
1domagoj1 kaže...
mbaksa kaže...
Jesi 100% siguran? Možda se to tako inače govori, ali je li zaista riječ o pointeru? Naime, ako je u pitanju pointer, onda bi vrijednost dodjeljivao ovako:

 

*recenica = "abcd";

 

A to ne ide. Ali zato:

 

recenica = "abcd";

Naravno da ne ide jer ti fali tip.

 

char *recenica = "abcd";

 

ide. Te recimo ispis s printf("%s", proba); ispisat će, pogodi :D, "proba". :D

 

recenica = "abcd"; također ne ide. Dok recimo char recenica[20] = "abcd"; može.

 

Stvar je u tome kaj u C-u ne postoje reference. To si pobrkao C i C++ :P. Naime, naredba:

 

a = x[2] ekvivalentna je naredbi a = *(x + 2); jer se u C-u radi sve sa pointerima. Zapravo samo ime x ima smisao pointera na prvi član polja. Recimo sa &(x[2]) možeš saznati adresu člana x[2]. Ma kužiš dalje :P.

 

EDIT: Ah ne znam onda ni ja kad da velim sad. :D

Nisam dovoljno upućen u C pa ako kažeš da u njemu ne postoje reference - OK. No to ne znači da je varijabla koja označava polje pokazivač na prvi član polja - jer ona to nije, nego funkcionira slično pokazivaču (zapravo funkcionira upravo kao referenca u C++-u). {#}

rustweaver čet 24.2.2011 23:20

Reference u C-u itekako postoje

 

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char t[]="Tekst";
    char *a="haha";
   
    //t+=1;
    a+=1;
   
    printf("%s %s\n", t+1, a);
   
    system("pause");   
    return 0;
}

 

varijabla "t" je referenca na const char "Tekst", a varijabla "a" je pointer koji sadrzi referencu na tekst "haha".

 

Da razjasnim sto je "varijabla" "t" u ovom primjeru. Kada se program kompajlira, svugdje u programu gdje se susrece varijabla "t" ona se zamjenjuje sa brojem koji je zapravo memorijska adresa na string "Tekst". Varijabla zapravo ne postoji, zato joj se ne moze mijenjati vrijednost (morao sam komentirati onu liniju t+=1;)

 

Varijabla "a" je pokazivac koji sadrzi referencu na string "haha" i njena se vrijednost moze mijenjati, zato sto je to stvarna varijabla (pointer).

 

printf dozvoljava da se varijabli "t" uveca vrijednost za jedan zato sto se "varijabla" "t" pretvorila u broj pa printf u biti samo ispisuje sadrzaj na memorijskoj adresi uvecanoj za 1.

mbaksa čet 24.2.2011 23:27
rustweaver kaže...

Reference u C-u itekako postoje

...

Varijabla "a" je pokazivac koji sadrzi referencu na string "haha" i njena se vrijednost moze mijenjati, zato sto je to stvarna varijabla (pointer).

 

printf dozvoljava da se varijabli "t" uveca vrijednost za jedan zato sto se "varijabla" "t" pretvorila u broj pa printf u biti samo ispisuje sadrzaj na memorijskoj adresi uvecanoj za 1.

Moglo bi se reći da u C-u postoje implicirane reference. {#}

jurluk pet 25.2.2011 01:18

zanima me ovo. našao sam kako ispisati tekst određene boje, pomoću cprintf bla, bla... može li se kako preprocesorskom naredbom ili nekako drukčije odrediti da svaki tekst koji se ispisuje na ekranu bude određene boje?

mbaksa pet 25.2.2011 01:55

Mislim da su mi sad stvar sjele na mjesto. Varijabla i referenca? Koja je razlika? U biti je nema. Reference nisu ništa drugo doli dodatna imena, aliasi za isti memorijski prostor, iste namjene (za isti tip varijable). Na primjer, imamo:

int var;

Ta varijabla je smještena na nekoj adresi, recimo 0x22ff34.

Imamo potom:

int &var2 = var;

Koja je njezina adresa? Isto 0x22ff34. Upravo zato jer upućuje na isti memorijski prostor. U knjizi će možda pisati da je var2 referenca na varijablu var, no to je malo nesretno sročeno, jer zvuči poput pokazivača, odnosno zvuči kao da referenca var2 preko varijable var tijekom izvođenja programa dolazi do memorijskog prostora, što nije slučaj. Naime, već prilikom kompajliranja svugdje gdje piše var i var2 napravit će se strojna instrukcija koja će kao argument imati adresu 0x22ff34 - dakle, nakon kompajliranja nema razlike između var i var2.

Valja upozoriti da reference u drugim programskim jezicima, recimo C# ili Jave (pa zapravi i u PHP-u, JavaScriptu, Delphiju...), nisu to isto - tamo je referenca u biti pokazivač (dakle, možemo mu/joj dodjeljivati vrijednost), ali kojem se ne pristupa preko operatora *. Mogli bismo to nazvati "transparentni" pokazivač.


No, vratimo se na C i C++. Do čega sam došao... Promotrimo sljedeći kod:

    typedef int Brojevi[8];    int brojevi [8] = { 333, 4, 5, 232, 54, 2, 552 };    int *a1 = brojevi;    int *a2 = &brojevi[0];    int &a3 = *brojevi;    int &a4 = brojevi[0];    Brojevi &a5 = brojevi;
    cout << endl  <<"Brojevi: " << brojevi << " \n a1: " << a1 << "\n a2: " << a2 << "\n &a3: "<< &a3 << "\n &a4: "<< &a4 <<      "\n a5: " << a5 << "\n brojevi: " << brojevi << endl << endl;

Što će se tu ispisati? U svakom od ovih slučajeva ispisat će se memorijska adresa na koju je smješteno polje int-ova. Čak i kad ispisujemo varijablu brojevi - dakle, polje se u ovom slučaju ponaša kao pokazivač. Primijetite da sam, da bi se sve to tako ispisalo, u slučaju a3 i a4 trebao upotrijebiti operator & (dakle, operator koji vraća adresu). U oba slučaja je to bilo potrebno jer su a3 i a4 reference na 0-ti element polja. Rezultat:

Brojevi: 0x22fed4 a1: 0x22fed4 a2: 0x22fed4 &a3: 0x22fed4 &a4: 0x22fed4 a5: 0x22fed4 brojevi: 0x22fed4

 
 Međutim, ako svugdje stavimo reference:

     cout << endl  <<"Brojevi: " << brojevi << " \n &a1: " << &a1 << "\n &a2: " << &a2 << "\n &a3: "<< &a3 << "\n a4: "<< &a4 << "\n &a5: " << &a5 << "\n &brojevi: " << &brojevi << endl << endl;
    
Dobivamo ovo:
 
Brojevi: 0x22fed4
 &a1: 0x22ff0c
 &a2: 0x22ff08
 &a3: 0x22fed4
 &a4: 0x22fed4
 &a5: 0x22fed4
 &brojevi: 0x22fed4
 
Iz čega je jasno da su a1 i a2 pokazivači, odnosno da je za njih rezerviran posebni memorijski prostor. Jasno je i to da se u ovom slučaju polje ne ponaša kao pokazivač, nego kao referenca (jer da je u pitanju pokazivač, ispisala bi se memorijska adresa tog pokazivača).


Zaključak? Polje ima dvojno državljanstvo! {#} Varijabla je u biti referenca na memorijski blok koji zauzima polje, međutim kad se koristi bez indeksa, kompajler je intepretira kao memorijsku adresu (kao pokazivač).


Ova priča je inače započela mojim komentarom: "Istina, pošto je varijabla u biti referenca na prvi znak u polju." Ovo i je i nije točno. Varijabla je, ili bolje reći može biti referenca na prvi (tj. nulti, ako gledamo indeks) element polja. Naime, sjetite se kako smo definirali a3:

int &a3 = *brojevi;

Ako ispišemo a3, dobit ćemo nulti element (dakle, ispisat će se 333). a3 nije nigdje spremljeno u memoriji - dakle, referenca je na nulti član. A do toga smo došli tako da smo referencirali a3 na "vrijednost" varijable brojevi (kod deklariranja reference kompajler uzima adresu inicijalizirane vrijednosti). S obzirom da smo tu trebali koristiti operator *, jasno je da kompajler varijablu brojevi "čita" kao da se radi o pokazivaču (ali pokazivaču koji nigdje ne postoji!). S obzirom da taj pokazivač ne postoji, tako ga ni ne možemo preusmjeravati - dakle, tu se polje ponaša kao referenca, tj. obična varijabla (koja nije pokazivač). Ako pak neki pokazivač uputimo na polje, on sadrži adresu nultog člana polja.


Pa bi moj konačni zaključak bio - varijabla za polje ima dvojnu prirodu - ovisno o situaciji, ponaša se kao obična varijabla/referenca na polje, ali može se ponašati i kao pokazivač na polje. Isto tako, varijabla za polje je u osnovi referenca ili virtualni pokazivač na nulti element polja. Kažem "virtualni", jer zapravo kao takav ne postoji (ne zauzima prostor u memoriji), niti se može preusmjeriti.


Eto, nadam se da smo s ovom digresijom svi nešto naučili. Ja definitivno jesam. {#}

mbaksa pet 25.2.2011 02:03
jurluk kaže...

zanima me ovo. našao sam kako ispisati tekst određene boje, pomoću cprintf bla, bla... može li se kako preprocesorskom naredbom ili nekako drukčije odrediti da svaki tekst koji se ispisuje na ekranu bude određene boje?

Možeš dati primjer što točno si to našao? Koje funkcije su u pitanju? Ili je u pitanju definiranje boje preko onih ANSI sekvence ili kako se to već zove? Imaj na umu da to ne radi na svim OS-evima, odnosno na svim terminalima/naredbenim retcima.

 

Nikad mi nije bilo jasno zašto u C ili C++ nije ugrađeno tih par ekstra funkcija za rad s tekstualnim sučeljem (a isto u QBasicu ili Turbo Pascalu smatramo pod normalnim).

jurluk pet 25.2.2011 02:36
mbaksa kaže...

A koje točno? I jel ti išta od toga uopće radi? Npr. meni onaj prvi primjer pod Code::Blocks ne radi.

LOL. ja nisam ni bio probo prije postanja Sramim se

 

prvi mi isto ne radi, a u drugom sam moro stavit getch(); da se zaustavi nakon ispisa i bude crvene boje. ali to nije ono što meni treba

mbaksa pet 25.2.2011 03:33
jurluk kaže...
mbaksa kaže...

A koje točno? I jel ti išta od toga uopće radi? Npr. meni onaj prvi primjer pod Code::Blocks ne radi.

LOL. ja nisam ni bio probo prije postanja Sramim se

 

prvi mi isto ne radi, a u drugom sam moro stavit getch(); da se zaustavi nakon ispisa i bude crvene boje. ali to nije ono što meni treba

BTW pa baš na početku ove teme sam počeo pisati o bojanju teksta - pročitaj moje postove (ima ih više komada) - ovo je prvi: http://www.bug.hr/forum/topic/programiranje/pomoc-c/60641.aspx?page=0&jumpto=1268928&sort=asc&view=flat

IRebic pet 25.2.2011 08:19

Evo, ovaj ispisuje vrijeme od kad je upaljen (koliko je prošlo)...

 

#include<stdio.h>
#include<conio.h>
#include<sys\timeb.h>     
#include<iostream>
struct timeb t_start, t_current;                   
int vr,a,b,c,d,e;
main()
{
   system("Vrijeme");                                                                                   
   int t_diff,t;   
   char c;                                       
   ftime(&t_start);                                          
   do                                                        
   { 
      if(a!=t)
      {                                                      
      a=t;
      system("CLS");
      printf("%d(sec)%d(min)%d(sat)%d(dan)",b,c,d,e);  
      b++; 
      }                                      
      t=t_diff/1000;
      if(b==60)//b=sec
      {b=0;
      c++;}
      if(c==60)//c=min
      {c=0;
      d++;}
      if(d==60)//d=sat
      {d=0;
      e++;}//e=dan                                           
      ftime(&t_current);                                     
      t_diff = (int) (1000.0 * (t_current.time - t_start.time)
        + (t_current.millitm - t_start.millitm));        
   }                                                       
   while(t_diff<60000000);
   getch();
}

 

MOže samo malo pomoći (što se ovoga tiče to radi super...)

htio bi da se upali minimiziran i to u tray(ako je to moguće)

i još nešto, htio bi da svaki put prije nego što se zatvori u neku posebnu txt datoteku upiše sljedeće;

Trenutni_datum ono što ispisiva na ekranu (("%d(sec)%d(min)%d(sat)%d(dan)",b,c,d,e)) (to sa datotekama još nismo učili pa ne znam...{#})

recimo: 22/02/2011 9(sec)55(min)7(sat)1(dan)

jurluk pet 25.2.2011 12:37
mbaksa kaže...

BTW pa baš na početku ove teme sam počeo pisati o bojanju teksta - pročitaj moje postove (ima ih više komada) - ovo je prvi: http://www.bug.hr/forum/topic/programiranje/pomoc-c/60641.aspx?page=0&jumpto=1268928&sort=asc&view=flat

e hvala! to je to. samo što ja nisam sa win api-jem, nego ovaj "obični"

 

captain_soap_McTawish kaže...
#include <stdio.h>

#include <cstdlib>

int main (void)

{

system("COLOR 1");

printf ("Tekst!\n");

getchar ();

return 0;

}

 

FiCoO pet 25.2.2011 17:08
cerberus kaže...

...
    switch (b)
    {
  ...
    case 'brzina': printf("Unesi brzinu u m/s: ");
            scanf("%f", &v);
   
            printf("Unesi vrijeme u sekundama: ");
            scanf("%f", &t);
   
            printf("Duljina puta iznosi: %.2f m", v*t);break;


...    

valjda je to to, bitno je da b primis kao string :)

jel ide samo jedna crtica ova gore ili dvije...

mbaksa pet 25.2.2011 17:11
FiCoO kaže...
cerberus kaže...

...
    switch (b)
    {
  ...
    case 'brzina': printf("Unesi brzinu u m/s: ");
            scanf("%f", &v);
   
            printf("Unesi vrijeme u sekundama: ");
            scanf("%f", &t);
   
            printf("Duljina puta iznosi: %.2f m", v*t);break;


...    

valjda je to to, bitno je da b primis kao string :)

jel ide samo jedna crtica ova gore ili dvije...

Zašto nisi sam probao? Neće ti se ništa strašno dogoditi ako probaš. Kompajler bi ti javio grešku.

rustweaver pet 25.2.2011 17:15
FiCoO kaže...

jel ide samo jedna crtica ova gore ili dvije...

Stringovi idu pod navodnike, ovo sto je on pokusao je koristiti multi byte konstantu kao switch caseove, sto ne ide (kao sto smo vec ustvrdili)

 

Dakle jos jednom, stringove pisi unutar navodnika:

 

"Neki tekst"

FiCoO pet 25.2.2011 17:18
rustweaver kaže...
FiCoO kaže...

jel ide samo jedna crtica ova gore ili dvije...

Stringovi idu pod navodnike, ovo sto je on pokusao je koristiti multi byte konstantu kao switch caseove, sto ne ide (kao sto smo vec ustvrdili)

 

Dakle jos jednom, stringove pisi unutar navodnika:

 

"Neki tekst"

to sam i mislio pa mi bilo cudno zas je napisao case 'brzina': ...