Типове, оператори и изрази - 2

Chapter 2 - Types, Operators and Expressions
2.7 Type Conversions
2.8 Increment and Decrement Operators
2.9 Bitwise Operators
2.10 Assignment Operators and Expressions
2.11 Conditional Expressions
2.12 Precedence and Order of Evaluation

Преобразуване на типове

* Преобразуване без загуба на информация
* Преобразуване със загуба на информация

За бинарни операции:
ebook - The C Programming Language Ritchie & kernighan -.doc • If either operand is long double, convert the other to long double.
• Otherwise, if either operand is double, convert the other to double.
• Otherwise, if either operand is float, convert the other to float.
• Otherwise, convert char and short to int.
• Then, if either operand is long, convert the other to long.

ebook - The C Programming Language Ritchie & kernighan -.do root2 = sqrt(2)

/* atoi: convert s to integer */
int atoi(char s[])
{
    int i, n;
    n = 0;
    for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
        n = 10 * n + (s[i] - '0');
    return n;
}

isdigit(s[i])

/* lower: convert c to lower case; ASCII only */
int lower(int c)
{
    if (c >= 'A' && c <= 'Z')
        return c + 'a' - 'A';
    else
        return c;
}


Unsigned се преобразува в signed
Преобразуване на числови типове без знак - машинно зависимо!

Явно преобразуване на типове.
int k1 = 3, k2 = 4;
double x;
x = (double)(k1 + k2);


Оператори за увеличаване и намаляване

Префиксна и постфиксна операция.
int a[] = { 0, 1, 2, 3 };
int i = 2;          
int j = i++;         // j = 2 and then i = 3
int k = --i;         // i = 2 and then k = 2
printf("%d", a[k++];      // a[2] (or 2) is output; then k = 3


/* squeeze: delete all c from s */
void squeeze(char s[], int c)

{
    int i, j;
    for (i = j = 0; s[i] != '\0'; i++)
        if (s[i] != c)

              s[j++] = s[i];
    s[j] = '\0';
}


Побитови операции

~exp
bitwise complement, ex. 
~100010 r. 011101 побитово отрицание
exp & exp bitwise and (conjunction), ex. 
1001 && 1100 r. 1000 побитово "и"
exp ^ exp bitwise exclusive-or
1001 ^ 1100 r. 0101
побитово изключващо "или"
exp | exp bitwise or (disjunction)
1001 | 1100 r. 1101
побитово "или"
exp << exp shift left 11001 << 1  r. 10010 
преместване наляво
exp >> exp shift right
11001 >> 1 r. 01100
преместване надясно

Операции за присвояване и изрази

Аритметичните операции (+, -, *,  /, % ) и побитовите бинарни операции (&, ^, |, <<, >>) се комбинират с оператора за присвояване =.

int i = 10; 
int j = 5;
int k = 1;
i -= 4; // i = i - 4; result 6

j *= -2; // j = j * (-2); result -10
k <<= 1; // k = k << 1; result 2


ebook - The C Programming Language Ritchie & kernighan -.doc /* bitcount: count 1 bits in x */
int bitcount(unsigned x)
{
    int b;
    for (b = 0; x != 0; x >>= 1)
         if (x & 01) b++;
    return b;
}


Условни изрази

* Условна операция (операция за избор, selection operator)
Триаргументна операция, състояща се от условие и два израза.
Пример:

	x >= 0 ? x : -x

Ако условието е вярно, се изпълнява втория аргумент, ако не е вярно се изпълнява третия аргумент.
Операторът

	y = x >= 0 ? x : -x;

е еквивалентен на

	if (x >= 0) y = x;
else y = -x;

и присвоява на променливата  y абсолютната стойност на променливата x.

    Израз (expression), операция (operator)
Оператор (statement)
  x >= 0 ? x : -x
if (x >= 0) y = x;
else y = -x;
  y = x
y = x;
  -b + sqrt(d)
-b + sqrt(d);


Приоритет и ред на изчисляване

Операциите в C имат приоритет, който определя реда, по който операциите се извършват при липса на скоби.
Operator Description Associativity
:: scope Left
() [ ] -> .
  Left
++ -- increment, decrement Right
~ bitwise complement
!
unary NOT
& * reference and dereference
(type)
type casting
+ - unary + and -
* / % arithmetic operators Left
+ - addition, subtraction Left
<< >> bitwise shifts
Left
< <= > >= relational operators Left
== != relational operators Left
& 
bitwise and
Left
^ bitwise exclusive-or Left
| bitwise or
Left
&&
logical operator and
Left
||
logical operator or
Left
?: conditional operator
Left
= += -= *= /= %=
>>= <<= &= ^= |=
assignment operators
Right
, comma, separator Left

int a = 10, b, c, d;  

// right associativity
d = c = b = a; // is equivalent to d = (c = (b = a));

// left associativity
d - c + b - a; // is equivalent to ((d - c) + b) - a;

// precedence
d > c && -b <= a // is equivalent to (d > c) && ((-b) <= a)
*Употреба на скоби
if ((x & MASK) == 0) ...

*Неопределен резултат.
Извикване на функция
a = f() + g();
Нарастване с 1
printf("%d %d\n", ++n, power(2, n));
a[i] = i++;