Start Lecture #4

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

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.

C has very few primitive types.

- char: One byte in size; can hold a character. C will coerce to int if needed.
- int: The
natural

size of an integer on the host machine. - float: Single precision floating point.
- double: Double precision floating point.

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 float`, `short 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.

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.

- 123 is an
`int` - 1234567 is an
`int`if`int`'s are 32-bits; it is a`long`if`long`'s are 32-bits and`int`'s are only 16. - 123u is an
`unsigned int`. - 1223ul is an
`unsigned long`. - A character constant is written inside single quotes,
e.g. '0'.
These constants have an
**integer**value. For '0' the value happens to be 48. Some**single**characters are**written**as two characters. For example '\0' is the ascii null character, which is used to terminate C strings. Its integer value is 0. Also important are '\n' and '\t'. There are others.

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.

- 'x' is a single character; 'x'+1 is a valid integer expression.
- "x" contains two characters, 'x' followed by '\0'; it is a string constant, not an integer.
- "xy" "yz" is combined (at compile time) into "xyyz".
- "" is the empty string consisting just of '\0'.
- strlen() returns the lenght of a string, excluding the terminating '\0'.

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};

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.

Mostly the same as java.

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

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.

There are two kinds of conversions: automatic conversion, called coercion, and explicit 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.

- This works only for ascii (or some other system where the character form of the digits is consecutive and in the correct order).
- Stops at first non digit. For example, it will stop at the terminating '\0'.

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

The syntax

(type-name) expressionconverts the value to the type specified. Note that e.g.,

**Homework:** 2-3.

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.

The same as Java

`& bit wise AND``| bitwise OR``^ bitwise XOR (exclusive or)``<< left shift``>> right shift``~ bitwise complement`

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.

The same as Java:

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

Operators | Associativity |
---|---|

() [] -> . | left to right |

! ~ ++ -- + - * & (type) sizeof | right 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.

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

C is an expression language; so 22

and

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

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

Same as Java.

Same as Java.

Same as Java.

#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 C library contains a number of string/character routines. In this program two simple ones are used.
- The first
`for`loop has an empty body; this is not strange. - The conditional expression is used.
- Again use is made of the ascii property that the digits are in numerical order.

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)