Mikuláš je tu! Získaj 90 % extra kreditov ZADARMO s promo kódom CERTIK90 pri nákupe od 1 199 kreditov. Len do nedele 7. 12. 2025! Zisti viac:
NOVINKA: Najžiadanejšie rekvalifikačné kurzy teraz s 50% zľavou + kurz AI ZADARMO. Nečakaj, táto ponuka dlho nevydrží! Zisti viac:

Diskusia – 3. diel - Aritmetika ukazovateľov v jazyku C

Späť

Upozorňujeme, že diskusie pod našimi online kurzami sú nemoderované a primárne slúžia na získavanie spätnej väzby pre budúce vylepšenie kurzov. Pre študentov našich rekvalifikačných kurzov ponúkame možnosť priameho kontaktu s lektormi a študijným referentom pre osobné konzultácie a podporu v rámci ich štúdia. Toto je exkluzívna služba, ktorá zaisťuje kvalitnú a cielenú pomoc v prípade akýchkoľvek otázok alebo projektov.

Komentáre
Posledné komentáre sú na spodnej časti poslednej stránky.
Avatar
DarkCoder
Člen
Avatar
Odpovedá na Martin Russin
DarkCoder:7.7.2021 17:08

V druhém řádku je definován ukazatel na typ int a je inicializován bázovou adresou pole nums.
Ukazateli nejsou přidělovány hodnoty pole. Jediné co jsem udělat je, že jsem hodnotu ukazatele p nastavil adresou pole nums, nic víc. Po tomto příkazu mohu pracovat s polem nums nepřímo pomocí ukazatele p. Ukazatel, je proměnná která obsahuje adresu jiného objektu. V tomto případě adresu pole nums.

Definuji-li pole a inicializuji-li ho nějakými hodnotami, leží tyto prvky v paměti za sebou. Adresa každého následující prvku je vyšší o velikost typu pole. Bude-li pole typu int a první prvek pole bude ležet např. na adrese 100, pak druhý prvek pole bude ležet na adrese 100 + sizeof(int).

Ano, ukazatel p bude ukazovat na začátek pole, adresa začátku pole je označována jako bázová adresa a na této adrese bude ležet prvek v našem případě s hodnotou 1. Pomocí bázové adresy a posunu mohu pomocí dereference ukazatele přistupovat k hodnotám pole na té které pozici.

V tomto případě nealokuji dynamicky žádnou paměť, paměť pro pole nums je přidělena staticky při spuštění programu. Dynamickou alokací se rozumí proces, při kterém si žádám od OS přidělení určitého množství paměti za běhu programu pomocí funkcí malloc() nebo calloc().

Odpovedať
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovedá na DarkCoder
Martin Russin:7.7.2021 18:08

V druhém řádku je definován ukazatel na typ int a je inicializován bázovou adresou pole nums. Ukazateli nejsou přidělovány hodnoty pole. Jediné co jsem udělat je, že jsem hodnotu ukazatele p nastavil adresou pole nums, nic víc.

Kedže si nastavil hodnotu ukazovateľa p na bázovú adresu poľa nums, nemal by potom kód vyzerať takto(keďže pracujeme s hodnotou adresy, nie z hodnotou na adrese)?

p = nums;

Po tomto příkazu mohu pracovat s polem nums nepřímo pomocí ukazatele p.

Má to nejakú výhodu oproti priamemu pracovaniu s poľom?

printf("%d\n", *(nums + 2));
printf("%d\n", *(p + 2));

V týchto prípadoch pracujem s adresami (či už poľa alebo ukazovateľa), na ktorých sa nachádzajú isté hodnoty a výsledok je rovnaký preto, lebo bázové adresy sú v oboch prípadoch rovnaké?

Avatar
DarkCoder
Člen
Avatar
Odpovedá na Martin Russin
DarkCoder:7.7.2021 19:18

Pokud definuji ukazatel a zároveň ho inicializuji adresou pole, pak se to zapisuje takto:

int nums[] = { 1,2,3,4,5 };
int *p = nums;

Pokud definuji ukazatel a v definici nepřiřazuji adresu objektu, pak se to zapisuje takto:

int nums[] = { 1,2,3,4,5 };
int *p = NULL;
p = nums;

Jméno pole bez indexu představuje ukazatel na začátek pole. Oproti klasickému ukazateli se liší v tom, že ukazatel na začátek pole je konstantní. Nelze jej tedy měnit. Pokud tedy chceme např. traversovat pole pomocí ukazatele, přiřadí se nejprve ukazatel na toto pole jinému ukazateli, který již lze modifikovat.

Máme-li

int  pole[] = {1, 2, 3, 4, 5};
int p = pole;

Pak:

pole++; // neplatný příkaz
p++; platný příkaz

Dále ve funkcích kde pole je předáváno jako parametr, respektivě je předáván ukazatel na toto pole a k poli se přistupuje pomocí tohoho formálního parametru.

Ano, pokud:

int nums[] = { 1,2,3,4,5 };
int *p = nums;

// pak p == nums

printf("%d\n", *(nums + 2));
printf("%d\n", *(p + 2));

// a oba příkazy jsou ekvivalentní, pouze přístup k hodnotě je nepatrně odlišný
Odpovedať
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovedá na DarkCoder
Martin Russin:7.7.2021 20:00

1, Čo hovorí/vykonáva tretí riadok kódu? Viem, že druhý riadok hovorí to, že ukazovateľ p na nič neukazuje.

int nums[] = { 1,2,3,4,5 };
int *p = NULL;
p = nums;

2, Nasledujúci riadok kódu je nesprávny? Ak áno, tak prečo?

int nums[] = { 1,2,3,4,5 };
int *p;
p = &nums;
Avatar
DarkCoder
Člen
Avatar
Odpovedá na Martin Russin
DarkCoder:7.7.2021 20:06
  1. Přiřadí adresu nums ukazateli p. Ukazatel p tak bude ukazovat na začátek pole nums.
  2. Jméno pole bez indexu je ukazatel na začátek pole. Příkaz je chybný, jelikož je nesprávný počet referencí. Kdyby nums byla obyčejná proměnná a nikoli pole, bylo by použití referenčního operátoru & správné.
Odpovedať
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovedá na DarkCoder
Martin Russin:7.7.2021 20:10

Aj meno poľa s indexom je ukazovateľ na začiatok poľa? Napr. nasledujúci kód je správny?

int pole[10];
int *p_pole = pole;
Avatar
DarkCoder
Člen
Avatar
Odpovedá na Martin Russin
DarkCoder:7.7.2021 20:44

Ne, pouze jméno pole bez indexu je ukazatel na začátek pole. Úryvek kódu je správný.

Odpovedať
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
DarkCoder
Člen
Avatar
DarkCoder:7. januára 21:15

Stálo by za to vysvětlit co vlastně vyjadřuje rozdíl ukazatelů. Že to udává počet prvků mezi nimi.

> Počet prvků v bloku (v našem případě 100) bohužel již nikdy nezjistíme a musíme si ho po založení pamatovat nebo uložit. To je také důvod, proč se textové řetězce ukončují znakem '\0'.

Důvodem, proč se řetězce ukončují znakem '\0', je to, aby fungovaly funkce ze standardní knihovny jazyka C. Pro identifikaci konce řetězce.

Specifikátor formátu %lf se pro typ double ve funkci printf() nepoužívá. Ten je pouze u funkce scanf(). Pro typ double u funkce printf() se používá %f stejně jako pro typ float.

Odpovedať
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Posledné komentáre sú na spodnej časti poslednej stránky.
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zobrazené 8 správy z 18.