» »

[C] pointer na pointer

[C] pointer na pointer

slovencl ::

Videl sem primere da je funkcija deklarirana kot:
int main(int argc, char **argv)

ali (identično),
int main(int argc, char *argv[])


A je to ista stvar? Zakaj?
  • spremenil: slovencl ()

fiction ::

Polje ni nič drugega kot zvezen kos pomnilnika. Spremenljivka s katero ga deklariraš in opišeš kako velike bodo "celice" (npr. int arr[]) je potem kazalec na začetek (na prvi element). Elementi so pa velikosti sizeof(int). Zato lahko vedno uporabljaš za dostop do i-tega elementa (pri čemer se jasno začne šteti z 0) sintakso arr[i] ali pa *(arr + i).

Vsa razlika pri int *arr je v tem, da je v tem primeru kazalec arr spremenljiv, če deklariraš vse skupaj kot array je pa arr const, ker nima smisla nekje imeti alociran kos pomnilnika in potem pozabiti na njega ter arr uporabiti kot kazalec za kaj drugega. Če deklariraš samo kazalec poleg tega seveda ni avtomatično alociranega pomnilnika, ampak moraš sam poskrbeti za alokacijo na kopici z malloc() ali pa za to, da stvar kaže na neko pametno lokacijo na skladu.

char *argv[] je v praksi čisto enako kot char **argv, samo da je drugo mogoče lažje napisati.

Prvo lahko prebereš kot array kazalcev na znake (po domače array stringov). Point je pomoje samo v tem, da argv ne moreš zlorabiti, da kaže na neko tvojo zadevo, medtem ko v drugem primeru to lahko narediš. Da je potem * in ne še en [] je pa zato ker same stringe pa načeloma lahko še spreminjaš v programu. Seveda ne moreš spreminjati velikosti, ampak lahko pa npr. spremeniš argumente "in-memory" v lowercase ali kaj takega.

Zgodovina sprememb…

  • spremenil: fiction ()

fiction ::

No ok, ker gre za string, se ga dejansko da skrajšati (nekam bolj na začetek napišeš še en ASCII 0 znak). Kar sem mislil povedati je samo to, da moraš za kakšno bolj konkretno spreminjanje sam niz skopirati nekam drugam (v buffer), kjer imaš alocirano malo več prostora.

Zgodovina sprememb…

  • spremenil: fiction ()

fiction ::

Ko smo ravno pri tem. Na Windows in UNIX OS-ih imaš lahko na koncu še:

int main(int argc, char *argv[], char *envp[])

pri čemer envp predstavlja spremenljivke okolja kot nize SPREMENLJIVKA=vrednost.

Na OS X je pa celo:
int main(int argc, char *argv[], char *envp[], char *apple[])

Ko se main() začne izvajati je poskrbljeno, da so te zadeve na skladu, ni pa treba da vse uporabiš, zato dela npr. tudi int main(), int main(int argc) ali pa celo int main(int mesni, char *burek[]) - imena nimajo veze.

Je pa dobro, če je return type vedno int, ker so drugače lahko problemi. Zakaj void main() ni ANSI C?

fiction ::

Ok, sem sprobal par stvari v praksi z gcc in se popravljam: če je parameter funkcije char buf[] je to čisto enako kot char *buf. Ni nobene dodatne "konstantnosti". Ta pride samo če deklariraš spremenljivko z npr. char buf[512]. (Zdaj ne moreš reči buf++) Itak pa bi v vsakem primeru lahko popravljal pomnilnik, kjer so znaki, tako da je tisto kar sem prej napisal neumnost.

const char* p1 oz. char const *p1 pomeni potem to, da ne moreš spreminjati vsebine kamor kaže pointer (*p1 = 'A' je narobe),
char* const p2 pa da sam pointer ne more nikamor drugam već kazati (to je tudi implicitno pri buf).

char *[] == char ** v obeh primerih gre za array char pointerjev aka stringov oz. pri ** pointer na začetek nekega bloka pomnilnika, kjer so char pointerji. Fora je v tem, da so sami stringi lahko na zelo različnih delih pomnilnika, skupaj so samo njihovi naslovi.

char (*)[] je pa pointer na prvi element (array) večdimenzionalnega arraya oz. char [][]. Pri char[M][N] imaš kos pomnilnika velikosti N*M. Zaradi row major indexinga funkciji ne moreš podati argumenta char[][], dela pa char[][N]. Je pa jasno zato char argv[][] narobe, se opravičujem.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[C++] problem z binarnimi datotekami

Oddelek: Programiranje
9862 (727) mallard
»

C (Izračun povprečja)

Oddelek: Programiranje
141517 (1151) joze67
»

C strukture, kazalci naloga pomoc

Oddelek: Programiranje
51385 (1280) DavidJ
»

C osnova

Oddelek: Programiranje
221478 (993) RunoTheDog
»

C - pomoč

Oddelek: Programiranje
111391 (1131) Thagirion

Več podobnih tem