Portál AbcLinuxu, 30. října 2025 09:42
V případě ukazatelů na struktury existují dvě možnosti, jak přistupovat k položkám struktur:Jsem jediný, komu chybí(*p).xnebo pohodlnějšíp->x
p-->x (ekvivalent zmíněného (*m)->rows → m-->rows)? Šlo by na to napsat makro?
m-->rows se parsuje jako (m--)->rows a asi by mi i víc smyslu dávalo m->>rows. Pocit chybějícího operátoru mám spíš u konstrukcí typu (*p)[idx]
protožem-->rowsse parsuje jako(m--)->rows
Oprava: mělo tam být "…jako (m--) > rows".
děte si mršit c++ jóóó??? :O >:C
jestli to teda eště jako nějak víc de :D :D ;D ;D
Ukazatel je špecialná premenná, ktorá pracuje s adresami.
const (hlavně ten nekonstantní pointer ukazující do string literal) nebo zbytečné přetypovávání pointerů vracených malloc().
.
Kromě chybějících const všude možně (například strlen v základní knihovně a všechny ostatní mají u vstupních proměnných všude consco se prakticnosti tyce bych mel jednu pripominku: kvuli tem miliardam dotazum na internetu, jak to s tim const hlavne u tech pointru na char vlastne je, jsem toho nazoru, ze my, kteri jsme s K&R zacinali se bez tech const dost dobre muzeme obejit. To ze me ten const u strlen-funkce ubezpecuje, ze ta funkce ten string pri zjistovani te delky nezmeni mi nijak zvlast nevzrusuje a ani neuklidnuje, nas starsi by v zivote nenapadlo, ze by nekdo mohl napsat funkci, ktera by to delela.
Taky bych se vsadil, ze 99,99% C-programatoru by nedokazalo z fleku napsat tu deklaraci toho nemeneho pointru na ten nemeny retezec. (ja bych to tedy nedokazal
)
Dlouho se rikalo, ze to const muze urychlit program. Na netu je rada clanku, ktere to vyvraci.
co si funkce dělá s parametrem vevnitř (kopií proměnné předávanou volajícím), mi může být ukradenéNóóó... úplně jedno to taky není, z tohohle důvodu byl přidán
restrict, kterým se vývojář zaklíná, že nebude vytvářet aliasy (kopie pointerů apod.), což umožňuje optimalizace přístupu do paměti / lepší cachování...
(Je to tak trochu směrem, kterým šel Rust, kde jsou pravidla aliasingu ještě o dost striktnější a jejich dodržování tvrdě vymáháno kompilátorem, v C jde jen o optimalizační hint a kompilátor maximálně háže warningy. Paradoxně Rust aktuálně ten optimalizační potenciál nevyuživá, protože v LLVM to je rozbité
)
printk() v jedné funkci modifikoval data, která ta funkce vůbec neměla co měnit - a která za určitých okolností byla opravdu read only. Kdyby tam byl const, tak by ho chyba při překladu hned trkla, že dělá něco špatného, a řešil by to jinak (nebo by tam ten ladící příkaz vůbec nedal).
Výrazy s poli a indexy jsou ekvivalentní výrazům s ukazateli a posunem, tudíž je možné napsat pole a[i] jako *(a+i)Můžeš to napsat i jako
i[a] ... kolegové to jistě ocení
Nicméně výrazy jakoNo, proměnná to je, ale to přiřazení neprojde, protože, AFAIKa=paneboa++nejsou správné, jelikož jméno pole není proměnná.
IMHO nejnázornější příklad ukazující, že pole a pointer opravdu není totéž (i když to spolu úzce souvisí), je
T *ptr;
T array[10];
printf("%zu, %zu\n", sizeof(ptr), sizeof(array));
void boo(char *bar) {…}
Pointer a polia su to iste.Ne, nejsou, jsou to různé datové typy.
Rozdíl tam bude, protože v prvním případě "Nazdar" bude globální konstanta, která v závislosti na kompilátoru může být i v read only sekci. Navíc překladač může dělat i taková kouzla, že např.
char *str1 = "Nazdar"; char *str2 = "zdar";
použije jen jeden řetězec "Nazdar" a druhý pointer nechá ukazovat do něj. To je možné právě díky tomu, že string literal je automaticky only. Proto je v takovém případě lepší použít const, aby vás překladač varoval, pokud byste ho zkusil přepisovat.
Oproti tomu to druhé je inicializace lokálního pole znaků, které je defaultně přepisovatelné. V praxi ale samozřejmě závisí na zbytku kódu, co s tím řetězcem dělá, protože po optimalizaci tam ve skutečnosti žádný string "Nazdar" nikde být ani nemusí.
<flame-war> Chápu, že článek se věnuje C a ne C++, ale to jsem vážně jediný, komu vadí psát tu hvězdičku k názvu proměnné a kdo by ji psal raději k typu? </flame-war>
Tohle je bohužel věc, která je navržená dost nešťastně. Na jednu stranu je pravda, že psát hvězdičku k typu je logičtější, hlavně když je tam inicializace:
T *p = &x; // kam že to tu adresu přiřazujeme? T* p = &x; // tady je to jasné, do p
Jenže problém nastává u vícenásobných deklarací:
T* p, x; // tohle vypadá, jako by p a x měly stejný typ T *p, x; // ale mají ho *p a x T* p, *q; // a kam napsat tu druhou hvězdičku tady?
Osobně se ale těm násobným deklaracím s pointery snažím vyhýbat.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.