Írj egy függvényt, ami bekér két egész számot és egy logikai változót!
Ha a logikai változó igaz, akkor adja vissza a két szám összegét!
Ha a logikai változó hamis, akkor adja vissza a két szám szorzatát!
Ezután a main-függvényben demonstráld a működését!
Ebben kell használnod a return-utasítást és ha ezt megcsinálod, valószínűleg meg is érted, hogy mi az.
Na, vivo válaszából azt hiszem egy új kapu nyílt meg előttem: a return az egy function-nek, vagy hogy hívjáknak az értéke, tehát ez:
int test()
{
a = 10;
b = 5;
return a + b;
}
cout << int test()
15-öt fog kiírni. Tudom, hogy nincs semmi include, meg int main()..., de most csak egy ilyen szemléltetésre gondoltam, nemtom helyes-e, ez itt a következő kérdés.
Egy nem típusos nyelv után szinte megváltás egy típusosra áttérni, mert egy csomó hibát eleve elkerülhetünk vele.
De az elején a programozás alapjait tanulni szerintem szuper egy olyan programnyelv, amit nem kell installálni, mindenhol ott van, és egyből ki lehet próbálni.
Jobban teszi, hogy ha nem JS-sel kezd (márcsak azért is, mert típus nélküli nyelvről típusosra váltani nagyon nehéz), főleg nem parancssorból, mert egy életre elmegy a szakmától a kedve.
Inkább a Turbo Pascal-t ajánlanám, de ha a topiknyitó ragaszkodik a C++-hoz, az az ő sara.
A Python-nak is lenne annyi értelme, hogy a helyes formázásra szoktatná, de sajnos az se típusos.
Jól elbeszélgetünk itt mindenféléről, de azért reagálnék a topicnyitóra:
A topicnyitó valószínűleg még nem érti azt, hogy mit jelent a 'függvény' fogalma programozási nyelvekben. (Ezek legtöbbünknek nyilvánvaló dolgok, de ez is infó, amit tanítani kell kezdőknek: bevezető tananyagok tárgyalják, hogy mik a formális paraméterek a lokális scope-ok, visszatérési értékek, stb...)
Mondjuk ezen a szinten én csak egy nyelvvel foglalkoznék és az nem a C++ lenne, hanem inkább max. a C.
A topicnyitónak ajánlom, hogy ismerjen meg egyetlen egy viszonylag egyszerű nyelvet viszonylag rendesen. Pl. Keressen valami jó bevezető könyvet Pl. Pascal-hoz vagy C-hez.
És írjon egy függvényt, ami egy szám négyzetét számolja ki.
Ha a baloldai kifejezés egyszerű változó, akkor valóban ugyan az lesz a kód hossza. De nézd végig az előző hsz-eimet! Ott mutatok egy példát (meg előttem már mutattak még sokan), amiben bizony teljesen más lesz a fordítás.
Amég nem voltak ilyen szuper optimalizált fordítók, mint ma, addig a 3 sor 3 különböző dolgot jelentett, és 3 különböző programot sikerült volna fordítani belőle. Ez ma már szeretem-nem szeretem jellegű, de régen teljesítmény szempontjából is számíthatott.
Pl:
Jah, és tök jó hogy az elvesztegetett 3 nanosec miatt aggódsz, de hashtableban tárolod az elemeket. Szerintem nagyságrendi különbség van a táblából a keresés és az összeadás között.
Kicsit vonatkoztass már el! Honnan tudod, hogy a hash_table-függvény nem egy sokterás adatbázisban keresgeti a megfelelő kulcsot, vagy honnan tudod, hogy az a egy tömb, ahol az indexelés az indextől függetlenül konstans időben fut és nem egy félgigás lista, ahol az indexelés ideje bizony lineáris, és mondjuk a 2345. adatelem megkeresése nem mindegy, hogy kétszer, vagy csak egyszer történik meg?
Vagy lehetne az a akár egy teljesen absztrakt adattípus is, ami a merevlemezről olvas be valamit és a merevlemez IO-műveletei sem éppen a sebességükről híresek.
Az kizárt.
Mutatok egy példát, amikor mást csinál.
#include <iostream>
//#define rovid
int hash_table(int b){
static int c=0;
std::cout << ++c << "-szer hívtad meg.\n";
return b;
}
int main(){
int a[5];
for (int i=0; i<5; i++) a[i]=0;
#ifdef rovid
a[hash_table(2)]+=15;
#else
a[hash_table(2)]=a[hash_table(2)]+15;
#endif
return 0;
}
Futtasd le, aztán vedd el a #define elől a //-jelet, és futtasd újra! Más lesz az eredmény.
Ha a hash_table egy másik forrásállományban van megvalósítva, akkor már elméletben is csak a linkernek tűnhet fel, hogy a hash_table ugyan azt csinálja-e a meghívások számától függetlenül, tehát a lefordított object-fájlok biztosan másra fordulnak.
Tehát a fordító ugyan nem fogja neked kiopimalizálni a a[hash_table(2)]=a[hash_table(2)]+15;-eidet a[hash_table(2)]+=15;-re.
Ez már kicsit erőltetett, mert attól függ a hash érték, hogy hányszor hívod meg a függvényt.
Eddig mindenütt azt olvastam, hogy a két kifejezés egyenértékű, mert a fordítók úgyis kioptimizálják. Gondolom akkor szimpla változókra csak igaz, de nem próbáltam ki. Ugyanakkor külön felül lehet definiálni az oprator+= -t.
"Ez teljesen ugyan az. Már a parser szinten ugyanaz a syntax tree lesz belőle. Akkor lenne ez fontos, ha az objektumnak felül lenne definiálva a + operatora."
Csaboka2 példája kiváló, de íme mégegy példa Mate12345 elméletéből kiindulva:
// Ebben az esetben elvileg tényleg mindegy:
int hash_table(int b)
{
return b;
}
// Ha ezt hívod, nem lehet belőle baj:
a[hash_table(1)] = a[hash_table(1)]+15;
// DE! Ha így írod meg a függvény törzsét:
int val = 0;
int hash_table(int b)
{
val += b;
return val;
}
// Aztán ezt így meghívod:
a[hash_table(1)] = a[hash_table(1)]+15;
// komoly bajban leszel, debug-olhatsz ezerrel...
// A legvalószínűbb hiba itt az intexhatár túllépése lehet a tömbön,
// ez már csak a kisebbik gond, hogy a program nagyon nem jól fog működni.
// De ha így használod, akkor a várt eredményt kapod:
a[hash_table(1)] += 15;
Mate12345 nagyon helyesen mondta, és ez a lényeg:
"A fordító biztosan nem fogja neked kioptimalizálni, mert nem tudja, hogy nem pont az-e a célod, hogy a hash_table kétszer hívódjon meg."
A C filozófia szerint a programozó tudja mit csinál, és ez a fordítóra is igaz. A compiler nem fogja a programozó helyett kitalálni, mit akart leprogramozni.
Nem tudjátok, a gcc-ből hogy lehet kicsikarni a C-ből fordított assembly kódot? (bár most jut eszembe, lehet, hogy rosszul keresgéltem a man-ban)
Kíváncsi lennék, ha nem függvényhívás áll az = két oldalán, akkor az optimizer boldogul-e vele, vagy akkor is eltérő kódot fordít.
Ez teljesen ugyan az. Már a parser szinten ugyanaz a syntax tree lesz belőle. Akkor lenne ez fontos, ha az objektumnak felül lenne definiálva a + operatora.
Hát pont hogy nem. A nyelv garantálja, hogy az összetett értékadás bal oldala csak egyszer értékelődik ki. Ha nem hiszed, járj utána:
#include <stdio.h>
int val = 42;
int* foo() {
puts("foo called");
return &val;
}
int main() {
puts("simple addition:");
*foo() = *foo()+2;
puts("compound addition:");
*foo() += 2;
return 0;
}
Ez nálam ezt adja:
simple addition:
foo called
foo called
compound addition:
foo called
Szóval Mate12345-nek igaza van, a += gyorsabb lehet, ha a bal oldalán drága kifejezés van.
Szerinted mihez adódik hozzá a konstans? Ahhoz nem kéne tudni az értékét vagy csak úgy hozzácsapjuk valamihez ami valahol van és már kész is ?
Megnyugtatásul, természetesen én is használom ezeket, csak kifejtettem róluk a véleményem. Egy kezdőnek amúgy is nehéz.
Jah, és tök jó hogy az elvesztegetett 3 nanosec miatt aggódsz, de hashtableban tárolod az elemeket. Szerintem nagyságrendi különbség van a táblából a keresés és az összeadás között.
Egy waldorf iskolaban talan. De ott az is eleg lehet, ha enekelsz egy dalt amiben van A, B, C betu.
Hmm.. Talán az lenne a jó megoldás, ha előre kitűznék a pontozási módszert. Az kiderült, hogy tudja használni a nyelvi elemeket, meg jól használta a változókat.
A cégeknél egyszerűen ki van adva egy coding style és azt kell követni. Ha nincs deklarálva, hogy ahol lehet melyik formát kell használni, akkor használhatod mindkét formát.
Az emberek meg egy idő után begyöpösödnek. Beáll a napi rutin, mindig ugyanakkor kell, elszívja, megissza, ugynazt az utat megteszi, ugyanazt az anyagot leadja, ugyanazokat a kérdéseket fölteszik, ugyanazokat a hibákat elkövetik, ugyanazzal védekeznek, stb..
a[hash_table(b)]=a[hash_table(b)]+15;
kontra
a[hash_table(b)]+=15;
Ez teljesen ugyan az. Már a parser szinten ugyanaz a syntax tree lesz belőle. Akkor lenne ez fontos, ha az objektumnak felül lenne definiálva a + operatora.