BF Summer sales
Pouze tento týden sleva až 80 % na HTML & CSS a JavaScript
80 % bodů zdarma na online výuku díky naší Letní akci!

Lekce 1 - Úvod do ukazatelů (pointerů) v jazyce C

Vítejte u první lekce pokročilého kurzu o programování v jazyce C. V tomto kurzu se naučíme pracovat s dynamicky alokovanou pamětí v jazyce C a dostaneme se také k práci se soubory. Asi vás nepřekvapí, že předpokladem ke zdolání seriálu je znalost základních konstrukcí jazyka C.

Adresy v paměti

Když jsme se poprvé zmiňovali o proměnných, říkali jsme si, že proměnná je "místo v paměti", kam si můžeme uložit nějakou hodnotu. Také víme, že proměnné mají různé datové typy (např. int) a ty zabírají v paměti různě místa (např. int zabírá 32 bitů, tedy 32 nul a jedniček).

Paměť počítače si můžeme představit jako dlouhou (téměř nekonečnou :) ) řadu nul a jedniček. Některé části paměti jsou obsazené jinými aplikacemi a některé jsou operačním systémem chápány jako volné místo. Aby se dalo s pamětí rozumně pracovat, je adresována, jako jsou např. domy v ulici. Adresy se většinou zapisují v šestnáctkové soustavě, ale stále se jedná o obyčejná čísla. Adresy jdou chronologicky za sebou a na každé adrese se nachází 1 bajt (tedy 8 bitů, protože adresování po drobných bitech by bylo nepraktické).

Jakmile v céčku deklarujeme nějakou proměnnou ve zdrojovém kódu a aplikaci spustíme, Céčko si řekne operačnímu systému o tolik paměti, kolik je pro tuto proměnnou třeba. Od systému získá přidělenou adresu do paměti, na kterou může hodnotu proměnné uložit (zjednodušeně řečeno). Tento proces nazýváme alokace paměti.

Získání adresy proměnné

Jazyk C nás od adres zatím plně odsťiňoval, paměť alokoval za nás a s našimi proměnnými jsme pracovali jednoduše pomocí jejich jmen. Vytvořme si nyní jednoduchý program, který založí proměnnou typu int a do ní uloží hodnotu 56. Adresu této proměnné si získáme pomocí tzv. referenčního operátoru & (ampersand) a vypíšeme ji do konzole. Ve formátovacím řetězci použijeme %p, což ji vypíše v šestnáctkové soustavě tak, jak se na paměťovou adresu sluší a patří.

int main(int argc, char** argv) {
    int a;
    a = 56;
    printf("Proměnná a s hodnotou %d je v paměti uložená na adrese %p", a, &a);
    return (EXIT_SUCCESS);
}

Výsledek:

c_pointery
Proměnná a s hodnotou 56 je v paměti uložená na adrese 0x23aadc

Vidíte, že na mém počítači si systém vybral adresu 0x23aadc. Vy tam budete mít jiné číslo. Situace v paměti počítače bude vypadat takto:

Paměť počítače

(Datový typ int má 32 bitů, proto tedy zabírá 4 osmice bitů na 4 adresách. Udáváme vždy adresu začátku hodnoty.)

Ukazatelé (pointery)

Získat číslo adresy je sice hezké, ale pokud bychom s pamětí takto pracovali, bylo by to poněkud nepraktické. Z toho důvodu jazyk C podporuje tzv. ukazatele (anglicky pointery). Ukazatel je proměnná, jejíž hodnotou je adresa někam do paměti. Céčko ukazatel však nebere jako pouhé číslo, ale ví, že ho má používat jako adresu. Když do ukazatele tedy něco uložíme nebo naopak vypíšeme jeho hodnotu, nevypisuje se adresa (hodnota ukazatele), ale použije se hodnota, na kterou ukazatel ukazuje.

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Vraťme se opět k našemu programu. Tentokrát si kromě proměnné a definujeme i ukazatel na proměnnou a. Ten bude také typu int, avšak před jeho názvem bude tzv. dereferenční operátor * (hvězdička). Zvykněte si pointery pojmenovávat vždy tak, aby začínaly na p_. Vyhnete se tak v budoucnu velkým problémům, protože pointery jsou poměrně nebezpečné, jak dále zjistíme, a měli bychom si srozumitelně označit, zda je proměnná pointerem či nikoli.

int main(int argc, char** argv) {
    int a, *p_a;
    a = 56;
    p_a = &a; // Uloží do p_a adresu proměnné a
    *p_a = 15; // Uloží hodnotu 15 na adresu v p_a
    printf("Ukazatel p_a má hodnotu %d ukazuje na hodnotu %d", p_a, *p_a);
    return (EXIT_SUCCESS);
}

Aplikace si vytvoří proměnnou typu int a dále ukazatel na int. Ukazatelé také mají vždy svůj datový typ podle toho, na hodnotu jakého typu ukazují. Do proměnné a se uloží hodnota 56.

Do ukazatele p_a (zatím bez hvězdičky) se uloží adresa proměnné a, kterou získáme pomocí referenčního operátoru &. Nyní chceme tam, kam ukazuje pointer p_a, uložit číslo 15. Použijeme dereferenční operátor (*) a tím neuložíme hodnotu do ukazatele, ale tam, kam ukazatel ukazuje.

Následně vypíšeme hodnotu ukazatele (což je nějaká adresa v paměti, obvykle vysoké číslo, zde ho vypisujeme v desítkové soustavě) a dále vypíšeme hodnotu, na kterou ukazatel ukazuje. Kdykoli pracujeme s hodnotou ukazatele (ne adresou), používáme operátor *.

Výsledek:

c_pointery
Ukazatel p_a má hodnotu 23374500 ukazuje na hodnotu 15

Opět si ukažme i situaci v paměti:

Paměť počítače

Předávání referencí

Umíme tedy na proměnnou vytvořit ukazatel. K čemu je to ale dobré? Do proměnné jsme přeci uměli ukládat i předtím. Jednou z výhod pointerů je tzv. předávání referencí. Vytvořme si funkci, které přijdou v parametru 2 čísla a my budeme chtít, aby jejich hodnoty prohodila (této funkci se anglicky říká swap). Naivně bychom mohli napsat následující kód:

// Tento kód nefunguje
void prohod(int a, int b)
{
    int pomocna = a;
    a = b;
    b = pomocna;
}

int main(int argc, char** argv) {
    int cislo1 = 15;
    int cislo2 = 8;
    prohod(cislo1, cislo2);
    printf("V cislo1 je číslo %d a v cislo2 je číslo %d.", cislo1, cislo2);
    return (EXIT_SUCCESS);
}

Výsledek:

c_pointery
V cislo1 je číslo 15 a v cislo2 je číslo 8.

Proč že aplikace nefunguje? Při volání funkce prohod() ve funkci main() se vezmou hodnoty proměnných cislo1 a cislo2 a ty se zkopírují do proměnných a a b v definici funkce. Funkce dále změní tyto proměnné a a b, avšak původní proměnné cislo1 a cislo2 zůstanou beze změny. Tomuto způsobu, kdy se hodnota proměnné do parametru funkce zkopíruje, říkáme předávání hodnodnou.

Všimněte si, že k prohození 2 čísel potřebujeme pomocnou proměnnou. Kdybychom ve funkci prohod() napsali jen a = b; b = a;, byla by v obou proměnných hodnota b, protože hodnota a se prvním příkazem přepsala.

Libovolnou proměnnou můžeme předat referencí a to tak, že funkci upravíme aby přijímala v parametrech pointery. Při volání takové funkce potom použijeme referenční operátor &:

void prohod(int *p_a, int *p_b)
{
    int pomocna = *p_a;
    *p_a = *p_b;
    *p_b = pomocna;
}

int main(int argc, char** argv) {
    int cislo1 = 15;
    int cislo2 = 8;
    prohod(&cislo1, &cislo2);
    printf("V a je číslo %d a v b je číslo %d.", cislo1, cislo2);
    return (EXIT_SUCCESS);
}

Výsledek:

c_pointery
V cislo1 je číslo 8 a v cislo2 je číslo 15.

Jelikož funkci nyní předáváme adresu, je schopna změnit původní proměnné.

Někteří programátoři v jazyce C používají často parametry funkcí k vracení hodnoty. To ovšem není příliš přehledné a pokud nás netlačí výpočetní čas a je to jen trochu možné, měla by funkce vždy vracet jen jednu hodnotu pomocí příkazu return, případně může vracet strukturu nebo ukazatel na strukturu/pole.

Možná vás napadlo, že konečně rozumíte funkci scanf(), která ukládá hodnoty do proměnných předaných parametry. Operátor & zde používáme proto, abychom funkci předali adresu, na kterou má data uložit:

int a;
scanf("%d", &a);

Předávání pole

Pole a pointery mají v céčku mnoho společného. Proto když předáme pole do parametru nějaké funkce a pole v ní změníme, změny se v původním poli projeví. Pole je na rozdíl od ostatních typů vždy předáváno referencí aniž bychom se o to museli snažit.

void napln_pole(int pole[], int delka)
{
    int i;
    for (i = 0; i < delka; i++)
    {
        pole[i] = i + 1;
    }
}

int main(int argc, char** argv) {
    int cisla[10];
    napln_pole(cisla, 10);
    printf("%d", cisla[5]); // Vypíše číslo 6
    return (EXIT_SUCCESS);
}

Jak jsme si řekli dříve, pole je vlastně spojité místo v paměti. Ale takové místo musíme umět nějak adresovat. Adresujeme ho právě pomocí ukazatele. Proměnná typu pole totiž není nic jiného než ukazatel. To znamená, že nám bez problémů projde následující operace přiřazení:

int pole[10];
int* p_pole = cisla;

V kapitole Aritmetika ukazatelů si ukážeme, že je úplně jedno, zda máme pole nebo ukazatel.

NULL

Všem pointerům libovolného typu můžeme přiřadit konstantu NULL. Ta udává, že je pointer prázdný a že zrovna na nic neukazuje. Na většině platforem se NULL rovná hodnotě 0 a tak se v některých kódech můžete setkat s přiřazením 0 místo NULL. To se obecně nedoporučuje kvůli kompatibilitě mezi různými platformami. Tuto hodnotu budeme v budoucnu hojně používat.

Co si zapamatovat: Pointer je proměnná, ve které je uložena adresa do paměti. Můžeme pracovat buď s touto adresou nebo s hodnotou na této adrese a to pomocí operátoru *. Adresu libovolné proměnné získáme pomocí operátoru &.

Ačkoli jsme si pointery poměrně slušně uvedli, jejich pravým účelem je zejména dynamické alokování paměti. Na které se podíváme hned v příští lekci, Dynamická alokace paměti v jazyce C.


 

Všechny články v sekci
Dynamická práce s pamětí v jazyce C
Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
7 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity (6)

 

 

Komentáře

Avatar
Eva D.
Člen
Avatar
Eva D.:3.12.2014 16:34

Dobrý den, chtěla bych Vás upozornit na chybu v posledním zdrojovém kódu ve funkci printf() chybí řídící řetězec formátu. Jinak bych Vám chtěla poděkovat za Vaše články, dost mi, jakožto "programátorovi - začátečníkovi", pomáhají.

 
Odpovědět
3.12.2014 16:34
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Eva D.
David Čápka:3.12.2014 16:55

Díky, opravil jsem :)

Odpovědět
3.12.2014 16:55
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Lukáš Hruda (Luckin):3.12.2014 21:02

Možná by bylo dobré uvést něco o endianitě. Třeba v příkladu přiřazení hodnoty 15 na adresu 0x23aadc by na Win 7 bylo pořadí bytů přesně obráceně. Pokud člověk nějakým způsobem pracuje s jednotlivými byty v paměti, je dobré o tom vědět.

 
Odpovědět
3.12.2014 21:02
Avatar
Matej
Člen
Avatar
Matej:11.10.2015 12:26

Ako si Ccko interpretuje argumenty? Resp v kode

void prohod(int *p_a, int *p_b)
{
    int pomocna = *p_a;
    *p_a = *p_b;
    *p_b = pomocna;
}

ked sa dosadi &a ,&b , sa len vymeni pamet premennej (tj pamat a = pamat b tj aj hodnota ) alebo iba hodnota (v pamati , (hodnota pameti a sa nadstavi na b ). Ak je to ten prvy pripad , neni zbytocne davat pointeri ako parametre funkcie?

Editováno 11.10.2015 12:26
 
Odpovědět
11.10.2015 12:26
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na Matej
tomisoka:11.10.2015 12:58

Vymění se jen hodnota.

Pokud se volá funkce tak argumenty se kterými pracuješ ve funkci jsou jenom kopie. Takže pokud by jsi tu funkci měl napsanou bez těch pointerů, tak by to prohodilo jenom ty kopie (z venku by to vypadalo, jako že ta funkce nic neudělala). Ale protože jako argument máš pointer, tak ten pointer je sice kopie, ale ukazuje na stejnou adresu jako originální pointer.

Editováno 11.10.2015 12:59
 
Odpovědět
11.10.2015 12:58
Avatar
Matej
Člen
Avatar
Matej:11.10.2015 14:42

ak dosadime do funkcie &a a &b

void prohod(int *p_a, int *p_b) // dosadime &a , &b
{
    int pomocna = *p_a; // pomocna je refencia na pamat a (&a)
    *p_a = *p_b; // pamat _a sa nadstavi na pamat _b tj aj na odkazujucu hodnotu
    *p_b = pomocna; // naopak
}

ak sa to bere takto , tnak sa nezmeni iba hodnota ale swapne sa cela pamat aj s hotou nie? podla predchadzajuceho prikladu na pointeri by sa hodota swapla iba ak by dany pointer (teda ak som pochopil spravne pointer v argument liste sa spava ako pointer) musel odkazovat na danu hodnotu tj

*p_a=b

a nie

*p_a=&b //referencia na pamat

V c som novy takze si to asi zle vykladam ale stale mi to nesedi :D

 
Odpovědět
11.10.2015 14:42
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na Matej
tomisoka:11.10.2015 16:00

Však taky platí:

p_a=&a

a z toho plyne:

*p_a=a

A okomentovaná funkce:

void prohod(int *p_a, int *p_b){ // dosadime &a, &b
  int pomocna = *p_a;//pomocna je přepsána hodnotou na kterou ukazuje pointer p_a(a)
  *p_a = *p_b; // hodnota na kterou ukazuje pointer p_a (a) je přepsána hodnotou na
  //kterou ukazuje pointer p_b (b)
  *p_b = pomocna; // hodnota na kterou ukazuje p_b (b) je přepsána hodnotou pomocna
}

Jinak dál se ve tvém komentáři nějak ztrácím, co znamená:

tnak sa nezmeni iba hodnota ale swapne sa cela pamat aj s hotou nie?

 
Odpovědět
11.10.2015 16:00
Avatar
Matej
Člen
Avatar
Odpovídá na tomisoka
Matej:11.10.2015 16:37

ak som to spravne pochopil tak ak das

*p_a=&a

tak vlastne nastane

p_a=&a;
*p_a= hodnota a

a ked dosadis do pointeru ktory je ako argument adresu k pameti ako parameter, tak sa priradi hodnota k tomu pointeru? :D

 
Odpovědět
11.10.2015 16:37
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na Matej
tomisoka:11.10.2015 17:03

Ale v tom kódu není nic jako:

*p_a=&a

Ta část v parametru "int *" je datový typ a "p_a" je název proměnné.
Pokud do pointeru "p_a" dosadíš adresu k paměti, tak pak pomocí "*p_a" pracuješ s hodnotou, která se nachází na té dosazené adrese. Samotná hodnota není k ničemu přiřazená, ta se prostě nachází na té adrese.

Editováno 11.10.2015 17:04
 
Odpovědět
11.10.2015 17:03
Avatar
pangas
Člen
Avatar
pangas:10.3.2016 14:10

Zdravím, měl bych malý dotaz. Nějak se mi nedaří inicializovat ukazatel na dvourozměrné pole. Chybové hlášení zní: cannot convert 'char()[26]' to 'char' in initialization.

char abcd[26][26];
char * u = abcd;

Díky za každý tip.

 
Odpovědět
10.3.2016 14:10
Avatar
ostrozan
Redaktor
Avatar
Odpovídá na pangas
ostrozan:10.3.2016 15:45
char abcd[26][26];

je sám o sobě ukazatel - a ty chceš ukazatel na ukazatel?

 
Odpovědět
10.3.2016 15:45
Avatar
B42P6
Člen
Avatar
Odpovídá na pangas
B42P6:10.3.2016 15:47

Ahoj, chyba musí byť niekde inde. Čo máš na riadku kde sa vyskytla chyba?

Odpovědět
10.3.2016 15:47
'long long long' is too long for GCC
Avatar
B42P6
Člen
Avatar
Odpovídá na ostrozan
B42P6:10.3.2016 16:45

Nemyslel si

char *pole[5];
(pole pointer-ov)

?
Teraz by získaním adresy tohto poľa dostal pointer na pointer.

Získaním adresy viacrozmerného poľa by získal len samotnú adresu poľa, pretože viacrozmerné pole je v pamäti uložené rovnako ako jednorozmerné.

Editováno 10.3.2016 16:45
Odpovědět
10.3.2016 16:45
'long long long' is too long for GCC
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
pangas
Člen
Avatar
pangas:10.3.2016 17:02

Děkuji, už jsem problém vyřešil. :) Potřeboval jsem vlastně do funkce předat dvourozměrné pole a protože jsem si neuvědomil, že už to vlastně ukazatel je, tak jsem si myslel, že potřebuji jako parametr předat ukazatel na to pole, aby jsem po skončení funkce neměl zase prázdné pole.. Moje chyba, děkuji za odpovědi :-)

 
Odpovědět
10.3.2016 17:02
Avatar
Tomáš Svoboda:20.4.2016 18:05

Zdarec, nedochází mi to.
Chápu co pointery dělají, chápu jakým způsobem asi fungují, nechápu ale jak je využít. Pro dynamické alokování to bude asi esenciální ale mě to nedochází.

Plácnu, když bych je nepoužíval bude alokovaná paměť pro můj daný program při běhu neustále růst.. ? Zavolat proměnou odkudkoliv mohu přeci i tak přimo jejím názvem.

Díky :) [ Tom, the "rozmazlen pythonem"]

Odpovědět
20.4.2016 18:05
Alea iacta est.
Avatar
gusto
Člen
Avatar
Odpovídá na tomisoka
gusto:22.9.2017 15:37

Ale od kedy je int* datovy typ ? Ved datovy typ je len int. A pokial si dobre pamatam, tak tato funkcia

void prohod(int *p_a, int *p_b)
{
    int pomocna = *p_a;
    *p_a = *p_b;
    *p_b = pomocna;
}

ma definovane 2 smerniky na datovy typ int a v tele je dalsia obycajna premenna "pomocna" datoveho typu int

 
Odpovědět
22.9.2017 15:37
Avatar
Honza Skřivánek:30.1.2018 18:41

Jen bych dodal na okraj k té poznámce, že pomocná proměnná není k prohození dvou hodnot potřeba. Například pomocí bitového XORu to jde udělat takto:

int x = 15;                     // 1111
int y = 7;                      // 0111
x = x^y;                        // 1000
y = x^y;                        // 1111 zde už je v y původní hodnota x
x = x^y;                        // 0111 a zde máme v x původní y

Jde to pochopitelně provést i například pomocí sčítání a odčítání (tam ale pozor na overflow)

Editováno 30.1.2018 18:42
 
Odpovědět
30.1.2018 18:41
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Honza Skřivánek
DarkCoder:30.1.2018 20:52

Ano, to je další způsob. Tento způsob se ale v praxi nepoužívá a to z důvodu efektivity. Většina moderních překladačů může optimalizovat dočasnou proměnnou tak, že používá stejné množství paměti a registrů jako za použití XOR. Způsob za použití dočasné proměnně je přinejmenším stejně tak rychlý a často i rychlejší.

Odpovědět
30.1.2018 20:52
"„Učíš-li se proto, aby sis zapamatoval, zapomeneš. Učíš-li se proto, abys porozuměl, zapamatuješ si."
Avatar
Odpovídá na DarkCoder
Honza Skřivánek:30.1.2018 21:10

To je fakt, je to spíš taková zajímavost, se kterou se člověk může setkat třeba u pohovoru :-) Navíc tam nastane problém pokud se obě hodnoty budou rovnat. Na druhou stranu, třeba u nějakých jednočipů to stále může mít smysl.

 
Odpovědět
30.1.2018 21:10
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Honza Skřivánek
DarkCoder:30.1.2018 21:30

Přesně tak. Jeho využití je hodně specifické, zejména mikrokontroléry, tam kde paměti není nazbyt a kryptografické aplikace. Z tohoto důvodu jsou překladače optimalizované jinak..

Odpovědět
30.1.2018 21:30
"„Učíš-li se proto, aby sis zapamatoval, zapomeneš. Učíš-li se proto, abys porozuměl, zapamatuješ si."
Avatar
Odpovídá na DarkCoder
Patrik Pastor:29.8.2019 20:32

to nechpu, XOR ma operator znaceny '^'? A proc by xorovani promennych bylo menne efektivni jako incializace pomocne promenne? (jak tvrdis, ze by byla prinejmensim stejne rychla). Jedna se tedy o efektivitu s pohledu mista v pameti nebo efektivitu vypocetnich instrukci? (pamet vs procesor)

 
Odpovědět
29.8.2019 20:32
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Patrik Pastor
DarkCoder:29.8.2019 21:01

Ano, jedná se o bitový operátor XOR (nonekvivalence) a ten má skutečně označení '^'. Operátor XOR nastavuje bit na 1, když jsou oba bity navzájem různé. Je třeba rozlišovat bitové operátory od logických. Jedná se o efektivitu z hlediska počtu výpočetních instrukcí při zachování stejné velikosti potřebné paměti.

Odpovědět
29.8.2019 21:01
"„Učíš-li se proto, aby sis zapamatoval, zapomeneš. Učíš-li se proto, abys porozuměl, zapamatuješ si."
Avatar
Odpovídá na DarkCoder
Patrik Pastor:29.8.2019 22:07

no ale stale nechapu proc by xorovani melo byt vypocetne slozitejsi. Chapu ze to je operace navic, ale prece to je skoro nic pro dnesni procesory

 
Odpovědět
29.8.2019 22:07
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Patrik Pastor
DarkCoder:29.8.2019 22:35

Je to z několika důvodů: Za použití pomocné proměnné dochází k přímému kopírování, kdežto u použití XOR dochází navíc k porovnávání jednotlivých bitů. Dále u procesorů řady x86 jak i Intelu tak i u AMD dochází při pohybu mezi registry k nulové odezvě (eliminace MOV). A nakonec XOR algoritmus je závislý na výsledku předchozí operace. Moderní CPU se snaží provádět instrukce paralelně prostřednictvím tzv. instrukčních rour. A jelikož výměna obsahu proměnných za použití XOR je závislá na předchozím subvýsledku, nelze použít výhod paralelismu. To způsobuje, že výměna obsahu proměnných za použití XOR bude pomalejší nežli za použití pomocné proměnné.

Odpovědět
29.8.2019 22:35
"„Učíš-li se proto, aby sis zapamatoval, zapomeneš. Učíš-li se proto, abys porozuměl, zapamatuješ si."
Avatar
Odpovídá na DarkCoder
Patrik Pastor:29.8.2019 22:49

predpokladam ze "(eliminace MOV)" - je prikaz pro ulozeni hodnoty na adresu? Nejsem si jisty , ale videl jsem to mam dojem v assembleru. Snad na to tady taky casem budou nejake clanky

 
Odpovědět
29.8.2019 22:49
Avatar
Michal H.
Člen
Avatar
Odpovídá na gusto
Michal H.:23. února 6:06

no nevím jak v c, ale například c ++ nejde uložit adresa do ukazatele takto...

int * p_int;
p_int = 0xC7000000;

tohle udělat nelze. Snažíš se do adresy uložit číslo. Číslo musíš explicitně přetypovat aby se z něj stala vlastně adresa.

p_int = (int *) 0xC7000000;

tak že int* bude asi typ :) A ukazatele patří mezi složené typy. Řekl bych že tady rozdíl mezi c a c++ moc velký nebude.

 
Odpovědět
23. února 6:06
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 26 zpráv z 26.