Sie sind auf Seite 1von 61

CS3101-1

Programming Languages – C
Lecture 2

Matthew P. Johnson
Columbia University
Fall 2003

10/17/08 CS3101-1, Lecture 2 1


Agenda
 Hw0 due last night
 Hw1 assigned tonight
 Last time: quick & dirty C tutorial
 This time: flesh out syntax for most
basic features
 Data types, constants, enum types
 Expressions & ops: arith, log, & bitwise
 Data conversion
 Control Flow
 A little more I/O
10/17/08 CS3101-1, Lecture 2 2
Primitive Data Types
Type Meaning Example
int Integer 3
float Non-whole 12345.6700
(rational) number (~7 sigdigs)
double Double-precision 12345.6789
rat’l (~14
char Typographical sigdigs)
‘A’ == 65
symbol (rep’ed by
1-byte integer, in
10/17/08 ASCII) CS3101-1, Lecture 2 3
Integral-type Variants
 short int
 long int
 “int” usually omitted
 Rule (in bits):
|char| = 8 <= |short| <= |int| <= |long|
usually: 16, 32, 32
or: 16, 16, 32
 Some systems: long double
 Also: double range larger than long/int
range
10/17/08 CS3101-1, Lecture 2 4
Int representations
 Numbers can be signed: +/-
 Or unsigned: non-negative
(magnitude)
 Usual rep of non-neg ints (and all
else) bitstrings (base-2 numbers)
 Notice: 8 bits  2^8 = 256 poss
vals
 Unsigned char: 0..255
10/17/08 CS3101-1, Lecture 2 5
Signed char
representation
 1 bit used for sign (“sign bit”)
 7 bits left for magnitude 2^7 = 128
poss magn vals
 Non-neg vals: 128 poss vals
  0..2^7-1 = 0..127
 Naïve neg encoding: 7-bit string
 Neg vals: 128 poss vals
  0..-2^7-1 = 0..-127
10/17/08 CS3101-1, Lecture 2 6
Signed char
representation
 Problems:
 Two reps of 0: +0: 00000000, -0: 10000000
 How to subtract?
 How to combine pos, neg, e.g., 1 + -1?
 Naïve addition doesn’t work:

00000001 = 1
+ 10000001 = -1
------------
10000010 = -2

10/17/08 CS3101-1, Lecture 2 7


Signed char
representation’
 One’s complement:
 Encode magnitude of neg num by flipping
the 7 bits
 Now addition is easy (naïve add words):
00000001 = 1
+11111110= -1
------------
11111111 = -0
 Subtraction is now easy: negate and then
add
10/17/08 Still: two reps of 0 Lecture 2
CS3101-1, 8
Signed char
representation’’
 Two’s complement:
 Encode pos-num magnitude as usual
 Encode neg-num magnitude in one’s comp,
and then add 1
 Addition/subtraction still easy:
00000001 = 1
+11111111= -1
------------
00000000 = 0
 And now only one rep of 0
10/17/08 CS3101-1, Lecture 2 9
Literals (/”constants”)
 Hard-coded
 Distinct from two other senses of
“constants”
 char literals: ‘a’, ‘\n’
 char[] (“string”) literals: “hi”
 Auto-concatenation for string literals
 “hi “ “there”  “hi there”
 No + op for strings

10/17/08 CS3101-1, Lecture 2 10


Literals
 Ints: 123  int
 123l | 123L  long
 Floating-point: 3.5  double
 3.5f | 3.5F  float

10/17/08 CS3101-1, Lecture 2 11


Constants
 Another sort: const
 double const PI = 3.14;
 Or: const double PI = 3.14;
 Like regular var, but if attempt to
change, get
 Error (cc)
 Warning (gcc)

10/17/08 CS3101-1, Lecture 2 12


enum types
 Saw last time: preprocessor
supports symbolic constants:
 #define name replace-text
 Define individually
 Sometimes have: group of related
concepts (“holism”)
 Want to represent one choice from
set
 “semantic types”
10/17/08 CS3101-1, Lecture 2 13
enum types example
 No built-in boolean type
 Maybe nice to have
  simulate one
enum boolean {FALSE = 0, TRUE = 1};
 Effects: consts named FALSE &
TRUE are defined, with vals 0 & 1
  FALSE & TRUE behave as “false” &
“true”
10/17/08 CS3101-1, Lecture 2 14
enum example’
 If vals are omitted, they default to ints
growing from 0 (or fromt last appearing
val)
 Same effects: enum boolean {FALSE,

TRUE};
 Req: names (but not vals) must be

unique
 Legal:

enum boolean {FALSE = 0, True = 1,


NO = 0, YES CS3101-1,
10/17/08
= 1,Lecture
ZERO2
= 0, ONE = 151};
Importance of enums
 Suppose ftn returns a certain day
of the week (on which…):
int getday();
 How should result be interp’ed?
 Maybe: 0 == Mon, 1 == Tues, etc.
 Or: 1 == Mon, 2 == Tues, etc.
 Or: 1 == Sun, 2 = Mon, etc.

10/17/08 CS3101-1, Lecture 2 16


Importances of enums
 Better soln:
enum day {MON, TUES, WED, THUR,
FRI, SAT, SUN};
 Before:
int getday(); …
if (getday() == 2) …
 Now: enum day getday(); …
if (getday() == WED) …
 “self-documenting code”
 Notice: type is enum day, not just day
10/17/08 CS3101-1, Lecture 2 17
Declarations
 Var declaration pattern:
data-type var-name;
 Last time:
 int low;
 int low, upr; /* combined */
 int step = 20; /* with init */
 Var names:
 Like all else, case-sensitive
 Usually: all lower-case
 Rules for number of sig chars – see text
10/17/08 CS3101-1, Lecture 2 18
Pos of declarations
 Must all appear at top of their
block
Ftn block, if/while block/arb. block
 Before any non-declar
 Will not  Will compile: stmts
 Will compile:

compile: int myftn() { int myftn() {


int myftn() { int i = 10; int i = 10;
int i = 10; int j; i = 11;
i++; i = 11; { int j = 12;
int j = 12; j = 12; j++; }
j++; j++; }
} }
10/17/08 CS3101-1, Lecture 2 19
Scopes of declarations
 Var is in scope (available for use):
 Local vars (inside a block): from declaration
until the end of that block
 Global vars (not in a block): from
declaration until the end of the file
 Notice: blocks (and corresponding
stacks) form a stack
 Each entry into a new block  push that
block’s vars to the stack
 Each exit from a block  pop that block’s
vars from the stack
10/17/08 CS3101-1, Lecture 2 20
Scopes of declarations – 2
 Also: any “higher-level” var overrides “lower-level”
var of same name
void ftn() {
int i = 10;
if (1) {
int i = 20;
printf(“i == %d\n”, i);
}
printf(“i = %d\n”, i);
}
 i == 20
i == 10

10/17/08 CS3101-1, Lecture 2 21


Arrays
 Already know:
 Complex data structure
 Fixed-length (later: dynamic arrays)
 Ordered seq of elms
 All elms of same type

10/17/08 CS3101-1, Lecture 2 22


Array declarations
 C style:
 int nums[10];
 Interp: for each i, num[i] is an int
 Can combine declars:

int i, num[10], j, myftn();
  10 new (unitialized!) ints on the stack
 Java style:
 int[] nums;
  merely creates array var, not ints
 Note: both styles compile in Java, but not in
C
10/17/08 CS3101-1, Lecture 2 23
Binary arithmetic & bool
ops
 +
 -
 *
 / - truncates non-int 5/3 == 1
 % - mod/remainder 5%3 == 2
 && - boolean and
 || - boolean or
10/17/08 CS3101-1, Lecture 2 24
Op e.g.: leap year
 When is leap  In code:

year?  year % 4 == 0
 If 4 | year
 Unless y % 100
 Unless 100 |
== 0
year
 Unless y % 400
 Unless 400 |

year == 0
 b1 && (!b2 || b3)
 If the second is

true, then the


third must beCS3101-1, Lecture 2
10/17/08 25
Op e.g.: leap year
 int isleapyear(int year) {
return year % 4 == 0 &&
(year%100 != 0 || year%400 == 0);
}
 Orders of ops to notice:
 Arith ops higher prec than compar:
  year % 4 == 0  (year % 4) == 0
 Compar ops higher prec than boolean:
  year % 4 == 0 && p1  (year%4==0) && p2
 && higher prec than ||
  p1 && p2 || p3  (p1 && p2) || p2
10/17/08 CS3101-1, Lecture 2 26
ints as booleans
 Remember:
 True expr  1, False expr  0
 0  false, !0 == 1  true

 year % 4 == 0 && (year%100 != 0 ||


year%400 == 0)
  !(year % 4) && (!(year%100 == 0) || !
(year%400))
  !(year%4) && (year%100 || !(year%400))
 Elegance ?= succinctness ?= difficulty to
read
10/17/08 CS3101-1, Lecture 2 27
Relational ops
 Comparison ops:
 >, <, >=, <=, same precedence
 Equality ops: ==, !=
 Lower precedence than compar ops
 Remember: using = as == will compile
 Why isn’t this a problem in Java?
 J has a bool type, test expr must be bool
 a=3 is of type int  if(a=3) doesn’t compile
 Not the case in C

10/17/08 CS3101-1, Lecture 2 28


Data type conversion
 Lots of num types
 Sometimes have one, want another
 Two directions of conversion
 Widening: smaller range type  larger
range type
 Narrowing: larger range  small
 (usually) only narrowing loses info
 short s = 10;
 long L = s; /* just more zeros on the
left */

10/17/08 CS3101-1, Lecture 2 29


Data type conversion
 Narrowing lose info in general:
int i = 1025;
char c = i; // c == 1
1000|0000001
Widening sometimes can lose info
 int i = 123456789;
float f = i; // c == 123456700

10/17/08 CS3101-1, Lecture 2 30


Data type conversion – 1
 Arithmetic promotion
 3 + 3.5
 int + double  double
 General rule: if two combined
types are distinct, narrower is
upgraded to wider
 Original val/var is unchanged, just
replaced in expr
 3.5 + 3.5 + 3  7.0 + 3  10.0
10/17/08 CS3101-1, Lecture 2 31
Data type conversion – 1
 Somewhat more complicated/tricky for
signed combined with unsigned
 Signed converted to unsigned
 Interp as 8-bit magnitude
 Sign bit of 1 makes large
  strange results:
unsigned int u = 0; int s = -1;
if (u > s) … executed?
 Yes!
 Advice: avoid unsigned (as Java does)

10/17/08 CS3101-1, Lecture 2 32


Data type conversion – 2
 Automatic conversion in assignment
char c = 10;
int i = c; /* fine */
int i = 10;
 char c = i; /* fine */
int i = 1025;
char c = i; /* info loss: c == 1 */
 Still: does compile (unlike Java)
 Example: printbits.c
10/17/08 CS3101-1, Lecture 2 33
Data type conversion – 3
 Casting
 Says explicitly to convert types
 One use: if calling a prototype-less ftn, may not know
to convert  tell it to

main() {
double sq = square(4); /* poss parse error
reads 4 as dbl */
double sq = sqaure((double)4);
}
double sqaure(double d) {
return d*d;
}
10/17/08 CS3101-1, Lecture 2 34
Casting
 General form: put desired type name in
parentheses, prepend to expr:
 (new-type)expr;
 (float)i;
 Also useful in I/O
 Saw (briefly) before: printf uses
pattern-matching for positioning:
 printf(“val = %d\n”, 3);
 printf(“val = %f\n”, 3.5);

10/17/08 CS3101-1, Lecture 2 35


Casting – 2
 But suppose:
 Printf(“val = %d\n”, 3.5);
 (the bytes of) 3.5 are now parsed as an int
  garbage
 Remember:
 %d  interp param as an int
 %f  interp param as a float
 Wilcard, param type must match
 One soln: casting
 printf(“val = %d\n”, (int)f);
10/17/08 CS3101-1, Lecture 2 36
Casting – 3
 Another example:
 char ch = ‘A’;

 Goal: print our char (‘A’)


 If we say:
 printf(“ch == %d\n”, ch);

  output is 65

 Do we need casting?
 No. ‘A’ is “really” the value 65;
don’t want to convert the value
 Want to change the presentation:
 printf(“ch == %c\n”, ch);

10/17/08 CS3101-1, Lecture 2 37


Unary Ops
 C has several shortcut ops (some
already seen):
 inc: ++, dec: --
i = 10;
i++; /* now, i == 11 */
--i;
i--; /* now, i == 9 */
 Both can be prefix (++a) or postfix (a--)

10/17/08 CS3101-1, Lecture 2 38


++/--
 Two things to know:
 a++/++a changes the value of a (a
 a+1)
 Value of expr depends on pos of
++/--

Intution: pos determines “when” as is
mod-ed

++a  a is inc-ed before expr is evaled
 a++  a is inc-ed after expr is evaled

10/17/08 CS3101-1, Lecture 2 39


++/-- - 2
 Examples:
a = 10;
b = ++a; /* a == 11, b == 11 */
a = 10;
b = a++; /* a == 11, b == 10 */
 ++/-- have side effects on their
operands
  can only be applied to lvalues (e.g., vars,
array elms): a++, a[10]++, not PI++
 Notice etymology: C++
10/17/08 CS3101-1, Lecture 2 40
Bitwise ops
 Manipulate numbers as bitstrings, not
as numbers
 Only for integral types (int, char, etc.)
& ~ bitwise and
| ~ bitwise or
^ ~ xor (not exp!)
<< shift left
>> shift right
~ complement

10/17/08 CS3101-1, Lecture 2 41


Bitwise ops
 Manipulate numbers as bitstrings, not as numbers
Only for integral types (int, char, etc.)

& ~ bitwise and (1010 & 1100) == 1000


| ~ bitwise or
(1010 | 1100) == 1110
^ ~ xor (not exp!)
<< shift left (1010 ^ 1100) == 0110
>> shift right (1010 << 1) == 10100
~ complement (1010 >> 1) == 101
 Notice: <</>> ~ must/div by 2^n

10/17/08 CS3101-1, Lecture 2 42


Bitwise ops – 2
 Not used as often as arith ops
 Sometimes, very useful elegant
 May be difficult to read
 Example: swap two ints, no third
var:
a ^= b ^= a ^= b;

a ^= b; b ^= a; a ^= b;
10/17/08 CS3101-1, Lecture 2 43
Attribute byte
 In DOS, each file has attribute byte
 8 flags describing the file
1 ~ 00000001 ~ read-only
2 ~ 00000010 ~ hidden
3 ~ 00000100 ~ system

 Given att byte, easy to check flags:
if (a & HIDDEN) printf(“it\’s hidden\n”);
 Why? Boolean and with HIDDEN zeros
out all bits except, possibly, the 0th
10/17/08 CS3101-1, Lecture 2 44
Bitwise ops v. boolean ops
 Boolean ops (&&, ||, !) treat on operands (ints) as
bools
 Bitwise ops (&, |, ~) treat on operands as bitstrings
 int a = 1, b = 2;
if (a && b) … true?
 Yes!
 if (a & b) … true?
 No!
 If (!b) … true?
 No
 If (~b) … true?
 Yes
10/17/08 CS3101-1, Lecture 2 45
Other shortcut ops
 Generally, shortcut ops for all standard
binary ops:
a += 2;  a = a + 2;
intuition: “add 2 to a”
a *= 2;
a /= 2;
a <<= 2;
etc.

10/17/08 CS3101-1, Lecture 2 46


Conditional stmts
 Seen:
if (expr)
a = b;
else
a = c;
 Also have: the ternary op ?:
 (the above)  a = expr ? b : c;
 Auto-promotion still applies:
 (expr ? 3.5 : 3) is always a dbl (3.5 or
3.0)
10/17/08 CS3101-1, Lecture 2 47
Orders of Precedence
unary ops ops bound to single ops a++ + b
eval-ed first
*, ., % mult/div before add/sub a*b + c

+, - arith before equal a+b == c

equality equal before bools – can a==b && c==d


combineT/F exprs
&& and before or b1&&b2 || b3

|| almost all ops before ?: expr ? a : b

?: Everything else before ?: a = expr

Assign. ops
10/17/08 CS3101-1, Lecture 2 48
Order of eval
 Most ops eval-ed L to R
 Two things to know:
1. Short-circuiting
if (a==b && c==ftn()) …
a!=b  c==ftn() is never eval-ed!
 ftn() (maybe with side-effects?) is not called!

Useful for prevent null-ptr problems:
if (a != NULL && a[4] == 2) …
 No error
2. Assign op eval-ed R-to-L:

a ^= b ^= a ^= b;

a = b = c = d = 0;
10/17/08 CS3101-1, Lecture 2 49
Flow control
 Saw if, if-else
 Suppose want to respond to many diff
poss vals:
 if (day == MON)
…;
else if (day == TUE)
…;
else if …  run-on if-else

10/17/08 CS3101-1, Lecture 2 50


switch
 More elegant soln: switch stmt:
switch (expr) {
case val1: …;
break;
case val2: …;
break;

default: …; /* optional */
}
10/17/08 CS3101-1, Lecture 2 51
switch – 2
 Day example:
switch (day) {
case MON: …;
break;
case TUE: …;
break;

case SAT:
case SUN: …;
break;
}
10/17/08 CS3101-1, Lecture 2 52
switch – 3
 Things to notice:
 Vals must be int-valued consts or const
(literal) exprs

Legal: case 2+3:

Legal: case MON: - enums are really ints

Illegal: case 2.5:
 Case values must be unique
 In general, must break at end of case
 Can combine cases by omitting breaks
 Here, SAT and SUN are treated the same
 Enter a case with no break at end
  “fall through” to next case
10/17/08 CS3101-1, Lecture 2 53
Loops
 Saw: while (expr) …
 Example:
double pwr(double base, int exp)
{
int i = 1; double res = 1;
while (i <= exp) {
res *= base;
i++;
}
return res;
10/17/08 CS3101-1, Lecture 2 54
Loops – 2
 More succinct:
double pwr(double base, int exp)
{
double res = 1;
while (exp > 0) {
res *= base;
exp--;
}
}
10/17/08 CS3101-1, Lecture 2 55
Loops – 3
 More succinct still, with for loop
 General form: for (init; test; inc)
 Here:
double pwr(double base, int exp) {
double res; /* can’t declare in
for init */
for (res = 1; exp > 0; exp--)
res *= base;
return res;
}
10/17/08 CS3101-1, Lecture 2 56
Loops – 4
 Also: do-while loops
 Form:
do

while (expr);
 Like while but always executes >=
once
 No braces needed for multi-line
10/17/08 CS3101-1, Lecture 2 57
Loops – 5
 For all three loops, fall out by
 Test failing
 Intentionally, by command
 Infinite loops:
 for(;;) …
 while (1) …
 Unless body executes break; or
return; or exit(i);

10/17/08 CS3101-1, Lecture 2 58


Loops – 5
 Another command: continue;
 Effect: skips rest of loop body; goes to
test expr (while/do-while) or inc (for):
while (expr) {
if (expr2)
continue;

}

10/17/08 CS3101-1, Lecture 2 59


I/O
 Seen: printf for input:
printf(“an int: %d\n”, i);
printf(“a char: %c\n”, ch);
 Input is similar, with scanf:
scanf(“%d”, &i);
scanf(“%c”, &ch);
 Use same wildcard as for printf
 Important: don’t forget
ampersand!
10/17/08 CS3101-1, Lecture 2 60
Next time
 All simple lang elms have been
covered
 Next time: some more advanced
topics
 Hw1 assigned tonight
 Reading on web

10/17/08 CS3101-1, Lecture 2 61

Das könnte Ihnen auch gefallen