Portál AbcLinuxu, 30. dubna 2025 22:51
int * pole_int; char * pole_char; pole_int = malloc(100 * sizeof(char)); // A kurna, spletl jsem se ale kompilator to zbastil, chtel sjem pole char.
pole_int = malloc(100 * sizeof(*pole_int));
A při nějakém dalších zásahu do zdrojáku změníte proměnnou a jste někde.
V tom je rozumnější C++ s jeho operátorem new, který je dokonale typové a s jeho zákazem automatického přetypování void *.
pole_int = new int[100]; je nepřekonatelné, zkontroluje se typově úplně všechno
případně
template<typename T>
T* typed_malloc(::std::size_t count)
{
return reinterpret_class<T*>(::std::malloc(sizeof(T) * count));
}
A následně
pole_int = typed_malloc<int>(100);
Dokonce i funkce memcopy, memset, memcmp a další je možné obalit do šablony, takže se stanou dokonale typovými.
Základem programování není trikovat. To se pozná až po několika letech vytáhnete svůj zdroják a máte do něj významně zasáhnout - opravit chybu, předělat chování a přidat nové vlastnosti.
Pokud i dnes jsem nucen zasáhnout do C kódu, přemýšlím jak kód udělat jasný a pokud možno odolný proti chybě i programátorově překlepu. Kašlu na nějakou módu jak se to píše - jde mi o praktičnost.
#define DYN_ARRAY(var, type, size) type *var = malloc(size * sizeof(type)) DYN_ARRAY(pole_int, int, 100);
A při nějakém dalších zásahu do zdrojáku změníte proměnnou a jste někde.Málokdy můžu něco takového napsat, ale... to se mi nestává. Používám ve vimu search&replace a ještě k tomu vždy po řádcích.
V tom je rozumnější C++ s jeho operátorem new.Porovnání s new je úplně nové téma, nikde jsem nepsal, že by se mi operátor new nelíbil. Nicméně příklad od Stena je taky hezký.
Pokud i dnes jsem nucen zasáhnout do C kódu, přemýšlím jak kód udělat jasný a pokud možno odolný proti chybě i programátorově překlepu. Kašlu na nějakou módu jak se to píše - jde mi o praktičnost.Což přidáním úplně zbytečného přetypování člověk rozhodně nedocílí. Ale tenhle názor už jsem tu myslím dal najevo dostatečně, takže pokud nemáš opravdu pádný argument (jakože nemáš), tak nemá smysl se v tom pitvat. Aneb, kecy nemaj cenu.
pnaint = (int *) malloc(POCET * sizeof(int));
Dvě poznámky:
1) malloc vrací void*
, ten se castuje implicitně. Explicitní cast z void*
je ošklivý C++-ismus.
2) Je lepší použít sizeof(*pnaint)
než sizeof(int)
, protože se to nerozbije když změníš typ.
Je až dojemné, jak programátoři dávají přednost nenávisti k C++ před fungujícím řešením a vyšší kontrolou chyb v programu.Je až dojemné, jak někdo dokáže vyplodit takovou myšlenku a ještě se přitom dojmout.
My ze staré školy...My, král programátorů, ředitel zeměkoule...? :)
Nenašel jsem bohužel v příspěvku ani jeden jediný bit informace či nějakého konkrétního argumentu.Přesně toto je můj pocit z tvého předchozího příspěvku.
Proč ty invektivy?Jaké?
Já s názory Miloslava Ponkráce na programování bez výhrad souhlasím.No jo, a jiní je zase považují za hluboce pomýlené
Já se snažím při programování postupovat podobně - mám-li prostředek, který mě dovede pohlídat, budu jej používat a budu se snažit mu ulehčit práci.To se někdy hodí, jindu zase takový prostředek ve výsledku přidělá daleko víc práce, než jí ušetří. Typický příklad je warning na "if (a=b)" – prakticky žádný zkušenější Céčkový programátor omylem "=" místo "==" do podmínky nenapíše, ale nejeden z nich připisuje závorky navíc, aby hloupý warning umlčel.
Typický příklad je warning na "if (a=b)" – prakticky žádný zkušenější Céčkový programátor omylem "=" místo "==" do podmínky nenapíše, ale nejeden z nich připisuje závorky navíc, aby hloupý warning umlčel.Možná nenapíše, ale při hledání, proč se hodnota a mění, když to nečekám, ty závorky navíc hodně pomůžou
int (*pole)[POCET1]; pole = malloc(POCET2 * sizeof(*pole));Tenhle zápis má výhodu v tom, že se používá jenom jeden ukazatel, což je na moderních počítadlech o hodně rychlejší. Jestli je to C++-izmus, tak mě prosím nekamenujte
Je třeba zdůraznit, že ukazatel je vždy "na něco", tedy ukazatel naTo není pravda, můžeš mít klidněint
, ukazatel nachar
apod.
void *p;
aneb polymorfismus á la C malloc()
alokuje paměť vždy na adrese zarovnané na násobek 16 a pokud se neuvede pragma pack
/u GCC __attribute__((__packed__))
, tak to dělá i u prvků struktur. To, že má ukazatel typ, ovlivňuje i to, jak s ním překladač zachází (tedy měl by, jak moc jsem v praxi jsem to netestoval).
sc_path_print(pbuf, sizeof(pbuf),(sc_path_t *) &(env->file_ref));O co jde? Máme (pointer na) strukturu, která obsahuje prvek file_ref typu sc_path, ale potřebujeme (pointer na) sc_path_t, přiznám se, že jsem nepochopil proč, ty struktury jsou obě shodné. Každopádně pomocí -> z env vytáhneme to file_ref, které ovšem není pointer, takže & a tento pointer přetypujeme na pointer na sc_path_p...
typedef struct sc_path { /*...*/ } sc_path_t;..., a ten
file_ref
je definován jako struct sc_path file_ref
, tak je tam to přetypování opravdu k ničemu a musí to fungovat i bez něj:
sc_path_print(pbuf, sizeof(pbuf), &env->file_ref);
*
má v C a C++ tři různé role, v praxi se ale v 99% nestane, že by se pletly...
to by nedavalo pak smysl (neni to Perl)
Další obvyklou konstrukcí je přetypovávání void pointeru. Například takové MS CryptoAPI má spoustu funkcí, které dostanou void pointer a číslo. Podle číselné konstanty poznají, co by volající chtěl a to mu do pointeru uloží. Takže jednou je to pointer na strukturu x, podruhé y a těch možností je třeba 50.To jako vážně? Humus. V c++ toho dělám poměrně dost, ale na tyhle konstrukce v podstatě nenarážím (qt).
void MUJOBJEKT::event(QEvent *e) { switch(e->type()) { case QEvent::KeyPress: // přetypovat QKeyEvent *ke = dynamic_cast<QKeyEvent *>(e); if (ke->key() == atd atd) } }můžu velmi snadno napsat i takto:
void MUJOBJEKT::keyPressEvent(QEvent *e) { if (e->key() == atd atd) }Zlaté C++
int
), příkaz (int
) a (nepovinný) ukazatel (void *
, i když historicky to býval char *
), zbytek je na programátorovi.
ioctl()
.
Na C a C++ je sympatické, že prakticky vždy je z datového typu jasné, s čím vlastně pracujete. Dělá se mi zle například z Javy, kde ukazatele neexistují, ale parametry se předávají někdy ukazatelem, jindy hodnotou, a programátor to má šanci vyčíst pouze z dokumentace.WTF?
void funkce(Objekt*); // předávám ukazatel void funkce(Objekt&); // předávám referenci void funkce(Objekt); // předávám hodnotuJava:
public void funkce(int i) // předávám hodnotu i=i+1; // nemá vliv na volající objekt } public void funkce(String s) // předávám ukazatel s="pojapený nesmysl"; // rozhodí volající objekt }Stejný zápis, pokaždé však znamená něco diametrálně odlišného. Co se kdy předává hodnotou a co ukazatelem musím vědět, nebo vyčíst z dokumentace, zdrojový tvar mi nijak nenapoví. Javu nemám v oblibě i z mnoha jiných důvodů, používám ji málo. A proto, když už do Javy vlezu, nechávám se často nachytat právě takovými detaily, které se zapisují sice stejně, ale podle kontextu dělají různé věci. Neberte mě úplně za slovo, nevím, jestli se funkci funkce(String) předávají parametry ukazatelem, nebo hodnotou. Podívejte se do dokumentace.
public void funkce(String s) // předávám ukazatel
s="pojapený nesmysl"; // rozhodí volající objekt
}
Na to neviem kde ste prisli, je to nezmysel, s v tele tej metody sa zmeni, nema to vsak vplyv na povodny parameter.
Objekt A; A = new Objekt(); funkce(A); static void funkce(Objekt x) { x.property = "xyz"; // přepisuji A, protože x je pouze ukazatel }je přesně totéž, jako v C++
Objekt *x; x = new Objekt(); funkce(x); static void funkce(Objekt *x) { x->property = "xyz"; }Java operátorem new vytváří ukazatel a ten pak - přesně podle příručky - předává hodnotou. Java se vůbec neunavuje programátora informovat, kdy používá hodnotu a kdy používá ukazatel. Ukazatele přece v Javě nejsou, aspoň to tak psali v příručce, tak proč tam ještě navíc nenapsat, že parametry se předávají vždy hodnotou! V C a C++ je jasno vždy - s hvězdičkou ukazatel, bez hvězdičky hodnota.
V C a C++ je jasno vždy - s hvězdičkou ukazatel, bez hvězdičky hodnota.V C++ žel nikoliv, předávání referencí je potvora :)
Java operátorem new vytváří ukazatel a ten pak - přesně podle příručky - předává hodnotou. Java se vůbec neunavuje programátora informovat, kdy používá hodnotu a kdy používá ukazatel. Ukazatele přece v Javě nejsou, aspoň to tak psali v příručce, tak proč tam ještě navíc nenapsat, že parametry se předávají vždy hodnotou!Co je to zase za nezmysel? Prestudujte si to este raz a poriadne. V Jave je kazda objektova premenna referenciou na instanciu daneho objektu - "ukazatel". V pripade predavania parametrov sa tato premenna skopiruje, stale vsak odkazuje na instanciu povodneho objektu.
Java vzdy predava parametre hodnotou. Aj primitivne typy, aj referencie na objekt - su skopirovane.Máte v tom vůbec jasno? Máte představu o tom, jak je v počítači implementovaný ukazatel a hodnota?
funkce(int x) // předává se hodnotou funkce(Int x) // předává se odkazemJiný datový typ, stejný zápis, naprosto odlišný způsob předávání parametru.
Vypovídá to o návrhu jazyka hodně. Já se jako programátor můžu splést a přepsat se - použít Double místo double. To se mi stává denně. V C++ takový omyl neprojde. V Javě takový omyl ladím celou noc.Možná by nebylo na škodu poohlédnout se po jiném zaměstnání. Tohle jsou problémy studentů z úvodních kurzů programování.
Možná by nebylo na škodu poohlédnout se po jiném zaměstnání.Mozna bylo. Sam jsem v situaci, kdy musim pro zamestnavatele delat veci, v kterych jsem zacatecnik, protoze on v podstate nema moc na vyber (a i tak je spokojeny).
Vypovídá to o návrhu jazyka hodně. Já se jako programátor můžu splést a přepsat se - použít Double místo double. To se mi stává denně. V C++ takový omyl neprojde. V Javě takový omyl ladím celou noc.Odolám pokušení říct něco jedovatého, takže jen pro informaci:
void do1(double d) { d = 10.0; } void so2(Double d) { d = 12.0; } void test() { double d1 = 1.0; Double d2 = 2.0; do1(d1); do1(d2); do2(d1); do2(d2); System.out.println(d1); System.out.println(d2); }Vypíše 1.0 a 2.0 Nejsem si zcela jistý proč tady dolik lidí píše že autoboxing je problém, ale s největší pravděpodobností naráží na problém s porovnáváním (operátor ==). Ten opravdu nefunguje u wrapperů dobře, ale nemá to naprosto nic společného s předáváním parametrů. V C# tento problém není a programátor ani nemusí vědět že tam nějaký boxing a autoboxing je. Groovy dtto. A to ani nezačnu o "dynamických" jazycích, kde je toto od začátku míněno jako implementační detail.
Ano. Zrovna porovnávání chování referencí/ukazatelů v C++ a předávání v Javě jsem měl u státnic.
//C++ void metoda(Typ* obj) { obj->neco = 5; // projevi se u volajiciho obj = new Typ; // neprojevi se u volajiciho } // Java - bude se chovat identicky void metoda(Typ obj) { obj.neco = 5; // projevi se u volajiciho obj = new Typ(); // neprojevi se u volajiciho }
Snad to trochu pomohlo objasnit. Z tohoto je pak jasné, že když v Javě napíšete
// arg je String arg = "abcdef"
tak to odpovídá něčemu jako
// arg je std::string* arg = new std::string("abcdef");
Ještě je nutné říct, že boxované typy v Javě jsou stejně jako řetězce neměnné. Takže když člověk přiřadí do Integeru novou hodnotu, vytvořil tím nový objekt, tudíž se to u volajícího neprojeví.
Nejspíš je myšleno Integer. Opět se to oboje předává hodnotou, protože Integer x je reference na objekt a int x je primitivní typ.funkce(Int x) // předává se odkazem
public class a { static void funkce(Integer x) { x = 5; } public static void main(String args[]) { Integer x = 4; funkce(x); System.out.println(x); } }Vypíše se 4 a ne 5.
public class Test {
public static void main(String [] args) {
Integer i = null;
t2(i);
System.out.println(i);
}
public static void t2(int i) {
i = 10;
}
}
Exception in thread "main" java.lang.NullPointerException at Test.main(Test.java:8)V zlozitejsom kode, kde sa autoboxuje hore dole z Integeru na int a naspat a niekde tam prebuble null moze byt celkom blbe hladat chybu.
Integer a = 10000; Integer b = 10000; System.out.println(a == b); // hodnota reference a se liší od hodnoty reference bVýstup na openjdk 1.7 je false (může se to lišit podle implementace, protože instance třídy Integer můžou být cachované). Ale tohle je klasický případ programu co dělá to co programátor napsal a ne to co chce napsat.
No to je právě ten problém... "equals" je pro něco tak často používaného jako porovnání hodnoty dvou čísel tak nepohodlné, že každý píše "==", kdykoliv mu to projde.Každý určitě ne. Asi neexistuje jazyk, který by neměl svá, nováčky matoucí, specifika. Alespoň mírně zkušenější java programátor by ovšem == místo equals prostě nenapsal.
(Nehledě na to, že používat u jazyka se syntaxí založenou na Céčku "==" k něčemu jinému než k porovnání hodnot, je vrchol nevkusu.)Nemůžu si pomoct, ale v C dělá operátor == to samé co v Javě.
Nemůžu si pomoct, ale v C dělá operátor == to samé co v Javě.Nedělá. Pokud mám v C dvě čísla, tak operátor
==
porovná jejich hodnoty. V Javě mám čísla, kde porovnává hodnotu, a jiná čísla, kde to nedělá.
Já bych to zkusil rozepsat, ať zjistíme v čem se mýlím (Pozn. budu brát jak velikost int tak velikost ukazatele 4B).
V C:
1) int i1 = 3; //Lokální proměnná velikosti 4B (do těch se uloží hodnota 3) int i2 = 4; //Lokální proměnná 4B (uloží se 4) i1 == i2; //Dej na stack 4B co patří i1, pak dej na stack 4B co patří i2, porovnej dvě poslední hodnoty na stacku. 2) struct neco *s1 = ...; //Lokální proměnná velikosti 4B, je to jen reference (uloží se do nich hodnota alokované adresy) struct neco *s2 = ...; //To samé s1 == s2; //Dej na stack 4B co patří s1, pak dej na stack 4B co patří s2, porovnej dvě poslední hodnoty na stacku. 3) struct neco s1; //Lokální proměnná o velikost sizeof(struct neco) struct neco s2; //To samé s1 == s2; //error
V Javě:
1) úplně stejné jako v C. 2) Integer i1 = 3; //Vytvoří se instance třídy Integer a ta se uloží na heapu. i1 je zase jen reference - všechno je pointer, proto se ani nepíše. i1 je vlastně zase jen 4B adresa. Integer i2 = 4; //To samé i1 == i2; //Dej na stack 4B co odkazují na objekt i1, pak dej na stack 4B co odkazují na objekt i2, porovnej dvě poslední hodnoty na stacku. 3) nemožné zapsat
Já tam ten rozdíl prostě nevidím.
int i = abs( 2 + 1 / 2);zatimco:
BigDecimal i = ( BigDecimal(2).add(BigDecimal(1)).divide(Bigdecimal(2)).abs();Numrika v Jave je peklo. PS: ty dva priklady jsou zamerne neekvivalentni.
Primitivni datove typy (ty co zacinaji malym pismenem) jsou vyjimka.A jak znamo, bez podpory vyjimek by neslo o ten spravy objektovy jazyk.
boolean isEqual(Object first, Object second) { return first == second; } String a = "A"; isEqual(a, a); // == false nebo true, podle implementace
x == y
je true, pokial odkazuje na instanciu rovnakeho objektu.
Operator == oznacuje shodu referenci, zatimco pro "ekvivalenci" instanci objektu se pouziva metoda equals.Takže chápu to správně, že pro porovnání hodnoty nemá Java jazykový prostředek, pouze konvenci?! ... To je tedy velmi vtipný jazyk, jak tak na to koukám
V C a C++ je jasno vždy - s hvězdičkou ukazatel, bez hvězdičky hodnota.Dokud se nenajde chytrák co udělá
typedef void* gpointer;
a tvrdí, že
An untyped pointer. gpointer looks better and is easier to use than void*.
easier to use
. Jediné co přináší je obfuskace -- ta hvězdička není vidět. Ale pořád si musíš pamatovat, že tam je.
libpng
to tak má. Pointa mi ale uniká... Asi se někomu nechtěj psát hvězdičky.
struct neco *a, b; // b není pointer typedef struct neco* p_neco; p_neco a, b; // b je pointerBtw. proto píšu hvězdičku k tomu, k čemu se vztahuje, u typedefu ke struktuře, u proměnných k proměnným.
Obzvlášť když ten pointer stejně mívá prefix nebo suffix „p“ nebo „p_“Hungarian notation sa urcite nepouziva vsade
ta hvězdička není vidětMno já nevím, já si vždycky myslel, že ta hvězdička v C znamená pointer. A že by slovo pointer v názvu gpointer nebylo vidět... není to spíš problém očí?
integer.toString()
a podobně), určitě by se to dalo nějak vhodně syntakticky pocukrovat.
Nizkourovnove ako aj hociake ine operacie mozes implementovat objektovo, nevidim dovod preco nie.No, tak nejsem si jist, jestli vidím důvod, proč ano. No ale dejme tomu, já v zásadě nejsem proti, pokud se to napíše rozumně - čili tak, aby ty objektové vlastnosti byly pouze asociovány s tím samým primitivním intem, oproti návrhu, kdy vytvářejí okolo primitivních typů vrstvu, to je akorát bloat.
nemoznost mat hodnotu nullNo to je snad dobře, ne? Možnost null mi u integeru přijde zbytečná obtíž. Ona je to teda zbytečná obtíž i u objektů obecně, což je důvod, proč se v C++ na null nehraje...
Co je ve skutečnosti potřeba jsou nullable a non-nullable typy. Nullable v případě, že potřebujeme vyjádřit singulární situaci "aktuální hodnota není známá". Magické konstanty (typicky oblíbená -1) nejsou řešení.nemoznost mat hodnotu nullNo to je snad dobře, ne? Možnost null mi u integeru přijde zbytečná obtíž. Ona je to teda zbytečná obtíž i u objektů obecně, což je důvod, proč se v C++ na null nehraje...
Co je ve skutečnosti potřeba jsou nullable a non-nullable typy. Nullable v případě, že potřebujeme vyjádřit singulární situaci "aktuální hodnota není známá". Magické konstanty (typicky oblíbená -1) nejsou řešení.null je celkove kontroverzni zalezitost a nechtel bych do toho zabredavat. Nicmene, zavedeni ,,null'' jako nedefinovane hodnoty je de facto stejny hack, jako zavedeni magicke konstanty.
null
může být pořešené na úrovni typového systému, toho s magickými konstantami nedosáhneš. Problém je v tom může být… ono totiž často není sin
(i když abs
bych skousnul), ale například je půjde cpát do kolekcí (konkrétně v Javě).
const
a goto
jsou klíčová slova, jejichž libovolné použití je syntakticky špatně Takze kolko krat je este treba zvyraznit, ze primitivne su hodnotove, vsetky ostatne referencne?Však ano, ale problém je v syntaxi, která tento rozdíl zamlčuje. Jsou v zásadě dvě možnosti, jak tuto situaci rozumně vyřešit: buďto explicitně rozlišovat mezi referencí a hodnotou (což dělá Céčko), nebo naopak přiblížit chování primitivních typů těm objektovým a nemíchat různé typy rovnosti (viz třeba Perl6).
Tu zatvorku nechapem, ktorych klucovych slov je lubovolne pouzitie syntakticky korektne?Ve slušné společnosti má každé klíčové slovo aspoň jedno syntakticky korektní použití. V Javě ho ani
const
, ani goto
nemají.
Referenční typy jsou v Javě pole a objekty (instance tříd). V místě deklarace proměnných (tedy i parametrů) se rozdíl mezi primitivním a referenčním typem pozná snadno – za typem pole jsou závorkyTakze kolko krat je este treba zvyraznit, ze primitivne su hodnotove, vsetky ostatne referencne?Však ano, ale problém je v syntaxi, která tento rozdíl zamlčuje.
[]
, třídy zase z konvence začínají velkými písmeny. V místě použití… hmm, a fakt to tolik vadí? S výjimkou toho šíleného auto(un)boxingu, kde může spadnout shůry NPE, bych řekl, že to není problém.
Ovšem souhlasím, že primitivní typy by bylo nejlepší vykopat (a s nimi spoustu dalších věcí).
Referenční typy jsou v Javě pole a objekty (instance tříd). V místě deklarace proměnných (tedy i parametrů) se rozdíl mezi primitivním a referenčním typem pozná snadno – za typem pole jsou závorky [], třídy zase z konvence začínají velkými písmeny. V místě použití… hmm, a fakt to tolik vadí?Presne tak.
Ovšem souhlasím, že primitivní typy by bylo nejlepší vykopat (a s nimi spoustu dalších věcí).Hromada tech veci je dana historicky a nejde s tim nic moc delat, ale myslim, ze Java je na tom jeste docela v pohode. V C# je tech zverstev daleko vic, napr. class vs. struct, modifikatory argumentu out/ref, ... a osobne si myslim, ze i pretezovani operatoru je zlo
a osobne si myslim, ze i pretezovani operatoru je zloNo počkat, zbavení se primtivních typů by bez přetěžování operátorů vůbec nešlo. Jakpak bys bez něj nadefinoval třeba operátor + pro (objektové) integery? Leda by se definice operátoru + svázala s nějakým konkrétním typem nějaké konkrétní knihovny a to mi přijde jako vyloženě blbej nápad...
list($var1, $var2) = funkce_vracejici_dvouprvkove_pole()
t = (x,y,z) # vytvoreni tuple t ... x,y,z = t # unpacking tuple t do promennych x,y,zSpecialne pak v Pythonu:
a,b = b,a # prehodi a a bV obecnejsi podobe tohle umi (Common) Lisp a rika se tomu destructuring.
t = 1, 3, 5 # ulozi do promenne t tuple (1, 3, 5) x, y, z = t # rozbali tuple do promennych x, y, z a, b, c = 1, 2, 4 # ulozi a=1, b=2, c=4 a, b = b, a # prohodi a s b a, b, c = b, c, a # rotuje a, b, c podil, zbytek = divmod(7, 3) # ulozi do promennych celociselny podil # a zbytek, pricemz delenec je 7 a delitel 3
Python (bohužel) neznám, ale moc se mi líbila syntaxe v PHP, kde šlo napsat něco jako:Python je v tomhle přirozenější, viz níže.
A je to problem? Pokud by to bylo striktne takhle (primitivni typy predavane hodnotou, vse ostatni referenci), tak to je IMHO konzistentni, protoze na hodnoty primitivnich typu[1] lze nahlizet jako na referenci na 'idealni immutable objekt' (ktery je navic jednoznacny pro kazdou hodnotu), a tedy pro ne neni rozdil mezi predavanim hodnotou a referenci [2]. [1] takhle se bezne chovaji primitivni typy, ale obecne lze toto chovani rozsirit i na jine 'immutable' objekty, ve Scheme se tak treba chovaji i symboly a bignumy. [2] samozrejme je treba rozlisit mezi predavanim reference na (realny ci idealni) objekt a predavanim reference na promennou/cell, kde je ta reference na ten objekt.Takze kolko krat je este treba zvyraznit, ze primitivne su hodnotove, vsetky ostatne referencne?Však ano, ale problém je v syntaxi, která tento rozdíl zamlčuje.
[1] takhle se bezne chovaji primitivni typy, ale obecne lze toto chovani rozsirit i na jine 'immutable' objekty, ve Scheme se tak treba chovaji i symboly a bignumy.V Javě je typický příklad String.
Ve slušné společnosti má každé klíčové slovo aspoň jedno syntakticky korektní použití. V Javě ho aniTo mi divne neprijde. Co je na tom divne je spis to, kdyz uz mit v jazyce rezervovana klicova slova, ktera (zatim) nemaji semanticky vyznam, proc nerezervovat nekonecnou mnozinu spis nez 2-prvkovou.const
, anigoto
nemají.
Je to předávání hodnotou, akorát někdy je ta hodnota typu "ukazatel".Kterýžto typ mimochodem údajně v Javě neexistuje a údajně je to jedna z jejích hlavních výhod oproti C/C++.
Že tam chybí hvězdička? V C být nemusí, viz uváděný gpointer.Souvislost s hvězdičkovou syntaxí mi zcela uniká.
Typ ukazatel v ponimani Cecka v Jave skutocne NEEXISTUJE. To, ze sa to tu obcas v uvodzovkach objavi, na tom nic nemeni. Ukazatel v cecku ma definovanu ukazovatelovu aritmetiku, pricom nic take v Jave neexistuje. V Jave je kazda premenna s vynimkou primitivnych typov referencnou premennou, tzn. odkazuje na instanciu nejakeho objektu a to je asi tak vsetko co ma spolocne s ukazatelom v Cecku.Je to předávání hodnotou, akorát někdy je ta hodnota typu "ukazatel".Kterýžto typ mimochodem údajně v Javě neexistuje a údajně je to jedna z jejích hlavních výhod oproti C/C++.
tzn. odkazuje na instanciu nejakeho objektuTo mimochodem odkazuje i obyčejná „hodnotová“ proměnná v C nebo C++, jak dokazuje i operátor &.
V cecku operator & vracia adresu v pamati.Thank you, Captain Obvious.
Snad uznate, ze v Jave nic take nebude mozne.Thank you, Captain Obvious.
Přidal jsem do digestu.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.