Declarations and Expressions C and Data Structures Baojian Hua
Overview Variable declaration the way to introduce variables into programs Operators do some useful operations on variables and constants Expressions form complex expressions with variables, operators, constants and other expressions
Variables Variable formation rules: consists of one or more letter or digit, ( “ _ ” counts as a letter) starts with a letter lower and upper cases are distinct different from key words It ’ s common practice not to start with “ _ ” variable names in C library Choose informative variable names Compare “ sldj_wdwp_ ” with “ name ”
Types and Constants type nameruleexample charnum or char ‘ a ’, 97 intnum or char97, ‘ a ’ longsuffixes: “ L ” or “ l ” 97L, 999l floatsuffixes: “ F ” or “ f ” 97.0f, 2.5e-2F double97.0, 2.5e-2
Types and Constants(2) octalstarts with 005, 013 hexadecimalstarts with 0x0x5, 0x13 escape sequence \ooo \xhh \013 \xb string “…” “ hello, world ” enumenumerationenum boolean { NO, YES };
Variable Declaration C obeys the variable use-after-declaration rule Variable declarations consists of these parts: Type name Variable list (may only one) initialization Ex: int x, y, z; double f; char c = ‘ c ’ ; Type qualifiers: signed, unsigned (default is signed), const
Sample Variable Declaration int low, high; char line[1000]; double pi = 3.14; const double e = 2.71; const char digits[] = “ abcdef”;
Variable Declaration A declaration makes clear a variable ’ s type, size and allocates memory for it int i, j; ?%*
Variable Initialization Programmers ’ duty to initialize that memory space int i, j; i = 9; 9 ?%*
Array Declaration int i, j; i = 9; int a[5]; 9 $? &^ a ?%*
Array Initialization int i, j; i = 9; int a[5]; for (int j=0; j<5; j++) a[j] = j*j; ?%* a
Arithmetic Operators Operator:Example: +x + y -x – y *x * y /x / y %x % y ++ x -- x
Relational and Logical Operators Operator:Example: >x > y >=x >= y <x < y <=x <= y ==x == y !=x != y &&x && y ||x || y !!x
Relational and Logical Operators Boolean operators are short-circuit Computations stop as soon as true or false is known x = 9; if ((3>2) || (x=8)); // what’s x’s value? 8 or 9?
Relational and Logical Operators // another example on && x = 9; if ((1<0) && (x=8)); // what’s x’s value? 8 or 9? // a more fancy example int i = 0; int a[10]; while (i<10 && a[i]!=0){ … }
“!”“!” Not “ ! ” converts 0 to 1, and non-zero values to 0 if (!a){ … } // reads “if a does not hold”, then … // be equivalent with if (0 == a) { … } // we’d see more examples later
Increment and Decrement int n = 9; int x; x = n++; // x == 9 // n == 10 int n = 9; int x; x = ++n; // x == 10 // n == 10
Bitwise Operators Name:Example: &x & y |x | y ^x ^ y <<x << y >>x >> y ~~ x
Bitwise Operators Example // count num of 1’s in an integer x int count (int x) { int num = 0; unsigned int y = (unsigned int)x; while (y) { if (y & 0x1) num++; y >>= 1; } return num; }
Assignment Operators and Expressions Assignment is a special kind of expression, so the following code fragment is legal int x; printf (“%d\n”, x=999); Other kind of assignment expressions are of the form: e1 op= e2 Equivalent to: e1 = e1 op e2 Example: x += 9; ====> x = x + 9; See the text for a complete list of op
Assignment Operators and Expressions // more examples on assignment operators: int a, b, c; a = b = 9; a = (b = 9) + (c = 8); a = (b = 9) / (c = 3); // even as the arguments of function calls: int a, b; x = sum (a = 1, b = 2);
Conditional Expressions if (a > b) max = a; else max = b; // C provides a more succinct way to do this: max = (a>b) ? a : b; // the general form is: e1 ? e2 : e3; // if e1 evaluates to true, then evaluates e2, // else evaluates e3.
Type Conversion (Cast) When the type of some expression is not compatible with the one expected, automatic type conversion occurs Example from our previous code: // all of c, ‘0’ and ‘9’ are automatic converted // into integer values by the compiler: if ((c>=‘0’) && (c<=‘9’)) a[c-’0’]++;
Type Conversion (Cast) Generally, there are two kinds of automatic cast: cast a “ big ” into “ smaller ” ones long ==> int cast a “ small ” into “ bigger ” ones char ==> int The former is not always safe
Type Conversion (Cast) The general scheme for “safe” cast is: doublefloat long unsigned intchar
Type Conversion (Cast) // Dirty simple? However, it’s more subtle than // it first looks. Consider: #include int main () { int i = -1; unsigned int j = 0; if (i < j) printf (“Never reach here, :-( \n”); else printf (“Shoot myself in the foot\n”); return 0; }
Type Conversion (Cast) Don ’ t expect the compiler will always behave as you desire Two general principals: Always use the C ’ s type system as strong as possible It ’ s your basic protection One reason for strong type system ’ s popularity Make use of C ’ s type conversion explicitly To make clear what we are doing
Explicit Type Cast General form of explicit type conversion: (type) expression // which converts the expression’s type to type // More examples: int i = (int) ; char c = (char)i; int a[10]; a[(int)2.71] = 99; As we see, data precision may be changed
Safety Issue Type conversion is an infamous source of C programs bugs especially with pointers (int *)999 will send your passwd to BillG … Any serious and well-designed C program should use type conversion really rarely General principle: do NOT use it, always use the explicit form