Пређи на садржај

Операција зарез

С Википедије, слободне енциклопедије

У C и C++ програмским језицима, операција зарез (често представљена као ,) је бинарна операција која оцењује свој први операнд и одбацује резултат, а онда оцењује други операнд и враћа вредност (и тип).

Коришћење зареза као операције се разликује од коришћења у дефиницијама и потпрограмима, декларацији променљивих, енум декларацији и сличним конструкцијама где он делује као растављач.

Синтакса

[уреди | уреди извор]

Операција зарез одваја изразе (који имају вредност) аналогно како тачка за зарезом пресеца изјаве, и секвенце израза су у заградама аналогно томе како су секвенце изјава затворене у заграда: (a, b, c) је низ израза, одвојених зарезима, која процењује до последњег израза c док {a; b; c;} је низ изјава, и не припада ниједној вредности. Зарез може доћи само између два израза – зарезом одвојени изрази - за разлику од тачке са зарезом, која долази на крају изјаве (не-блока) – тачка са зарезом прекида изјаву.

Оператор зарез има најнижи приоритет сваког оператора C, и делује као тачка секвенце. У комбинацији зареза и зареза са тачком, зарези са тачком имају нижи приоритет од зареза, као и одвојене изјаве са зарезом са тачком, али зарези долазе у изјавама, које су у сагласју са њиховом употребом као обичном интерпункцијом:  a, b; c, d је група као (a, b); (c, d) јер ова два представљају два одвојена елемнта.

У овом примеру, различита понашања између другог и трећег реда су због операција зарез имајући мању предност него задатак. Последњи пример разликује се као добро пошто повраћени израз мора бити потпуно процењен пре него што функција може бити враћена .

// Примери: Описи: Вредности након реда се процењују:
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".

У Паскалу, више-димензионални низови су индексирани коришћењем зареза, на пример A[i, j]. У C,  међутим, A[i, j] је еквивалентно са  A[j], откако је вредност i избачена. Правилан начин за индексирање више-димензионалних низова у C је са конструкцијама као што је A[i][j].

Употреба

[уреди | уреди извор]

Операција зарез има релативно ограничене случајеве коришћења. Јер одбацује свој први операнд, генерално је само користан када први операнд има жељене неспојиве ефекте. Даље, јер се ретко користи ван специфичних идиома, и лако се створи заблуда  са другим зарезима или тачка зарезима, потенцијално је збуљујуће и склоно грешкама.  Ипак, постоје одређене околности у којима се најчешће користе, посебно за петље и у СФИНАЕ (http://en.cppreference.com/w/cpp/language/sfinae). За уграђене системе који могу да имају ограничено отклањање грешака могућности, оператер зарез може да се користи у комбинацији са макроима да неприметно замени функцију позива, да убаци код непосредно пре позива функције. 

Најчешћа употреба је да омогући више додела изјаве без употребе блок изјаве, пре свега у иницирању и прирасту израза фор петљи. Ово је једина идиоматска употреба у основи C програмирања. У следећем примеру, редослед иницирања петље је значајан:

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

Алтернативно решење овог проблема је паралелни задатак, који омогућава да се деси више задатака у једној изјави, а такође користи зарез, али са различитим синтаксама и семантикама. Ово се користи у Гоу и за аналогне петље.[1]

Изван за петље (који имају посебну употребу зареза са тачком), зарез може бити синоним за зарез са тачком, нарочито када су изјаве у функцији питања слично као петље прираста (нпр на крају вајл петље):

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

Међутим, како употреба постиже исту ствар као и зарез са тачком на визуелно другачији начин, ово је сумњиво корисно и може збунити читаоце.

Зарез се може користити у препроцесорским макроима за обављање више операција у простору појединачног синтактичног израза.

Један од уобичајених употреба је да пружи прилагођену поруку о грешки у неуспелим тврдњама. Ово је учињено доношењем израза за тврђење макроа, где је први израз грешка стринга а други израз је кондиционал који се тврди.тврђење макро излаза његових аргумената дословно на неуспех тврдње. Следеће је пример:

#укључује <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;
}

Излаз:

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

Зарез може да се користи у оквиру кондиционала (иф, док, до времена, или) да би омогућио помоћне прорачуне, а посебно позивањем функција и коришћењем резултата, са блок одређивањем оквира

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

Сличан идиом постоји у Гоу, где синтакса иф изјава експлицитно дозвољава оптималну изјаву.[2]

Комплексни повратак

[уреди | уреди извор]

Зарез може да се користи у повратним изјавама, да додели глобалне променљиве или ван параметара (које доносе референце). Овај идиом указује на то да су задаци део повратка, а не помоћних задатака у блоку који завршава са стварним повратком. На пример, у подешавању глобалног броја грешке: 

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

Ово може бити написано опширније као на пример:

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

Избегавање блока

[уреди | уреди извор]

Да би сажели, зарез може да се користи да би смо избегли блок или претеће заграде као на пример:

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

уместо:

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

Други језици

[уреди | уреди извор]

У Окамл и Руби програмским језицима, запета (";") се користи за ову сврху. Јаваскрипт и Перл користе операцију зарез на исти начин као и C и C++.

Референце

[уреди | уреди извор]
  1. ^ Effective Go: for, "Finally, Go has no comma operator and ++ and -- are statements not expressions.
  2. ^ The Go Programming Language Specification: If statements

Спољашње везе

[уреди | уреди извор]