V této části budou zveřejněny vaše dotazy i s naší odpovědí. Tak si budou moci odpověď přečíst všichni zájemci a ne pouze tazatel. Dotazy ke Kurzu C/C++ posílejte na email mého kolegy: mrandrew@atlas.cz a dotazy ke kurzu o DirectX posílejte na můj email: jiri.formanek@centrum.cz.
Pro větší přehlednost jsem rozdělil tuto sekci do více částí:
Obecné otázky
Dotazy k C++
Dotazy k DirectX
Krátké příklady
Je lepší Microsoft Visual C++ nebo Borland C++?
Osobně bych Vám doporučoval Visual C++, ale je to také věc vkusu. Pokud
nemáte nic proti Microsoftu tak jděte do Visual C++, v opačném případě do
Borlandu, který sice není špatný, ale podle mého názoru se VC++ nevyrovná.
Microsoft má určitě lepší podporu nebo spíš reklamu:)
Poznámka k
publikování článku mimo ChipCD.
Články jsou publikovány s přibližně tří měsíčním zpožděním na serveru
casopis.programator.cz.
Články na tomto serveru mohou být ochuzeny o příklady a některé obrázky.
Lze změnit nastavení již rozpracovaného
projektu na statické linkovaní MFC, aniž bych musel projekt znovu zavádět?
Samozřejmě. V menu Project zvolte položku Settings. Tam hned na
první kartě najdete způsob linkovaní. Dávejte si ale pozor na to, že konfigurace
projektu je rozdělena pro Release a Debug režim. Musíte ji
nastavit nejlépe pro oba režimy, ale hlavně pro Release, protože tuto verzi pak
distribuujete.
Mám nějakou třídu (například CMujEdit zděděný od CEdit) a
mám ji zobrazenu v panelu ClassView. Občas se stane následující věc,
které nerozumím: přidám třídě pomocí položky kontextoveho menu "Add
Windows Message Handler" nějakou oblužnou funkci, pak se mi nelíbí
co dělá a já ji chci odstranit. Pokud ji smažu ručně přímo
v kódu, stejně jako odkaz na ní v mapě zpráv a v hlavičkovém
souboru, je vše v pořádku. Pokud však kliknu v ClassView u příslušné
metody na Delete a potvrdím, že se mají odkazy smazat a tělo metody
zakomentovat, pak se někdy stane, že mi celá třída zmizí z ClassView
a zpět se mi objeví teprve poté, co pomoci ClassWizardu znovu
přidám smazanou metodu. Když ji následně vymažu "ručně", je vše
v pořádku. Čím to je způsobeno?
ClassView není dokonalé. Pokud
vymažete kousek klíčového slova "class", tak třída z ClassView zmizí
a to je v pořádku, protože vývojové prostředí tuto třídu nenajde,
ale občas se stane, že třída zmizí při normalní operaci s třídou
jako je například přidávání a mazání funkcí. Toto je chyba samotného vývojového prostředí a ani nejnovější
SP (Service Pack) tuto chybu neopravuje. Pokud se vám stane, že třída
zmizí, pokuste se vratit krok, po kterém třída zmizela a posléze ho
proveďte znovu. Pokud nejde krok vrátit, musíte buďto čekat až se jednoho
krásneho dne třída znovu objeví nebo by mělo stačit vyjmout a zase přidat
hlavičkový i implementační soubor, ve kterém je třída. Zkuste restartovat
VC++ i cely počítač a poslední možnost je, že vymažete soubory s
příponami .ncb a .opt v adresáři vašeho projektu. To jsou soubory,
ve kterých je uložena právě struktura ClassView a vy tak přinutíte
VC++, aby ji znovu vytvořilo.
Existuje nějaké freeware vývojové prostředí pro jazyk C/C++ a
kde jej mohu získat?
Ano, existuje Dev-C++ a stáhnout si ho můžete na této adrese: www.bloodshed.nu.
Nové Dev-C++ by mělo být k dispozici na ChipCD.
Jaký je rozdíl mezi cout a printf()?
Ve VC++ je možné používat
obojí, cout i
printf(). Osobně mám radši
printf(), protože
umožňuje lepší formátování – kratší a přehlednější, ale jinak je to zcela na
Vás.
Mohl byste mi vysvětlit rozdíl mezi
ukazatelem a normální proměnnou? Proč některé funkce chtějí jako parametry
ukazatele a jiné normální proměnnou?
Všimněte si, že např. funkce
SelectObject() bere
jako parametr ukazatel na objekt. Když se funkci předává parametr hodnotou (to
znamená jako normální proměnnou bez hvězdičky), udělá se kopie předávaného
objektu na stacku. Když se jedná o objekt, musí se
udělat kompletní kopie, všechny proměnné! Představte si, že objekt bude mít 20
proměnných a navíc může obsahovat další objekty – to jistě uznáte, že je značně
neefektivní, když pak tuto kopii stejně zahodíte. Mnohem lepší je, když předáte
pouze ukazatel. Takže obecně platí, že když předáváte objekty je lepší používat
ukazatele, i když nechcete objekt uvnitř funkce měnit. Naopak u běžných typů se
předává hodnota, samozřejmě pokud chcete hodnotu proměnné ve funkci měnit,
musíte předat buď ukazatel nebo referenci.
Je lepší Java nebo C++, a v čem?
Nedá se říci, jestli je lepší Java nebo C++. Za prvé, každý jazyk má své přednosti a své
nevýhody. Za druhé se jedná o dva různé typy programovacích jazyků. I když je
syntaxe velice podobná, C++ je jazyk kompilovaný tzn. že program se jednou přeloží
a pak už se jen spouští. Ale Java je jazyk interpretovaný tzn. že se kód
překládá při každém spuštění. Proto také C++ nemá svůj skriptovací jazyk (známe
JavaScript, VBScript, ale C++Script nikoliv:). Takže by
se dalo říci, že program v C++ bude vždy rychlejší než stejný program v Javě, ale
také to záleží na mnoha dalších okolnostech.
Používá se v C++ v deklaraci proměnné slovo var, co to var
znamená?
Nepoužívá. Klíčové slovo var se používá v Pascalu k
deklaraci proměnných a k předávání parametrů funkcím odkazem. Jinak
var je zřejmě od slova variable, což je proměnná.
Na základě vašeho kurzu jsem se začal učit
programovací jazyk C, za použití knihy "Učebnice jazyka C 1.". Mám však problém:
vždy když zkompiluji svůj program, ten se zpustí,ale po provedení všech příkazů
se ihned ukončí a já nejsem schopen zkontrolovat správnost výpočtů na obrazovce.
Po zkušenostech s Pascalem jsem hledal v knize nějaký příkaz podobný READKEY,
ale nic takového jsem nenašel. Má jazyk C nějaký podobný příkaz? Nebo je chyba v
mém kompileru?
Chyba to není. Program
prostě skončí a výstupní okno se zavře. Pokud je výpočet programu rychlý, člověk
postřehne jen probliknutí. Úplný ekvivalent funkci READKEY
z Pascalu v C nenajdete, ale můžete použít funkci getchar(),
která funguje podobně (navíc vrací ordinální číslo stisknutého znaku).
Abyste mohli tuto funkci použít, musíte vložit hlavičkový soubor
stdio.h.
Bude plynulý přechod z C++ na C#?
Snad ano. C# má být něco mezi Visual Basicem a Visual C++, takže prostředí
bude zřejmě "přátelštější", ale stále se bude používat jazyk C++. Nyní s
odstupem času můžu tento dotaz doplnit. O C# se říká,
že je spojením toho nejlepšího z jazyků C++, Visual Basic a Java. Skutečně, když
se podíváte na syntaxi, tak je velice podobná Javě a přesto nejde o
interpretovaný jazyk. C# je zcela objektově
orientovaný jazyk určený pro novou platformu .NET. Pro toho, kdo se učí C++ bude
přechod na C# velice rychlý.
Co je to sprite?
Odpověď byste jistě našli v některém kurzu DirectX. Sprite je z
anglického překladu něco jako duch:-) Sprite je vlastně vykreslovaný
obrázek. Sprite je většinou vytvořen z bitmapy, kterou načtete z externího
souboru. Pokud budete mít pohybující se letadlo, právě letadlo bude sprite. Za
sprite můžeme považovat například tlačítko menu nebo kurzor myši.
Jak zakomponovat zvuk do
stávajících projektu DirectX?
Asi nejlepším řešením je použít další komponentu DirectX a tou je
DirectMusic. Tato komponenta umožňuje, jak přehrávání hudby, tak i samostatných
zvuků. DirectMusic částečně nahrazuje komponentu DirectSound, který je rovněž k
dispozici, ale řekl bych, že s DirectMusic se lépe pracuje. Mám v plánu udělat
malý kurz DirectMusic, kde vysvětlím základy, abyste mohli svou aplikaci
ozvučit. Nebude to ovšem nic podrobného.V příštím díle DirectX se budu tomuto
tématu věnovat.
Poznámka k jiným verzím
Visual C++ a DirectX SDK.
Praktickým zkoušením jsem zjistil, že s novým DX SDK 8.0 pracuje pouze
Visual C++ 6.0 a vyšší. Na nižších verzích nelze projekty z kurzů zkompilovat
kvůli zřejmé nekompatibilitě. Proto pokud vlastníte verzi 4.0 nebo 5.0 nemůžete
používat DirectX 8.0. DirectX SDK 8.0 vyšlo na ChipCD vydání 11/01.
Existuje česky psaná kniha o DirectX?
Bohužel jsem o takové publikaci neslyšel. V angličtině je
takových knih několik (viz. www.microsoft.com).
Bude nejaky seriál o DirectShow?
Nebude. Po DirectDraw bych chtěl pokračovat komponentou DirectInput a pak ještě nevím, ale DirectShow to nebude.
Víme. Stačí použít pointer na pointer na integer. Nejprve vytvoříte pole ukazatelů na integer, potom přes ukazatele v tomto poli vytvořite pole integeru. Srozumitelnější bude spíš ukázka:
#include "stdafx.h"
#include <stdio.h>
int **pp_pole;
typedef int *PINT;
int main(int
argc, char* argv[])
{
pp_pole = NULL;
pp_pole = new PINT[10];
pp_pole[0]
= new int[1];
pp_pole[1] = new int[2];
pp_pole[2] = new int[4];
pp_pole[0][0] = 5;
pp_pole[1][0] = 6;
pp_pole[1][1] = 7;
pp_pole[2][0] = 8;
// atd.
printf("V poli jsou:\n%u\n%u %u\n", pp_pole[0][0], pp_pole[1][0],
pp_pole[1][1]);
return
0;
}
1. Program pro převod čísla z desítkové soustavy do binární
1. Trocha teorie
Vezmeme desítkové číslo a stále ho celočíselně dělíme dvěma, zbytek po tomto dělení sepíšete a pak odspoda přečtete číslo vyjádřené ve dvojkové soustavě. Tedy například pro 157:
Operace | Výsledek | Zbytek |
157 : 2 | 78 | 1 |
78 : 2 | 39 | 0 |
39 : 2 | 19 | 1 |
19 : 2 | 9 | 1 |
9 : 2 | 4 | 1 |
4 : 2 | 2 | 0 |
2 : 2 | 1 | 0 |
1 : 2 | 0 | 1 |
A přečteme zespoda. Tedy: (157)dec = (10011101)bin.
2. Praxe
Proměnné:
length je délka binárního čísla, můžete ale zvolit
pevně.
retezec je již alokované pole znaku o dostatečné
velikosti (max. počet znaku bin. čísla + 1 znak na ukončovací \0) dělíme bitovým
posunem, kdy prostě zahodíme nejméně významný bit a tím se číslo vydělí dvěma.
Výsledný řetězec je vytvářen od konce.
Vlastní program:
if(0 == cislo)
// osetrime 0
{
retezec[length - 2] = '0';
}
else
{
short index = length-1;
while(cislo > 1)
{
retezec[--index] = (char)('0' + (cislo
% 2));// zbytek dame do spravne
pozice
cislo >>= 1;
// vydelime dvema (bitovy posun)
}
retezec[--index] = '1';
}