Operacija zarez

S Vikipedije, slobodne enciklopedije

U C i C++ programskim jezicima, operacija zarez (često predstavljena kao ,) je binarna operacija koja ocenjuje svoj prvi operand i odbacuje rezultat, a onda ocenjuje drugi operand i vraća vrednost (i tip).

Korišćenje zareza kao operacije se razlikuje od korišćenja u definicijama i potprogramima, deklaraciji promenljivih, enum deklaraciji i sličnim konstrukcijama gde on deluje kao rastavljač.

Sintaksa[uredi | uredi izvor]

Operacija zarez odvaja izraze (koji imaju vrednost) analogno kako tačka za zarezom preseca izjave, i sekvence izraza su u zagradama analogno tome kako su sekvence izjava zatvorene u zagrada: (a, b, c) je niz izraza, odvojenih zarezima, koja procenjuje do poslednjeg izraza c dok {a; b; c;} je niz izjava, i ne pripada nijednoj vrednosti. Zarez može doći samo između dva izraza – zarezom odvojeni izrazi - za razliku od tačke sa zarezom, koja dolazi na kraju izjave (ne-bloka) – tačka sa zarezom prekida izjavu.

Operator zarez ima najniži prioritet svakog operatora C, i deluje kao tačka sekvence. U kombinaciji zareza i zareza sa tačkom, zarezi sa tačkom imaju niži prioritet od zareza, kao i odvojene izjave sa zarezom sa tačkom, ali zarezi dolaze u izjavama, koje su u saglasju sa njihovom upotrebom kao običnom interpunkcijom:  a, b; c, d je grupa kao (a, b); (c, d) jer ova dva predstavljaju dva odvojena elemnta.

Primeri[uredi | uredi izvor]

U ovom primeru, različita ponašanja između drugog i trećeg reda su zbog operacija zarez imajući manju prednost nego zadatak. Poslednji primer razlikuje se kao dobro pošto povraćeni izraz mora biti potpuno procenjen pre nego što funkcija može biti vraćena .

// Примери: Описи: Вредности након реда се процењују:
int a=1, b=2, c=3, i=0; // зарези се понашају као сепаратори у овом реду, не као операција 
                        // ... a=1, b=2, c=3, i=0
i = (a, b); // складишта b унутар i 
                        // ... a=1, b=2, c=3, i=2
i = a, b; // sскладишта a унутар i. Еквивалентно са (i = a), b;
                        // ... a=1, b=2, c=3, i=1
i = (a += 2, a + b); // повећава a за 2, онда складишта a+b = 3+2 унутар i
                        // ... a=3, b=2, c=3, i=5
i = a += 2, a + b; // повећава a за 2, онда складишта a до i, и одбацује неискоришћене
                        // a + b рвредности. Еквивалентно са (i = (a += 2)), a + b; 
                        // ... a=5, b=2, c=3, i=5
i = a, b, c; // складишти a унутар i, одбацивајући некоришћено b и c рвредности
                        // ... a=5, b=2, c=3, i=5
i = (a, b, c); // скалдишта c унутар i, одбацивајући неискоришћено a и b рвредности
                        // ... a=5, b=2, c=3, i=3
return a=4, b=5, c=6; // враћа 6, не 4, пошто операција зарез ниже бодове
                        // пратећи тастатуру 'врати' се сматра синглом
                        // израз оцењује рвредности коначног подизраза c=6
return 1, 2, 3; // враћа 3, не 1, због истог разлога као горе
return(1), 2, 3; // враћа 3, не 1, још увек због истог разлога као горе. Овај
                        // пример функционише тако зато што повратак је тастатура, не 
                        // функција зове. Иако ће компајлери одобрити за
                        // конструкт повратак (вредност), заграде су само
                        // у односу на "вредност" и нема посебног ефекта на
                        // повратак tastatura.  Повратак једноставно добија израз и
                        // овде је израз "(1), 2, 3".

U Paskalu, više-dimenzionalni nizovi su indeksirani korišćenjem zareza, na primer A[i, j]. U C,  međutim, A[i, j] je ekvivalentno sa  A[j], otkako je vrednost i izbačena. Pravilan način za indeksiranje više-dimenzionalnih nizova u C je sa konstrukcijama kao što je A[i][j].

Upotreba[uredi | uredi izvor]

Operacija zarez ima relativno ograničene slučajeve korišćenja. Jer odbacuje svoj prvi operand, generalno je samo koristan kada prvi operand ima željene nespojive efekte. Dalje, jer se retko koristi van specifičnih idioma, i lako se stvori zabluda  sa drugim zarezima ili tačka zarezima, potencijalno je zbuljujuće i sklono greškama.  Ipak, postoje određene okolnosti u kojima se najčešće koriste, posebno za petlje i u SFINAE (http://en.cppreference.com/w/cpp/language/sfinae). Za ugrađene sisteme koji mogu da imaju ograničeno otklanjanje grešaka mogućnosti, operater zarez može da se koristi u kombinaciji sa makroima da neprimetno zameni funkciju poziva, da ubaci kod neposredno pre poziva funkcije. 

Za petlje[uredi | uredi izvor]

Najčešća upotreba je da omogući više dodela izjave bez upotrebe blok izjave, pre svega u iniciranju i prirastu izraza for petlji. Ovo je jedina idiomatska upotreba u osnovi C programiranja. U sledećem primeru, redosled iniciranja petlje je značajan:

void rev(char *s, size_t len)
{
    char *first;
    for (first = s, s += len - 1; s >= first; --s)
        putchar(*s);
}

Alternativno rešenje ovog problema je paralelni zadatak, koji omogućava da se desi više zadataka u jednoj izjavi, a takođe koristi zarez, ali sa različitim sintaksama i semantikama. Ovo se koristi u Gou i za analogne petlje.[1]

Izvan za petlje (koji imaju posebnu upotrebu zareza sa tačkom), zarez može biti sinonim za zarez sa tačkom, naročito kada su izjave u funkciji pitanja slično kao petlje prirasta (npr na kraju vajl petlje):

++p, ++q;
++p; ++q;

Međutim, kako upotreba postiže istu stvar kao i zarez sa tačkom na vizuelno drugačiji način, ovo je sumnjivo korisno i može zbuniti čitaoce.

Makroi[uredi | uredi izvor]

Zarez se može koristiti u preprocesorskim makroima za obavljanje više operacija u prostoru pojedinačnog sintaktičnog izraza.

Jedan od uobičajenih upotreba je da pruži prilagođenu poruku o greški u neuspelim tvrdnjama. Ovo je učinjeno donošenjem izraza za тврђење makroa, gde je prvi izraz greška stringa a drugi izraz je kondicional koji se tvrdi.тврђење makro izlaza njegovih argumenata doslovno na neuspeh tvrdnje. Sledeće je primer:

#укључује <stdio.h>
#укључује <assert.h>

int main ( void )
{
    int i;
    for (i=0; i<=9; i++)
    {
        assert( ( "i is too big!", i <= 4 ) );
        printf("i = %i\n", i);
    }
    return 0;
}

Izlaz:

i = 0
i = 1
i = 2
i = 3
i = 4
assert: assert.c:6: test_assert: Assertion `( "i is too big!", i <= 4 )' failed.
Aborted

Stanje[uredi | uredi izvor]

Zarez može da se koristi u okviru kondicionala (if, dok, do vremena, ili) da bi omogućio pomoćne proračune, a posebno pozivanjem funkcija i korišćenjem rezultata, sa blok određivanjem okvira

if (y = f(x), y > x) {
    ... //  изјава која укључује x и y
}

Sličan idiom postoji u Gou, gde sintaksa if izjava eksplicitno dozvoljava optimalnu izjavu.[2]

Kompleksni povratak[uredi | uredi izvor]

Zarez može da se koristi u povratnim izjavama, da dodeli globalne promenljive ili van parametara (koje donose reference). Ovaj idiom ukazuje na to da su zadaci deo povratka, a ne pomoćnih zadataka u bloku koji završava sa stvarnim povratkom. Na primer, u podešavanju globalnog broja greške: 

if (failure)
    return (errno = EINVAL, -1);

Ovo može biti napisano opširnije kao na primer:

if (failure) {
    errno = EINVAL;
    return -1;
}

Izbegavanje bloka[uredi | uredi izvor]

Da bi saželi, zarez može da se koristi da bi smo izbegli blok ili preteće zagrade kao na primer:

if (x == 1) y = 2, z = 3;
if (x == 1)
    y = 2, z = 3;

umesto:

if (x == 1) {y = 2; z = 3;}
if (x == 1) {
    y = 2; z = 3;
}

Drugi jezici[uredi | uredi izvor]

U Okaml i Rubi programskim jezicima, zapeta (";") se koristi za ovu svrhu. Javaskript i Perl koriste operaciju zarez na isti način kao i C i C++.

Vidi još[uredi | uredi izvor]

Reference[uredi | uredi izvor]

  1. ^ Effective Go: for, "Finally, Go has no comma operator and ++ and -- are statements not expressions.
  2. ^ The Go Programming Language Specification: If statements

Spoljašnje veze[uredi | uredi izvor]