Friday, November 18. 2005Et par programmer...I denne forgangne uge har denne dogg ikke fået skrevet så meget kode til større projekter, men derimod brugt tid på at skrive to mindre utilityprogrammer. Begge programmer er skrevet i portabel C++ og har kommenteret kildekode. Vi er i datalogi blevet færdige med at bruge ondskabens sprog, og jeg kan således gå i gang med at glemme min frygtelige skam. I stedet er vi gået over til maskinarkitektur og assemblyprogrammering, til hvilket vi benytter en noget primitiv virtuel maskine ved navn WinDavid. Den maskine WinDavid simulerer har 0 general purpose-registre, og et instruktionssæt der er så begrænset, at det knapt er muligt at fatte. Ydermere er standardindstillingen for den interne repræsentation af tal decimal, og ikke binær, som på næsten alle virkelige maskiner. Det tog mig en rum tid at fatte helt præcist hvor ulækkert dette er. Nuvel, det var en smule kedeligt blot at skrive kode i det meget simple assemblysprog, derfor har jeg i stedet valgt at skrive en selvstændig assembler, davidasm. Det er en meget simpel assembler, men den kan generere gyldige WinDavid DBI-filer. Den understøtter labels, så man ikke behøver bruge rene adresser som adresseparameter til instruktionerne, og har begyndelsen til understøttelse af segmenter. Jeg arbejder stadigvæk på programmet (i datalogitimerne). For femte gang. Pis! Det andet program jeg har arbejdet på er nok noget mere interessant og alment brugbart. Der er tale om en eHTML-parser, der kan parse en fil indeholdende eHTML/UBBC (det markup-sprog man bruger på webfora, med [i], [b], [url], etc) og generere HTML - eller stort set ethvert andet nested markup-sprog. Koden er meget velkommenteret, og er designet til at være let at forstå, og ikke bruge mange obskure C++-features. Parseren blev skrevet til Kasper Tanggaard, for at han kunne bruge den på næste udgave af Udvikleren.dk, og blev derfor portet til C# af Simon Valter. Hans kode kan hentes her. Parseren udfører grundlæggende fejlretning af input, og er designet til så vidt muligt ikke at generere ugyldig HTML, selv hvis den modtager uhyre fejlfyldt input. Monday, August 8. 2005Brøøøl, Ogre!I de seneste par dage har jeg arbejdet med OGRE, en open-source grafikmotor skrevet i C++. Jeg havde ikke regnet med at jeg nogensinde skulle finde programmering af 3D-miljøer interessant, eller arbejde på at udvikle spil, men jeg må nødvendigvis indrømme at det er rigtigt rart at arbejde i OGRE. OGRE har en meget veldesignet og objektorienteret API (selvom jeg synes at det er lidt plat at de har reimplementeret reelle tal), der næsten kun kan betegnes som "god C++." Nu og da opfører det sig lidt mærkeligt (sær med hensyn til skygger), men det kan muligvis være et hardwareproblem, da jeg for tiden bruger et aldrende Geforce2 MX. En af de helt store fordele ved OGRE er at det er 100% portabelt, og kan bruge både OpenGL og DirectX som underliggende renderer. Det er helt klart et plus, når man skal arbejde sammen med andre. Jeg anbefaler alle med interesse i programmering af 3D-miljøer til at tage et kig på OGRE. Er der forresten nogen der ved hvornår undervisningen på Avedøre Gymnasium starter igen? Saturday, July 16. 2005Tilbage til rødderneOm lidt over en uge skal jeg til Game Development Camp 2005, hvor jeg regner med at jeg primært skal koncentrere mig om C++ og Virtools. I den seneste tid har jeg primært beskæftiget mig med Lisp, så derfor er jeg i gang med at lave nogle små programmer, bare for at komme i træning igen. En populær begynder-opgave inden for objektorienteret C++ går ud på at designe et klassehieraki, hvor en klasse som "Figur" er rod, og så har diverse subklasser som "Firkant," "Cirkel" og "Trekant." Denne opgave kan naturligvis løses i simpel C++ (derfor er det en begynderopgave), men hvorfor lade sig nøjes med det? Multiple inheritance er da et must (highlightet kode). Lad det program stå som et tegn på C++'s ekstreme verbositet, og mine yderst ringe evner til at tegne ASCII-trekanter programmatisk. Sunday, March 6. 2005Comments (2) Trackbacks (0) Min digitale tissemand er større end din digitale tissemand!Monogami fra IRC-kanalen #udvikleren.dk præsenterede i dag en udfordring for mig: <vuSti-Monogami> Athas tag den her udfordring - skriv en max(a,b,c,d,e,f) uden brug af variabler i c Det virkede som en meget interessant lille udfordring. Desværre var det med et begrænset antal variabler (a,b,c,d,e,f), så det var en del lettere end først antaget. Monogami's egen løsning, der er O(n^2+k), ser således ud:
max(a,b,c,d,e,f)
{
return f>(e>(d>(c>(a>b?a:b)?c:(a>b?a:b))?d:
(c>(a>b?a:b)?c:(a>b?a:b)))?e: (d>(c>(a>b?a:b)?c:(a>b?a:b))?d:
(c>(a>b?a:b)?c:(a>b?a:b))))?f:
(e>(d>(c>(a>b?a:b)?c:(a>b?a:b))?d:
(c>(a>b?a:b)?c:(a>b?a:b)))?e:(d>(c>(a>b?a:b)?c:
(a>b?a:b))?d:(c>(a>b?a:b)?c:(a>b?a:b))))
}
Den virker, men er som nævnt langsom, og stort set ulæselig (det ligner faktisk Brainfuck). Efter at have konsumeret henved en halv kande the, fandt jeg på følgende program (C++):
#include <iostream>
#include <cstdarg>
using namespace std;
// This is a comment. In fact, this is the only comment you will see in this code.
template <typename T>
T max(T a, T b, T c, T d, T e, T f)
{
// Okay, I lied, here's another comment.
if (a > b) {
b = a;
for (a = reinterpret_cast<T>(&c); reinterpret_cast<T*>(a) <= &f; a+= sizeof(T)) {
if (*(reinterpret_cast<T*>(a)) > b)
b = *(reinterpret_cast<T*>(a));
}
return b;
}
else {
a = b;
for (b = reinterpret_cast<T>(&c); reinterpret_cast<T*>(b) <= &f; b+= sizeof(T)) {
if (*(reinterpret_cast<T*>(b)) > a)
a = *(reinterpret_cast<T*>(b));
}
return a;
}
}
int main(int argc, char** argv)
{
cout << "Max er: " << max(3212, 32120, 32, 3, 666, 1337) << endl;
}
// This is the last comment.
Så kom jeg i tanke om at programmet skulle være i C. Det blev til følgende:
#include <stdio.h>
int max(int a, int b, int c, int d, int e, int f)
{
if (a > b) {
b = a;
for (a = &c; (int*)a <= &f; a+= sizeof(int)) {
if (*(int*)a > b)
b = *(int*)a;
}
return b;
}
else {
a = b;
for (b = &c; (int*)b <= &f; b+= sizeof(int)) {
if (*(int*)b > a)
a = *(int*)b;
}
return a;
}
}
int main(int argc, char** argv)
{
printf("Max er: %d\n", max(666, 1337, 67000, 412300, 3221, 32123));
}
Lad mig med det samme sige at programmerne ikke er portable. De bruger grimme konverteringer mellem int og int*, hvilket er no-no. Det burde dog virke på næsten alle platforme (hvis ikke alle), men ifølge de respektive sprogs standarder, er programmernes opførsel udefineret. Ideen er at de to første parametre analyseres, for at se hvilket af dem der er størst (eller om de er lige store). Det parameter der har den mindste værdi (eller bare et af dem, hvis de er lige store) bliver så "discarded," og brugt til at indeholde adressen på næste parameter. Det parameter der har den største værdi (eller det andet af dem, hvis de var lige store), bliver så brugt til at indeholde den pt. største værdi. Derefter itereres der blot igennem parameterstakken (hvor adressen på det sidste parameter bruges som terminator for itereringen), og hvis der findes en ny største værdi, overskrives den eksisterende største værdi. Til sidst returneres det parameter hvori den største værdi er gemt. Det er lige så simpelt som det er elegant (*host* *host*). Algoritmerne er så vidt jeg kan se O(n+k), så det burde teoretisk set ikke kunne gøres hurtigere. Hvis I har nogle gode idéer til hvordan dette problem ellers kan løses, så må I meget gerne fortælle mig om det. :-) Wednesday, February 23. 2005Døde træer styrer!Mine nye bøger er netop ankommet - der er tale om Algorithms in C++ Parts 1-4 og Algorithms in C++ Part 5. Begge bøger er skrevet af Robert Sedgewick, og der findes også udgaver til C og Java. Begge bøger er naturligvis udgivet af Addison-Wesley (udgiver de alt det gode i disse år?), hvilket bringer antallet af AW-bøger jeg ejer op på 7. Som en ekstra bonus undlod Post Danmark at ødelægge bøgerne, hvilket unægteligt er et stort plus. Det eneste minus er at jeg måtte slippe over 800kr for fornøjelsen - penge jeg godt kunne have brugt andetsteds (på flere bøger!) Friday, February 18. 2005Lidt af hvertKasper Tanggaard (KasperTSW), manden bag udvikleren.dk, Tanggaard SoftWare, TSW WebCoder, IRC-kanalen #udvikleren.dk på QuakeNet og en masse andre ting, har lavet sig en blog: Clicky. Han skriver om sådanne fascinerende ting som gigantiske messingtommelfingre (naturligvis en allegori for en fallos) og hans piven over at være militærnægter. Han har også en shoutbox, så fly fluks til hans online domicil, og informér ham om graden af hans lyriske brug af hans rektum. Han programmerer i Delphi og C#, men han er god nok alligevel. De af jer der er mere end almindeligt opmærksomme, vil nok have bemærket at dette indlæg er postet under C++-kategorien. Dette er fordi jeg nu vil skamrose en bog jeg købte for nogle uger siden: The C++ Standard Library: A Tutorial and Reference (Josuttis). Bogen gennemgår, overraskende nok, C++'s standardbibliotek, som den er specificeret af den seneste ISO-standard. Tutorial-delen af bogen er nok noget tvivlsom, med mindre man i forvejen har erfaring med C++, men som reference er bogen uovertruffen - hvert emne kan læses fuldstændigt isoleret, og hvor der er behov for eksterne referencer benævnes det med sidenummer. Der er også et meget fyldigt stikordsregister, så det skulle være muligt at finde selv de mindste detaljer om standardbiblioteket. Bogen påpeger også visse bugs i standarden, og forklarer hvordan de fleste implementationer arbejder omkring dem. Bogen gennemgår kun standardbiblioteket - der er intet om selve sproget, men kombineret med en bog som The C++ Programming Language (Stroustrup) er bogen suveræn som reference. Den kan anbefales til alle brugere af C++'s standardbibliotek, hvilket forhåbentligt er næsten alle C++-programmører. Monday, January 10. 2005Han har gjort det igen!
Mit episke opus er færdiggjort, og er tilmed blevet godkendt på Udvikleren.dk! Jeg refererer her til en større artikel om templates, containers og algoritmer i C++, en artikel der udspringer fra en mindre en om containers, som jeg påbegyndte i sommers. Artiklen er at finde her: http://www.udvikleren.dk/article.php?techid=1&aid=236
Nu mangler jeg bare at finde ud af hvad min næste artikel skal handle om...
Sunday, January 2. 2005C vs C++ vs C#
I disse dage er der meget hype omkring et såkaldt programmeringssprog kaldet C#. Hypen er muligvis ikke så meget omkring selve sproget, som omkring det framework det er designet til, navnlig det næsten mytologiske .NET-framework, en Java Virtual Machine der ikke er portabel. Oprindeligt var .NET bare et marketing brand, Microsoft hypede det ved at messe "XML, XML, XML" ved enhver given lejlighed, og ingen vidste rigtigt hvad det var. Der var dog en masse tech-journalister der spekulerede meget over det, og disse journalister skrev om hvad de troede .NET ville blive. Microsoft tog så de bedste af disse idéer, og gjorde dem til et produkt. Jeg har nogle .NET artikler fra starten af årtusindet, og fra dem virker det mest som om at .NET er en XML-baseret indkøbsvogn der kan køre på Smartphones. Måske skulle de være blevet ved det...
Nuvel, det er ikke .NET jeg vil kritisere i dette indlæg, men derimod vil jeg svine C# til. Mange erklærer det som en arvtager til såvel Java som C++, men det er jo helt tydeligt at C# ikke kan bruges til dette. I denne sammenligning vil jeg udelade Java, idet diskussionen ellers vil blive alt for kompleks.
Lad os sammenligne C# med andre sprog, på hvad der virkelig tæller:
Monday, December 27. 2004Comments (2) Trackbacks (0) Templates styrer noget så grusomt!
I forbindelse med Gnusay har jeg udviklet et variabelsystem til de gnufiles programmet benytter sig af. Hele systemet er opbygget via C++ templates, hvilket giver mig en fantastisk flexbilitet. F.eks. har jeg en variabeltype (gnuvar_dep) der er afhængig af en anden variables værdi. Den metode information hentes ud af den anden variabel på, er ikke hardcoded ind i klassen, men specificeres derimod via et template-parameter, et funktionsobjekt der definerer operator(), og derved specificerer hvordan variablen skal analyseres.
Eg:
template<typename T, class P = policies::basic<T> >
class gnuvalue_dep : public gnuvalue<T>
{
public:
gnuvalue_dep(gnuvalue<T> *n_gvp, P n_o = P()):
m_gvp(n_gvp), m_policy(n_o)
{}
gnuvalue<T>& operator=(const T& rhs)
{
m_policy.assign(m_gvp->m_real_val, rhs);
}
T val() const
{
return m_policy(m_gvp->val());
}
protected:
gnuvalue<T> *m_gvp;
const P m_policy;
};
Et policy-objekt kan så være:
template<class T>
class basic
{
public:
T operator()(const T& n_p)
{
return n_p;
}
basic& assign(T& n_p, const T& rhs)
{
n_p = rhs;
return *this;
}
};
Dette er et meget simpelt objekt, men i princippet kan man gøre alt hvad et objekt af typen T understøtter. Min teknik er stadigvæk meget kluntet, men jeg er allerede blevet meget fascineret af de muligheder opfindsom brug af templates leverer. Templates er også en 100% compile-time feature, så koden kører ikke langsommere af det. Med denne sprogfeature har Bjarne virkelig skudt papegøjen.
Wednesday, December 8. 2004Comments (2) Trackbacks (0) The Design and Evolution of C++
I de sidste to uger har jeg læst Bjarne Stroustrups bog The Design and Evolution of C++, en bog der i detaljer beskriver C++'s udvikling fra C with Classes til ISO C++. Bogen er skrevet før sproget blev fuldstændigt standardiseret, men det er ligegyldigt, da de fleste større features var på plads (multiple inheritance, templates, RTTI, etc.). Bogen beskriver de overordnede idéer der ligger til grund for C++'s design, og Stroustrup fortæller om hans filosofi om sproget som et redskab der ikke skal forsøge at begrænse programmøren, men levere stærke faciliteter der enten kan misbruges eller bruges korrekt. Stroustrup mener ikke at sproget skal fungere som en babysitter, og dette vil jeg give ham ret i. Der er mange der bruger det som et argument imod C++, at sproget er så komplekst, og at det er så let at lave ulæselig kode og rodede designs, men det handler jo i grunden bare om at bruge redskaberne ordentligt. Du kan da heller ikke tillade at brokke dig, hvis din nyindkøbte boremaskine fungerer dårligt som brødkniv, vel?
Bogen er meget præget af Stroustrups egne holdninger, hvilket især kommer til udtryk i det sidste (heldigvis meget korte) kapitel hvor han fortæller om cpp - C's preprocessor. Denne kan han tydeligvis ikke lide, for hele kapitlet handler om hvor meget han hader den og hvordan C++ skal have et include-direktiv der kan erstatte #include (dog ikke en dårlig idé). Dette synes jeg er lidt i konflikt med hans teori om "trust the programmer," men ham om det, han indrømmer selv at det nok bliver meget svært at få fjernet preprocessoren.
Alt i alt en spændende bog som jeg vil råde enhver C++ programmør til at læse. Stroustrup forklarer meget godt hvordan C++ er opbygget, hvilket kan være nyttig viden når man skriver programmer. Så kan du lære at arbejde med sproget, i stedet for imod det.
Wednesday, November 3. 2004The C++ Programming Language
Det er ikke en ny bog, jeg har tilmed haft den i lang tid, men den er så god at jeg bare må reklare for den. Jeg snakker om Stroustrups bog The C++ Programming Language - den "store" C++-bog (Amazon). Det er tør læsning og bogen er på ingen måde beregnet på nye programmører der vil lære C++, men derimod erfarne programmører der vil have en definitiv guide til sproget. Praktisk taget alle detaljer gennemgås, lige fra så "uanvendelige" begreber som reglerne for størrelsesforhold mellem de grundlæggende datatyper, til designovervejelser i forbindelse med multiple inheritance. Bogen går meget kategorisk frem, men der er ingen garanti for at en feature er gennengået før den bruges i de mange kodeeksempler, så det er en forudsætning at man har en rimeligt bred viden om C++ før man går i lag med denne bog.
Men, helt ærligt, vi ved jo allesammen at det er en myte at man køber bøger for indholdet - det er indbindingen der tæller, og ej her skuffer The C++ Programming Language. Min hardcover-udgave har en flot, solid hvid indbinding der ligger godt i hånden. Papiret er af den tynde, men alligevel slidstærke, art som de fleste større værker trykkes i, og med en lavere kvalitet ville bogens godt 1000 sider nok også hurtigt falde ud.
Generelt er dette dog en helt fantastisk bog, jeg har kun fået læst en 300-400 sider, men jeg er allerede meget begejstret for den. Når jeg har fået den læst færdig vil jeg skrive en mere fyldestgørende anmeldelse.
Saturday, October 16. 2004Om C++
Forleden dag faldt jeg over denne artikel: http://www.artima.com/cppsource/spiritofc.html
Den omhandler C, C's filosofi, og visse andre sprog af C-stammens overholdelse af disse. Især simplicitet er et af de emner forfatteren berører, og han afholder sig da ikke fra at give C++ et par hug for dets kompleksitet. Han mener at C++'s komplicerede typesystem bryder en af grundreglerne for C, navnligt det der handler om at sproget bør holdes let og simpelt. Dette kan meget vel være korrekt, men samtidigt er han offer for en udbredt misforståelse, en misforståelse der går ud på at mange programmører mener, at fordi C++ understøtter flere features end de fleste andre sprog, så skal de udnyttes.
Dette kunne ikke være mere forkert. Et program hvor alle C++'s features blev brugt, ville være uoverskueligt og næsten umuligt at vedligeholde - det forhindrer dog ikke mange i at forsøge! C++ kan praktisk taget gøre alt hvad C kan (med nogle få, obskure undtagelser), så hvis man virkelig har lyst til det, kan man skrive usikker, C-agtig kode. Ja, hvis man mener at typesikkerhed er djævlens værk kan man jo altid nøjes med at bruge void*!
C++ er et sprog der programmeres som programmøren ønsker - generic programming, OOP, procedureorienteret programmering, stort set alt kan lade sig gøre, hvilket er uhyre smart, fordi der ikke er én gylden metode til al softwareudvikling (selvom OOP ofte fremhæves som en sådan). Jeg mener ikke at C++, som sprog, er værre end C, bedre, hvis programmøren kan udnytte sprogets styrke, men hvis det misbruges kunne en højere produktivitet være opnået med ren C.
Det eneste større, konkrete kritikpunkt jeg ser ved moderne C++ er manglen på en garbage collector, men uden en virtual machine er noget sådan yderst kompliceret at have med at gøre. Som artiklen dog fremhæver, er en garbage collector dog ikke altid en velsignelse...
Jeg vil nok modtage hug for dette, men: C++ - et sprog for den modne programmør.
|
Language selectionFoobar (EN)
My name is Troels Henriksen, known as Athas in some parts of the Internet. This is my weblog, where I write about everything and nothing in particular. I am, at the time of this writing, a student of datalogy at the University of Copenhagen. I spend my free time programming, mostly in C++ and Common Lisp. Calendar
ArchivesQuicksearchCategoriesCreative CommonsSyndicate This Blog |
|||||||||||||||||||||||||||||||||||||||||||||||||
All original material on this website is copyright Troels Henriksen, and may only be used in accordance with the license listed in the sidebar.
