i != (ne ravno) v tochnosti analogichny
operaciyam otnosheniya, za isklyucheniem togo, chto oni imeyut
bolee nizkij uroven' starshinstva. (poetomu znachenie vyrazhe-
niya a<b==c<d ravno 1 vsyakij raz, kogda vyrazheniya a<b i c<d
imeyut odinakovoe znachenie istinnosti).
Ukazatel' mozhno sravnivat' s celym, no rezul'tat budet
mashinno-nezavisimym tol'ko v tom sluchae, esli celym yavlyaetsya
konstanta 0. Garantiruetsya, chto ukazatel', kotoromu prisvo-
eno znachenie 0, ne ukazyvaet ni na kakoj ob容kt i na samom
dele okazyvaetsya ravnym 0; obshcheprinyato schitat' takoj ukaza-
tel' nulem.
4.8. Pobitovaya operaciya 'i'
vyrazhenie_i:
vyrazhenie & vyrazhenie
Operaciya & yavlyaetsya associativnoj, i vklyuchayushchie & vyrazheniya
mogut byt' pereuporyadocheny kompilyatorom. Vypolnyayutsya obych-
nye arifmeticheskie preobrazovaniya; rezul'tatom yavlyaetsya
pobitovaya funkciya 'i' operandov. |ta operaciya primenima
tol'ko k operandam celogo tipa.
4.9. Pobitovaya operaciya isklyuchayushchego 'ili'
vyrazhenie_isklyuchayushchego_ili:
vyrazhenie ^ vyrazhenie
Operaciya ^ (znak nadcherkivaniya, kod v KOI-8 0136) yavlyaetsya
associativnoj, i vklyuchayushchie ^ vyrazheniya mogut byt' pereupo-
ryadocheny kompilyatorom. Vypolnyayutsya obychnye arifmeticheskie
preobrazovaniya; rezul'tatom yavlyaetsya pobitovaya funkciya isk-
lyuchayushchego 'ili' operandov. Operaciya primenima tol'ko k ope-
randam celochislennogo tipa.
4.10. Pobitovaya operaciya vklyuchayushchego 'ili'
vyrazhenie_vklyuchayushchego_ili:
vyrazhenie | vyrazhenie
-17-
Operaciya | yavlyaetsya associativnoj, i soderzhashchie | vyrazheniya
mogut byt' pereuporyadocheny. Vypolnyayutsya obychnye arifmetiches-
kie preobrazovaniya; rezul'tatom yavlyaetsya pobitovaya funkciya
vklyuchayushchego 'ili' operandov. Operaciya primenima tol'ko k
operandam celochislennogo tipa.
4.11. Logicheskaya operaciya 'i'
vyrazhenie_logicheskogo_i:
vyrazhenie && vyrazhenie
Operaciya && gruppiruetsya sleva napravo. Ona vozvrashchaet 1,
esli oba ee operanda otlichny ot nulya, i 0 v protivnom slu-
chae. V otlichie ot & operaciya && garantiruet vychislenie sleva
napravo; bolee togo, esli pervyj operand raven 0, to znache-
nie vtorogo operanda voobshche ne vychislyaetsya.
Operandy ne obyazany byt' odinakovogo tipa, no kazhdyj iz
nih dolzhen byt' libo odnogo iz osnovnyh tipov, libo ukazate-
lem. Rezul'tat vsegda imeet tip int.
4.12. Operaciya logicheskogo 'ili'
vyrazhenie_logicheskogo_ili:
vyrazhenie || vyrazhenie
Operaciya || gruppiruetsya sleva napravo. Ona vozvrashchaet 1,
esli odin iz operandov otlichen ot nulya, i 0 v protivnom slu-
chae. V otlichie ot operacii | operaciya || garantiruet vychis-
lenie sleva napravo; bolee togo, esli pervyj operand otlichen
ot nulya, to znachenie vtorogo operanda voobshche ne vychislyaetsya.
Operandy ne obyazany byt' odinakovogo tipa, no kazhdyj iz
nih dolzhen byt' libo odnogo iz osnovnyh tipov, libo ukazate-
lem. Rezul'tat vsegda imeet tip int.
4.13. Uslovnaya operaciya
uslovnoe_vyrazhenie:
vyrazhenie ? vyrazhenie : vyrazhenie
Uslovnye vyrazheniya gruppiruyutsya sleva napravo. Vychislyaetsya
znachenie pervogo vyrazheniya, i esli ono otlichno ot nulya, to
rezul'tatom budet znachenie vtorogo vyrazheniya; v protivnom
sluchae rezul'tatom budet znachenie tret'ego vyrazheniya. Esli
eto vozmozhno, provodyatsya obychnye arifmeticheskie preobrazova-
niya, s tem, chtoby privesti vtoroe i tret'e vyrazheniya k
obshchemu tipu; v protivnom sluchae, esli oba vyrazheniya yavlyayutsya
ukazatelyami odinakovogo tipa, to rezul'tat imeet tot zhe tip;
v protivnom sluchae odno vyrazhenie dolzhno byt' ukazatelem, a
drugoe - konstantoj 0, i rezul'tat budet imet' tip ukaza-
telya. Vychislyaetsya tol'ko odno iz vtorogo i tret'ego vyrazhe-
nij.
-18-
4.14. Operaciya prisvaivaniya
Imeetsya ryad operacij prisvaivaniya, kazhdaya iz kotoryh
gruppiruetsya sleva napravo. Vse operacii trebuyut v kachestve
svoego levogo operanda l_znachenie, a tipom vyrazheniya prisva-
ivaniya yavlyaetsya tip ego levogo operanda. Znacheniem vyrazheniya
prisvaivaniya yavlyaetsya znachenie, hranimoe v levom operande
posle togo, kak prisvaivanie uzhe budet proizvedeno. Dve
chasti sostavnoj operacii prisvaivaniya yavlyayutsya otdel'nymi
leksemami.
vyrazhenie_prisvaivaniya:
l_znachenie = vyrazhenie
l_znachenie += vyrazhenie
l_znachenie -= vyrazhenie
l_znachenie *= vyrazhenie
l_znachenie /= vyrazhenie
l_znachenie %= vyrazhenie
l_znachenie >>= vyrazhenie
l_znachenie <<= vyrazhenie
l_znachenie &= vyrazhenie
l_znachenie ^= vyrazhenie
l_znachenie |= vyrazhenie
Kogda proizvoditsya prostoe prisvaivanie '=', znachenie
vyrazheniya zamenyaet znachenie ob容kta, na kotoroe ssylaetsya
l_znachenie. Esli oba operanda imeyut arifmeticheskij tip, to
pered prisvaivaniem pravyj operand preobrazuetsya k tipu
levogo operanda.
V vyrazhenie vida e1 op= e2, gde op - odna iz perechis-
lennyh vyshe operacij, ekvivalentno vyrazheniyu
e1 = e1 op (e2), s tem otlichiem, chto vyrazhenie e1 vychislya-
etsya tol'ko odin raz. V sluchae operacij += i -= levyj ope-
rand mozhet byt' ukazatelem, prichem pri etom (celochislennyj)
pravyj operand preobrazuetsya takim obrazom, kak ob座asneno v
p. 0.4; vse pravye operandy i vse otlichnye ot ukazatelej
levye operandy dolzhny imet' arifmeticheskij tip.
Ispol'zuemye v OS DEMOS kompilyatory dopuskayut prisvai-
vanie ukazatelya celomu, celogo ukazatelyu i ukazatelya ukaza-
telyu drugogo tipa. Takoe prisvaivanie yavlyaetsya chistym kopi-
rovaniem bez kakih-libo preobrazovanij. Takoe upotreblenie
operacij prisvaivaniya yavlyaetsya neperenosimym i mozhet privo-
dit' k ukazatelyam, kotorye pri ispol'zovanii vyzyvayut oshibki
adresacii. Tem ne menee garantiruetsya, chto prisvaivanie uka-
zatelyu konstanty 0 daet nulevoj ukazatel', kotoryj mozhno
otlichat' ot ukazatelya na lyuboj ob容kt.
-19-
4.15. Prisvaivanie struktury
Struktury mogut byt' prisvoeny, a takzhe peredany funk-
ciyam v kachestve argumentov i vozvrashcheny funkciyami. Tipy
uchastvuyushchih operandov dolzhny sovpadat'.
4.16. Operaciya 'zapyataya<
vyrazhenie_s_zapyatoj:
vyrazhenie , vyrazhenie
Para vyrazhenij, razdelennyh zapyatoj, vychislyaetsya sleva nap-
ravo i znachenie levogo vyrazheniya otbrasyvaetsya. Tipom i zna-
cheniem rezul'tata yavlyaetsya tip i znachenie pravogo operanda.
|ta operaciya gruppiruetsya sleva napravo. V kontekste, gde
zapyataya imeet special'noe znachenie, kak, naprimer, v spiske
fakticheskih argumentov funkcij ili v spiskah inicializato-
rov, operaciya zapyataya, opisyvaemaya v etom razdele, mozhet
poyavlyat'sya tol'ko v kruglyh skobkah; naprimer, funkciya
f(a,(t=3,t+2),c)
imeet tri argumenta, vtoroj iz kotoryh imeet znachenie 5.
4.17. Starshinstvo i poryadok vychisleniya.
V privodimoj nizhe tablice svedeny pravila starshinstva i
associativnosti vseh operacij. Operacii, raspolozhennye v
odnoj stroke, imeyut odin i tot zhe uroven' starshinstva;
stroki raspolozheny v poryadke ubyvaniya starshinstva. Tak, nap-
rimer, operacii *, "/" i "%" imeyut odinakovyj uroven' star-
shinstva, kotoryj vyshe, chem uroven' operacij "+" i "-".
-20-
Tablica 2
------------------------------------------
| Operator | Associativnost' |
|____________________|___________________|
| () [] -> . | sleva napravo |
|____________________|___________________|
| ~ ++ -- - f | sprava nalevo |
|(type) * & sizeof| |
|____________________|___________________|
| * / % | sleva napravo |
|____________________|___________________|
| + - | sleva napravo |
|____________________|___________________|
| << >> | sleva napravo |
|____________________|___________________|
| < <= > >= | sleva napravo |
|____________________|___________________|
| == != | sleva napravo |
|____________________|___________________|
| & | sleva napravo |
|____________________|___________________|
| ^ | sleva napravo |
|____________________|___________________|
| | | sleva napravo |
|____________________|___________________|
| && | sleva napravo |
|____________________|___________________|
| || | sleva napravo |
|____________________|___________________|
| ?: | sprava nalevo |
|____________________|___________________|
| = += -= i t.p. | sprava nalevo |
|____________________|___________________|
| , | sleva napravo |
|____________________|___________________|
Otmetim, chto uroven' starshinstva pobitovyh logicheskih
operacij &, ^ i | nizhe urovnya operacij == i !=. |to privodit
k tomu, chto osushchestvlyayushchie pobitovuyu proverku vyrazheniya,
podobnye
if ((h & mask) == 0) ...
dlya polucheniya pravil'nyh rezul'tatov dolzhny zaklyuchat'sya v
kruglye skobki, v protivnom sluchae ono budet ponyato tak:
vyrazhenie: x & mask == 0
ponyato kak: x & ( mask == 0 )
-21-
* 5. OPISANIYA
Opisaniya ispol'zuyutsya dlya ukazaniya interpretacii, koto-
ruyu yazyk Si budet davat' kazhdomu identifikatoru; oni ne obya-
zatel'no rezerviruyut pamyat', sootvetstvuyushchuyu identifikatoru.
Opisaniya imeyut formu
opisanie:
specifikatory_opisaniya spisok_opisatelej;
neob
Opisateli v spiske opisatelej soderzhat opisyvaemye identifi-
katory. Specifikatory opisaniya predstavlyayut soboj posledo-
vatel'nost' specifikatorov tipa i specifikatorov klassa
pamyati.
specifikatory_opisaniya:
s_tipa s_opisaniya
neob
s_klassa_pamyati s_opisaniya
neob
gde c_... - specifikator_...
Spisok opisatelej dolzhen byt' soglasovannym v smysle, opisy-
vaemom nizhe.
5.1. Specifikatory klassa pamyati
nizhe perechislyayutsya specifikatory klassa pamyati:
specifikator_klassa_pamyati:
auto
static
extern
register
typedef
Specifikator typedef ne rezerviruet pamyat' i nazyvaetsya
"specifikatorom klassa pamyati" tol'ko po sintaksicheskim
soobrazheniyam; eto obsuzhdaetsya nizhe. Smysl razlichnyh klassov
pamyati byl obsuzhden ranee (sm. "Ob容kty yazyka Si").
Opisaniya auto, static i register sluzhat takzhe v
kachestve opredelenij v tom smysle, chto oni vyzyvayut rezervi-
rovanie nuzhnogo kolichestva pamyati. V sluchae extern dolzhno
prisutstvovat' vneshnee opredelenie ukazyvaemyh identifikato-
rov gde to vne funkcii, v kotoroj oni opisany.
Opisanie register luchshe vsego predstavlyat' sebe kak
opisanie auto vmeste s namekom kompilyatoru, chto opisannye
takim obrazom peremennye budut chasto ispol'zovat'sya. |ffek-
tivny tol'ko neskol'ko pervyh takih opisanij. Krome togo, v
-22-
registrah mogut hranit'sya tol'ko peremennye opredelennyh
tipov; na CM-|VM eto int, char ili ukazatel'. Sushchestvuet i
drugoe ogranichenie na ispol'zovanie registrovyh peremennyh:
k nim nel'zya primenyat' operaciyu vzyatiya adresa &. Pri razum-
nom ispol'zovanii registrovyh opisanij mozhno ozhidat' poluche-
niya men'shih po razmeru i bolee bystryh programm, no v budu-
shchem uluchshenie generirovaniya kodov mozhet sdelat' ih nenuzh-
nymi.
V kompilyatore dlya SM |VM vosprinimayutsya pervye 3 opisa-
niya register v kazhdoj funkcii.
Opisanie mozhet soderzhat' ne bolee odnogo specifikatora
klassa pamyati. Esli opisanie ne soderzhit specifikatora
klassa pamyati, to schitaetsya, chto on imeet znachenie auto,
esli opisanie nahoditsya vnutri nekotoroj funkcii, i extern v
protivnom sluchae. Isklyuchenie: funkcii nikogda ne byvayut
avtomaticheskimi.
5.2. Specifikatory tipa
Nizhe perechislyayutsya specifikatory tipa.
specifikator_tipa:
char
short
int
long
unsigned
float
double
specifikator_struktury_ili_ob容dineniya
specifikator_perechisleniya
opredelyayushchee_tip_imya
Slova long, short i unsigned mozhno rassmatrivat' kak prila-
gatel'nye; dopustimy sleduyushchie kombinacii:
short int
long int
unsigned int
long float
Poslednyaya kombinaciya oznachaet to zhe, chto i double. V ostal'-
nom opisanie mozhet soderzhat' ne bolee odnogo specifikatora
tipa. Esli opisanie ne soderzhit specifikatora tipa, to schi-
taetsya, chto on imeet znachenie int.
Specifikatory struktur i ob容dinenij obsuzhdayutsya v p.
0.5, specifikaciya perechislimogo tipa - v p.0.6; opisaniya s
opredelyayushchimi tip imenami typedef obsuzhdayutsya v p. 0.9.
-23-
5.3. Opisateli
Vhodyashchij v opisanie spisok opisatelej predstavlyaet
soboj posledovatel'nost' razdelennyh zapyatymi opisatelej,
kazhdyj iz kotoryh mozhet imet' inicializator.
spisok_opisatelej:
inicializiruemyj_opisatel'
inicializiruemyj_opisatel',spi-
sok_opisatelej
inicializiruemyj_opisatel':
opisatel' inicializator
neob
Inicializatory opisyvayutsya v p.0.6. Specifikatory i opisaniya
ukazyvayut tip i klass pamyati ob容ktov, na kotorye ssylayutsya
opisateli. Opisateli imeyut sleduyushchij sintaksis:
opisatel':
identifikator
( opisatel' )
* opisatel'
opisatel' ()
opisatel' [konstantnoe-vyrazhenie]
neob
Gruppirovanie takoe zhe, kak i v vyrazheniyah.
5.4. Smysl opisatelej
Kazhdyj opisatel' rassmatrivaetsya kak utverzhdenie togo,
chto kogda konstrukciya toj zhe samoj formy, chto i opisatel',
poyavlyaetsya v vyrazhenii, to ona vydaet ob容kt ukazannogo tipa
i ukazannogo klassa pamyati. Kazhdyj opisatel' soderzhit rovno
odin identifikator; eto imenno tot identifikator, kotoryj i
opisyvaetsya.
Esli v kachestve opisatelya poyavlyaetsya prosto identifika-
tor, to on imeet tip, ukazyvaemyj v specificiruyushchem zago-
lovke opisaniya.
Opisatel' v kruglyh skobkah identichen opisatelyu bez
kruglyh skobok, no kruglye skobki mogut izmenyat' svyazi v
sostavnyh opisatelyah. Primery smotri nizhe.
Predstavim sebe opisanie
t di
gde t - specifikator tipa (podobnyj int i t.d.), a di - opi-
satel'. Predpolozhim, chto eto opisanie privodit k tomu, chto
sootvetstvuyushchij identifikator imeet tip ...t, gde "..."
pusto, esli di prosto otdel'nyj identifikator (tak chto tip h
-24-
v int h prosto int). Togda, esli di imeet formu
*d
to soderzhashchijsya identifikator budet imet' tip ... ukazatel'
na t.
Esli di imeet formu
d()
to soderzhashchijsya identifikator imeet tip ... funkciya, vozvra-
shchayushchaya t.
Esli di imeet formu
d[konstantnoe_vyrazhenie]
ili
d[ ]
to soderzhashchijsya identifikator imeet tip ... massiv t. V per-
vom sluchae konstantnym vyrazheniem yavlyaetsya vyrazhenie, znache-
nie kotorogo mozhno opredelit' vo vremya kompilyacii i kotoroe
imeet tip int. (tochnoe opredelenie konstantnogo vyrazheniya
dano nizhe). Kogda neskol'ko specifikacij vida "massiv iz"
okazyvayutsya primykayushchimi, to sozdaetsya mnogomernyj massiv;
konstantnoe vyrazhenie, zadayushchee granicy massivov, mozhet
otsutstvovat' tol'ko u pervogo chlena etoj posledovatel'-
nosti. Takoe opuskanie polezno, kogda massiv yavlyaetsya vnesh-
nim ili formal'nym i ego fakticheskoe opredelenie, kotoroe
vydelyaet pamyat', privoditsya v drugom meste. Pervoe konstant-
noe vyrazhenie mozhet byt' opushcheno takzhe togda, kogda za opi-
satelem sleduet inicializaciya. V etom sluchae razmer oprede-
lyaetsya po chislu privedennyh inicializiruemyh elementov.
Massiv mozhet byt' obrazovan iz elementov odnogo iz
osnovnyh tipov, iz ukazatelej, iz struktur ili ob容dinenij
ili iz drugih massivov (chtoby obrazovat' mnogomernyj mas-
siv).
Ne vse vozmozhnosti, kotorye razresheny s tochki zreniya
ukazannogo vyshe sintaksisa, fakticheski dopustimy. Imeyutsya
sleduyushchie ogranicheniya: funkcii ne mogut vozvrashchat' massivy
ili funkcii, hotya oni mogut vozvrashchat' ukazateli na takie
veshchi; ne sushchestvuet massivov funkcij, hotya mogut byt' mas-
sivy ukazatelej na funkcii. Analogichno, struktury ili ob容-
dineniya ne mogut soderzhat' funkciyu, no oni mogut soderzhat'
ukazatel' na funkciyu.
V kachestve primera rassmotrim opisanie
-25-
int i, *ip, f(), *fip(), (*pfi)();
v kotorom opisyvaetsya celoe i, ukazatel' ip na celoe, funk-
ciya f, vozvrashchayushchaya celoe, funkciya fip, vozvrashchayushchaya ukaza-
tel' na celoe, i ukazatel' pfi na funkciyu, kotoraya vozvra-
shchaet celoe. Osobenno polezno sravnit' dva poslednih opisa-
telya. Svyaz' v *fip() mozhno predstavit' v vide *(fip()), tak
chto opisaniem predpolagaetsya, chto v vyrazhenii trebuetsya
obrashchenie k funkcii fip i posleduyushchee ispol'zovanie kosven-
noj adresacii dlya vydachi s pomoshch'yu poluchennogo rezul'tata
(ukazatelya) celogo. V opisatele (*pfi)() dopolnitel'nye
skobki neobhodimy, poskol'ku oni tochno tak zhe, kak i v vyra-
zhenii, ukazyvayut, chto kosvennaya adresaciya cherez ukazatel'
vydaet funkciyu, kotoraya zatem vyzyvaetsya; eta vyzvannaya
funkciya vozvrashchaet celoe.
V kachestve drugogo primera privedem opisanie
float fa[17], *afp[17];
v kotorom opisyvaetsya massiv chisel tipa float i massiv uka-
zatelej na chisla tipa float. Nakonec,
static int h3d[3][5][7];
opisyvaet staticheskij trehmernyj massiv celyh razmerom
3*5*7. Bolee podrobno: h3d yavlyaetsya massivom iz treh elemen-
tov; kazhdyj element yavlyaetsya massivom pyati massivov; kazhdyj
poslednij massiv yavlyaetsya massivom iz semi celyh. Kazhdoe iz
vyrazhenij h3d, h3d[i], h3d[i][j] i h3d[i][j][k] mozhet razum-
nym obrazom poyavlyat'sya v vyrazheniyah. Pervye tri imeyut tip
"massiv", poslednee imeet tip int.
5.5. Opisanie struktur i ob容dinenij
Struktura - eto ob容kt, sostoyashchij iz posledovatel'nosti
imenovannyh chlenov. Kazhdyj chlen mozhet byt' proizvol'nogo
tipa. Ob容dinenie - eto ob容kt, kotoryj v dannyj moment
mozhet soderzhat' lyuboj iz neskol'kih chlenov. Specifikatory i
ob容dineniya imeyut odinakovuyu formu.
specifikator_struktury_ili_ob容dineniya:
struktura_ili_ob容dinenie { spi-
sok_opisanij_struktury }
identifikator_struktury_ili_ob容dine-
niya { spisok-opisanij-struktury }
identifikator_struktury_ili_ob容dineniya
struktura_ili_ob容dinenie:
struct
union
-26-
Spisok_opisanij_struktury yavlyaetsya posledovatel'nost'yu opi-
sanij chlenov struktury ili ob容dineniya:
spisok_opisanij_struktury:
opisanie_struktury
opisanie_struktury spi-
sok_opisanij_struktury
opisanie_struktury:
specifikator_tipa spi-
sok_opisatelej_struktury
spisok_opisatelej_struktury:
opisatel'_struktury
opisatel'_struktury,spisok_opi-
satelej_struktury
V obychnom sluchae opisatel' struktury yavlyaetsya prosto opisa-
telem chlena struktury ili ob容dineniya. CHlen struktury mozhet
takzhe sostoyat' iz specificirovannogo chisla bitov. Takoj
chlen nazyvaetsya takzhe polem; ego dlina otdelyaetsya ot imeni
polya dvoetochiem.
opisatel'_struktury:
opisatel'
opisatel': konstantnoe_vyrazhenie
: konstantnoe_vyrazhenie
Vnutri struktury opisannye v nej ob容kty imeyut adresa, koto-
rye uvelichivayutsya v sootvetstvii s chteniem opisanij ob容ktov
sleva napravo. Kazhdyj chlen struktury, kotoryj ne yavlyaetsya
polem, nachinaetsya s adresnoj granicy, sootvetstvuyushchej ego
tipu; sledovatel'no v strukture mogut okazat'sya neimenovan-
nye dyry. CHleny, yavlyayushchiesya polyami, pomeshchayutsya v mashinnye
celye; oni ne perekryvayut granicy slova. Pole, kotoroe ne
umeshchaetsya v ostavshemsya v dannom slove prostranstve, pomeshcha-
etsya v sleduyushchee slovo. Polya vydelyayutsya sprava nalevo na
CM-|VM, no mogut vydelyat'sya sleva napravo na drugih mashinah.
Opisatel' struktury, kotoryj ne soderzhit opisatelya, a
tol'ko dvoetochie i shirinu, ukazyvaet neimenovannoe pole,
poleznoe dlya zapolneniya svobodnogo prostranstva s cel'yu
sootvetstviya zadavaemym izvne shemam. Special'nyj sluchaj
neimenovannogo polya s shirinoj 0 ispol'zuetsya dlya ukazaniya o
vyravnivanii sleduyushchego polya na granicu slova. Pri etom
predpolagaetsya, chto "sleduyushchee pole" dejstvitel'no yavlyaetsya
polem, a ne obychnym chlenom struktury, poskol'ku v poslednem
sluchae vyravnivanie osushchestvlyaetsya avtomaticheski.
Sam yazyk ne nakladyvaet ogranichenij na tipy ob容ktov,
opisannyh kak polya, no ot realizacij ne trebuetsya obespechi-
vat' chto-libo otlichnoe ot celyh polej. Bolee togo, dazhe polya
-27-
tipa int mogut rassmatrivat'sya kak ne imeyushchie znaka. Na CM-
|VM polya ne imeyut znaka i mogut prinimat' tol'ko celye zna-
cheniya. Vo vseh realizaciyah otsutstvuyut massivy polej i k
polyam ne primenima operaciya vzyatiya adresa &, tak chto ne
sushchestvuet i ukazatelej na polya.
Ob容dinenie mozhno predstavit' sebe kak strukturu, vse
chleny kotoroj nachinayutsya so smeshcheniya 0 i razmer kotoroj dos-
tatochen, chtoby soderzhat' lyuboj iz ee chlenov. V kazhdyj moment
ob容dinenie mozhet soderzhat' ne bolee odnogo iz svoih chlenov.
Specifikator struktury ili ob容dineniya vo vtoroj forme,
t.e. odin iz:
struct ident {spisok_opisanij_struktury}
union ident {spisok-opisanij-struktury}
opisyvaet ident v kachestve yarlyka struktury (ili yarlyka
ob容dineniya) dlya struktury, specificirovannoj etim spiskom.
Posleduyushchee opisanie mozhet zatem ispol'zovat' tret'yu formu
specifikatora, odin iz
struct ident
union ident
YArlyki struktur dayut vozmozhnost' opredeleniya struktur, koto-
rye ssylayutsya na samih sebya; oni takzhe pozvolyayut neodnok-
ratno ispol'zovat' privedennuyu tol'ko odin raz dlinnuyu chast'
opisaniya. Zapreshchaetsya opisyvat' strukturu ili ob容dinenie,
kotorye soderzhat obrazec samogo sebya, no struktura ili ob容-
dinenie mogut soderzhat' ukazatel' na strukturu ili ob容dine-
nie takogo zhe vida, kak oni sami.
Imena chlenov i yarlykov struktur mogut sovpadat' s ime-
nami obychnyh peremennyh. Odnako imena yarlykov i chlenov
dolzhny byt' vzaimno razlichnymi.
Dve struktury mogut imet' obshchuyu nachal'nuyu posledova-
tel'nost' chlenov; eto oznachaet, chto tot zhe samyj chlen mozhet
poyavit'sya v dvuh razlichnyh strukturah, esli on imeet odina-
kovyj tip v obeih strukturah i esli vse predydushchie chleny
obeih struktur odinakovy. Fakticheski kompilyator tol'ko pro-
veryaet, chto imya v dvuh razlichnyh strukturah imeet odinakovyj
tip i odinakovoe smeshchenie, no esli predshestvuyushchie chleny
otlichayutsya, to konstrukciya okazyvaetsya neperenosimoj.
Vot prostoj primer opisaniya struktury:
-28-
struct tnode {
char tword[20];
int count;
struct tnode *left;
struct tnode *right;
};
takaya struktura soderzhit massiv iz 20 simvolov, celoe i dva
ukazatelya na takie zhe struktury. Kak tol'ko privedeno takoe
opisanie, opisanie
struct tnode s, *sp;
govorit o tom, chto s yavlyaetsya strukturoj ukazannogo vida, a
sp yavlyaetsya ukazatelem na strukturu ukazannogo vida. Pri
nalichii etih opisanij vyrazhenie
sp->count
ssylaetsya na pole count struktury, na kotoruyu ukazyvaet sp;
vyrazhenie
s.left
ssylaetsya na ukazatel' levogo poddereva v strukture s, a
vyrazhenie
s.right->tword[0]
ssylaetsya na pervyj simvol chlena tword pravogo poddereva iz
s.
5.6. Perechislimyj tip
Perechislimyj tip dannyh analogichen skalyarnym tipam
yazyka Paskal'. Specifikator perechislimogo tipa imeet sledu-
yushchij vid:
specifikator_perechisleniya:
enum spisok_perechisleniya
enum identifikator spisok_perechisleniya
enum identifikator
spisok_perechisleniya:
perechislyaemoe
spisok_perechisleniya, perechislyaemoe
perechislyaemoe:
identifikator
identifikator = konstantnoe vyrazhenie
-29-
Rol' identifikatora v specifikatore_perechisleniya pol-
nost'yu analogichna roli yarlyka struktury v
specifikatore_struktury; identifikator oboznachaet opredelen-
noe perechislenie. Naprimer, opisanie
enum color {red, white, black, blue };
. . .
enum color *cp, col;
ob座avlyaet identifikator color yarlykom perechisleniya tipa,
opisyvayushchego razlichnye cveta i zatem ob座avlyaet cr ukazatelem
na ob容kt etogo tipa, a col - ob容ktom etogo tipa.
Identifikatory v spiske_perechisleniya stanovyatsya kons-
tantami i mogut poyavlyat'sya tam, gde trebuyutsya (po kontekstu)
konstanty. Esli ne ispol'zuetsya vtoraya forma perechislyaemogo
(s ravenstvom =), to velichiny konstant nachinayutsya s 0 i voz-
rastayut na 1 v sootvetstvii s prochteniem ih opisaniya sleva
napravo. Perechislyaemoe s prisvoeniem = pridaet sootvetstvuyu-
shchemu identifikatoru ukazannuyu velichinu; posleduyushchie identi-
fikatory prodolzhayut progressiyu ot pripisannoj velichiny.
YArlyki perechislenij i imena konstant dolzhny byt' raz-
lichnymi i ne sovpadat' s imenami yarlykov i chlenov struktur.
Ob容kty dannogo tipa perechisleniya rassmatrivayutsya kak
ob容kty, imeyushchie tip, otlichnyj ot lyubyh tipov i kontroliruyu-
shchaya programma lint soobshchaet ob oshibkah nesootvetstviya tipov.
V realizacii na CM_|VM so vsemi perechislyaemymi peremennymi
operiruyut tak, kak esli by oni imeli tip int.
5.7. Inicializaciya
Opisatel' mozhet ukazyvat' nachal'noe znachenie opisyvae-
mogo identifikatora. Inicializator sostoit iz vyrazheniya ili
zaklyuchennogo v figurnye skobki spiska znachenij, pered koto-
rymi stavitsya znak =.
inicializator:
= vyrazhenie
= {spisok_inic}
= {spisok_inic,}
spisok_inic:
vyrazhenie
spisok_inic,spisok_inic
{spisok_inic}
gde
spisok_inic - spisok_inicializatorov
-30-
Vse vyrazheniya, vhodyashchie v inicializator staticheskoj ili
vneshnej peremennoj, dolzhny byt' libo konstantnymi vyrazheni-
yami, libo vyrazheniyami, kotorye svodyatsya k adresu ranee opi-
sannoj peremennoj, smeshchennomu na konstantnoe (vozmozhno,
nulevoe) vyrazhenie. Avtomaticheskie i registrovye peremennye
mogut byt' inicializirovany proizvol'nymi vyrazheniyami, vklyu-
chayushchimi konstanty i ranee opisannye peremennye i funkcii.
Garantiruetsya, chto neinicializirovannye staticheskie i
vneshnie peremennye poluchayut v kachestve nachal'nyh znachenij 0;
neinicializirovannye avtomaticheskie i registrovye peremennye
v kachestve nachal'nyh znachenij soderzhat musor.
Kogda inicializator primenyaetsya k skalyaru (ukazatelyu
ili ob容ktu arifmeticheskogo tipa), to on sostoit iz odnogo
vyrazheniya, vozmozhno zaklyuchennogo v figurnye skobki. Nachal'-
noe znachenie ob容kta nahoditsya iz vyrazheniya; vypolnyayutsya te
zhe samye preobrazovaniya, chto i pri prisvaivanii.
Kogda opisyvaemaya peremennaya yavlyaetsya agregatom (struk-
turoj ili massivom), to inicializator sostoit iz zaklyuchen-
nogo v figurnye skobki i razdelennogo zapyatymi spiska inici-
alizatorov dlya chlenov agregata. |tot spisok sostavlyaetsya v
poryadke vozrastaniya indeksa ili v sootvetstvii s poryadkom
chlenov. Esli agregat soderzhit podagregaty, to eto pravilo
primenyaetsya rekursivno k chlenam agregata. Esli kolichestvo
inicializatorov v spiske okazyvaetsya men'she chisla chlenov
agregata, to ostavshiesya chleny agregata zapolnyayutsya nulyami.
Zapreshchaetsya inicializirovat' ob容dineniya ili avtomaticheskie
agregaty.
Figurnye skobki mogut interpretirovat'sya sleduyushchim
obrazom. Esli inicializator nachinaetsya s levoj figurnoj
skobki, to posleduyushchij razdelennyj zapyatymi spisok iniciali-
zatorov inicializiruet chleny agregata; budet oshibkoj, esli v
spiske okazhetsya bol'she inicializatorov, chem chlenov agregata.
Esli odnako inicializator ne nachinaetsya s levoj figurnoj
skobki, to iz spiska beretsya tol'ko nuzhnoe dlya chlenov dan-
nogo agregata chislo elementov; ostavshiesya elementy ispol'zu-
yutsya dlya inicializacii sleduyushchego chlena agregata, chast'yu
kotorogo yavlyaetsya nastoyashchij agregat. Sledovatel'no, skobki v
nekotoryh sluchayah mozhno opuskat'.
Poslednee sokrashchenie dopuskaet vozmozhnost' inicializa-
cii massiva tipa char s pomoshch'yu stroki. V etom sluchae chleny
massiva posledovatel'no inicializiruyutsya simvolami stroki.
Naprimer,
int h[] = {1,3,5};
opisyvaet i inicializiruet h kak odnomernyj massiv; pos-
kol'ku razmer massiva ne specificirovan, a spisok
-31-
inicializatora soderzhit tri elementa, schitaetsya, chto massiv
sostoit iz treh chlenov.
Vot primer inicializacii s polnym ispol'zovaniem figur-
nyh skobok:
float *y[4][3] = {
( 1, 3, 5 ),
( 2, 4, 6 ),
( 3, 5, 7 ),
};
Zdes' 1, 3 i 5 inicializiruyut pervuyu stroku massiva y[0], a
imenno y[0][0], y[0][1] i y[0][2]. Analogichnym obrazom sle-
duyushchie dve strochki inicializiruyut y[1] i y[2]. Inicializator
zakanchivaetsya prezhdevremenno, i, sledovatel'no, massiv y[3]
inicializiruetsya nulyami. V tochnosti takogo zhe effekta mozhno
bylo by dostich', napisav
float y[4][3] = {
1, 3, 5, 2, 4, 6, 3, 5, 7
};
Inicializator dlya y nachinaetsya s levoj figurnoj skobki, no
inicializatora dlya y[0] net. Poetomu ispol'zuetsya 3 elementa
iz spiska. Analogichno sleduyushchie tri elementa ispol'zuyutsya
posledovatel'no dlya y[1] i y[2]. Sleduyushchee opisanie
float y[4][3] = {
{1}, {2}, {3}, {4}
};
inicializiruet pervyj stolbec y (esli ego rassmatrivat' kak
dvumernyj massiv), a ostal'nye elementy zapolnyayutsya nulyami.
I nakonec, opisanie
char msg[] = "syntax error on line %s\n";
demonstriruet inicializaciyu elementov simvol'nogo massiva s
pomoshch'yu stroki.
5.8. Imena tipov
V dvuh sluchayah (dlya yavnogo ukazaniya tipa preobrazovaniya
v konstrukcii perevoda i dlya argumentov operacii sizeof)
zhelatel'no imet' vozmozhnost' zadavat' tip dannyh. |to osu-
shchestvlyaetsya s pomoshch'yu "imeni tipa", kotoroe po sushchestvu
yavlyaetsya opisaniem ob容kta takogo tipa, v kotorom opushcheno
imya samogo ob容kta.
-32-
Imya tipa:
specifikator_tipa abstraktnyj_opisatel'
abstraktnyj_opisatel':
pusto
(abstraktnyj_opisatel')
*abstraktnyj opisatel'
abstraktnyj_opisatel' ()
abstraktnyj_opisatel' [konstant-
noe vyrazhenie]
neob
Vo izbezhanie dvusmyslennosti v konstrukcii
(abstraktnyj_opisatel')
trebuetsya, chtoby abstraktnyj_opisatel' byl nepust. Pri etom
ogranichenii vozmozhno odnoznachno opredelit' to mesto v
abstraktnom_opisatele, gde dolzhen poyavit'sya identifikator,
esli by eta konstrukciya byla opisatelem v opisanii. Imeno-
vannyj tip sovpadaet togda s tipom gipoteticheskogo identifi-
katora. Naprimer, imena tipov
int
int *
int *[3]
int (*)[3]
int *()
int (*)()
imenuyut sootvetstvenno tipy "celyj", "ukazatel' na celoe",
"massiv iz treh ukazatelej na celoe", "ukazatel' na massiv
iz treh celyh", " funkciya, vozvrashchayushchaya ukazatel' na celoe"
i "ukazatel' na funkciyu, vozvrashchayushchuyu celoe".
5.9. Opisatel' typedef
Opisaniya, v kotoryh "klass pamyati" specificirovan kak
typedef, ne vyzyvayut vydeleniya pamyati. Vmesto etogo oni
opredelyayut identifikatory, kotorye pozdnee mozhno ispol'zo-
vat' tak, slovno oni yavlyayutsya klyuchevymi slovami, imeyushchimi
osnovnye ili proizvodnye tipy.
opredelyayushchee_tip_imya:
identifikator
V predelah oblasti dejstviya opisaniya so specifikatorom
typedef kazhdyj identifikator, opisannyj v nem, stanovitsya
sintaksicheski ekvivalentnym klyuchevomu slovu, imeyushchemu tot
tip, kotoryj associiruet s identifikatorom v opisannom v p.
0.4 smysle. Naprimer, posle opisanij
typedef int miles, *klicksp;
typedef struct { double re, im;} complex;
-33-
konstrukcii
miles distance;
extern klicksp metricp;
complex z, *zp;
stanovyatsya zakonnymi opisaniyami; pri etom tipom distance
yavlyaetsya int, tipom metricp - "ukazatel' na int", tipom z -
specificirovannaya struktura i tipom zp - ukazatel' na takuyu
strukturu.
Specifikator typedef ne vvodit kakih-libo sovershenno
novyh tipov, a tol'ko opredelyaet sinonimy dlya tipov, kotorye
mozhno bylo by specificirovat' i drugim sposobom. Tak v pri-
vedennom vyshe primere peremennaya distance schitaetsya imeyushchej
tochno takoj zhe tip, chto i lyuboj drugoj ob容kt, opisannyj v
int.
* 6. OPERATORY
Za isklyucheniem osobo ogovarivaemyh sluchaev, operatory
vypolnyayutsya posledovatel'no.
6.1. Operatornoe vyrazhenie
bol'shinstvo operatorov yavlyayutsya operatornymi vyrazheni-
yami, kotorye imeyut formu
vyrazhenie;
Obychno operatornye vyrazheniya yavlyayutsya prisvaivaniyami ili
obrashcheniyami k funkciyam.
6.2. Sostavnoj operator (ili blok)
S tem, chtoby dopustit' vozmozhnost' ispol'zovaniya nes-
kol'kih operatorov tam, gde ozhidaetsya prisutstvie tol'ko
odnogo, predusmatrivaetsya sostavnoj operator (kotoryj takzhe
nazyvayut "blokom"):
sostavnoj operator:
{spisok_opisanij spisok_operatorov}
neob neob
spisok_opisanij:
opisanie
opisanie spisok_opisanij
spisok_operatorov:
operator
operator spisok_operatorov
Esli kakoj-libo identifikator iz spiska_opisanij byl opisan
-34-
ranee, to vo vremya vypolneniya bloka vneshnee opisanie podav-
lyaetsya i snova vstupaet v silu posle vyhoda iz bloka.
Lyubaya inicializaciya avtomaticheskih i registrovyh pere-
mennyh provoditsya pri kazhdom vhode v blok cherez ego nachalo.
V kompilyatore OS DEMOS razreshaetsya (no eto plohaya praktika)
peredavat' upravlenie vnutr' bloka; v takom sluchae eti ini-
cializacii ne vypolnyayutsya. Inicializacii staticheskih pere-
mennyh provodyatsya tol'ko odin raz, kogda nachinaetsya vypolne-
nie programmy.
Nahodyashchiesya vnutri bloka vneshnie opisaniya ne rezervi-
ruyut pamyati, tak chto ih inicializaciya ne razreshaetsya.
6.3. Uslovnye operatory
Imeyutsya dve formy uslovnyh operatorov:
if (vyrazhenie) operator
if (vyrazhenie) operator else operator
V oboih sluchayah vychislyaetsya vyrazhenie i, esli ono otlichno ot
nulya, to vypolnyaetsya pervyj podoperator. Vo vtorom sluchae,
esli vyrazhenie ravno nulyu, vypolnyaetsya vtoroj podoperator.
Kak obychno, dvusmyslennost' else razreshaetsya svyazyvaniem
else s poslednim vstrechayushchimsya if, u kotorogo net else.
6.4. Operator while
Operator while imeet formu
while (vyrazhenie) operator
Podoperator vypolnyaetsya povtorno do teh por, poka znachenie
vyrazheniya ostaetsya otlichnym ot nulya. Proverka proizvoditsya
pered kazhdym vypolneniem operatora.
6.5. Operator do
Operator do imeet formu
do operator while (vyrazhenie)
Operator vypolnyaetsya povtorno do teh por, poka znachenie
vyrazheniya ne stanet ravnym nulyu. Proverka proizvoditsya posle
kazhdogo vypolneniya operatora.
6.6. Operator for
Operator for imeet formu
(vyrazhenie1;vyrazhenie2;vyrazhenie3)operator
neob neob neob
-35-
Operator for ekvivalenten sleduyushchemu:
vyrazhenie1;
while (vyrazhenie2) {
operator
vyrazhenie3;
}
Takim obrazom, pervoe vyrazhenie opredelyaet inicializaciyu
cikla; vtoroe specificiruet proverku, vypolnyaemuyu pered kazh-
doj iteraciej, tak chto vyhod iz cikla proishodit togda,
kogda znachenie vyrazheniya stanovitsya nulem; tret'e vyrazhenie
chasto zadaet prirashchenie parametra, kotoryj vychislyaetsya posle
kazhdoj iteracii.
Lyuboe vyrazhenie ili vse oni mogut byt' opushcheny. Esli
otsutstvuet vtoroe vyrazhenie, to predlozhenie s while schita-
etsya ekvivalentnym while(1); drugie otsutstvuyushchie vyrazheniya
prosto opuskayutsya iz privedennogo vyshe rasshireniya.
6.7. Operator switch
Operator switch (pereklyuchatel'), vyzyvaet peredachu
upravleniya k odnomu iz neskol'kih operatorov, v zavisimosti
ot znacheniya vyrazheniya. Operator imeet formu
switch (vyrazhenie) operator
V vyrazhenii provodyatsya obychnye arifmeticheskie preobrazova-
niya, rezul'tat dolzhen imet' tip int. Operator obychno yavlya-
etsya sostavnym. Lyuboj operator vnutri etogo operatora mozhet
byt' pomechen odnim ili bolee variantnym prefiksom case, ime-
yushchim formu:
case konstantnoe vyrazhenie:
Gde konstantnoe vyrazhenie dolzhno imet' tip int. Nikakie dve
variantnye konstanty v odnom i tom zhe pereklyuchatele ne mogut
imet' odinakovoe znachenie. Tochnoe opredelenie konstantnogo
vyrazheniya privoditsya nizhe.
Krome togo, mozhet prisutstvovat' odin operatornyj pre-
fiks vida
default:
Pri vypolnenii operatora switch vychislyaetsya vhodyashchee v
nego vyrazhenie i sravnivaetsya s kazhdoj variantnoj konstan-
toj. Esli odna iz variantnyh konstant okazyvaetsya ravnoj
znacheniyu etogo vyrazheniya, to upravlenie peredaetsya opera-
toru, kotoryj sleduet za sovpadayushchim variantnym prefiksom.
Esli ni odna iz variantnyh