Hledám člověka na konzultace v C – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Hledám člověka na konzultace v C – C / C++ – Fórum – Programujte.comHledám člověka na konzultace v C – C / C++ – Fórum – Programujte.com

 

Ryan99
~ Anonymní uživatel
15 příspěvků
15. 4. 2015   #1
-
0
-

Dobrý den,

našel by se někdo kdo by mi za nějakou rozumnou hodinovku po skypu pomohl pochopit základy Cčka? Mám nějaké úkoly se kterými bych potřeboval pomoci.

Pokud ano, můj email: olomoucak1@email.cz , pokud připojíte i svůj skype, vše tím urychlíme.

Nahlásit jako SPAM
IP: 88.100.30.–
KIIV
~ Moderátor
+43
God of flame
15. 4. 2015   #2
-
0
-

se ptej rovnou tady a treba i usetris :D

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Ryan99
~ Anonymní uživatel
15 příspěvků
15. 4. 2015   #3
-
0
-

To jsem původne chtěl, ale nevím zda toho nebude na veřejné fórum příliš :d , máme asi 10 úkolů a zaseknul jsem se na 3. kde máme udělat alokaci paměti podle toho kolika rozměrnou matici si uživatel vyžádá. Pokud si vyžádá menší, tak paměť uvolnit. Potřebuji tak trochu nakopnout správným směrem abych to dokázal pochopit.

Já chápu princip malloc(), že mi vyhradí místo v paměti a vrátí ukazatel na začátek. Vyhradí mi tedy třeba místo od 69000 do 70000. A vrátí ukazatel na 69001. Pokud bych použil calloc() tak je to to samé, jen v paměti všude přepíše hodnoty na 0.

Ale problém je s tím použitím, našel jsem použití:

void *malloc(size_t size);

Čemuž už nerozumím. Void se používá jako parametr funkce pokud žádný nechci main(void), ale tady je jako proměnná ve které mám ten ukazatel? Size_t (vím že musí být inicializována speciální knihovna) je vlastní datový typ, hodně velký, místo toho size napíšu počet bitů které chci vyhradit? Čili třeba void *malloc(size_t 256) mi vyhradí 256 míst v paměti? A ukazatel tedy vrátí hodnotu třeba 8000 a paměť bude vyhrazena do 8256?

Nahlásit jako SPAM
IP: 88.100.30.–
KIIV
~ Moderátor
+43
God of flame
15. 4. 2015   #4
-
0
-

Ten void pointer se vraci aby to bylo "univerzalnejsi". Malloc beztak jen alokuje zadany pocet bajtu v pameti a vrati pointer na jeji zacatek. To, co do ty pameti zapises, je uz na tobe:

int pocet = 1000;
int * ptr = malloc(sizeof(int)*pocet); // sizeof se postara o zjisteni, na kolik bytu je jeden int

size_t zase tak moc resit nemusis, staci tam zadat spravnou velikost v bajtech

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Junker
~ Anonymní uživatel
5 příspěvků
15. 4. 2015   #5
-
0
-

Mně vždy připadalo elegantnější napsat místo sizeof(int) rovnou 4, ale nevím co je výkonově lepší, nebo tam kompilátor tu 4 stejně napíše?

Nahlásit jako SPAM
IP: 178.72.234.–
KIIV
~ Moderátor
+43
God of flame
15. 4. 2015   #6
-
0
-

No, problem nastane, kdyz int nebude zrovna 4... gcc napriklad i na 64b procesoru drzi 4B integer, ale jsou jine, ktere ho maji 8B a pak by ses teprve divil :)

Tj. gcc pouziva  I32LP64 ale jsou i takove, co davaji ILP64   http://www.unix.org/version2/whatsnew/lp64_wp.html

A vykonove by to melo byt stejne, sizeof by se melo pocitat pri kompilaci

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
15. 4. 2015   #7
-
0
-

sizeof říká překladači, že si má velikost datového typu spočítat sám. Použití tohoto operátoru eliminuje chyby, které uděláš při stanovení velikosti datového typu - jde nejen o velikost int, ale i o velikost heterogenních datových typů jako např. struktury, kde vlivem zarovnávání nemusí být velikost struktury shodná se součtem velikostí ve struktuře použitých datových typů. Tyto "implementační pravidla" překladač zná velice dobře a bezchybně je aplikuje. Proto je vhodnější to nechat na překladači.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:89d8:5e...–
Ryan99
~ Anonymní uživatel
15 příspěvků
15. 4. 2015   #8
-
0
-

Aha, takže pokud to správně chápu, int zabírá 4B, čili pokud napíši malloc(sizeof(int)*5), vyhradím si paměť pro 5 čísel typu int.

Mám za úkol kde uživatel bude zadávat rozměry matice a podle toho se bude alokovat/uvolňovat paměť. Matici máme doplnit náhodnými čísly a uložit do jednorozměrného pole.

Načtu tedy od uživatele rozměr matice, třeba 4x3. Potřebuji tedy 12 prvků pole pro uložení všech čísel. Celé to bude v nekonečném cyklu, pro jednoduchost to tady udělejme bez něj. Bude to vypadat nějak takto?

printf("Zadejte prvni rozmer matice:\n");
scanf("%d",&prvni);

printf("\nZadejte druhy rozmer matice:\n");
scanf("%d",&druhy);

rozmer = prvni*druhy;

int * ptr = malloc(sizeof(int)*rozmer);


for(c=1; c<=rozmer;c++){

    matice[c] = c;

    }

int free(*ptr);

Pokud zadám 4 a 3 tak obsah pole[] bude "1,2,3,4,5,6,7,8,9,11,12"). Pokud bych chtěl čísla generovat náhodně, jak to udělat? Existuje nějaká funkce random?

Nahlásit jako SPAM
IP: 88.100.30.–
Ryan99
~ Anonymní uživatel
15 příspěvků
15. 4. 2015   #9
-
0
-

Teď si říkám že je to nesmysl, protože tam nikde nemám dáno že to pole bude v té vyhrazené paměti.

Takže tam bude ještě něco namísto klasického

int matice[rozmer] tam bude int matice* ptr?

Nahlásit jako SPAM
IP: 88.100.30.–
KIIV
~ Moderátor
+43
God of flame
15. 4. 2015   #10
-
0
-

#8 Ryan99
existuje.. jmenuje se rand() a nekde na zacatku se jeste vetsinou vola srand(time(NULL)), coz nastavi takzvany seed pro generator nahodnych cisel podle aktualniho casu. Bez toho bys sice mel nahodna cisla, ale sekvence by byla pri kazdem spusteni presne stejna.

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
ondrej39+1
Věrný člen
15. 4. 2015   #11
-
0
-

#8 Ryan99
Toto by ti spadlo. Pokud bychom přepokládali, že uživatel zadá matici 3x4, tedy velikost 12 * 4 byty (na standardním systému), budeš ti pointer ptr ukazovat na první element v tobě vytvořeném poli, nicméně první element je 0., nikoliv 1.

Při alokaci pole pro 12 prvků již k pole[12] přistoupit nemůžeš.

K tomu free, tam se předává pointer bez dereferenčního operátoru.

Nahlásit jako SPAM
IP: 213.226.234.–
Inject all the dependencies!
KIIV
~ Moderátor
+43
God of flame
15. 4. 2015   #12
-
0
-

#9 Ryan99
V C je jednorozmerne pole v pointeru a normalni jednorozmerne pole prakticky to same. Jen u toho statickeho pole nemuzes zmenit adresu, kde zacina.

int pole[100];

int * ptr = pole;

pak jde pouzit jak:  pole[index] tak *(pole+index) tak  ptr[index]  i  *(ptr+index)

U pointeru pak muzes pouzivat i pointerovou aritmetiku jako:  ++ptr  => posune adresu na dalsi int, to same u promenne pole samozrejme udelat uz nesmis.

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
15. 4. 2015   #13
-
0
-

Pod pojmem "kolika rozměrnou matici" si představuji dvou, tří, pěti ..... rozměrnou matici na rozdíl od velikosti matice, kde třeba dvourozměrná by mohla mít velikost např. 8 x 6 prvků.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:89d8:5e...–
ondrej39+1
Věrný člen
15. 4. 2015   #14
-
0
-

#13 hlucheucho
Mám trošku strach, že udělat dynamicky n-rozměrnou matici, aby měla n-rozměrů na základě toho, kolik zadá uživatel, moc dobře udělat ani nejde. Kdybys měl 3rozměrnou matici integerů, potřebuješ int *** pointer, ale co kdyby uživatel chtěl matici třeba 14rozměrnou (int ************** pointer vypadá fakt dobře)? Pravděpodobně bys musel mít switch case na nekonečně mnoho možností, tj. typů rozměrů matic.

Nahlásit jako SPAM
IP: 213.226.234.–
Inject all the dependencies!
KIIV
~ Moderátor
+43
God of flame
15. 4. 2015   #15
-
0
-

#14 ondrej39
na co, pole[ROZMX][ROZMY] bude stejne v pameti za sebou akorat se pak vypocitava  *(pole + x*ROZMY+y) 

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
ondrej39+1
Věrný člen
15. 4. 2015   #16
-
0
-

#15 KIIV
V paměti to za sebou bude, to ano, ale jednorozměrné pole prostě není dvojrozměrné, trojrozměrné, nebo n-rozměrné pole. Způsob, jak se vytváří například dvojrozměrné pole

int ** pole = (int**)malloc(pocetRadku * sizeof(int*));

int i = 0;
for (i; i < pocetRadku; ++i)
{
	pole[i] = (int*)malloc(pocetSloupcu * sizeof(int));
}

prostě na n rozměrů převést podle mě nejde.

Nahlásit jako SPAM
IP: 213.226.234.–
Inject all the dependencies!
15. 4. 2015   #17
-
0
-

#16 ondrej39
alokuješ jednorozměrné pole a z velikosti jednotlivých rozměrů matice a indexů počítáš umístění prvku v jednorozměrném poli.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:89d8:5e...–
KIIV
~ Moderátor
+43
God of flame
15. 4. 2015   #18
-
0
-

#16 ondrej39
ale podle me nemyslel N-rozmernou, ale jen dvourozmernou. A ten rozmer patril k poctu radku a sloupcu

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
15. 4. 2015   #19
-
0
-

#18 KIIV
 ta námitka s rozměrem a velikostí vzešla ode mne

trefená husa   

Nahlásit jako SPAM
IP: 2001:67c:1222:800:89d8:5e...–
KIIV
~ Moderátor
+43
God of flame
15. 4. 2015   #20
-
0
-

#19 hlucheucho
tak se v tom aspon shodujeme :D Kazdopadne stale pokracoval s N rozmerama, tak to beztak chtelo pripomenout (i bez toho, ze sem stihl zapomenout, zes to psal)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
15. 4. 2015   #21
-
0
-

Výpočet polohy prvku z indexů a alokování jednorozměrného pole a tím souvislého bloku paměti se mi zdá jednodušší na implementaci než pole ukazatelů na řádky (nebo sloupce). Navíc to povede k efektivnější práci s pamětí.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:89d8:5e...–
Ryan99
~ Anonymní uživatel
15 příspěvků
15. 4. 2015   #22
-
0
-

Ano, jde o jednorozměrnou matici s X x Y prvků. Čili 2x5, 8x8 atd. Čili pokud to správně chápu tak nějak takto?

srand(time(NULL))

printf("Zadejte prvni rozmer matice:\n");
scanf("%d",&prvni);

printf("\nZadejte druhy rozmer matice:\n");
scanf("%d",&druhy);

rozmer = prvni*druhy;

int *ptr = malloc(sizeof(int)*rozmer);

int * ptr = matice;

for(c=1; c<=rozmer;c++){

    matice[c] = rand();

    }

int free(ptr);

S tím že srand zajistí to že fce rand() bude mít pokaždé jiné hodnoty. Potom čtu vstupy, vytvořím rozměr matice, např. 2x3 = 6. Alokuji paměť pro 6*int (čili 24B). Jak teď zajistím to aby v té vyhrazené paměti bylo to moje pole s maticí? Zápisem *ptr =matice[rozmer]? V tomto případě *ptr=matice[6]. Tím mám matici v paměti kterou jsem si alokoval. Teď cyklem zapíšu náhodné hodnoty (12ks) od 0 do 99. Je to tak, nebo se funkce rand() používá jinak? Je celý kód v pořádku?

Díky moc

Nahlásit jako SPAM
IP: 88.100.30.–
KIIV
~ Moderátor
+43
God of flame
16. 4. 2015   #23
-
0
-

 Proc tam mas tolikrat deklaraci ptr? Sice by to nemelo projit, prekladac hlasi vetsinou chyby u redefinici promennych a matice asi taky mozna nebude moc existovat.

int *ptr = malloc(sizeof(int)*rozmer);
int * ptr = matice; // prave sis znicil jediny pointer, ktery si dostal z mallocu
Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
ondrej39+1
Věrný člen
16. 4. 2015   #24
-
0
-

#22 Ryan99
Ryane, abys měl to tvoje pole, tu tvou matici, v paměti, kterou si vyhrazuješ použitím malloc, tak už pak nemusíš dělat žádné ptr = matice. Jakmile si přes malloc alokuješ (rezervuješ) místo na heapu, tak to rezervované místo už je rovnou to tvoje pole. Pokud tedy uděláš

int * ptr = malloc(rozmer * sizeof(int));


tak můžeš normálně pracovat s pointerem jako s polem, tj přistupovat k prvkům

ptr[index] = neco;


kde index začíná nulou a je menší než rozměr v mallocu. Pokud chceš pracovat se slovem matice, tak si namísto int * ptr nadeklaruj int * matice a pro něj malloc proveď.

Nahlásit jako SPAM
IP: 213.226.234.–
Inject all the dependencies!
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 42 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý