370 likes | 528 Views
Types, Operators & Expressions. CSE 105 Structured Programming Language (C) Presentation - 3. Basic Data Types (K n R – 2.2). char a single byte, holds one character in local character set int natural size of integers in the host machine float Single-precision floating point double
E N D
Types, Operators & Expressions CSE 105 Structured Programming Language (C) Presentation - 3
Basic Data Types (KnR – 2.2) • char • a single byte, holds one character in local character set • int • natural size of integers in the host machine • float • Single-precision floating point • double • double-precision floating point
7-bits magnitude Data type : char (KnR – 2.2) unsigned 8-bits magnitude signed 1-bit sign: 1 means negative and 0 means positive
Data types: floating points (KnR – 2.2) • float • single-precision • double • double-precision • long double • extended-precision • All of these types are implementation dependent • They can be of one, two or three distinct sizes.
Caution with floating point (KnR – 2.2) • Consider following code: • value of x will be very close to zero e.g. 10-7. Hence this won’t work correct code is:
Constants : Character (KnR – 2.3) • A character constant is an integer, which can be presented in different formats: • `A` : represents ASCII 65th character i.e., A • int var = `A` + 10; // value of var will be 75 • `0` : represents ASCII 48th character i.e., zero • int var = `0` + 10; // value of var will be 58 • `\0101` : represent octal 101. `A` = 6510 = 1018 • `\x41` : represent hexadecimal 41. `A` = 6510 = 4116 • Character constants can participate in numeric operations just as any other integer.
Constant : Escape Sequence (KnR – 2.3) • Back slash “\” is called escape character • Characters following “\” bear special meaning as follows:
Constant : String (KnR – 2.3) • String constant is a sequence of zero or more characters surrounded by double quote. E.g., • I am a string • /* the empty string */ • String constants can be concatenated at compile time: • hello, world. hello, world. • This is useful for splitting long strings in several lines • String is an array of characters terminated by `\0` • Observe the difference between string and character constants below: hello, world. h e l l o , w o r l d \0 0 1 ……………….. 12
A `A` 65 \0 65 Constant : Usage (KnR – 2.3) • Constant expression • Contains only constants • Can be evaluated in compile time. • A and `A` are not the same • char v = `A` + 3; /* OK */ • char w = A + 3; /* Wrong */ • Try these out: • printf(\b Alert is %d, `\b`); • printf(line is %c %d tested, `\n` , `\n`); • printf(Backspace h\bas effect ); • printf (He said, \I am fine, thank %s.\, you); #define LO `A` #define HI `Z` int cap_count[HI-LO+1]
Constant: Enumeration (KnR – 2.3) • Enumerations are used to define multiple constants • Alternate to #define, but values are auto-generated. • Examples: #define NO 0 #define YES 1 enum { NO, YES }; enum escapes { BELL = `\a`, BACKSPACE = `\b`, TAB = `\b` NEWLINE = `\n`, VTAB = `\v`, RETURN = `\r`}; enum months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC }; /* FEB is 2, MAR is 3, etc. */
Arithmetic Operators (KnR – 2.5) • + , – , * , /, % • Division operator / • For –ve operand, direction of truncation is m/c dependent • -7/2 = ? -3 or -4 • Mod operator % • Cannot be applied on float or double • For –ve operand, sign of result is m/c dependent • Precedence : • Highest : unary + and – • 2nd highest : * and / • Lowest : + and – • Arithmetic operators associate left to right. • A * B * C = (A * B) * C
Relational & Logical Operators (KnR – 2.6) • Relational Operators: > >= < <= • have lower precedence than arithmetic operators • thus, i < lim – 1 i < (lim – 1) • Equality Operators: • == != • has lower precedence than Relational operators • Logical Operators: && || … also ! • Left to right associative • Evaluation stops as soon as truth or falsehood is known • Example follows
&& and || have “short circuit” evaluation • left operand evaluated first; right operand evaluated only if necessary • &&: if left operand evaluates to 0, immediately return 0 • ||: if left operand evaluates to nonzero value, immediately return 1 • This allows you to write code like this with confidence: if (y == 0 || x / y > MAX) ... 16 CS 3090: Safety Critical Programming in C
Relational & Logical Operators (KnR – 2.6) for (i=0; i<lim—1 && (s[i]=getchar())!=`\n` && s[i]!=EOF; i++) ; • Condition in for loop is executed left to right • Array bound must be checked (i<lim-1) before s[i]=getchar( ) is executed • If the test i<lim-1 fails we cannot assign value to s[i] • Similarly it would be unfortunate to check s[i]!=EOF before s[i]=getchar( ) is executed • Since precedence of != is higher than assignment parentheses are needed in (s[i]=getchar())!=`\n` • s[i]=getchar()!=`\n` would be 1 or 0 • DIY Ex. 2.2: Write a loop equivalent to above for loop without using && or ||
Type Conversions (KnR – 2.7) • Automatic conversions convert narrower operand into a wider one. • Warnings are generated for expressions that may loose information. • Binary operators (like +, *) with mixed operand types the lower or narrower type is converted to higher or wider type. • long double > double > float > long int > short int > char. • unsigned > signed • -1L < 1U // 1U is promoted to signed long • -1L > 1UL // -1L is promoted to unsigned long • Explicit type conversion can be specified as follows • (type-name) expression
Type Conversions (KnR – 2.7) • char can be used just like int. /* 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 = n * 10 + (s[i] - `0`); return n; } /* lower: convert ct to lower case; ASCII only; */int lower(int c) { if (c >= `A` && c <= `Z`) return c + `a` - `A`; else return c; }
Bitwise Operators (KnR – 2.9) • Bitwise operators can only be applied to integral operands: i.e., all versions of char and int • & : bitwise AND • Mask off some bits • n = n & 0177; • sets all bit of n to zero except the rightmost 7 bits • | : bitwise OR • Turn on some bits • x = x | 0100; • Turns on the 6th (zero based) bit of x • Must be distinguished from && and || operators • int x = 1, y = 2; x && y 1 x & y 0 x || y 1 x | y 3
Example: setting a bit to one value = value | 1 << bit_number; 0xAA | 1 << 2 10101010 00000100 10101110
Example: setting a bit to zero value = value & ~ ( 1 << bit_number ); 0xAA & ~ (1 << 3) 00001000 11110111 10101010 10100010
Bitwise Operators (KnR – 2.9) • ^ : bitwise XOR • Toggle (complements) some bits. • x = x ^ 0100; • Turns on the 6th (zero based) bit of x • ~ : one’s complement (unary) • x = x & ~077; • Sets the last six bits of x to 0 • Since sizeof(int) varies it is better than, x = x & 0177700 • ~ (bit-wise not) vs ! (logical not) operators • int x = 0; ~x -1 !x 1
Bitwise Operators (KnR – 2.9) • << : Left shift • x = x << 3; • Shifts x left by 3 bits x = x * 23 • >> : Right shift • x = x >> 3; • Shifts x right by 3 bits x = x / 23 • If x is unsigned then vacated bits are filled with 0 • If x is signed then vacated bits are filled with 0 or 1 depending on the machine.
~0 1111 ... 1111111111 ... 9876543210 x 0110 ... 0101101011 ~0<<n 1111 ... 1111110000 x>>(p+1-n) 00000110 ... 010110 ~(~0<<n) 0000 ... 0000001111 (x>>(p+1-n))&~(~0<<n) 00000000 ... 000110 Bitwise Operators (KnR – 2.9) • Application: /* getbits: get n bits from position p*/ Unsigned getbits (unsigned x, int p, int n) { return (x >> (p+1-n)) & ~(~0 << n); } n=4, p=7 DIY: Exercise 2-6, 2-7, 2-8
Conditional Expressions (KnR – 2.11) if (a > b) z = a; else z = b; • Only ternary operator ?: • expr1 ? expr2 : expr3; • The wider type of expr2 and expr3 is the result’s type • floatf and intn • (n > 0) ? f : n will be float regardless of the value of n • Example usage: printf(“You have %d item%s.”, n, n == 1 ? “”, “s”); z = (a > b) ? a : b;
Assignment Operators : LValue vs RValue • LValue • It is the result of an expression that has an address • usually used at the left side of assignment operator ( = ) • RValue • It is the result of an expression that has a vlaue • Usually used at the right side of assignment operator (=) • Example: LValue RValue a = a + 10; a: 48357 55 [48375] 55 + 10;
How x = y = z = 17 works? z is assigned 17; return value is 17 y is assigned 17; return value is 17 x is assigned 17; return value is 17 = is right-associative – so the expression is interpreted as: x = ( y = ( z = 17 )
= vs. == • It is easy to confuse equality with assignment • In C, the test expression of an if statement can be any int expression — including an assignment expression if (y = 0) printf("Sorry, can't divide by zero.\n"); else result = x / y; • The compiler will not catch this bug! Assignment performed; y set to 0 (oops) Expression returns result of assignment: 0, or "false" else clause executed: divide by 0!
Assignment Operators (KnR – 2.10) • For binary operators there exists short hand of the form: • += –= *= /= %= <<= >>= &= |= ^= • expr1 op= expr2 expr1 = (expr1) op (epxr2) • x *= y + 1 x = (x) * (y + 1) • Ease: yyval[yypv[p3+p4] + yypv[p1+p2]] += 2; • DIY : Exercise 2-9. • Faster version of bitcount using x &= (x – 1) /* bitcount: count 1 bits in x */ int bitcount (unsigned x) { int b; for (b = 0; x != 0; x >>= 1) b += x & 1; return b; }
x y a b a^b b x ^= y a^b a y ^= x b a x ^= y Assignment Operators (KnR – 2.10) • Swap two integers in one statement • x ^= y ^= x^= y; • Number of odd and even integers in input
Increment & Decrement Operators (KnR – 2.8) • Unary ++ (increment) and unary -- (decrement) • Effect of Prefix and Postfix placement. (x++ vs. ++x) • At some places effect is same • if (c == `\n`) if (c == `\n`) nl++; ++nl; • At some places it has different effect : n = 5; x = n; n = n+1; n = 5; x = n++; x == 5 n == 6 n = 5; n = n+1; x = n; n = 5; x = ++n; x == 6 n == 6
Increment & Decrement Operators (KnR – 2.8) • Effect of Prefix and Postfix placement. (x++ vs. ++x) • A more complicated example: i = 4; s[i] = 8; i = i+1; i = 4; s[i++] = 8; s[4] == 8 i == 5 i = 4; i = i+1; s[i] = 8; i = 4; s[++i] = 8; s[5] == 8 i == 5 a = a + 1; c = a + b; b = b + 1; a == 1 c == 1 b == 1 int a = 0, b = 0, c = 0; c = a++ + ++b;
Increment & Decrement Operators (KnR – 2.8) • Proper application of these operators can produce efficient and concise code: • DIY: • Exercise: 2-4 • Exercise: 2-5 /* strcat: concatenate t to end of s; s must be big enough */ void strcat(char s[ ], char t[ ]) { int i = 0, j = 0; while (s[i++] != `\0`) ; /* find end of s */ while ((s[i++] = t[i++]) != `\0`) ; /* copy t */ }
Increment & Decrement Operators (KnR – 2.8) • The operand of ++ and -- operator must have LValue • i++; // is ok • (i + j)++; // is not ok • (i + j) has only RValue • (i = 0)++; // is ok • i = 0 returns the LValue of I • (i = j + 2)++; // is ok • i = j + 2 i is assigned to (j + 2) and LValue of i is returned • then the i is incremented by 1 • (i = j = 0) ++; // is ok • i = j = 0 i and j is assigned 0 and LValue of i is returned • i is then incremented by 1. i: 48123 20 50 j: 48567 30
Precedence, Associativity & Evaluation order • Precedence: given two operators of different types, which is evaluated first? • Associativity: given a sequence of instances of the same operator, are they evaluated left-to-right or right-to-left? • Evaluation order: given an operator with a number of operands, in what order are the operands evaluated?
Precedence (KnR – 2.12) Higher Precedence