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

Sve što mi nije jasno u vezi C jezika.

[es] :: C/C++ programiranje :: C/C++ za početnike :: Sve što mi nije jasno u vezi C jezika.

[ Pregleda: 4700 | Odgovora: 14 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Lazoman

Član broj: 261300
Poruke: 93
*.dynamic.sbb.rs.



+5 Profil

icon Sve što mi nije jasno u vezi C jezika.17.10.2014. u 12:01 - pre 115 meseci
Problem koji imam je u vezi operacija sa bitovima, kao i zadacima na kraju poglavlja koji se nalaze u knjizi O Reilly - Practical C Programming, 3rd Edition koju trenutno čitam.

Dakle da li može neko da mi pojasni #define SET_BIT(x,y) graphics[(x)/8][y] |= (0x80 >>((x)%8)) , sta se ustvari desava i kada, koji se bit setuje i kako da protumacim graphics [(x)/8][y] |= (0x80 >>((x)%8)), znam da je makro u pitanju i jasno mi je kako on funkcionise ali mešanje aritmetičkih operatora i operatora za rad nad bitovima me buni i to dosta.

Kod programa je sledeci:

Code:
#include <stdio.h>
#define X_SIZE 40 /* size of array in X direction */
#define Y_SIZE 60 /* size of array in Y direction */
/*
* We use X_SIZE/8 because we pack 8 bits per byte
*/
char graphics[X_SIZE / 8][Y_SIZE]; /* the graphics data */
#define SET_BIT(x,y) graphics[(x)/8][y] |= (0x80 >>((x)%8))
int main()
{
int loc; /* current location we are setting */
void print_graphics(void); /* print the data */
for (loc = 0; loc < X_SIZE; ++loc)
SET_BIT(loc, loc);
print_graphics();
return (0);
}
/********************************************************
* print_graphics -- Prints the graphics bit array *
* as a set of X and .'s. *
********************************************************/
void print_graphics(void)
{
int x; /* current x BYTE */
int y; /* current y location */
unsigned int bit; /* bit we are testing in the current byte */
for (y = 0; y < Y_SIZE; ++y) {
/* Loop for each byte in the array */
for (x = 0; x < X_SIZE / 8; ++x) {
/* Handle each bit */
for (bit = 0x80; bit > 0; bit = (bit >> 1)) {
if ((graphics[x][y] & bit) != 0)
printf("X");
else
printf(".");
}
}
printf("\n");
}
}


Hvala unapred na odgovoru :)

[Ovu poruku je menjao Lazoman dana 17.10.2014. u 13:11 GMT+1]
 
Odgovor na temu

Odin D.
Mlađi referent za automatizaciju
samoupravljanja

Član broj: 37292
Poruke: 2549



+8370 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.17.10.2014. u 18:04 - pre 114 meseci
Kad god radiš sa grafikom, nije zgoreg malo crtati, obično se tako sve razjasni.

Dakle, gledaj priloženu sliku.



Recimo da je na slici taj tvoj "ekran" iz primjera, širine 40 pixela/tačaka/elemenata... i visine 60.
On je predstavljen dvodimenzionalnim nizom čiji su elementi char:

char graphics[5][60]

Obrati pažnju da je jedan char veličine jednog byte-a, tj ima 8 bitova, zato jedan char element iz tvog niza graphics pokriva 8 tačaka na ekranu,
jer je svakoj tački pridružen jedan bit.
Na slici vidiš iscrtane char-ove debljim crnim boxovima.

Ti pojedinačnim tačkama ne možeš da pristupaš pojedinačno (jer jezik C ne poznaje manje elemente od byte-a) - nego moraš da se bakćeš sa čitavim char-om (byte-om) u kome se posmatrana tačka nalazi.
Fazon na kome se to bazira je taj da u nekom byte-u možeš da promjeniš vrednost nekog bita, ali tako da ne utičeš na vrednost ostalih bitova u tom bajtu.

Dakle, kad želiš da promjeniš vrednost nekog bita(tačke) na ekranu, ti prvo moraš da pristupiš tom byte-u u kome se ona nalazi.
Na slici su adrese bajtova(char-ova) predstavljene plavom bojom.
Tako npr. vidiš dva zaplavljena char-a, jedan je graphics[0][5], a drugi graphics[3][7].

Kada recimo hoćeš da čeprkaš sa tačkom ekrana na koordinati (20,12), onda moraš u stvari da čeprkaš sa char-om graphics[2][12] jer je to onaj u kome
se nalazi ta tačka.
Pošto jedan char pokriva 8 horizontalnih tačaka (vidi sliku), to kad podjeliš koordinatu x sa 8 dobićeš prvu dimenziju dvodimenzionalnog niza graphics.
Pošto jedan char po vertikali pokriva samo jednu tačku (vidi sliku), to je druga koordinata direktno i druga dimenzija niza dvodimenzionalnog niza graphics.

Znači, sa graphics[2][12] ti si "dohvatio" potreban char (žuti blok na slici).
Sad je samo potrebno setovati odgovarajući bit u tom char-u, tj. byte-u.

To se radi pomoću bit operatora.
Setovanje nekog bita zasniva se na principu da bilo koja vrednost tog bita kada se OR-uje sa "1" daje za rezultat "1".
Što se tiče ostalih bitova - koji treba da ostanu nepromjenjeni, oni treba da se OR-uju sa "0", jer kad se bilo šta OR-uje sa "0" ono ostaje ono što je i bilo.

Recimo, ako u nekom bajtu hoćeš da setuješ 3 bit (sa početka) onda to ide ovako:

Code:
neki_byte |= 0b00100000;


Dakle, potrebno je da ga OR-uješ sa bit-maskom koja ima "1" na trećoj poziciji, a na svim ostalim nula.
Ono gore na desnoj strani je binarni broj, i takav zapis nije standard C jezika i mnogi kompajleri ga ne podržavaju, ali je npr. uobičajeno da postoji u kompajlerima za mikrokontrolere i sl.
Zbog toga takve brojeve moraš da pišeš ili u heksadecimalnom, ili u oktalnom ili u decimalnom zapisu.
Recimo, u heksadecimalnom zapisu to je 0x20, a u decimalnom 32.

Da bi izračunao tačnu poziciju tvoje tačke u okviru posmatranog byte, koristi se deljenje po modulu:

Code:
x%8


Dobijeni broj predstavlja poziciju bita (u okviru char-a) koji treba da se setuje.

Da bi dobio bit-masku koja samo na toj poziciji ima "1", a na svim ostalim "0", polaziš od broja koji samo na prvoj poziciji ima "1":

0x80 heksidecimalno je ustvari 10000000 binarno

Kada sad taj broj shift-uješ u desno za 4 mjesta dobijaš

00001000

To je ta bit maska koja ti treba. Pogledaj sliku, to je mjesto na kom se nalazi onaj crveni kvadratić koji predstavlja tu tačku sa koordinatama (20,12). Kada svoj orginalni byte OR-uješ sa ovim, onaj bit koji se poklopa sa "1" iz ove bit-maske će biti setovan, a svi ostali nepromjenjeni (pošto se OR-uju sa "0", što nema nikakav efekt u OR operaciji).

Kada hoćeš da resetuješ neki bit, koristiš komplementarnu operaciju AND.
U tom slučaju bit maska sa kojom AND-uješ svoj byte treba da sadrži nule na onim mjestima na kojima hoćeš da ti se bitovi resetuju,
a jedinice na mjestima onih bitova koji hoćeš da ostanu nepromjenjeni.
Npr. nakon ovoga

Code:
neki_byte &= 0b01111110;  //bin 
tj.
neki_byte &=0x7E;   // hex


tvoj bajt će imati resetovane bitove na prvoj i zadnjoj poziciji, a svi ostali će ostati nepromjenjeni jer AND-ovanje nečeg sa "1" ne mijenja ništa:
0 AND 1 = 0
1 AND 1 = 1


[Ovu poruku je menjao Odin D. dana 17.10.2014. u 19:30 GMT+1]
Prikačeni fajlovi
 
Odgovor na temu

Lazoman

Član broj: 261300
Poruke: 93
*.dynamic.sbb.rs.



+5 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.17.10.2014. u 22:46 - pre 114 meseci
Hvala Odine, svaka čast na objašnjenju, pomoglo je dosta :)

Samo me zanima zasto se X kordinate dele sa 8 a Y ne, taj dvodimenzionalni niz cine char-ovi, koji su 8bitne varijable, zar ne bi trebalo onda i Y da se prikaze kao X, tj raspodeli na byte-ove ?
Kako po horizontali imamo 8 bitova tako bi i po vertikali trebalo da imamo isto, zar ne?
 
Odgovor na temu

Odin D.
Mlađi referent za automatizaciju
samoupravljanja

Član broj: 37292
Poruke: 2549



+8370 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.17.10.2014. u 23:09 - pre 114 meseci
Pa ne baš, pogledaj sliku: jedan char (bajt) leži horizontalno i ako pogledaš char [2][12] vidjećeš da u njemu leže tačke sa koordinatama
(16, 12)
(17, 12)
(18, 12)
(19, 12)
(20, 12)
(21, 12)
(22, 12)
(23, 12)

Znači, x se mijenja, a y je uvijek 12.
Tako i za bilo koju drugu tačku koju uzmeš - [y] dimenzija niza graphics[x][y] na kojoj se nalazi char u kome je bit koji odgovara tvojoj tački uvijek je isti kao i y koordinata tačke.
Npr, uzmi tačku (7, 3) -> potreban ti je char graphics[0][3]
uzmi tačku (10, 7) -> potreban ti je char graphics[1][7]
uzmi tačku (27, 60) -> potreban ti je char graphics[3][60]

Da je zamišljeno da je ekran popločan uspravno polegnutim char-ovima onda bi imao obrnut slučaj: x koordinata tačke bi odgovarala [x] dimenziji niza graphics[x][y], a [y] bi se izračunavao djeljenjem sa 8.


 
Odgovor na temu

Lazoman

Član broj: 261300
Poruke: 93
*.dynamic.sbb.rs.



+5 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.18.10.2014. u 19:12 - pre 114 meseci
Problem sa zadatkom.

Write a program that takes a 32 -bit integer (long int) and splits it
into eight 4-bit values. (Be careful of the sign bit.)

Gde smestiti 4bitnu vrednost i kako ovo odraditi.

Zamisao mi je bila da se unese traženi long int broj i da se pomocu for petlje
Code:
for(i=0x80000000; i>0; i = (i >> 1))
kao i
Code:
if(i & broj !=0)
koji ce proveravati da li trenutna vrednost broja i ima poklapanja sa unesenim long int brojem, ukoliko ima (definisano je 8 integera, za smestanje svih 8 cetvorobitnih vrednosti, znam da ce ostati 12 bitova neiskoristenih od integera ali to sad nije bitno), promenljiva x koja je inace neka vrsta brojaca se inkrementuje sa 1 (na pocetku vrednost inicijalizovana na 0), e sad malo mi glomazno da pisem osam if-ova koji ce proveravati trenutnu vrednost x-a, i ukoliko je on npr u granicama 0-7 broj ce biti shiftovan na ovaj nacin
Code:
broj1 |=0x8000>>((x%4)+12)
, to je primer za broj1, broj2 ce biti shiftovan npr ovako
Code:
 broj2 |= 0x8000>>((x%4)+8)
(jer je x vec presao u 5 bit tj. x=5 pa ce i manje shiftovanje biti potrebno)...dalje se vec gubim, da li sam na dobrom putu i da li to moze tako, verujem da ima laksih nacina, ali posto sam neki vid pocetnika ne vidim drugo resenje...?
 
Odgovor na temu

Odin D.
Mlađi referent za automatizaciju
samoupravljanja

Član broj: 37292
Poruke: 2549



+8370 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.18.10.2014. u 22:03 - pre 114 meseci
Citat:
Lazoman: definisano je 8 integera, za smestanje svih 8 cetvorobitnih vrednosti

Četverobitni broj ima 16 mogućih vrednosti.
 
Odgovor na temu

Lazoman

Član broj: 261300
Poruke: 93
*.dynamic.sbb.rs.



+5 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.19.10.2014. u 09:39 - pre 114 meseci
Da znam da mi je potrebno samo 4 bita, ali posto ne postoji promenljiva manja od 8 bita (char), jos ona nije namenjena za prikazivanje brojeva, uzeo sam int, i to 8 integera, gde mi od svakog trebaju samo prva cetiri bita da bi prikazao tu cetvorobitnu vrednost iz jednog cetvorobitnog bloka tog 32bitnog integera koji unosim na pocetku.

Ne pada mi trenutno napamet kako da smestim te cetvorobitne vrednosti, gde?
 
Odgovor na temu

HeYoo

Član broj: 72595
Poruke: 491



+1017 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.19.10.2014. u 09:55 - pre 114 meseci
Pa to je verovatno definisano u zadatku.
 
Odgovor na temu

Lazoman

Član broj: 261300
Poruke: 93
*.dynamic.sbb.rs.



+5 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.19.10.2014. u 10:16 - pre 114 meseci
Write a program that takes a 32 -bit integer (long int) and splits it
into eight 4-bit values. (Be careful of the sign bit.)

Krenuo sam ovako nekako:

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

int main()
{
    unsigned long int broj, i;
    int x, pombrojac;
    char vrednost[8];

    scanf("%lu", &broj);

    x=0;

    for(i=0x80000000; i>0; i=(i>>1))  
    {
        if(broj & i != 0) 
        {
            x++;
            if(x>=0 && x<4)
            {
                vrednost[1]|=0x80>>(x%4)+4;
            }
            else if(x>=4 && x<8)
            {
                vrednost[2]|=0x80>>(x%4);
            }
            .
            .
            .
        }
    }
}




[Ovu poruku je menjao Lazoman dana 19.10.2014. u 11:33 GMT+1]
 
Odgovor na temu

HeYoo

Član broj: 72595
Poruke: 491



+1017 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.19.10.2014. u 10:57 - pre 114 meseci
Komplikujes.

Treba da maskiras 4 bita, castujes i upises u 0ti clan niza; shift, pa ponovo maskiras, castujes i upises u prvi clan niza, itd..

Pre svega toga treba da proveris da li je taj 32-bitni int negativan ili pozitivan (provera najznacanijeg bita) i da li za isecke treba uzeti regularne ili invertovane vrednosti.
 
Odgovor na temu

Lazoman

Član broj: 261300
Poruke: 93
*.dynamic.sbb.rs.



+5 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.19.10.2014. u 11:23 - pre 114 meseci
Hvala na ideji, probam pa javim kad zavrsim.
 
Odgovor na temu

Lazoman

Član broj: 261300
Poruke: 93
*.dynamic.sbb.rs.



+5 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.19.10.2014. u 16:36 - pre 114 meseci
Kod programa :)

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

char array[8];
unsigned long int number, i;
int x;

int main()
{

scanf("%lu", &number);

for(x=0; x<8; x++)
{
    array[x] = (char)(((number)>>4*x) & 0x0F);
    printf("%d \n", array[x]);
}
}
 
Odgovor na temu

technotize
Linux System & Network Administrator

Član broj: 238671
Poruke: 215
95.180.41.*



+31 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.20.10.2014. u 00:31 - pre 114 meseci
OT, ali da pitam Odina u cemu nacrta onu sliku? Izgleda ekstra, da nije nesto sto ide uz tablete i sl? pozz
 
Odgovor na temu

Odin D.
Mlađi referent za automatizaciju
samoupravljanja

Član broj: 37292
Poruke: 2549



+8370 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.20.10.2014. u 01:44 - pre 114 meseci
SmoothDraw + Wacom Bamboo tablet.
http://www.elitesecurity.org/p3076854
 
Odgovor na temu

technotize
Linux System & Network Administrator

Član broj: 238671
Poruke: 215
95.180.41.*



+31 Profil

icon Re: Sve što mi nije jasno u vezi C jezika.30.11.2014. u 19:07 - pre 113 meseci
Hvala!
 
Odgovor na temu

[es] :: C/C++ programiranje :: C/C++ za početnike :: Sve što mi nije jasno u vezi C jezika.

[ Pregleda: 4700 | Odgovora: 14 ] > FB > Twit

Postavi temu Odgovori

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