Computer Systems Organization


Start Lecture #4

Remark: Lab 1 assigned. Due in 2 weeks. See the course home page.

Chapter 2: Types, Operators, and Expressions

2.1: Variable Names

Similar to Java: A variable name must begin with a letter and then can use letters and numbers. An underscore is a letter, but you shouldn't begin a variable name with one since that is conventionally reserved for library routines. Keywords such as if, while, etc are reserved and cannot be used as variable names.

2.2: Data Types and Sizes

C has very few primitive types.

There are qualifiers that can be added. One pair is long/short. Typically short int is abbreviated short and long int is abbreviated long.

long must be at least as big as int, which must be as least as big as short.

There is no short floatshort double,   or  long float. The type long double specifies extended precision.

The qualifiers signed or unsigned can be applied to char or any integer type. They basically determined how the sign bit is interpreted. An unsigned char uses all 8 bits for the integer value and thus has a range of 0–255; whereas, a signed char has an integer range of -128–127.

2.3: Constants

Integer Constants

A normal integer constant such as 123 is an int, unless it is too big in which cast it is a long. But there are other possibilities.

String Constants

Although there are no string variables, there are string constants, written as zero or more characters surrounded by double quotes. A null character '\0' is automatically appended.

Enum Constants

Alternative method of assigning integer values to symbolic names.

    enum Boolean {false, true}; // false is zero, true is 1
    enum Month {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
  

2.4: Declarations

Perhaps they should be called definitions since space is allocated.

Similar to Java for scalars.

    int x, y;
    char c;
    double q1, q2;
  

(Stack allocated) arrays are simpler as the entire array is allocated not just a reference (no new/malloc required).

    int x[10];
  

Initializations may be given.

    int x=5, y[2]={44,6}; z[]={1,2,3};
    char str[]="hello, world\n";
  

The qualifier const makes the variable read only so it better be initialized in the declaration.

2.5: Arithmetic Operators

Mostly the same as java.

Please do not call % the mod operator, unless you know that the operands are positive.

2.6: Relational and Logical Operators

Again very little difference from Java.

Please remember that && and || are required to be short-circuit operators. That is, they evaluate the right operand only if needed.

2.7: Type Conversion

There are two kinds of conversions: automatic conversion, called coercion, and explicit conversions.

Automatic Conversions

C coerces narrow arithmetic types to wide ones.

    {char, short} → int → long
    float → double → long double
    long → float   // precision can be lost
  

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

The program on the right (ascii to integer) converts a character string representing an integer to the integral value.

Unsigned coercions are more complicated; you can read about them in the book.

Explicit Casts

The syntax

    (type-name) expression
  
converts the value to the type specified. Note that e.g., (double x) converts the value of x; it does not change x itself.

Homework: 2-3.

2.8: Increment and Decrement Operators

The same as Java.

Remember that x++ or ++x are not the same as x=x+1 because, with the operators, x is evaluated only once, which becomes important when x is itself an expression with side effects.

    x[i++]++ // increments some (which?) element of an array
    x[i++] = x[i++]+1 // puts incremented value in ANOTHER slot
  

Homework: 2-4.

2.9: Bitwise Operators

The same as Java

2.10: Assignment Operators and Expressions

  int bitcount (unsigned x) {
    int b;
    for (b=0; x!=0; x>>= 1)
      if (x&01) // octal (not needed)
        b++;
    return b;
  }
  

The same as Java: += -= *= /= %= <<= >>= &= ^= |=

The program on the right counts how many bits of its argument are 1. Right shifting the unisigned x causes it to be zero-filled. Anding with a 1, gives the LOB (low order bit). Writing 01 indicates an octal constant (any integer beginning with 0; similarly starting with 0x indicates hexadecimal). Both are convenient for specifying specific bits (because both 8 and 16 are powers of 2). Since the constant in this case has value 1, the 0 has no effect.

Homework: 2-10.

2.11 Conditional Expressions

The same as Java:

    printf("You enrolled in %d course\s.\n", n, n==1 ? "" : "s");
  

2.12: Precedence and Order of Evaluation


Precedence and Associativity of C Operators
OperatorsAssociativity
() [] -> .left to right
! ~ ++ -- + - * & (type) sizeofright to left
* / %left to right
+ -left to right
<< >>left to right
< <= > >=left to right
== !=left to right
&left to right
^left to right
|left to right
&&left to right
||left to right
?:right to left
= += -= *= /= %= &= ^= |= <<= >>=right to left
,left to right

The table on the right is copied (hopefully correctly) from the book. It includes all operators, even those we haven't learned yet. I certainly don't expect you to memorize the table. Indeed one of the reasons I typed it in was to have an online reference I could refer to since I do not know all the precedences.

Homework: Check the table above for typos and report any on the mailing list.

Not everything is specified. For example if a function takes two arguments, the order in which the arguments are evaluated is not specified.

Also the order in which operands of a binary operator like + are evaluated is not specified. So f() could be evaluated before or after g() in the expression f()+g(). This becomes important if, for example, f() alters a global variable that g() reads.

Chapter 3: Control Flow

3.1: Statements and Blocks

int t[]={1,2};
int main() {
    22;
    return 0;
}

C is an expression language; so 22 and x=33 have values. One simple statement is an expression followed by a semicolon; For example, the program on the right is legal.

As in Java, a group of statements can be enclosed in braces to form a compound statement or block.

3.2: If-Else

Same as Java.

3.3: Else-IF

Same as Java.

3.4: Switch

Same as Java.

3.5: Loops—While and For

#include <ctype.h>
int atoi(char s[]) {
  int i, n, sign;
  for (i=0; isspace(s[i]); i++) ;
  sign = (s[i]=='-' ? -1 : 1);
  if (s[i]=='+' || s[i]=='-')
    i++;
  for (n=0; isdigit(s[i]); i++)
    n = 10*n + (s[i]-'0');
  return sign * n;
}

Same as Java.

The program on the right (ascii to integer) illustrates a number of points.

The Comma Operator

If two expressions are separated by a comma, they are evaluated left to right and the final value is the value of the one on the right. This operator often proves convenient in for statements when two variables are to be incremented.

    for (i=0; i+j<n; i++,j+=3)