1) Nejak porad nechapu jak fungujou headery, konkretne mam v jednom headeru (header1) napsanou definici struktury (struct1), v headeru mainu mam dalsi definici struktury (struct2) ve ktere je jako clen pouzita struktura struct1. Jenze to nefunguje ikdyz je pripojen header1, funguje to jen kdyz tu strukturu v niz je jina struktura hodim do .cpp a v headeru necham jen deklaraci struct2 a predbezne deklarovanou struct1.
Takze ma pro header to, ze je v nem pres #include pripojenej jinej header vubec nejakej vliv, nebo se to projevi az v cpp.
2) Jo mozne napsat strukturu tak, aby clenem byla trida bez specifikovaneho konstruktoru. Me to porad hazi chybu dokud tam nedam napevno jeden z konstruktoru.
Doufam ze to oboji staci obecne, kdyztak poslu i kod.
#1Scrat
struktůry by správně měli být pouze v hlavičce nebo tam, kde jsou potřeba.. rozhodně bych z nich nedělal deklaraci a definici jinde - to je naprosto k ničemu
hlavně když to takto uděláš, tak je potřeba definovat i bezparametrický konstruktor
Hlavičkové soubory lze vkládat do sebe: hlavičkový soubor (např hl1.h) se struct1 vložíš do hlavičkového souboru (např hl2.h) se struct2. Hl2.h pak vložíš do .c souboru s funkcí main. Důležité je zabránit cyklickému a opakovanému vkládání hlavičkových souborů.
A jeste otazka mimo, jak probiha vypocet pri pouziti ruznych typu.
Jako treba: long = int * float + double
Jestli se pouziva pro vypocet jeden z uvedenych typu podle nejakeho klice, jako treba prvni pouzity, nebo ten nejpresnejsi... Jde me o to jestli se vysledek pocita presne a zaokrouhli se az nakonec do longu, nebo se treba protoze je prvni int pocita porad jen v celych cislech.
#8hlucheucho
Jestli je tim main.c mysleno to cemu rikam main.cpp, tak tam neni. Respektive ve vsech cpp mam Includnutej jen header kterej k nemu patri.
Jinak kdyz najedu ve struct test na struct rectInt a dam najet na definici nebo deklaraci tak skoci do spravneho headeru (kde je struktura definovana), ikdyz je v headeru mainu, kde pri kompilaci hodi ze struktura rectInt neni definovana.
Jeste me napada jestli to nemuze souviset s nastavenim cpp, kde mam asi u vsech aktivni volbu "Precompiled header" -> Not Using Precompiled Headers
#12hlucheucho
V teto typedef verzi to hlasi chybu (jmeno promenne "a" je podtrzeno) hned po zapsani, po najezdu to pise "incomplete type is not allowed". A po najezdu na rectInt a odkliknuti "go to definition" ho to nenajde.
MS VS má vnořené hlavičkové soubory např v stdafx.h. Pokud struktura adresářů a názvů souborů neobsahuje diakritiku není problém, ty konstrukce, co jsem ti s typedef dal, se bez potíží přeloží.
#21hlucheucho
Jeste jeden pokus... nasel jsem radek, kterej rozhoduje o tom, jestli se to zkompiluje nebo ne.
struct.h
#pragma once
#include "c:\Programovani\test\test\test.h"
struct rectInt
{
int left;
int top;
int right;
int bottom;
public:
void inline Set(int x, int y, int x2, int y2){left=x; top=y; right=x2; bottom=y2; return;};
};
struct.cpp - pokud vykomentuju tento include (a nasledne i pouziti struktury ve funkci), tak se to zkompiluje
do struct.h vkládáš test.h a do test.h vkládáš struct.h. To je cyklické vkládání a vzniká zmatek. Tím, že je použita pragma se zabrání opakovanému vložení a tak se to někam vloží, otázka kam. Že se to nevloží opakovaně současně způsobí, že to někde chybí. Prostě se takovým konstrukcím vyhni. Vkládané soubory mohou tvořit strom, různě rozvětvený - s tím není problém, ale nesmí tvořit kruh - do toho se snadno zamotáš.
hlavičkový soubor by měl obsahovat datové typy (třeba struktury) a deklarace funkcí. cpp by pak měl obsahovat implementaci funkcí. Pokud "struktura" obsahuje funkci, asi by bylo vhodnější to mít jako class, tam hlavičkový soubor obsahuje deklarace atributů (proměnné) a metod (funkce), cpp pak implementaci metod. U class je pak potřeba se zamyslet i nad tím, jak se s takovým objektem bude pracovat - vznik objektu, kopírování a zánik objektu. Ne vždy vyhovují defaultní konstruktory a destruktor.
#24hlucheucho
Diky za pomoc. Vedel jsem ze je to cyklicke, ale veril jsem ze toto resi pragma :(
Do tech struktur davam max. funkci na jejich snadne plneni, protoze jinak to musim rozepisovat po clenech. Respektive
test x = {10,10,10}; //pri inicializaci jde vsechny cleny zapsat //najednou
x = {20,20,20}; //tohle uz nefunguje a nevim jak jinak to udelat //nez pres tu funci
long pomIdx[100];
//tohle funguje
long * arPt = pomIdx;
funkce (&arPt); //fce chce parametr long **
//a tohle ne
funkce (&pomIdx);
Tedy nekde jsem zahlid, ze je nejakej rozdil mezi ukazatelem a polem, tak to bude asi tim, ze z pole nejde udelat ukazatel na ukazatel, zatimco z ukazatele to jde. Ale at uz je to tim nebo ne, tak kdyby to slo nejak jednoduse vysvetlit.
V prvním případě arPt je ukazatel, v podstatě "proměnná jako každá jiná". Takže pro něj platí to, co pro běžnou proměnnou, lze získat adresu kde se nachází pomocí &. U druhého příkladu bych zkusil
#29Scrat
cela pointa long ** neco je v tom, ze se muze zmenit pointer na adrese v neco.. no a u statickyho pole by to byl dost problem. Proto funguje udelat si pointer a predat adresu na ten, a je to problem zvladnout bez toho mezikroku.
Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
// IN/OUT pole, OUT nova velikost
void update(long* arr, int& len)
{
long newArr[] = { 1, 2, 3, 4, 5 }; // novy pole
len = sizeof(newArr) / sizeof(*newArr);
memmove(arr, newArr, sizeof(newArr));
}
v main() použiješ potom normálně
int main()
{
long arr[100] = { 0 };
int len; // v tomhle pripade se nastavi fci 'update' hodnota 5
update(arr, len); // nahradi za {1,2,3,4,5}
return EXIT_SUCCESS;
}
PS: se statickým polem se s v tomhle případě špatně pracuje, tady bych spíš použil alokovaný pole (ideálně kolekci)... nebo fci vracet nový pole návratovou hodnotou a né přes parametr
#34Scrat
teoreticky null být nemůže, protože statický pole nejde nastavit na null - není to přímo ptr, ale špíše reference, ale klidně si tam dej kontrolu na null ;)
výpočet velikosti tam být musí, protože nová velikost nemusí být stejná (jednoduše vypočteš velikost celého pole v bytech a potom vydělíš bytovou velikosti typu prvku)
pokud by to bylo návratovou hodnotou, tak vracet novou velikost musíš stejně, jen si ušetříš jeden řádek kódu - vlastně ne, nahradíš jeden řádek za return
Aha, uz to vidim moje chyba. Udelal jsem ty funkce vlastne 2, jednu pro dynamicky a jednu pro staticky pole, pricemz prvni byla ty dynamicka a tak jsem pouzil jeji kod a lehce ho upravil pro staticky... takze, na to staticky bude asi lepsi ta verze s memmove.
#38Scrat
nemůžeš míchat statický a dyn, to co jsem psal se týkalo statickýho pole, protože jsem vycházel z tvého kódu viz.
long pomIdx[100];
u něj není možný, aby do fce přišel null... pro dyn. pole je situace úplně jiná, hlavně nesmíš zapomenou uvolňovat pamět původního pole !! a pole jde předat parametrem jako ukazatel na referenci a opět se nevyhneš předání nové velikosti pole
např.
void update(long*& arr, int& len)
{
cout << "Zadej velikost pole: ";
cin >> len;
long* newArr = new long[len];
for (int i = 0; i < len; i++) *(newArr + i) = i + 1;
delete[] arr;
arr = newArr;
}
#39ingiraxo
Jsem jen nejak zapomel, ze jsem kdesi nahore poslal ten kod se statickym a presel jsem tedy na tu druhou fci. s dynamickym, Jo delete tam uz je i druhej parametr s velikosti pole.
Jeste kdyz mam tady vas chytry, nevite o nejake matematicke knihovne, ktera umi spocitat plochy jakekoliv uzavreneho polygonu, jehoz strany jsou kombinaci cehokoliv od usecek, po casti elips, parabol atd.
noo.. vzhledem k tomu, že tenhle topic se NEjmenuje "Pomožme Scatovi", ale "Headery a struktury" a už rozebíráme 3 téma z úplně jiného soudku, tak bych to možná utnul v zárodku a vytvořil nový topic.. co ty na to? hm?