Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Moze li neko naslutiti sta program ispisuje?

[es] :: C/C++ programiranje :: Moze li neko naslutiti sta program ispisuje?

[ Pregleda: 3725 | Odgovora: 8 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

c0d3r

Član broj: 90349
Poruke: 28
*.etf.bg.ac.yu.



Profil

icon Moze li neko naslutiti sta program ispisuje?04.04.2006. u 01:12 - pre 200 meseci
Kako mogu da znam sta ce ovaj program da ispise bez pokretanja istog? I da li neko zna kako bi to bilo na little endian, a kako na big endian sistemima?

Code:

#include <stdio.h>

main() {
  typedef union {
    int a;
    char b[10];
    float c;
  } Union;

  Union x, y = { 100 };

  x.a = 50;
  strcpy (x.b, "hello");
  x.c = 21.50;

  printf ("Union 2: %d %s %f", x.a, x.b, x.c);
  printf ("Union Y: %d %s %f", y.a, y.b, y.c);
}
 
Odgovor na temu

[email protected]
Zarko Bulatovic
H1 Telekom, UNIX Systems Engineer
Split, Spinut

Član broj: 29849
Poruke: 443
*.cmu.carnet.hr.



+25 Profil

icon Re: Moze li neko naslutiti sta program ispisuje?04.04.2006. u 02:53 - pre 200 meseci
Koji je problem? Za razliku od struktura, unija moze sadrzavat samo jednu varijablu u koristenju. Znaci ako imas 10 varijabli u uniji, i svih deset ih inicjaliziras kasnije, samo zadnja je valjana.

Znaci u ovom kodu ti je samo ovaj float c za uniju x operativan, samo ce njega valjano ispisat. U uniji y si agregatirao varijablu int a na 100, pa nisi dirao nista kasnije, pa samo nju ispisuje.


[12:33am] <alek> deca od 3-5 godina prvi spoznaju ljubav bozju :)


Q: HSP56 Micromodem nece da radi kompjuter ga prepozna a kad treba da se konektujem nece ne daje ni znaka zivota. u cemu je problem.

A: Crko mozda od grmljavine mozda od spanaca. Uglavnom baci ga u WC solju jako povuci vodu. Skupi 5e i uzmi drugi i ne postuj temu na pogresno mesto.
 
Odgovor na temu

c0d3r

Član broj: 90349
Poruke: 28
*.ETF.BG.AC.YU.



Profil

icon Re: Moze li neko naslutiti sta program ispisuje?04.04.2006. u 19:37 - pre 200 meseci
Ne, gresis, ako stavim odredjeni broj u x.a koji je integer, onda mogu dobijati neko slovo pri ispisu x.b tipa char... Zato sto koriste isti memorijski prostor... A moje je pitanje kako da znam sta ce ispisati, i imali neke razlike kod little endian i big endian sistema?
 
Odgovor na temu

Marko Stankovic

Član broj: 11
Poruke: 306
212.200.120.*



Profil

icon Re: Moze li neko naslutiti sta program ispisuje?04.04.2006. u 20:52 - pre 200 meseci
Hehe, ovo je zadatak sa subotnjeg testiranja za elektrijadu :P Ovaj zadatak nisam uradio jer sam zaboravio koliko bitova zauzimaju mantisa i eksponent a i zaboravio sam konverzije iz decimalnog u binarni oblik... U svakom slucaju znam u cemu je caka sa zadatkom.
Razlika izmedju bin endian i little endian jeste u smestanju visebajtnih podataka u memoriju. Odnosno, recimo ako je jedna memorijska lokacija siroka 1 Bajt za smestanje podatka tipa int bice potrebno nekoliko lokacija... Neka je u nasem primeru int veliki 4 bajta i neka int ima vrednost 100 decimalno. E sad hexadecimalno ce izgledati 0x00000064, a binarno ce biti 00000000 00000000 00000000 01100100. Kada bismo smestali taj podatak u recimo lokaciju X u memoriji na big endian sistemima onda bi najvisi bajt isao na najnizu adresu odnosno:

Code:

     bin:                  hex:
X   |   00000000         00
X+1 |   00000000         00
X+2 |   00000000         00
X+3 |   01100100         64


Kod little endian ide obrnuto, najvisi bajt na najvisu adresu:

Code:

      bin:                hex:
X   |   01100100         64
X+1 |   00000000         00
X+2 |   00000000         00
X+3 |   00000000         00


E sad vratimo se na zadatak. Znaci znamo da unija zauzima mesta u memoriji onoliko koliko je potrebno najvecem podatku iz nje da se smesti. Sto znaci kada ispisujes string on ce da krene od prvog bajta da procita njegovu vrednost i da ispise karakter iz ASCII tabele kojoj odgovara ta vrednost i tako ce da ispisuje dok ne naleti na bajt koji ima vrednost 0, odnosno NULL. Kada se ispisuje integer ili float procitace prva 4 bajta i i ispisace vrednost broja koju formiraju ta 4 bajta. E sad imamo da je u uniju X poslednji put upisan broj 21.50 a u uniju Y vrednost 100. E sad ove vrednosti treba da predstavis binarno i da popunis memoriju na big/little endian nacin i posle je jednostavno, string ispisujes do prvog NULL bajta, integer je najlaksi a za float treba da znas ono sto sam ja zaboravio, odnosno da poznajes tamo neki standard o predstavljanju realnih brojeva :)
Iskreno mene mrzi da se sad prisecam tih stvari ali mozda se javi neka dobra dusa koja zna pa napise odgovor :)

pozdrav


UPDATE: ispravio sam izgled memorije jer sam tek sada video da sam upisao po svega 4 bita u jednu lokaciju :)



[Ovu poruku je menjao Marko Stankovic dana 06.04.2006. u 19:35 GMT+1]
I drink to make other people interesting.
 
Odgovor na temu

[email protected]
Zarko Bulatovic
H1 Telekom, UNIX Systems Engineer
Split, Spinut

Član broj: 29849
Poruke: 443
*.cmu.carnet.hr.



+25 Profil

icon Re: Moze li neko naslutiti sta program ispisuje?05.04.2006. u 00:37 - pre 200 meseci
Krivo si me shvatio, a ja nisam pogledao tvoje pitanje do kraja :

Samo jedan clan unije moze bit operativan odjednom. Pogledaj ovaj svjeze napisani primjer.

Code:

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

union test
{
    int a;
    char c;
}t2;

int main()
{
    t2.a = 78;
    printf("%c %d\n", t2, t2); 
    t2.c = 'x';
    printf("%c %d\n", t2, t2);
    system("PAUSE"); return EXIT_SUCCESS;    
}


Primjer vraca :

Citat:

N 78
x 120
Press any key to continue . . .


Dakle imamo uniju jednog integera i jednog znaka. Mi mozemo postavit uniju na samo jednu vrijednost. Da mozemo na dvije, znaci char na jednu, int na drugu, to bi bila struktura. Prvo smo postavili integer iz unije na 78, char ne diramo. Ali, mi vrijednost unije mozemo interpretirati kao broj, ili kao char, sta ce povuc broj na ASCII tabelu i ispisat popratnu vrijednost. Isto tako, kad inicijaliziramo znak na 'x', deinicjalizira se gornji integer, tj. broj 78, a cjelobrojna reprezentacija unije je broj 120, dakle lookup znaka 'x' iz ASCII tabele.

E sad, gornja unija je uvjek velika 4 bajta, zato sta je najveci clan unije 32-bitni integer. Big endian sistemi ce zapisat ta cetri bajta pocevsi od najnize adrese, a little endian sistemi obrnuto. Ali, isto tako big endian sistemi iscitavaju vrijednosti tim redosljedom, kao i little endian sistemi. Znaci, ako kompajliras i pokrenes taj tvoj kod na x86 platformi, pa opet kompajliras i pokrenes tvoj kod na 68k platformi, isti je rezultat. Problem je jedino ako projektiras tvoj program da koristi big-endian sekvence na najnizem nivou, dakle da tom unijom baratas preko jednobajtnih (char) pointera i na taj nacin radis operacije nad njenim sadrzajem, imat ces problema na little endian platformi, jer jednostavno podatci nisu u istom redu zapisani. Ako koristis standardne C nacine, bez neke velike aritmetike pointera i direktnom pristupanju memorijskim adresama, nemas problema, jer C kompajler zna gdje se nalazi i kakvim redosljedom treba radit memorijske operacije.
[12:33am] <alek> deca od 3-5 godina prvi spoznaju ljubav bozju :)


Q: HSP56 Micromodem nece da radi kompjuter ga prepozna a kad treba da se konektujem nece ne daje ni znaka zivota. u cemu je problem.

A: Crko mozda od grmljavine mozda od spanaca. Uglavnom baci ga u WC solju jako povuci vodu. Skupi 5e i uzmi drugi i ne postuj temu na pogresno mesto.
 
Odgovor na temu

Marko Stankovic

Član broj: 11
Poruke: 306
212.200.120.*



Profil

icon Re: Moze li neko naslutiti sta program ispisuje?06.04.2006. u 14:23 - pre 200 meseci
Hmmm, aj malo bolje da razjasnimo sta je ovde fora. Kao prvo, ja se ne bih slozio sa tim da je samo jedan clan unije aktivan, vec su svi aktivni, ali se u uniji nalazi isti binarni sadrzaj. Odnosno mi mozemo u bilo kom trenutku da pristupimo bilo kom clanu unije i da predvidimo sta ce da ispise takav pristup ako znamo sadrzaj svih bajtova potrebnih za ispis tog podatka. Naravno ovako nesto nema mnogo smisla za koriscenje a i plus razlikovace se ispis na big endian i little endian masinama.
Recimo prethodni primer ce na big endian masini da ispise u prvom slucaju 'NULL' i 78, dok u drugom ce ispisati 'x' dok ce broj biti 0xF000004E odnosno 4026531918, naravno ovo je pod pretpostavkom da je char 1 bajt, a int 4 bajta.

Citat:

Mi mozemo postavit uniju na samo jednu vrijednost. Da mozemo na dvije, znaci char na jednu, int na drugu, to bi bila struktura.


Apsolutno se slazem sa ovim.

Citat:

Prvo smo postavili integer iz unije na 78, char ne diramo.


Ali sa ovim se ne slazem uopste. Cim mi nesto upisemo u uniju mi najverovatnije menjamo sve clanove unije. Jer svi clanovi unije pocinju od iste memorijske lokacije i upisuju se na naredna nekoliko bajta zavisno od njihove velicine, sto znaci kada ja kazem t2.c='x' (hex je 'x'=0xF0, jer char zauzima 1 bajt), to znaci pocni od lokacije na kojoj se nalazi unija i upisi u prvi bajt vrednost 120d odnosno 0xF0h. Kada kazemo t2.a=120 (120=0x000000F0 jer int 4 bajta) onda to znaci kreni od lokacije na kojoj se nalazi unija i u narednih cetiri bajta upisi 0x000000F0. Naravno zavisno od nacina upisa drugacija ce biti vrednost za char elemenat unije. Ako je big endian masina onda je char 0x00 iliti NULL, ako je little endian onda je char 0xF0 odnosno 'x'.

Citat:

Isto tako, kad inicijaliziramo znak na 'x', deinicjalizira se gornji integer, tj. broj 78, a cjelobrojna reprezentacija unije je broj 120, dakle lookup znaka 'x' iz ASCII tabele.


Ne deinicijalizira se nista u tom slucaju vec jednostavno se na prvi bajt unije upise binarana vrednost tog chara, dok ostala 3 bajta ostaju nepromenjena.

Sve u svemu odgovornost programera je da ispravno koristi podatke iz unije, odnosno on moze da upise float u uniju i da u sledecem trenutku taj podatak tumaci kao integer, naravno to nema mnogo smisla ali je dozvoljeno i sasvim regularno. E sad ovaj zadatak koji je naveo coder je sa takmicenja i on sluzi bas da testira poznavanje upisa u memoriju i poznavanje IEEE 754 standarda za binarnu aritmetiku realnih brojeva, jer je u zadatku potrebno protumaciti binarnu vrednost broja 100 kao float i obrnuto da float 21.50 predstavite kao integer. Naravno da ispisete int kao char je smesno i obrnuto. E pa koga ne mrzi nek prevodi ove brojeve i nek ostavi resenje.

poz

I drink to make other people interesting.
 
Odgovor na temu

c0d3r

Član broj: 90349
Poruke: 28
213.244.197.*



Profil

icon Re: Moze li neko naslutiti sta program ispisuje?07.04.2006. u 13:08 - pre 200 meseci
Ajde kad si vec tu ako mozes da mi pojasnis onaj zadatak u kojem je trebalo da se prikaze sadrzaj memorije pre i posle, kao i da se objasni svaka recenica po malo...

Code:

  int n=3;
  int *p1, *p2;
  double *q1, *q2;
  p1=(int *) malloc(n*sizeof(int));
  p2=&(p1[n-1]);
  *p1=5;
  p1[n-1]=3;
  q2=(double *) malloc(n*sizeof(double));
  q1=&(q2[0]);
  q1=5.5;
  q1[n-1]=*q2;
 
Odgovor na temu

[email protected]
Zarko Bulatovic
H1 Telekom, UNIX Systems Engineer
Split, Spinut

Član broj: 29849
Poruke: 443
*.cmu.carnet.hr.



+25 Profil

icon Re: Moze li neko naslutiti sta program ispisuje?07.04.2006. u 18:00 - pre 200 meseci
Ne postoji na niskom nivou clanovi unije, jer unija je jedna jedina memorijska lokacija, ma koliko varijabli bilo u njoj. To sta ja pisem "aktivan", "inicjalizacija", to je radi lakseg objasnjavanja stvari.

Code:

  int n=3;
  int *p1, *p2;
  double *q1, *q2;
  p1=(int *) malloc(n*sizeof(int));
  p2=&(p1[n-1]);
  *p1=5;
  p1[n-1]=3;
  q2=(double *) malloc(n*sizeof(double));
  q1=&(q2[0]);
  q1=5.5;
  q1[n-1]=*q2;


1. n = 3.
2. deklariramo dva pointera tipa int.
3. deklariramo dva pointera tipa double.
4. alociramo memoriju dovoljnu za postavljanje tri integera (n*sizeof(int)), i adresu alocirane memorije saljemo u p1.
5. p2 postavljamo na pocetnu adresu p1 + 64 bajta. p1[n-1] == p1[2], a p1[2] je lokacija 64 bajta otklona od p1, (2 * sizeof(int)).
6. ono na sta p1 pokazuje, mozemo promatrat kao dinamicki alocirano polje od tri ineger elementa. sad smo prvi clan polja postavili na broj 5.
7. isto tako, zadnji clan polja smo postavili na 3. sad i p2 ispod sebe ima vrijednost 3, jer gledaju na istu memorijsku lokaciju.
8. alociramo memoriju dovoljnu za postavljanje tri doublea, pocetnu adresu bloka saljemo u q2.
9. q1==q2, zato sta je memorijska adresa prvog elementa bloka jednaka adresi koja je prosljedjena u q2 prilikom alociranja.
10. ova linija je cudna. mozda je trik. ali uglavnom, po ovome sta pise gore, pointer q1 ima vrijenost 5.5. a to je nedopusteno, konverzija izmedju double i double*. ako je trebalo bit *q1= 5.5, onda je ista stvar kao kod stavke 6.
11. ako zanemarimo stavku broj 10. q1 pointer gleda upravo gdje i q2. sad, ako posmatramo q2 kao adresu dinamicki alociranog bloka gdje je polje za nasa tri doublea, zadnji element bloka smo postavili na vrijednost prvog elementa bloka.


[Ovu poruku je menjao [email protected] dana 07.04.2006. u 19:01 GMT+1]
[12:33am] <alek> deca od 3-5 godina prvi spoznaju ljubav bozju :)


Q: HSP56 Micromodem nece da radi kompjuter ga prepozna a kad treba da se konektujem nece ne daje ni znaka zivota. u cemu je problem.

A: Crko mozda od grmljavine mozda od spanaca. Uglavnom baci ga u WC solju jako povuci vodu. Skupi 5e i uzmi drugi i ne postuj temu na pogresno mesto.
 
Odgovor na temu

c0d3r

Član broj: 90349
Poruke: 28
*.vdial.verat.net.



Profil

icon Re: Moze li neko naslutiti sta program ispisuje?08.04.2006. u 00:25 - pre 200 meseci
Hvala vam svima na odgovorima! Nadam se da ce jos nekome ovo znaciti...
 
Odgovor na temu

[es] :: C/C++ programiranje :: Moze li neko naslutiti sta program ispisuje?

[ Pregleda: 3725 | Odgovora: 8 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.