Programiranje u C-u

poruka: 216
|
čitano: 64.779
|
moderatori: Lazarus Long, XXX-Man, vincimus
+/- sve poruke
ravni prikaz
starije poruke gore
13 godina
offline
Re: Programiranje u C-u
alias_noname kaže...

znaci ovako, iman neku tekstualnu datoteku u kojoj prva 3 reda su neke gluposti a onda od 4. reda pa na dolje su stvari poslozene po stupcima, i sad kako bi ja pomakao pointer da mogu čitati od 4. reda pa do određenog i kako da te podatke iz stupaca spreman u različita polja?
EDIT: i kako ide onda za binarne datoteke? 

Nekakav fseek možda, mada mislim da bi se to teško implementiralo. Moraš povući i smeće iz filea, ali ga ignorirati.

Povući podatke možeš sa fscanf-om gdje ti on može pomoći s parsanjem (format specifieri) ili fgets-om spremati liniju po liniju u nekakav buffer pa iz njega onda vaditi što ti treba sa sscanf-om.

Za binarne datoteke imaš fread i fwrite.

 

EDIT: Postavi pitanje u ovu temu.

0100011001000001010100000010000000110100001000000100110001001001010001100100010100100001
Poruka je uređivana zadnji put sri 26.6.2013 1:27 (pr0n_addict).
15 godina
offline
Programiranje u C-u

Valja li inicijalizacija svakog člana polja pointera na NULL?

http://pastebin.com/d844SFkr

 

Ne mogu više razmišljati

hvala unaprijed!

 

Edit:

Siguran sam da ve valja jer compiler baca error

 

Imam polje pointera i trebam svaki taj pointer postaviti na NULL

gdje griješim?

 

 

void init (struct zapis ** tablica)

 

i init(&tablica[0]) će učiniti svoje

 

Ujutro skužiti zašto

You have to be odd to be number one
Poruka je uređivana zadnji put pon 6.6.2016 20:05 (Top Bugovac).
Moj PC  
0 0 hvala 0
13 godina
neaktivan
offline
Re: Programiranje u C-u

Malo si pobrkao arraye i pointere.

 

Koliko vidim, htio si array pointera na neku strukturu.

 

Iz koda: void init (struct zapis *** tablica).

Čak i da si napravio ovo: init (struct zapis **tablica), to opet ne bi radilo, osim uz kemijanje.

 

Kada prosljeđuješ podatak u tu funkciju, compiler ne zna što ti zapravo želiš, jer prilikom deklariranja te funkcije nema informaciju da ćeš proslijediti array.

On samo zna da će tu ići nekakav pointer na pointer. A array pointera je i dalje samo array.

 

Ovo bi možda moglo biti ono što tražiš:

 


void init (struct zapis *tablica[], int duzina) {
    int i;
    for (i=0;i<duzina;++i) {
        tablica[i]=NULL;
    }
}
 
int main (void) {
   struct zapis *tablica[HASH_VEL];   

   init(tablica, HASH_VEL);
    return 0;
}

 

 

 

Pod pretpostavkom da je NULL zapravo 0 i ako ti kod ne mora biti 100% portabilan:

 

Za razumne veličine arraya:
memset(tablica, 0x00, (sizeof(struct zapis*))*HASH_VEL);

 

A možeš i ovo:

struct zapis *tablica[HASH_VEL]={0};

15 godina
offline
Re: Programiranje u C-u
Djuro von Prekoplotovich kaže...

Malo si pobrkao arraye i pointere.

 

Koliko vidim, htio si array pointera na neku strukturu.

 

Iz koda: void init (struct zapis *** tablica).

Čak i da si napravio ovo: init (struct zapis **tablica), to opet ne bi radilo, osim uz kemijanje.

 

Kada prosljeđuješ podatak u tu funkciju, compiler ne zna što ti zapravo želiš, jer prilikom deklariranja te funkcije nema informaciju da ćeš proslijediti array.

On samo zna da će tu ići nekakav pointer na pointer. A array pointera je i dalje samo array.

 

Ovo bi možda moglo biti ono što tražiš:

 


void init (struct zapis *tablica[], int duzina) {
    int i;
    for (i=0;i<duzina;++i) {
        tablica[i]=NULL;
    }
}
 
int main (void) {
   struct zapis *tablica[HASH_VEL];   

   init(tablica, HASH_VEL);
    return 0;
}

 

 

 

Pod pretpostavkom da je NULL zapravo 0 i ako ti kod ne mora biti 100% portabilan:

 

Za razumne veličine arraya:
memset(tablica, 0x00, (sizeof(struct zapis*))*HASH_VEL);

 

A možeš i ovo:

struct zapis *tablica[HASH_VEL]={0};

 Puno hvala!
Samo mi nije jasno zašto struct zapis ** tablica nije isto što i struct zapis tablica []

Zapravo si rekao da bi to valjalo ali uz kemijanje, što se točno mijenja?

 

Podcrtano potvrđujem :)

You have to be odd to be number one
13 godina
neaktivan
offline
Re: Programiranje u C-u

U primjeru koji si dao, ovo bi također bilo ispravno:
void init (struct zapis **tablica, int duzina)
Ali vidiš da opet dajem informaciju o dužini/veličini kao parametar funkcije.
Kada to radiš s globalnim varijablama ili pomoću preprocesora, e to je kemijanje.
Može se skompajlirati, može se izvršavati, ali je kemijanje.
I to će ti se prije ili kasnije obiti od glavu kada kreneš modificirati malo kompleksniji kod.
Pogledaj C library funkcije, sve koje rade s arrayima i stringovima (i nisu proglašene kao nesigurne ili "deprecated") kao argument primaju informaciju o dimenziji (broju elemenata).

Objašnjenje pokazivača i nizova:
U tvom slučaju u memoriji računala "tablica" je niz pokazivača na strukturu "zapis".
Niz počinje na adresi "tablica".
Ovisno o tome koji IDE i debugger koristiš, to možeš i vidjeti kada prekreneš debugger.
Nakon toga provjeri i rezultat ovog:
size_t data=sizeof(struct zapis);  
size_t ptr_data=sizeof(struct zapis*);
size_t ptr_ptr_data=sizeof(struct zapis**);
size_t ptr_ptr_ptr_data=sizeof(struct zapis***);
Tu ćeš vidjeti u kojem obliku se sprema koji tip podatka u memoriji.

struct zapis *tablica je pokazivač koji može sadržavati adresu memorijske lokacije gdje se nalazi struktura tipa "zapis".
struct zapis **tablica je pokazivač koji može sadržavati adresu memorijske lokacije gdje se nalazi pokazivač na strukturu tipa "zapis".
struct zapis ***tablica je pokazivač koji može sadržavati adresu memorijske lokacije gdje se nalazi pokazivač na pokazivač na strukturu tipa "zapis".

struct zapis *tablica[] je niz pokazivača na strukturu "zapis", u memoriji se nalazi na adresi "tablica", a prvi element mu je pokazivač na strukturu "zapis".
Zbog toga ga možeš tretirati kao pokazivač na pokazivač.

Dok ovo: struct zapis tablica[] je niz sastavljen od struktura zapis, u memoriji počinje na adresi "tablica", a prvi element mu je struktura zapis.
Prvom elementu niza možeš pristupiti ili preko tablica[0] ili njegovu uzeti adresu preko
struct zapis *ptr=tablica, pa zatim pristupiti elementima strukture preko ptr->podatak i ptr->sljedeci.
A ako inkrementiraš ptr, dobiješ adresu drugog elementa u nizu.
U tvom zadatku niz sadrži pokazivače, pa zbog toga možeš koristiti pokazivač na pokazivač kada pristupaš elementu.
Jasnije?

Idući problem na koji ćeš naletjeti su dvodimenzionalni nizovi.
Kod njih zapamti da su to u memoriji jednodimenzionalni nizovi, jedino što ti C preko sintakse donekle olakšava život time što ti ih u kodu možeš prezentirati kao redove i stupce.
Kod njih su česte greške oko korištenja pokazivača na pokazivač.

Ono što mi nitko nije rekao kada sam počeo raditi s C-om:
Omogući na kompajleru sva upozorenja, a ako koristiš GCC omogući i -Wextra.

Čitaj upozorenja. Ako je nešto neinicijalizirano, kasnije iz toga može nastati zanimljiv problem.
Skini cppcheck http://cppcheck.sourceforge.net/ uključi sve provjere (greške, upozorenja, portabilnost, stil, informacije) i zavrti na kodu na kojem radiš,
Iako ima "cpp" u nazivu, uredno radi i na C kodu.

Poruka je uređivana zadnji put uto 7.6.2016 12:19 (Djuro von Prekoplotovich).
15 godina
offline
Programiranje u C-u

Prošao sam 2D nizove, shvatio sam sve sada

hvala!

 

Koristim gcc, inače s pedantic-error opcijom (kako su nas učili na faksu)

Javi neinicijalizirane varijable uvijek (ubacit ću wextra također)

 

samo mi nije jasno ovo s #define i prenošenje veličine polja

zašto je bolje ovo tvoje?

Možeš li navesti neki primjer?

 

Shvatio preko ovoga:
"Pogledaj C library funkcije, sve koje rade s arrayima i stringovima (i nisu proglašene kao nesigurne ili "deprecated") kao argument primaju informaciju o dimenziji (broju elemenata)."

 

Ako napišem funkciju koju netko drugi treba koristiti (ili ja kasnije) taj #define nije baš poželjan

 

Jednostavno je lakše ubaciti da funkcija traži još jedan parametar, nego pisati u nekakvoj dokumentaciji da funkcija traži predefiniran neki define

You have to be odd to be number one
Poruka je uređivana zadnji put uto 7.6.2016 13:52 (Top Bugovac).
Moj PC  
0 0 hvala 0
Nova poruka
E-mail:
Lozinka:
 
vrh stranice