Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
Software
Programovací jazyk C: velmi, velmi stručně
29. dubna 2004, 00.00 | Tento článek je určen těm, kdo v jazyce C příliš neprogramují a chtějí si jej zběžně oživit; snad i těm, kdo jsou zběhlí v jiných jazycích a snadno se dokáží adaptovat na mírně odlišnou syntaxi a sémantiku jiného programovacího jazyka.
Tento článek je určen těm, kdo v jazyce C příliš neprogramují a chtějí si jej zběžně oživit; snad i těm, kdo jsou zběhlí v jiných jazycích a snadno se dokáží adaptovat na mírně odlišnou syntaxi a sémantiku jiného programovacího jazyka. Pokud však někdo C nezná vůbec a k tomu není zkušeným programátorem, tento krátký přehled mu rozhodně nebude stačit: v takovém případě je zapotřebí si sehnat, přečíst a nastudovat některou z knih o jazyce C (nejraději některou z těch mých, samozřejmě ;)
Naopak zkušeným programátorům v "Céčku" tento díl nepřinese zhola nic, a mohou jej klidně přeskočit. Nebojte se, hned příště se pustíme do nadstavby Objective C, a ta již bude nová a zajímavá i pro vás. Zatím však prosím ještě mějte chvilku strpení s těmi, kdo v C zdaleka tak moc doma nejsou.
"Céčko" patří mezi nejjednodušší programovací jazyky vůbec; přesto se o něm dá napsat celá kniha. Zde ovšem neaspirujeme ani zdaleka na takovou důslednost – jen si stručně připomeneme základní principy a základní konstrukce jazyka, bez nároku na absolutní přesnost a úplnost. O rysech jazyka, jež se v Objective C běžně neužívají (kupříkladu unie či bitová pole) pak se nebudeme zmiňovat vůbec.
Co je nám vůbec do nějakého C?!?
Inu, to je jednoduché: Objective C je nadstavba jazyka C, libovolný korektní program v C je tedy zároveň korektním programem v Objective C (naopak to samozřejmě neplatí). To je ovšem zcela úmyslné, aby (a) se zkušení programátoři v C mohli Objective C naučit snadno a rychle (a jak uvidíme příště, sama nadstavba je opravdu velmi, velmi jednoduchá), (b) bylo snadné přenést do prostředí Objective C libovolný již existující kód či knihovnu.
Řada věcí se tedy v Objective C řeší přesně stejně jako v C: chceme naprogramovat podmínku, cyklus či využít celočíselné proměnné? Máme k dispozici příkazy if či for nebo deklaraci typu int přesně – skutečně úplně přesně – stejně, jako v klasickém jazyce C (tedy, "klasickém" – dnes překladač GNU ObjC++, užívaný v Mac OS X, podporuje dokonce i C99; na úrovni, na které se zde ale budeme jazykem zabývat, relativně nepodstatné rozdíly mezi variantami ANSI či C99 nejsou vůbec důležité).
V následujících několika odstavcích tedy "z rychlíku" projedeme nejdůležitější z vlastností jazyka C, s nimiž se v programech, psaných v Objective C běžně pracuje (všechny ostatní prvky C jsou samozřejmě také k dispozici; jen se jich užívá výjimečně – a my se jimi proto nebudeme zabývat).
Komentáře
Cokoli, co je mezi dvojicemi znaků /* ... */, nebo na řádku za dvojicí znaků //, se ignoruje.
Typy a proměnné
Základem každého jazyka jsou jeho příkazy a datové typy. Datové typy jazyka C jsou
- char, unsigned char, unichar, int, unsigned (int), long, unsigned long, long long, unsigned long long: celočíselné typy, všechny určují různě velká celé čísla, od jediného byte až po osmibytovou obludu long long. Modifikátor unsigned znamená číslo bez znaménka (libovolná hodnota je větší nebo rovna nule). Speciální typ unichar je dvoubytové číslo, běžně reprezentující jeden znak v kódu Unicode; namísto unsigned char lze používat pohodlnější zkratku u_char. Znak se v C vždy interpretuje jako odpovídající číslo v patřičné kódové tabulce; speciální typ "znak" tedy není zapotřebí, celočíselné typy char a unichar jej snadno nahradí. Není třeba také typ "boolean" – i na jeho místě lze užít libovolný jiný typ s konvencí "pravda==nenulová hodnota, nepravda==nula";
- float a double jsou typy užívané pro čísla s pohyblivou řádovou čárkou;
- speciální typ void znamená "nic";
- cokoli* je "ukazatel na cokoli": typ, representující adresu v paměti, na níž se nalézá hodnota typu "cokoli". Kupříkladu typ int* je tedy adresa, na níž je celé číslo; často se užívá void* pro adresu, k níž není žádná typová informace k dispozici.
Proměnné lze deklarovat uvedením jména typu a za ním seznamu jmen proměnných: "int a,b,c,d" deklaruje čtyři proměnné typu int. Modifikátor "*" pro ukazatel se týká pouze nejbližšího identifikátoru – "int *a,b,*c" tedy deklaruje dva ukazatele na int (a, c), a jeden prostý int (b). Deklarace se ukončuje středníkem a (v současné versi jazyka) může stát prakticky kdekoli.
Pro libovolný typ můžeme vytvořit nové jméno pomocí klíčového slova typedef – např. tedy "typedef int XXX" zajistí, že nadále bude XXX typ, ekvivalentní typu int; "typedef int *IntPtr" pak vytvoří typ IntPtr, representující ukazatel na int.
Konstanty a výrazy
Celočíselné konstanty jsou čísla v běžném desítkovém zápisu nezačíná-li nulou; pokud číslo obsahuje tečku nebo "e" (pro exponent) nebo obojí, jde o konstantu typu float či double. Celočíselné konstanty lze zapisovat i osmičkově (začínají-li nulou) nebo šestnáctkově (začínají-li znaky "0x" či "0X"). Znaková konstanta je prostě znak v apostrofech (třeba 'a').
Číselné výrazy lze spojovat pomocí standardních operátorů +, -, * (násobení), /, a jen pro celočíselné výrazy také % (zbytek po dělení). Pozor – dělení celočíselných výrazů je celočíselné, takže "5/3" je 1. Pro celá čísla lze použít také operátory & (operace AND bit po bitu), | (operace OR bit po bitu), ^ (operace XOR bit po bitu) a ~ (unární operátor, negace bit po bitu), << (posun levého operandu doleva o počet bitů, zadaný pravým operandem) a >> (posun doprava).
Unární operátor * je dereference ukazatele: je-li tedy např. "ip" ukazatel na proměnnou typu int, pak výraz "*ip" odpovídá obsahu této celočíselné proměnné.
Operátor = musí mít na levé straně proměnnou (či dereferenci ukazatele), a do ní uloží hodnotu výrazu na pravé straně. Celé přiřazení je výraz, jehož hodnotou je "to, co se přiřadilo" – díky tomu jsou korektní mj. i výrazy typu "a=(b=c+3)+1", kde se nejprve do proměnné "b" uloží součet proměnné "c" a 3, k tomu se přičte jednička, a výsledek se uloží do "a".
Pro pohodlí programátora jsou v C k dispozici kombinované operátory X=, jež užijí cílovou proměnnou zároveň jako prvý operand – kupříkladu "a+=3" je tedy totéž, jako "a=a+3"; "b<<=2" je totéž, jako "b=b<<2".
Nad proměnnými (a dereferencemi ukazatelů) máme k dispozici i speciální příkazy autoinkrementace a autodekrementace: je-li např. "i" proměnná, pak výraz "i++" má hodnotu "i", ale bezprostředně po jeho vyhodnocení se hodnota "i" o jedničku zvýší. Výraz "++i" má hodnotu "i", zvýšenou o 1. Obdobně je tomu s výrazy "--i" a "i--".
Operátor & může stát také jako unární před proměnnou; pak vytvoří ukazatel na tuto proměnnou (tj. deklarujeme-li např. "int i,*ip", můžeme do ukazatele ip uložit adresu proměnné i příkazem "ip=&i". Ukazatel vytvoří také speciální řetězcová konstanta: řada znaků v uvozovkách je typu char*, a hodnotou je adresa dané sekvence znaků v paměti. Speciální konstanta NULL je prázdný ukazatel – adresa, jež "neukazuje nikam" (samozřejmě, ukazuje na adresu 0, ta však je z definice nevalidní).
Speciální podmínkový operátor "v1?v2:v3" vyhodnotí výraz v1; je-li nenulový, je hodnotou celého výrazu v2, pokud byl nulový, je hodnotou celého výrazu v3. Náš překladač GNU C z Mac OS X navíc jako příjemné rozšíření oproti standardu umožňuje v2 vynechat – příkaz "v1?:v2" je ekvivalentní příkazu "v1?v1:v2".
Výrazy můžeme porovnávat pomocí operátorů ==, <=, >=, <, >, != (kde == zjišťuje rovnost, != nerovnost, a význam ostatních je zřejmý). Výsledkem je nula nebo nenula podle konvence "pravda==nenulová hodnota, nepravda==nula". Tyto výrazy pak můžeme spojovat do složitějších logických výrazů pomocí operátorů && (logické AND) a || (logické OR) a ! (logická negace).
Struktury
Více proměnných lze spojovat do bloků, jimž říkáme struktury. Jejich deklarace užívá klíčové slovo struct, za nímž je ve složených závorkách seznam všeho, co do struktury patří:
struct X { int a,b; float c; }
deklaruje strukturu jménem struct X (v praxi se častěji používá pojmenování pomocí výše zmíněného klíčového slova typedef), jež obsahuje dvě proměnné typu int a jednu typu float. K proměnným uvnitř struktury se přistupuje pomocí tečky – je-li kupříkladu foo proměnná typu struct X, pak "foo.b" je druhá z jejích celočíselných proměnných. V Cocoa se často struktury používají pro jednoduché složené hodnoty, např. "bod", složený z dvojice hodnot "x" a "y".
Příkazy
Libovolný výraz v C můžeme ukončit středníkem, a stane se příkazem. Libovolnou skupinu příkazů můžeme uzavřít do složených závorek, a stane se tzv. blokem – jednotkou, na niž můžeme pohlížet jako na celek (a např. rozhodnout, zda se celý blok příkazů provede nebo ne). Obecně může vždy blok stát kdekoli, kde může stát příkaz.
Kromě toho C nabízí několik málo speciálních příkazů:
if (výraz) then příkaz if (výraz) then příkaz else příkaz2
Podmínkové příkazy; pokud je hodnota výrazu nenulová, provede se příkaz (a neprovede příkaz2, je-li uveden). Je-li výraz nulový, je tomu naopak.
while (výraz) příkaz
Výraz se vyhodnotí, a je-li nenulový, provede se příkaz. A tak pořád dokola, dokud není výraz nulový.
Velmi flexibilní je příkaz for – zápis
for (v1;v2;v3) příkaz
zhruba odpovídá následující sekvenci:
v1; while (v2) { příkaz v3; }
Běžně se užívá pro standardní cykly – např. "for (i=0;i<10;i++) foo" provede příkaz foo pro všechny hodnoty i od nuly do devíti –, avšak jeho flexibilita je velmi šikovná právě v Objective C: až se později seznámíme s třídami NSEnumerator či NSIndexSet, uvidíme, jak se nám bude obecnost příkazu for skvěle hodit.
V jazyce nízké úrovně je samozřejmostí klasický příkaz goto, který předá řízení na zadané návěští; návěštím je libovolný identifikátor, ukončený dvojtečkou.
Speciálním případem, který se velmi podobá využití goto, je příkaz switch; ten má jeden celočíselný argument, a předá řízení na návěští case N, kde N musí odpovídat skutečné hodnotě argumentu. Pro opuštění příkazu switch je nutné použít příkazu break:
switch (n) { case 0: // následující kód se provede, je-li n nulové ... case 1: // následující kód se provede je-li n==1 // a také je-li n nulové, protože jsme nepoužili break ... break; case 2: // následující kód se provede jen je-li n==2 ... }
V příkazu switch může být i speciální návěští default, jež znamená "jakákoli jiná hodnota".
Funkce a struktura programu
Příkazy lze sdružovat do funkcí: funkce je pojmenovaný blok (viz výše), jenž může užívat formálních parametrů. Navíc funkce buď vrací hodnotu nějakého typu (pomocí speciálního příkazu return), nebo je typu void. Funkce se deklaruje tak, že nejprve uvedeme návratový typ, pak jméno funkce, a za ním v závorkách seznam parametrů. Za seznamem je blok, jenž popisuje vlastní obsah funkce:
int max(int a,int b) { if (a>b) return a; return b; }
Funkci můžeme kdykoli volat tím, že uvedeme její jméno a na místech parametrů konkrétní hodnoty – např. "i=max(2,3)".
Program v klasickém jazyce C se skládá z libovolného množství funkcí, mezi nimiž je jedna výjimečná; ta má jméno main a je deklarována speciálním způsobem. Po zavedení do paměti se automaticky spustí právě funkce main, a ta pak podle potřeby volá funkce ostatní.
Preprocesor
Jazyk C standardně obsahuje velmi výkonný preprocesor; my si z něj ukážeme jen ty nejzákladnější služby:
#define IDENTIFIKATOR cokoli
v následujícím kódu nahradí všechny výskyty řetězce IDENTIFIKATOR (jež nejsou v uvozovkách) řetězcem cokoli. Definice maker lze i parametrizovat, takže např. namísto funkce max z minulého odstavce jsme mohli definovat makro
#define MAX(a,b) ((a)>(b)?(a):(b))
jež by fungovalo (téměř) stejně dobře (existuje určitý drobný rozdíl, avšak na úrovni, na níž se pohybujeme, není podstatný).
Speciální direktiva include vloží zadaný soubor; to je proto, aby více různých zdrojových souborů mohlo snadno užívat společných deklarací:
#include <jméno_souboru> #include "jméno_souboru"
V Objective C se na místě této direktivy používá důsledně direktiva import, jež funguje podobně, je však "chytřejší" v případech, kdy by se při vzájemném vkládání souborů mohlo stát, že by se jeden soubor interpretoval vícekrát za sebou. Objective C však není naše dnešní téma: do něj se podrobně ponoříme hned příště!
Obsah seriálu (více o seriálu):
- Nastal čas na kakao...
- Tak nejdřív kakao ochutnáme...
- Programovací jazyk C: velmi, velmi stručně
- Objective C: to si vysvětlíme podrobněji
- Co jsme si o Objective C ještě neřekli...
- Nastal čas na kakao - Vznik a zánik objektů
- Nastal čas na kakao - Kopírování objektů
- Nastal čas na kakao - Skryté podtřídy
- Nastal čas na kakao - Základní služby objektů
- Nastal čas na kakao - Jak správně psát v Objective C
- Nastal čas na kakao - Jak správně importovat
- Nastal čas na kakao - Podtřídy, delegáti, vkládání, jak se to rýmuje?
- Nastal čas na kakao - Využití kategorií namísto dědičnosti
- Nastal čas na kakao - Vkládání objektů a přesměrování zpráv
- Nastal čas na kakao - Inicializace a rušení objektů
- Nastal čas na kakao - Metody initWith... a designovaný inicializátor
- Nastal čas na kakao - Inicializace: tipy a triky
- Nastal čas na kakao - Accesory: přístup k proměnným instancí
- Nastal čas na kakao - Šedá je teorie, zelený je strom života...
- Nastal čas na kakao - Více o XCode: inspektory
- Nastal čas na kakao - Aplikace RSS2: datový model
- Nastal čas na kakao - Aplikace RSS: implementace datového modelu
- Nastal čas na kakao - Aplikace RSS: parsování XML
- Nastal čas na kakao - Interface Builder a uživatelské rozhraní
- Nastal čas na kakao - Interface Builder: atributy objektů
- Nastal čas na kakao - Interface Builder: atributy objektů
- Nastal čas na kakao - Druhý kontrolér a dokončení aplikace
- Nastal čas na kakao - Drobná vylepšení a zdokonalení...
- Nastal čas na kakao - Ladění
- Nastal čas na kakao - Třídy Foundation Kitu
- Nastal čas na kakao - Třídy Foundation Kitu (2)
- Nastal čas na kakao - Textové řetězce: NS(Mutable)String
- Nastal čas na kakao - Čísla, binární data a další...
- Nastal čas na kakao - Archivace objektů
- Nastal čas na kakao - Trocha magie, aneb distribuované objekty
- Nastal čas na kakao - Málem bychom zapomněli: NSAutoreleasePool
- Nastal čas na kakao - Zpracování výjimek: NSException
- Nastal čas na kakao - NSInvocation a černá magie
- Nastal čas na kakao - Kakao v Tygrovi
- Nastal čas na kakao - Notifikace: nepřímé předávání zpráv
- Nastal čas na kakao - NSUserDefaults
- Nastal čas na kakao - Co nového ve Foundation Kitu
- Nastal čas na kakao – s Intelem, s Intelem, jedeme do...
- Co nového v Xcode
- Začínáme s AppKitem
- Jak MVC v Kakau vypadá doopravdy?
- Jak MVC v Kakau vypadá doopravdy: dokončení
- Přehled tříd AppKitu
- Nastal čas na kakao - Přehled tříd AppKitu 2
- Přehled tříd AppKitu 3: zbývající třídy GUI
- Přehled tříd AppKitu 4: textový systém
- Nastal čas na kakao - Přehled tříd AppKitu 5: hlavně grafika
- Přehled tříd AppKitu 6: dokumentový systém
- Přehled tříd AppKitu 7: dokončení
- Pojmenované vlastnosti objektů
- Pojmenované vlastnosti objektů: implementace
- Pojmenované vlastnosti objektů: relace 1:N
- Pojmenované vlastnosti objektů: řazení jmen a agregační funkce
- Sledování změn objektů
- Sledování změn objektů – ukázka
- Sledování změn objektů – zdrojový kód
- Sledování změn objektů: kód modelu
- Sledování změn objektů: přímý přístup
- Kontroléry a vazby
- Vázání vazeb
- Další vazby s jednoduchým kontrolérem
- Implementace a použití převodu hodnot
- Validace hodnot
- Validace a chyby, a jedna hezká vazba...
- Práce s polem objektů
- Základní vazby NSArrayControlleru
- Převodníky, přepínače, placeholdery
- Mírná vylepšení v mezích zákona
- Objective C 2.0 - novinky z Leoparda
- NSTreeController
- Programování v Cocoa - Pár tipů a triků
- Programování v Cocoa - Základy kreslení
- Kterak nakreslit modrý obdélník...
- Další služby pro kreslení
- Obrázky a písmenka...
- Události a myš
- Lepší práce s myší
- Události klávesnice
- Input Management
- Příkazy a schránka
- Další události
- Táhni a padni
- Byli jsme na tahu; nyní padneme.
- Zvolme si, jak vhodit
- Drobnosti a chybičky
- Speciální případy tahání či házení
- Kterak táhnout něco, co neexistuje?
- Jak na sítě...
- NSURLConnection
- Safari za minutu
- Služby WebKitu
- Kakao v Leopardu
- Druhé Objective C
- Druhé Objective C: různé drobnosti
- Druhé Objective C: kategorie a protokoly
- Druhé Objective C: nový příkaz cyklu
- Druhé Objective C: atributy a accesory
- Druhé Objective C: atributy a accesory
- 64 je dvakrát 32
- Ubicumque dulce est, ibi et acidum invenies...
- Irbis: že prý žádné novinky?
- Blok sem, blok tam, nám už je to všechno jasné...
- Bloky jsou i v AppKitu
- Irbis a Foundation Kit
- Kde jsou má data?
- Kde jsou má data? V NSCache!
- Soubor, jméno, URL, jak se to rýmuje...
- Další podpora NSURL
- Zabíjení!
- A máme tady i...OS!
- Systémové prvky GUI
- Programování pro iOS 1. díl - Rozdíly mezi "i" a "Mac"
- Programování pro iOS - 2. Začínáme programovat
- Programování pro iOS - 3. základní ovladače a propojení GUI s kódem
- Programování pro iOS - 4. Varovná hlášení
- Programování pro iOS - 5. Rámce a jejich řídicí objekty
- Programování pro iOS - 6. Ukládání dat
- Programování pro iOS - 7. Správa paměti a starý restík
- Programování pro iOS - 8. Dokončení aplikace
- Programování pro iOS - 9. Jak dostat aplikaci do iPhone
- Programování pro iOS - 10. Instalace aplikace do cizího iPhone
- Programování pro iOS - 11. Jak dostat aplikaci do libovolného iPhone
- Programování pro iOS - 12. Touching!
- Programování pro iOS - 13. Kreslíme na iPhone
- Programování pro iOS - 14. Udělejme gesto
- Programování pro iOS - 15. Další gesta
- Programování pro iOS - 16. Více prstů, více zábavy
- Programování pro iOS - 17. Podpora standardních gest
- Programování pro iOS - 18. Recognizery v iOS
- Programování pro iOS - 19. Další standardní recognizery
- Programování pro iOS - 20. Co nového v iOSu
- Programování pro iOS - 21. "Multitasking"
- Programování pro iOS - 22. Nulla est honesta avaritia nisi temporis
- Programování pro iOS - 23. Jak se aktivovat, jsme-li v pozadí
- Programování pro iOS - 24. Zbývající drobnosti
- Programování pro iOS - 25. Řídicí objekty rámců
- Programování pro iOS - 26. Jak se dělá UIViewController
- Programování pro iOS - 27. Kde vzít rámce
- Programování pro iOS - 28. Základní služby
- Programování pro iOS - 29. Práce s rámci
- Programování pro iOS - 30. Rotace zařízení
- Programování pro iOS - 31. Správa paměti v rámcích
- Programování pro iOS - 32. Řídicí objekt pro tabulky
- Programování pro iOS - 33. Řídicí objekt pro strom
- Programování pro iOS - 33. Více o UINavigationControlleru
- Programování pro iOS - 35. Ještě jednou UINavigationController
- Programování pro iOS - 36. Po navigátoru taby
- Programování pro iOS - 37. Více o UITabBarControlleru
- Programování pro iOS - 38. Dokončení UITabBarControlleru
- Programování pro iOS - 39. UIPopoverController
- Programování pro iOS - 40. Další triky UIPopoverControlleru
- Programování pro iOS - 41. Zbývající služby UIPopoverControlleru
- Programování pro iOS - 42. UISplitViewController
- Programujeme v
iTunesXcode 4 - Programování pro iOS - 44. Předvolby Xcode 4
- Programování pro iOS - 45. Práce v Xcode 4
- Xcode 4: projekt a cíle
- Xcode 4: práce s cíli
- Xcode 4: Build Settings
- Xcode 4: Build Phases
- Xcode4: Build Phases podruhé
- Xcode 4: Co jsou to Build Rules?
- Xcode4: taje editoru
- Xcode4: automatické doplňování v editoru
- XIBy chyby
- Více o XIBech
- Editor XIBů
- Inspektory pro XIBy
- Vazby mezi objekty v XIBech
- Vazby mezi objekty v kódu
- Paletky Xcode pro XIBy
- Xcode 4: levý sloupec
- Xcode 4: okno Organizer
- Xcode 4: okno Organizer, část druhá
- Xcode 4: co je to Workspace?
- Xcode 4: základy schémat
- Xcode 4: akční schémata
Tématické zařazení:
» Rubriky » Začínáme s