NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Rozsah pole

V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Kdosi
Neregistrovaný
Avatar
Kdosi:13.10.2013 15:33

Zdravím,
můj kód v šabloně T*:

List(T* source)
{
        count = jak?;
        printf("%i\n", count);
        list = (T*)malloc(count);

        *list = *source;
}

Vstupem je třeba pole string[3], přičemž string je "const char*". Když mám tedy 3 itemy, tak za jak dám ručně 96 a jede to jak má. Jenže já potřebuji řešení pro počet prvků n... sizeof vrací jak pro source, tak i pro *source 4.
Děkuji.

 
Odpovědět
13.10.2013 15:33
Avatar
vitamin
Člen
Avatar
Odpovídá na
vitamin:13.10.2013 15:40
template <class T, size_t N> //N je pocet prvkov pola (velkost musi byt znma pri preklade)
void List(T (&source)[N]){
        //...
}
Editováno 13.10.2013 15:41
 
Nahoru Odpovědět
13.10.2013 15:40
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:13.10.2013 15:44

To je blbost. To tam rovnou dám parametr pro počet prvků a vynásobím jej pak 32... Jenže je to tedy pěkně naprd - chtěl jsem to jako deklaraci Listu s n prvky. Takhlen je už jednodušší volat Add, jelikož nejen, že neexistuje zkrácená verze initializace pole, ale jak v poli, tak v parametru budu muset dávat velikost pole...

 
Nahoru Odpovědět
13.10.2013 15:44
Avatar
vitamin
Člen
Avatar
Odpovídá na
vitamin:13.10.2013 15:48

Co sa snazias naprogramovat?
Vies o tom ze malloc nevola constructory?

 
Nahoru Odpovědět
13.10.2013 15:48
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:13.10.2013 15:51
List<string> strings = *new List<string>(new string[3]{ ":((", ":D", "....." }, 3);

List třídu mám už dlouho, chtěl jsem jen zkrátit deklaraci, znám-li už nějaký počet prvků předem... Tohle to celé jen komplikuje - místo zjednodušení... :D

Jistě - jsem debil a dělám dynamické pole....

 
Nahoru Odpovědět
13.10.2013 15:51
Avatar
Kdosi
Neregistrovaný
Avatar
Kdosi:13.10.2013 15:57

Pročež doteď jsem v cyklu volal:

void Add(T item)
{
        count += 32;

        list = (T*)realloc(list, count);

        list[count / 32 - 1] = item;
}

Takhlen to nastavím rovnou - bez cyklu...

 
Nahoru Odpovědět
13.10.2013 15:57
Avatar
vitamin
Člen
Avatar
vitamin:13.10.2013 15:59
#include  <initializer_list>
template <class T>
class List{

        public:
                template<size_t N>
                List(const T (&source)[N]){
                        std::cout << "List sa inicializuje z pola o " << N << " prvkoch\n";
                }

                List(std::initializer_list<T>&& ilist){
                        std::cout << "List sa inicializuje z inicializer_listu o " << ilist.size() << " prvkoch\n";

                }
};


int main(){
        using namespace std;

        List<char> list1{"string"};
        List<char> list2{'a', 'b', 'c', 'd'};

        return 0;
}

Pouzivas strasne vela alokacii na heape, c++ nie je java ani c#...

Editováno 13.10.2013 16:00
 
Nahoru Odpovědět
13.10.2013 15:59
Avatar
Kdosi
Neregistrovaný
Avatar
Kdosi:13.10.2013 16:07

Já myslel, že to půjde s tím sizeof... Includovat se mi nechtělo. No nic - díky... Když už - C++ řeší kolize includů nějak lépe, než C? (Jako u Objective-C je import...)

 
Nahoru Odpovědět
13.10.2013 16:07
Avatar
vitamin
Člen
Avatar
Odpovídá na
vitamin:13.10.2013 16:14

includy funguju rovnako ako v c, vecsina kompilatorov podporuje ale #pragma once alebo si spravys guary sam cez ifndef, define, endif.

Inak ta tvoja funkcia Add ma velku chybu, nevola sa konstruktor takze ti to v lepsom pripade bude padat alebo budu vznkat memory lake-y.

Editováno 13.10.2013 16:15
 
Nahoru Odpovědět
13.10.2013 16:14
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:13.10.2013 17:46

A pole/pointer z toho udělám jak? (Myslím tím T*...)

 
Nahoru Odpovědět
13.10.2013 17:46
Avatar
vitamin
Člen
Avatar
vitamin:13.10.2013 18:41
void* mem = malloc(sizeof(T));   //alokujes pamet

new(mem) T(...);   //zavolas konstruktor

reinterpret_cast<T*>(mem)->~T();     //zavolas destructor

free(mem);    //dealokujes pamet

Akonahle pouzivas malloc, realloc a free, tak si konstruktory a destruktory musis valoat rucne. Napr std::vector je podobne implementovany.

 
Nahoru Odpovědět
13.10.2013 18:41
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:13.10.2013 18:51

Ale já se ptal na to, co mám dělat s tím "std::initiali­zer_list"...

 
Nahoru Odpovědět
13.10.2013 18:51
Avatar
vitamin
Člen
Avatar
Odpovídá na
vitamin:13.10.2013 18:54

Musis mat kompilator co podporuje c++11.
Musis includovat: <initializer_list>
A potom mozes pouzit ten priklad co som ti dal.

 
Nahoru Odpovědět
13.10.2013 18:54
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:13.10.2013 18:55

Nemůžu. Já používám T*. Ne list...

>g++ -W -Wall -Werror -std=gnu++11 -I ./ -o main.exe main.cpp
In file included from /usr/include/System.h:2:0,
                 from main.cpp:3:
/usr/include/System/Collections/Generic/List.h: In instantiation of ‘System::Collections::Generic::List<T>::List(std::initializer_list<_Tp>&&) [with T = const char*]’:
main.cpp:10:46:   required from here
/usr/include/System/Collections/Generic/List.h:39:6: error: invalid conversion from ‘std::initializer_list<const char*>::const_iterator {aka const char* const*}’ to ‘const char**’ [-fpermissive]
/usr/include/System/Collections/Generic/List.h:42:10: error:   initializing argument 1 of ‘void System::Collections::Generic::List<T>::Allocate(T*, int) [with T = const char*]’ [-fpermissive]
>Exit code: 1

Potřebuji z toho mít T*/[]...

 
Nahoru Odpovědět
13.10.2013 18:55
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:13.10.2013 18:57

Já nevím - připadám si, jako by jsi si myslel, že jsem úplně negramotný...

 
Nahoru Odpovědět
13.10.2013 18:57
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:13.10.2013 19:02

A cyklus jsem tam měl předtím - viz. hoře. Přijde mi zbytečné cyklit, když je to vše v požadovaném formátu - stačí T* nastavit na T*. Jediná věc byla, že jsem musel zadat jak do pole, tak do dalšího parametru velikost - je to ale lepší než cyklus zase...

 
Nahoru Odpovědět
13.10.2013 19:02
Avatar
Kit
Tvůrce
Avatar
Odpovídá na
Kit:13.10.2013 19:03

Nemůžu si pomoct, ale občas mi jako negramotný připadáš :)

Možná by nebylo špatné, kdyby ses konečně zaregistroval. Takhle mám tendenci si z tebe dělat srandu, i když vidím, že něco přece jen umíš.

Nahoru Odpovědět
13.10.2013 19:03
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
vitamin
Člen
Avatar
Odpovídá na
vitamin:13.10.2013 19:07

Ak to spravne chapem tak sa snazis implementovat dynamicke pole na sposob std::vector. Aby si nas zmiatol tak si ho nasval List co sa pouziva vecsinou na zretaene zoznamy. Chces implementovat konstruktor v ktorom budes moct specifikovat zoznam prvkov ktore chces mat v poly po inicializacii. Chapem to spravne?

 
Nahoru Odpovědět
13.10.2013 19:07
Avatar
Kit
Tvůrce
Avatar
Odpovídá na vitamin
Kit:13.10.2013 19:13

Seznam se dá implementovat nejen zřetězením elementů, ale i pomocí pole. Přitom pole je v běžných případech o dost rychlejší.

Nahoru Odpovědět
13.10.2013 19:13
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na vitamin
Kdosi:13.10.2013 19:13

Tvl. Je to list jako vyšitý - stejný jako v C#. (Pak udělám i slovník - jako v C# - List.Add, List.Remove, List.RemoveAt, List.Count,...) Jen jsem doteď neměl v konstruktoru možnost zadat počáteční prvky. To jsem zařídil přes pole. Nevýhodou toho ale bylo, že se nedala dynamicky zjistit velikost - a když jsem se zde zeptal, začal jsi z toho dělat kdovíco...

List(T* source)
{
       count = jak?;
       list = (T*)malloc(count);

       *list = *source;
}

sizeof prostě nefunguje no. Tak já budu zadávat tu velikost ročně a smířím se s tím asi... :D

Negramotný fakt nejsem. A programuji už pár let - a to i komerčně... (Od strojáku po dotazovací jazyky + se dnes a denně hrabu v HW.)

 
Nahoru Odpovědět
13.10.2013 19:13
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na
David Hartinger:13.10.2013 19:27

Je zvláštní, že všechny tvé diskuze na všech fórech dopadají stejně.

Nahoru Odpovědět
13.10.2013 19:27
New kid back on the block with a R.I.P
Avatar
Kit
Tvůrce
Avatar
Odpovídá na David Hartinger
Kit:13.10.2013 19:29

Myslíš, jak v nich tvrdí, že není negramotný?

Nahoru Odpovědět
13.10.2013 19:29
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kdosi
Neregistrovaný
Avatar
Odpovídá na David Hartinger
Kdosi:13.10.2013 19:30

Přečti si první příspěvek. Kde jsem udělal chybu?

 
Nahoru Odpovědět
13.10.2013 19:30
Avatar
vitamin
Člen
Avatar
Odpovídá na
vitamin:13.10.2013 19:45

To ze si predtym programoval v jave/c# ma hned napadlo po tom ako som zbadal toto: :D

List<string> strings = *new List<string>(new string[3]{ ":((", ":D", "....." }, 3);

To moje riesenie co som ti dal v na zaciatku pomocou referencie na staticke pole a incializer listu ta moholo naviest na spravne riesenie ale asi ti to moc nepomohlo. Budem taky velkoisi ze ti sem dam ukazkovy kod:

#include  <initializer_list>

template <class T>
class Vector{
                void* raw_data;
                T* data(size_t s = 0){return reinterpret_cast<T*>(raw_data) + s;}
                const T* data(size_t s = 0)const {return reinterpret_cast<const T*>(raw_data) + s;}

                size_t data_size = 0;
                size_t alloc_size = 0;

        public:
                Vector(size_t reserve = 0){
                        alloc_size = reserve +1;
                        raw_data = malloc(sizeof(T)*alloc_size);
                }

                ~Vector(){
                        clear();
                        free(raw_data);
                }

                size_t size()const{return data_size;}

                void clear(){
                        for(T* i = data(data_size-1); i >= data(); --i)
                                i->~T();

                        data_size = 0;
                }

                void Add(const T& x){           //prida prvok na koniec
                        if(data_size >= alloc_size){
                                alloc_size *= 2;
                                raw_data = realloc(raw_data, sizeof(T)*alloc_size);
                        }
                        new(data(data_size)) T(x);

                        ++data_size;
                }

                void Remove(){                  //odstrani prvok z konca
                        if(data_size){
                                data(--data_size)->~T();
                        }
                }

                Vector(std::initializer_list<T>&& ilist):Vector(ilist.size()){
                        for(const T& x: ilist)
                                Add(x);
                }

                T* begin(){return data();}
                const T* begin()const{return data();}
                T* end(){return data(data_size);}
                const T* end()const{return data(data_size);}
};

#include <iostream>
#include <string>

int main(){
        using namespace std;

        Vector<string> vec{"string1", "string2", "string3"};
        vec.Add("string4");
        vec.Add("string5");
        vec.Add("string6");
        vec.Remove();
        vec.Add("string7");

        for(auto& str : vec)cout << str << '\n';

        return 0;
}
Editováno 13.10.2013 19:45
 
Nahoru Odpovědět
13.10.2013 19:45
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 24 zpráv z 24.