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.
naturalsize of an integer on the host machine.
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.
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.
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.
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., (double x) converts the value of x; it does not change x itself.
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
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
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.
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.
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)