Transcript Review
Review of Lectures 6, 7, 8 and 10
Compilation (1)
• Compilation translates your source code (in the file
hello_world.c) into object code (machine dependent
instructions for the particular machine you are on).
– Note the difference with Java:
• The javac compiler creates Java byte code from your Java program.
• The byte code is then executed by a Java virtual machine, so it’s
machine independent.
• Linking the object code will generate an executable file.
• There are many compilers for C under Unix
– SUN provides the Workshop C Compiler, which you run
with the cc command
– There is also the freeware GNU compiler gcc
Compilation (2)
•
To compile a program:
•
Compile the program to object code.
>> gcc –c hello_world.c
Link the object code to executable file.
>> gcc hello_world.o –o hello
You can do the two steps together by running:
>> gcc hello_world.c –o hello
•
To run your program:
>> hello
If you leave off the
-o, executable goes into
the file a.out
Error Messages
• Error messages can be quite descriptive, or really terse.
• Suppose you forgot the semi-colon after the printf
>> gcc hello.c –o hello
"hello.c", line 5: syntax error before or at: return
gcc: acomp failed for hello.c
• Notice that the compiler flags and informs you about
the error at the first inappropriate token.
– In this case, the return statement.
• Always try to fix problems starting with the first error
the compiler gives you - the others may disappear too!
Variable Names in C
Variable Names
• Names may contain letters, digits and
underscores
• The first character must be a letter or an
underscore.
– the underscore can be used but watch out!!
• Case matters!
• C keywords cannot be used as variable names.
Variable Names in C - Examples
present, hello, y2x3, r2d3, ...
/* OK */
_1993_tar_return
/* OK but don’t */
Hello#there
/* illegal */
double
/* shouldn’t work */
2fartogo
/* illegal */
Variable Declaration
• Generic Form
typename varname1, varname2, ...;
• Examples:
int count;
float a;
double percent, total;
unsigned char x,y,z;
long int aLongInt;
long AnotherLongInt
unsigned long a_1, a_2, a_3;
unsigned long int b_1, b_2, b_3;
typedef long int32;
int32 n;
• Where declarations appear affects their scope and visibility
– Rules are similar to those in Java
– Declaration outside of any function are for global variables
• e.g., just before the main routine
Variable Declaration
Initialization
• ALWAYS initialize a variable before using it
– Failure to do so in C is asking for trouble
– The value of an uninitialized variables is undefined in the C standards
• Examples:
int count;
count = 0;
/* Set aside storage space for count */
/* Store 0 in count */
• This can be done at definition:
int count = 0;
double percent = 10.0, rate = 0.56;
• Warning: be careful about “out of range errors”
unsigned int value = -2500;
– The C compiler does not detect this as an error
• What do you suspect it does?
Basic Data Types in C
• There are only a few basic data types in C
– char:
a single byte, capable of holding one character
– int:
an integer of fixed length, typically reflecting the
natural size of integers on the host machine (i.e., 32 or
64 bits)
– float:
single-precision floating point
– double:
double precision floating point
Data Types in C
Numeric Variable Types
• Integer Types:
– Generally 32-bits or 64-bits in length
– Suppose an int has b-bits
• a signed int is in range -2b-1..2b-1-1
– -32768 .. 32767 (32767+1=-32768)
• an unsigned int is in range 0..2b-1
– 0 .. 65535 (65535+1=0)
• no error message is given on this "overflow"
Data Types in C
• Floating-point Types:
– Generally IEEE 754 floating point numbers
• float (IEEE single): 8 bits exponent, 1-bit sign, 23 bits mantissa
• double (IEEE double): 10 bits exponent, 1-bit sign, 53 bits mantissa
• long double (IEEE extended)
– Only use floating point types when really required
• they do a lot of rounding which must be understood well
• floating point operations tend to cost more than integer
operations
Qualifiers for Data Types
• There are a number of qualifiers which can be applied to the basic types
– length of data
• short int:
• long int:
• long double
v
v
v
v
v
v
– signed and unsigned
• unsigned int
v
v
v
• unsigned char
v
• signed char
v
v
"shorter" int, <= number of bits in an int
can also just write "short"
a "longer int", >= number of bits in an int
often the same number of bits as an int
can also just write "long"
generally extended precision floating point
an int type with no sign
if int has 32-bits, range from 0..232-1
also works with long and short
a number from 0 to 255
a number from –128 to 127 (8-bit signed value)
very similar to byte in Java
Example Size of Data Types with
Qualifiers
A typical 32-bit machine
Type
Keyword
Bytes
character
integer
short integer
long integer
long long integer
char
int
short
long
long long
1
4
2
4
8
unsigned character
unsigned integer
unsigned short integer
unsigned long integer
single-precision
double-precision
unsigned char
unsigned int
unsigned short
unsigned long
float
double
1
2
2
4
4
8
Range
-128...127
-2,147,483,648...2,147,438,647
-32768...32367
-2,147,483,648...2,147,438,647
-9223372036854775808 …
9223372036854775807
0...255
0...4,294,967,295
0...65535
0...4,294,967,295
1.2E-38...3.4E38
2.2E-308...1.8E308
Formatted I/O in C – printf()
• The printf function is used to output information (both data
from variables and text) to standard output.
– A C library function in the <stdio.h> library.
– Takes a format string and parameters for output.
• printf(format string, arg1, arg2, …);
– e.g. printf("The result is %d and %d\n", a, b);
• The format string contains:
– Literal text: is printed as is without variation
– Escaped sequences: special characters preceeded by \
– Conversion specifiers: % followed by a single character
• Indicates (usually) that a variable is to be printed at this location in the
output stream.
• The variables to be printed must appear in the parameters to printf
following the format string, in the order that they appear in the
format string.
printf()
• Conversion Specifiers
Specifier
%c
%d
%x
%f
%e
%s
%u
%%
%ld, %lld
Meaning
Single character
Signed decimal integer
Hexadecimal number
Decimal floating point number
Floating point in “scientific notation”
Character string (more on this later)
Unsigned decimal integer
Just print a % sign
long, and long long
• There must be one conversion specifier for each argument being
printed out.
• Ensure you use the correct specifier for the type of data you are
printing.
• Escape Sequences:
Sequence
\a
\b
\n
\t
\\
\'
\"
\xhh
\ooo
printf()
Meaning
Bell (alert)
Backspace
Newline
Horizontal tab
Backslash
Single quote
Double quotation
ASCII char specified by hex digits hh
ASCII char specified by octal digits ooo
Formatted I/O in C – scanf()
• The scanf function is the input equivalent of printf
– A C library function in the <stdio.h> library
– Takes a format string and parameters, much like printf
– The format string specifiers are nearly the same as those used in
printf
• Examples:
scanf ("%d", &x);
/* reads a decimal integer */
scanf ("%f", &rate); /* reads a floating point value */
• The ampersand (&) is used to get the “address” of the
variable
– All the C function parameters are “passed by value”.
– If we used scanf("%d",x) instead, the value of x is passed. As a
result, scanf will not know where to put the number it reads.
– More about this in “Functions”
scanf()
• Reading more than one variable at a time:
– For example:
int n1, n2; float f;
scanf("%d%d%f",&n1,&n2,&f);
– Use white spaces to separate numbers when input.
5 10 20.3
• In the format string:
– You can use other characters to separate the numbers
scanf("value=%d,ratio=%f", &value,&ratio);
• You must provide input like:
value=27,ratio=0.8
– scanf returns an int
• If end-of-file was reached, it returns EOF, a constant defined in <stdio.h>
• Otherwise, it returns the number of input values correctly read from standard
input.
scanf()
• One tricky point:
– If you are reading into a long or a double, you must
precede the conversion specifier with an l (a lower case
L)
– Example:
int main() {
char p;
int x;
long y;
float a;
double b;
scanf("%d %ld %f %lf %c", &x, &y, &a, &b, &p);
return 0;
}
Type Conversions
• C allows for conversions between the basic types, implicitly
or explicitly.
• Explicit conversion uses the cast operator.
• Example 1:
int x=10;
float y,z=3.14;
y=(float) x;
/* y=10.0 */
x=(int) z;
/* x=3 */
x=(int) (-z); /* x=-3 -- rounded approaching zero */
• Example 2:
int i;
short int j=1000;
i=j*j;
/* wrong!!! */
i=(int)j * (int)j; /* correct */
Implicit Conversion
• If the compiler expects one type at a position, but another type is
provided, then implicit conversion occurs.
• Conversion during assignments:
char c='a';
int i;
i=c; /* i is assigned the ASCII code of ‘a’ */
• Arithmetic conversion – if two operands of a binary operator are not the
same type, implicit conversion occurs:
int i=5 , j=1;
float x=1.0 , y;
y = x / i;
/* y = 1.0 / 5.0 */
y = j / i;
/* y = 1 / 5 so y = 0 */
y = (float) j / i;
/* y = 1.0 / 5 */
/* The cast operator has a higher precedence */
Comments
• Comments: /* This is a comment */
– Use them!
– Comments should explain:
• special cases
• the use of functions (parameters, return values,
purpose)
• special tricks or things that are not obvious
– explain WHY your code does things the what it
does.
C Statements
• In the most general sense, a statement is a part of your
program that can be executed.
• An expression is a statement.
a=a+1;
a--;
• A function call is also a statement.
printf("%d",a);
• Other statements ……
• C is a free form language, so you may type the statements
in any style you feel comfortable:
a=
a+
1;a--;
line breaks can be anywhere
Compound Statements
• Sequences of statements can be combined into
one with {...}
• Much like Java:
{
printf ("Hello, ");
printf ("world! \n");
}
• The C compiler treats the collection of these
statements like they are a single statement.
The if Statement
• Form 1:
• Form 2:
• Form 3:
if (expression)
statement1;
next statement;
if (expression)
statement1;
else
statement2;
next statement;
if (expression)
statement1;
else if (expression)
statement2;
else
statement3;
next statement;
Execute statement1
if expression is non-zero
(i.e., it does not have to be exactly 1)
The for Statement
•
•
The most important looping structure in C.
Generic Form:
for (initial ; condition ; increment )
statement
•
•
initial, condition, and increment are C expressions.
For loops are executed as follows:
1.
2.
3.
4.
5.
6.
initial is evaluated. Usually an assignment statement.
condition is evaluated. Usually a relational expression.
If condition is false (i.e. 0), fall out of the loop (go to step 6.)
If condition is true (i.e. nonzero), execute statement
Execute increment and go back to step 2.
Next statement
Forms of for
#include <stdio.h>
int main () {
int count,x,y;
int ctd;
/* 1. simple counted for loop */
for (count =1; count <=20; count++)
printf ("%d\n", count);
/* 2. for loop counting backwards */
for (count = 100; count >0; count--) {
x*=count;
printf("count=%d x=%d\n", count,x);
}
/* 3. for loop counting by 5's */
for (count=0; count<1000; count += 5)
y=y+count;
/* 4. initialization outside of loop */
count = 1;
for ( ; count < 1000; count++)
printf("%d ", count);
/* 5. very little need be in the for */
count=1; ctd=1;
for ( ; ctd; ) {
printf("%d ", count);
count++; ctd=count<1000;
}
/* 6. compound statements for initialization
and increment */
for (x=0, y=100; x<y; x++, y--) {
printf("%d %d\n", x,y);
}
return 0;
}
Nested for
• Nesting for Statements
– for statements (and any other C statement) can go inside
the loop of a for statement.
– For example:
#include <stdio.h>
int main( ) {
int rows=10, columns=20;
int r, c;
for ( r=rows ; r>0 ; r--)
{
for (c = columns; c>0; c--)
printf ("X ");
printf ("\n");
}
}
The while statement
•
Generic Form
while (condition)
statement
•
Executes as expected:
1.
2.
3.
4.
5.
•
condition is evaluated
If condition is false (i.e. 0), loop is exited (go to step 5)
If condition is true (i.e. nonzero), statement is executed
Go to step 1
Next statement
Note:
–
–
for ( ; condition ; )
is equivalent to
stmt;
for (exp1; exp2; exp3) stmt;
is equivalent to
exp1;
while(exp2) { stmt; exp3; }
while (condition)
stmt;
The do… while Statement
•
Generic Form:
do
statement
while (condition);
•
Standard repeat until loop
•
•
•
Like a while loop, but with condition test at bottom.
Always executes at least once.
The semantics of do...while:
1.
2.
3.
4.
Execute statement
Evaluate condition
If condition is true go to step 1
Next statement
break and continue
• The flow of control in any loop can be changed through the use of the
break and continue commands.
• The break command exits the loop immediately.
– Useful for stopping on conditions not controlled in the loop condition.
– For example:
for (x=0; x<10000; x++) {
if ( x*x % 5==1) break;
... do some more work ...
}
– Loop terminates if x*x % 5 == 1
• The continue command causes the next iteration of the loop to be started
immediately.
– For example:
for (x=0; x<10000; x++) {
if (x*x % 5 == 1) continue;
printf( "%d ", 1/ (x*x % 5 – 1) );
}
– Don't execute loop when x*x % 5 == 1 (and avoid division by 0)
The switch statement
•
•
Switch statement is used to do “multiple choices”.
Generic form:
switch(expression)
{
case constant_expr1 : statements
case constant_expr2 : statements
…
case constant_exprk : statements
default : statements
}
1. expression is evaluated.
2. The program jumps to the corresponding constant_expr.
3. All statements after the constant_expr are executed until a break (or
goto, return) statement is encountered.
The goto Statement
• The goto statement will jump to any point of your program.
• Use only if it is absolutely necessary – there is always a better way
for(;;)
{
……
while(…)
{
switch(…)
{
……
case … : goto finished; /* finished is a label */
}
}
}
finished: /* Jumped out from the nested loops */
Arithmetic Operators
Operator
Symbol Action
Addition
Subtraction
Negation
Multiplication
Division
+
*
/
Modulus
%
Adds operands
Subs second from first
Negates operand
Multiplies operands
Divides first by second
(integer quotient)
Remainder of divide op
Example
x+y
x-y
-x
x*y
x/y
x%y
Assignment Operator
• x=3
– = is an operator
– The value of this expression is 3
– = operator has a side effect -- assign 3 to x
• The assignment operator =
– The side-effect is to assign the value of the right hand side
(rhs) to the left hand side (lhs).
– The value is the value of the rhs.
• For example:
x = ( y = 3 ) +1;
/* y is assigned 3 */
/* the value of (y=3) is 3 */
/* x is assigned 4 */
Compound Assignment
• Often we use “update” forms of operators
– x=x+1, x=x*2, ...
• C offers a short form for this:
– Generic Form
variable op= expr
Operator
x *= y
y -= z + 1
a /= b
x += y / 8
y %= 3
equivalent to variable = variable op expr
Equivalent to:
x=x*y
y = y - (z + 1)
a=a/b
x = x + (y / 8)
y=y%3
– Update forms have value equal to the final value of expr
• i.e., x=3; y= (x+=3); /* x and y both get value 6 */
Increment Operator
• Other operators with side effects are the preand post-increment and decrement operators.
– Increment:
++
++x, x++
• ++x is the same as : (x = x + 1)
– Has value xold +1
– Has side-effect of incrementing x
• x++
– Has value xold
– Has side-effect of incrementing x
– Decrement -• similar to ++
--x, x--
Relational Operators
• Relational operators allow you to compare variables.
– They return a 1 value for true and a 0 for false.
Operator
Symbol
Example
Equals
Greater than
Less than
Greater/equals
Less than/equals
Not equal
==
>
<
>=
<=
!=
• C uses:
– 0 as false
– Non-zero integer as true
x == y NOT x = y
x > y
x< y
x >= y
x <= y
x != y
Logical Operators
• && AND
• ||
OR
• !
NOT
• See example program
Operating on Bits
• C allows you to operate on the bit representations of
integer variables.
– Generally called bit-wise operators.
• All integers can be thought of in binary form.
– For example, suppose ints have 16-bits
• 6552010 = 1111 1111 1111 00002 = FFF016 = 1777608
• In C, hexadecimal literals begin with 0x, and octal
literals begin with 0.
• x=65520;
• x=0xfff0;
• x=0177760;
base 10
base 16 (hex)
base 8 (octal)
Operating on Bits
Bitwise operators
• The shift operator:
– x << n
• Shifts the bits in x n positions to the left, shifting in zeros on the
right.
• If x = 1111 1111 1111 00002
x << 1 equals 1111 1111 1110 00002
– x >> n
• Shifts the bits in x n positions right.
– shifts in the sign if it is a signed integer (arithmetic shift)
– shifts in 0 if it is an unsigned integer
• x >> 1 is 0111 1111 1111 10002 (unsigned)
• x >> 1 is 1111 1111 1111 10002 (signed)
Bitwise Logical Operators
Work on all integer types
• & Bitwise AND
x= 0xFFF0
y= 0x002F
x&y= 0x0020
• | Bitwise Inclusive OR
x|y= 0xFFFF
• ^ Bitwise Exclusive OR (XOR)
x^y= 0xFFDF
• ~ The complement operator
~ y= 0xFFD0
» Complements all of the bits of X
Operator Precedence
Operator
Precedence level
()
1
~, ++, --, unary 2
*, /, %
3
+, 4
<<, >>
5
<, <=, >, >=
6
==, !=
7
&
8
^
9
|
10
&&
11
||
12
=, +=, -=, etc.
14
We’ll be adding more to this list later on...
Conditional Operator
• The conditional operator essentially allows you to embed an “if”
statement into an expression
• Generic Form
exp1 ? exp2 : exp3
• Example:
z = (x > y) ? x : y;
• This is equivalent to:
if (x > y)
z = x;
else
z = y;
if exp1 is true (non-zero)
value is exp2
(exp3 is not evaluated)
if exp1 is false (0),
value is exp3
(exp2 is not evaluated)
Comma Operator
• An expression can be composed of multiple subexpressions
separated by commas.
– Subexpressions are evaluated left to right.
– The entire expression evaluates to the value of the rightmost
subexpression.
• Example:
x = (a++, b++);
• a is incremented
• b is assigned to x
• b is incremented
– Parenthesis are required because the comma operator has a
lower precedence than the assignment operator!
• The comma operator is often used in for loops.