Ahoj. Mám dotaz. Proč mi při vytváření furt háže tuhle chybu? Jak to NULL mám deklarovat? Díky :)
Ahoj. Mám dotaz. Proč mi při vytváření furt háže tuhle chybu? Jak to NULL mám deklarovat? Díky :)
vložit hlavičkový soubor, chtělo by to pogůůůglit... ale mohlo by to být stdlib.h
hu
#2 hlucheucho
Bohužel ani tak mi to nefunguje.
Mám vytvořenou vlastní knihovnu. Není to tím? Pořád nemohu přijít na to, kde mám chybu. :/
Systémové includy se normálně píšou do pičatých závorek #include <stdlib.h>.
Program se nepíše do stdafx.cpp. Při použití předkompilovaných knihoven v MSVC musí každý .cpp soubor začínat includem "stdafx.h".
Ten nullptr znamená, že místo NULL budeš psát nullptr.
#6 gna
Děkuji za rady, ale mám ještě jeden problém. Mám knihovnu (.h) ten by měl být dobře.
struct Tstruct;
void StackInit(Tstruct* *TOP);
Tstruct * StackPush(Tstruct * TOP, long VALUE);
long StackPop(Tstruct* *TOP);
long StackShow(Tstruct *TOP);
bool StackIsEmpty(Tstruct *TOP);
void QueueInit(Tstruct* *HEAD, Tstruct* *TAIL);
Tstruct* Enqueue(Tstruct* *HEAD, Tstruct *TAIL, int VALUE);
long Dequeue(Tstruct* *HEAD, Tstruct* *TAIL);
long QueueShow(Tstruct *HEAD);
bool QueueIsEmpty(Tstruct *HEAD);
A pak mám (.cpp)
struct Tstruct
{
long value;
Tstruct *next;
};
void StackInit(Tstruct* *TOP)
{
*TOP = nullptr;
}
Tstruct * StackPush(Tstruct *TOP, long VALUE)
{
Tstruct *hlp = new Tstruct;
if (hlp != nullptr)
{
hlp->value = VALUE;
if (TOP != nullptr)
{
hlp->next = TOP;
}
else
{
hlp->next = nullptr;
}
}
return hlp;
}
long StackPop(Tstruct* *TOP){
Tstruct *hlp;
long val;
hlp = *TOP;
*TOP = hlp->next;
val = hlp->value;
delete hlp;
return val;
};
long StackShow(Tstruct *TOP)
{
if (TOP != nullptr)
{
return TOP->value;
}
else
{
return nullptr;
}
}
bool StackIsEmpty(Tstruct *TOP)
{
return (TOP == nullptr);
}
void QueueInit(Tstruct* *HEAD, Tstruct* *TAIL)
{
*HEAD = nullptr;
*TAIL = nullptr;
}
Tstruct* Enqueue(Tstruct* *HEAD, Tstruct *TAIL, int VALUE)
{
Tstruct *hlp = new Tstruct;
if (hlp != nullptr)
{
hlp->value = VALUE;
hlp->next = nullptr;
if (TAIL == nullptr)
{
TAIL = hlp;
}
else
{
TAIL->next = hlp;
}
if (*HEAD == nullptr)
{
*HEAD = hlp;
}
}
return hlp;
}
long Dequeue(Tstruct* *HEAD, Tstruct* *TAIL)
{
long value = nullptr;
if (*HEAD != nullptr)
{
Tstruct *headPrvek = *HEAD;
value = headPrvek->value;
*HEAD = headPrvek->next;
delete(headPrvek);
}
return value;
}
long QueueShow(Tstruct *HEAD)
{
if (HEAD != nullptr)
{
return HEAD->value;
}
else
{
return nullptr;
}
}
bool QueueIsEmpty(Tstruct *HEAD)
{
return (HEAD == nullptr);
}
A u long StackShow, long Dequeue, long QueueShow mi to u nullptr hlásí chybu a nechce mi to vzít. Kde mám chybu prosím?
v .cpp není žádný include?
hu
#7 Sss
nullptr se bere z hlediska jazyka jako pointer a pokud se ho snazis narvat do typu long (o coz se tim return nullptr snazis), tak to bude hlasit chybu. Takovy NULL byl vetsinou definovan jako 0, takze to proste vratilo 0L. Otazkou je, jestli je tohle zrovna spravne chovani. Nula muze byt i vcelku zadana hodnota.
Pokud ale vis co delas, tak muzes pouzit explicitni konverzi, nebo rovnou vracet primo 0L misto nullptr. (jen jako priklad, jak by to slo udelat, jinak je to prasecina)
#10 Sss
Jelikoz pouzivas C++, tak by se cela fronta dala zabalit do tridy. To co tam mas ted, je ve stylu C. Jelikoz je to skolni uloha, tak se neda pouzit neco existujiciho ze STL (standard template library), jelikoz ucelem zadani je zjistit, jak to vlastne funguje interne.
Pri ziskavani prvku z prazdneho zasobniku bys mohl vyvolat vyjimku. U STL knihoven je to tam popane jako undefined behavior (muze to udelat temer cokoliv), do toho by asi padlo i vraceni nuly :D
#14 Staon
o tom bych si rad pocetl, proc.
Kazdopadne, co se pouzije tak trochu naznacuje programatoruv zamer. Kdyz se pro pointer pouzije NULL nebo nullptr, tak je zrejme, ze autor chtel nastavit pointer.
char * retezec = "whatever";
retezec = 0; // ????? co tim chtel autor rici?
// je to "veskrze" to same jako:
retezec = NULL; // ale ano, tady chtel nastavit pointer na NULL (nebo lepe nullptr)
// ale mozna ho chtel jen "vyprazdnit" ale ponechat "buffer" a zapomnel na dereferenci:
*retezec = 0; // opet neni uplne jasny zamer
// stale mohl chtit jen na prvni pozici v poli
// nastavit znak '0' a ne znak NUL (znak pro ukonceni retezce)
*retezec = '\0'; // tady je zrejme, ze to mel byt opravdu znak NUL
Je to stale ta sama 0, ale pro cloveka, co to cte je pak daleko jasnejsi zamer. A tim padem se da snadneji odhalit chyba.
#15 KIIV
NULL se nedoporučuje používat kvůli přenositelnosti a jednoznačnosti následujícího kódu:
void f(void* p_);
void f(int i_);
void f(long l_);
f(NULL);
Vzhledem k tomu že NULL je pro různé překladače a různé konfigurace jednoho překladače definovaný různě, se na každém zavolá jiná funkce. Máte naprostou pravdu, že NULL vyjadřuje záměry programátora, ale zároveň dokáže způsobit nečekané chyby - v tomto konkrétním případě na většině překladačů zavolá právě úplně jinou funkci, než byl autorův záměr. Autoři standardu si toho byli vědomi, proto od C++11 zavedli nullptr.
#21 Kit
V C bez sance.
Null objekty - v C++ ne vzdy potrebujes polymorfizmus (tabulka virtualnich trid ma jistou malou cenu - obvykle je to spis na bazi branch prediction a podobne) a bez nej to bude zase trida, s nejakym testovanim uvnitr, jestli je to zrovna ten "null objekt" nebo ne. Neco jako end pro istream_iterator a podobne...
Kazdopadne, to co sem dal autor vlakna za kod, to je tezke C (kompilovane v C++)
Krom toho si neumim moc predstavit null objekt pro POD typ (pokud nepocitame 0, ale to je furt validni hodnota). Muze vyhodit akorat vyjimku, ze ma kontrolovat, jestli je nejaky prvek vubec k dispozici, pred tim, nez ho ziska a odebere.
#19 Radek Chalupa
Nemůžete si nadefinovat sám NULL. Tohle makro je ve standardních knihovnách, a pokud ho nadefinujete jinak, získáte od překladače spoustu chyb, že definice makra je rozdílná. A obecně nepomůže ani undef, protože stačí, aby se systémová definice v pořadí vkládaných hlaviček dostala za vaši definici.
Navíc, pokud byste chtěl, aby se NULL chovalo "očekávaně", pak byste makro musel nadefinovat nějak takto:
#define NULL ((void*) 0)
Pak by se skutečně vybrala očekávaná funkce s ukazatelem. Některé překladače používají tuhle definici; pokud si dobře vzpomínám svého času BorlandC na MS-DOSu.
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku