» »

Pointer-ji v C-ju

Pointer-ji v C-ju

rokpok ::

Imam eno vprašanje glede pointer-jev v C-ju. Primer: pregledovanješ nekega vnosa iz ukazne vrstice (command line):

if (**++argv==opt[0] && *++*argv==opt[1] && *++*argv++=='\0') printf ("%s", *argv); //primer

Je smiselno vse te * (in +) uporabljati v eni vrstici, ali pa rajši tvegaš par vrstic več in narediš stvar dosti bolj pregledno? Zanima me tudi, kako počnete vi.

Lp
Rad bi bil pingvin.

hatch ::

Hmm.. ni najbolje..

ti bom dal lepsi primer...

char *szName;

szName = (char*)malloc(20);
sprintf(szName, "blabla");
szName++;
printf("out:%s\n", szName); //bos dobil ven "labla"
free(szName); //tu pa bos dobil napako pri izvedbi... ker si zjebal originalni pointer.. oz morda ti bo na dolocenih sistemih celo potegnilo.. samo memory leak bo pa vseeno

Moras vedno prekopirati originalni pointer in hendlat kopijo...

char *szName;
char *szBuf;

szName = (char*)malloc(20);
szBuf = szName;
sprintf(szName, "blabla");
szBuf++;
printf("out:%s\n", szBuf); //bos dobil ven "labla"
free(szName);

tako pa bo vse vredu... argv je sicer skopiran pointer (vsaj moral bi bit na vseh sistemih).. samo vseeno priporocam da pointerje vedno skopiras preden jih manipuliras.

Zgodovina sprememb…

  • spremenilo: hatch ()

trs ::

sleepy_net: Ti si nor :)) Zakaj ne das enostavno:
if (strncmp(argv[1], opt, strlen(opt) + 1) == 0) ? :)

Uni pointer mumbo-jumbo je zrelo kvecjemu za obfuscated c contest;)

rokpok ::

hatch -> Hvala za nasvet o prekopiranju pointerjev. Ga bom upošteval. Sicer se še nisem kaj pretirano seznanil s funkcijama mallloc() in pa free() , ampak mislim, da razumem point.

trs -> Počutim se kot :8) . Hvala. Še eno vprašanje imam. Obstaja kje kakšen help, z opisi (vsaj tistih osnovnih) headerjev in pa funkcij, ki ji najdeš v njih?

Lp
Rad bi bil pingvin.

trs ::

@sleepy_net

Verjetno v kaki knjigi o Cju so opisane standard C funkcije. Drugace na netu pa ne vem ... pogooglaj malo, pa da vidimo kaj spljune ven ;)

lp,
trs

hatch ::

Sej ubistvu je dobr da delas to s pointerji zdej.. ko se ucis.. bos vsaj vedel kako strcmp deluje.

Samo potem v prakticni uporabi se pa strcmp uporablja.. (ce ne rabis ravno kake specifike.. in se hoces znebit nepotrebnih ciklov)... predvsem pa uporabljamo strcmp in podobne ze narejene funkcije zarad portabilnosti.. (ansi - unicode)... precej olajsajo delo...

pridejo pa pointerji fajn pr kakih bolj simple zadevcah..

naprimer mas neki string.. recimo "filename.txt"... pa hoces dobit samo string do pike.. torej "filename"

char *szFile = "filename.txt";

char *szBuf;
szBuf = szFile;
for (;*szBuf!='\0';szBuf++)
if (*szBuf=='.') break;
*szBuf = '\0';

In imas v "szFile" samo do pike string... seveda pa moras pazit da je vhodni string tudi null-terminated.. je pa uporabno pri kakih casovno kriticnih ciklih kjer se to klice redno.. sploh kake baze podatkov in to... kak strtok (str token), katerega bi lahko uporabil za to, je veliko pocasnejsi.

rokpok ::

No kaj tako lepega kot PHP manual seveda na netu ni, sem pa našel tole:

Klik1
Klik2

Hatch -> kot si rekel. Sedaj, ko se učim, hočem čim več kode napisati sam, da pobliže spoznam, kako deluje. Ko pa se enkrat "vklopim" v C, potem pa bom uporabljal funkcije, ki so že napisane.

Lp
Rad bi bil pingvin.

Zgodovina sprememb…

  • spremenil: rokpok ()

rokpok ::

(da ne bom odpiral nove teme)

Imam en problem:
static char *pattern[]={
	"-n",
	"-u",
	"-a"
};

Kako sedaj ugotoviti, da se v *pattern[] nahajajo tri opcije?
Rad bi bil pingvin.

Zgodovina sprememb…

  • spremenil: rokpok ()

napsy ::

Poskus prebirati za arraya, dokler ne naletiš na NULL oz. '\0'.
"If you die, you die. But when you live you live. There is no time to waste."

OwcA ::

Če se ne motim, s takšno inicilizacijo ne zagotoviš string terminatorja.
Otroška radovednost - gonilo napredka.

CCfly ::

Ne bo šlo napsy. Pri tabeli nizov, lahko da na koncu prazen niz ali pa nek unikaten niz. Še najbolje bi bilo deklarirati en short za dolžino tabele, čeprav ni najbolj elegantno. Tisto kar se pač bolj splača, odvisno od dolžine tabele.

OwcA ::

Povsem generično se v C++ da takole:
template <typename T, int size>
  int array_size(T (&)[size]) 
  { 
    return size; 
  }

Ampak pozor, to deluje samo za v naprej (med prevajanjem) izračunljive argumente.
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

rokpok ::

OwcA: v c-ju pa ne gre? Saj bi lahko dal (kot je CCfly omenil) neko spremenljivko, v kateri bi določil, koliko opcij se nahaja v array-u. Lahko bi tudi naredil takole,
 static char *pattern="-n -u -a"

vendar potem imam spet več dela pri preverjanju/primerjanju teh opcij.

Lp
Rad bi bil pingvin.

Zgodovina sprememb…

  • spremenil: rokpok ()

BigWhale ::

Za unix imas ze cel command line paramteres library... samo par includov naredis, pa je problem resen... Hyummm, ko bi se zdaj spomnil knjiznjice...

OwcA ::

V C-ju ne gre s kalupi, seveda so tudi drugi načini. Verjetno je CCflyev še najelegantnejši.
Otroška radovednost - gonilo napredka.

CCfly ::

Saj generično programiranje v C++ je fantastična zadeva ampak če imaš eno ubogo tabelo je skoraj škoda komplicirati. Če delaš knjižnico pa zelo verjetno ni bolj fleksibilne stvari kot šablone v C++.

Za command line bi ti tole pomagalo: http://argtable.sourceforge.net/.

rokpok ::

CCfly -> hvala za link.
Rad bi bil pingvin.

trs ::

char *pattern[] = {
"-a",
"-b",
"-c"
};

To se da cisto lepo ugotovit kolko je nizov not brez templateov in podobnih abominacij.

sizeof(pattern) / sizeof(pattern[0]) -> 3

Vendar to deluje samo za staticne array, za dinamicne ... je treba naredit tako kot pravi CCFly.

CCfly ::

sizeof(pattern) / sizeof(pattern[0]) -> 3

Ugly. I like it !
Kaj pa če po naključju sistem ne dodeli pomnilnika za tabelo zaporedno ?

trs ::

CCFly ne vem kaj mislis s tem zaporedno. Tisto ti samo preracunas kolko je velika tabela pointerjev, nic vec nic manj. Tabela pa je zmeraj zaporedno alocirana ;)

In je malo ugly, vendar ni drugega nacina. Sicer pa se vedno lahko vrzes macro cez

ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

lp,
trs

CCfly ::

Kolikor vem je alokacija pomnilnika v tem primeru OS specific zadeva.

trs ::

CCFly

Ta trik se zanasa na to, da C compiler ve kolko je sizeof(array). Nima veze tle alokacija. Enostavno delis velikost celega array v bytih z velikostjo enega elementa v bytih. In dobis ven kolko je stevilo elementov ;)

CCfly ::

Ups zafrknil sem. Lapsus. Jaz sem razmišljal o inkrementaciji kazalcev za dostop do elementov tabele.

rokpok ::

Še en problem:
 
static char *ime[] = {
	"janez",
	"jože",
};
int main (void) {
	char **iBuf;
	nekaj (tukaj mora biti pot do iBuf pa nevem kako);
	printf ("%s", *iBuf);
	return 0;
}
void nekaj (pot do iBuf) {
	pot do iBuf=ime;
}


Upam, da je iz kode razviden problem

Lp
Rad bi bil pingvin.

OwcA ::

Dopušča,, da sem naivna duša, ampak:
char **iBuf = ime;
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

rokpok ::

Ja, ampak jaz bi rad to naredil s funkcijo nekaj(). Problem pa je to:
nekaj (tukaj mora biti pot do iBuf pa nevem kako);
Rad bi bil pingvin.

OwcA ::

Aja, potem pa
void nekaj(char ***p)
{
  *p = ime;
}
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

rokpok ::

Tako sem naredil, vendar ne dela, oziroma kaj pa potem napišem, kjer kličem funckcijo?
nekaj(iBuf); //ne dela
nekaj(&iBuf); // ne dela
Rad bi bil pingvin.

OwcA ::

Saj res. Dodaj še eno zvezdico, dereferenciraj kazalec (sem popravil prejšni primer) in pošlji funkciji naslov.
Otroška radovednost - gonilo napredka.

rokpok ::

To pa ja. Hvala OwcA.
Rad bi bil pingvin.


Vredno ogleda ...

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

[C++] problem z binarnimi datotekami

Oddelek: Programiranje
9861 (726) mallard
»

C strukture, kazalci naloga pomoc

Oddelek: Programiranje
51385 (1280) DavidJ
»

[C/C++] pointerji in reference

Oddelek: Programiranje
111942 (1766) Matako
»

[c++] prenos po referenci

Oddelek: Programiranje
92432 (2367) atasmrk
»

Coding Style

Oddelek: Programiranje
433306 (2498) 64202

Več podobnih tem