Beruflich Dokumente
Kultur Dokumente
2-2
2-3
2-4
2-5
2-6
/*
* File : main.c
* Author: Robert C. Carden IV
*/
#include <stdio.h>
int main (void)
{
const double pi = 3.14159;
double radius, area;
printf ("Enter the radius of the circle: ");
scanf ("%lf", &radius);
/* area = PI times R^2 */
area = pi * radius * radius;
printf ("Using PI=%g to compute the area...\n", pi);
printf ("The area of a circle of radius %f is %-10.4f\n",
radius, area);
return 0;
}
2-7
2-8
2-9
2-10
2-11
2-12
2-13
PTR
PTR
PTR
PTR
_pi$[ebp]
_radius$[ebp]
_radius$[ebp]
_area$[ebp]
On the Unisys A-Series computer, the object code might look something like:
VALC
VALC
VALC
MULT
MULT
NAMC
STOD
3,2
3,3
3,3
3,4
2-14
2-15
2-16
[a-zA-Z]
_
[0-9]
(letter | underscore)(letter | underscore | digit)*
examples
identifier
3id
__yes
o_no_o_no
00_go
star*it
1_i_am
one_i_aren't
me_to-2
xYshouldI
int
legal?
no
yes
yes
no
no
no
no
no
yes
yes
2-17
C keywords (such is int or while) are identifiers but may not be used as variable
or function names.
C is case sensitive
the identifiers xyz, xYz, and XyZ are all different
Internally, identifiers (variable and function names) are significant to at least the
first 31 characters
Internal identifiers are those that are declared and referenced within a single
compilation unit, i.e. a file. These include:
local variables
static global variables
local functions within a single file
Externally, it may be less (e.g., 14 or 6)
External identifiers are those which are visible to other files
Identifiers are considered to be equivalent if their significant characters are the
same, i.e. if the compiler guarantees at least 31 significant characters, then if at
least one corresponding character in the first 31 are different, the two identifiers
are considered to be different.
2-18
semantic meaning
char
size
on
PC
1
size
under
Unix
1
size on
A-Series
C
1
2 or 4
4
4
4
6
6
6
6
16
8
12
-
The int data type is specified to be the natural integer type for the target
machine. Modifiers short and long request short and long representations of
int.
All we know is that
sizeof short sizeof int sizeof(long)
sizeof(float) sizeof(double) sizeof(long double)
sizeof(int) sizeof(signed int) sizeof(unsigned int)
The double data type is specified under ANSI to be the natural floating point
type for the target machine.
The long long data type is part of GNU C. GNU (Gnu's not Unix) is a
research laboratory at MIT headed by Richard Stallman dedicated to writing a
public domain version of the Unix operating system.
2-19
usual meaning
unsigned char
signed char
signed short int
unsigned short int
signed int
unsigned int
signed long int
unsigned long int
double (archaic)
2-20
SHRT_MIN
SHRT_MAX
USHRT_MAX
INT_MIN
INT_MAX
UINT_MAX
LONG_MIN
LONG_MAX
ULONG_MAX
(-32768)
/*
32767
/*
0xffff
/*
(-2147483647 - 1) /*
2147483647
/*
0xffffffff
/*
(-2147483647L - 1)/*
2147483647L
/*
0xffffffffUL
/*
minimum
maximum
maximum
minimum
maximum
maximum
minimum
maximum
maximum
(signed)
(signed)
unsigned
(signed)
(signed)
unsigned
(signed)
(signed)
unsigned
short value
short value
short value
int value
int value
int value
long value
long value
long value
*/
*/
*/
*/
*/
*/
*/
*/
*/
From this I can tell that shorts are 16 bits, and that ints and longs are both 32 bits
2-21
SHRT_MIN
SHRT_MAX
USHRT_MAX
INT_MIN
INT_MAX
UINT_MAX
LONG_MIN
LONG_MAX
ULONG_MAX
(-32768)
/*
32767
/*
0xffff
/*
(-2147483647 - 1) /*
2147483647
/*
0xffffffff
/*
(-2147483647L - 1)/*
2147483647L
/*
0xffffffffUL
/*
minimum
maximum
maximum
minimum
maximum
maximum
minimum
maximum
maximum
2-22
(signed)
(signed)
unsigned
(signed)
(signed)
unsigned
(signed)
(signed)
unsigned
short value
short value
short value
int value
int value
int value
long value
long value
long value
*/
*/
*/
*/
*/
*/
*/
*/
*/
unsuffixed decimal:
unsuffixed octal or hexadecimal:
suffixed by letter u or U:
suffixed by letter l or L:
unsigned int,
unsigned long
long, unsigned long
unsigned long
example
integer
25
semantics
integer
25L
long integer
long
25U
unsigned integer
unsigned int
25LU
unsigned long
025
octal integer 25
int
0xff
int
0x23AF
int
025LU
0x25U
2-23
unsigned int
2-24
int
int
unsigned long int
SHRT_MIN
SHRT_MAX
USHRT_MAX
INT_MIN
INT_MAX
UINT_MAX
LONG_MIN
LONG_MAX
ULONG_MAX
(-32768)
/*
32767
/*
0xffff
/*
(-2147483647 - 1) /*
2147483647
/*
0xffffffff
/*
(-2147483647L - 1)/*
2147483647L
/*
0xffffffffUL
/*
minimum
maximum
maximum
minimum
maximum
maximum
minimum
maximum
maximum
(signed)
(signed)
unsigned
(signed)
(signed)
unsigned
(signed)
(signed)
unsigned
short value
short value
short value
int value
int value
int value
long value
long value
long value
*/
*/
*/
*/
*/
*/
*/
*/
*/
2-25
type
double
semantics
25, double precision
2.5e1
double
2.5 * power(10,1)
25e0
double
25 * power(10,0)
25.0F
float
25.0L
long double
.23
0.23
1.
1.0
1.2e10
1.23e-10 25e0
21
2-26
FLT_DIG
6 /* # of decimal digits of precision */
FLT_MANT_DIG 24
/* # of bits in mantissa */
FLT_MAX 3.402823466e+38F /* max value */
FLT_MAX_10_EXP
38
/* max decimal exponent */
FLT_MAX_EXP
128
/* max binary exponent */
FLT_MIN 1.175494351e-38F /* min positive value */
FLT_MIN_10_EXP
(-37)
/* min decimal exponent */
FLT_MIN_EXP
(-125)
/* min binary exponent */
FLT_RADIX
2
/* exponent radix */
The first thing to understand is that floating point numbers are stored in binary
scientific notation
That is it looks something like
e e e p
b1b2 bn bn 1bn 2 bn m 2 1 2
In the normalized form, we have two integers: a 24 bit integer consisting of the
b's and an 8 bit integer consisting of the f's
The 24 bit integer is called the mantissa
The 8 bit integer (32-8) is called the exponent or characteristic
The RADIX (which on this system is defined to be 2) is the exponent to which
we raise the exponent
2-27
FLT_DIG
6 /* # of decimal digits of precision */
FLT_MANT_DIG 24
/* # of bits in mantissa */
FLT_MAX 3.402823466e+38F /* max value */
FLT_MAX_10_EXP
38
/* max decimal exponent */
FLT_MAX_EXP
128
/* max binary exponent */
FLT_MIN 1.175494351e-38F /* min positive value */
FLT_MIN_10_EXP
(-37)
/* min decimal exponent */
FLT_MIN_EXP
(-125)
/* min binary exponent */
FLT_RADIX
2
/* exponent radix */
DBL_DIG
15 /* # of decimal digits of precision */
DBL_MANT_DIG
53 /* # of bits in mantissa */
DBL_MAX
1.7976931348623158e+308 /* max value */
DBL_MAX_10_EXP 308
/* max decimal exponent */
DBL_MAX_EXP
1024
/* max binary exponent */
DBL_MIN 2.2250738585072014e-308 /* min positive value */
DBL_MIN_10_EXP (-307)
/* min decimal exponent */
DBL_MIN_EXP
(-1021)
/* min binary exponent */
_DBL_RADIX
2
/* exponent radix */
I would have added a section on long double but the current Microsoft compiler
does not support it
In my experience long double is either not supported or poorly supported and
should be avoided
2-28
alert (bell)
\b
backspace
\f
formfeed
\n
newline
\r
carriage return
\t
horizontal tab
\v
vertical tab
\\
backslash
\?
\'
single quote
\"
\0
\ooo
\xhh
The following list gives examples of how any machine's character set can be
represented as either an octal constant, a hex constant, or integer ascii value
2-29
'\x6'
'\x30'
6
48
ASCII ack
ASCII '0'
'\137'
'\x5f'
95
ASCII '_'
2-30
A string constant begins with a double quote character ("), then contains 0 or
more characters or character escape sequences, and then ending with a double
quote character.
legal examples
"hello world\n"
illegal examples
"hello world
"
Strings are null terminated, that is enough space is set aside for all characters
within the string plus one more
The end of the string contains a zero, i.e. '\0'
The null character '\0' has ordinal value of 0
All other characters are nonzero
Adjacent string literals are concatenated
examples
string literal
"Hello"
size
5+1=6
representation
l o \0
"\"Quote\""
7+1=8
"
"
\0
"un"
7+1=8
\0
"Hello\\n\n"
8+1=9
\n
""
0+1=1
\0
"happy"
2-31
\0
5+1=6
\xfa
\12
\0
"a\xfah\129"
5+1=6
\xfa
\12
\0
"a\xad\129"
4+1=5
\xad
\12
"a\xad3\1372"
6+1=7
\xad
2-32
\0
\137
\0
#
[
\
]
^
{
|
}
~
"No other trigraph sequences exist. Each ? that does not begin one of the
trigraphs listed above is not changed."
example
with trigraphs
??=include <stdio.h>
int main()
??<
printf("Eh???/n");
return(0);
??>
??=
??<
??/
??>
#
{
\
}
2-33
[Instructor: Review identifiers, keywords, variable names, and constants in this program]
/*
* File : main.c
* Author: Robert C. Carden IV
*/
#include <stdio.h>
int main()
{
const double pi = 3.14159;
double radius, area;
printf("Enter the radius of the circle: ");
scanf("%lf", &radius);
/* area = PI times R^2 */
area = pi * radius * radius;
printf("Using PI=%g to compute the area...\n", pi);
printf("The area of a circle of "
"radius %f is %-10.4f\n",
radius, area);
}
return(0);
2-34
syntax:
<declaration>
<decl>
examples
int x;
const int x;
const int y = 5;
int z = 10;
int x, y, z = 20;
::
::
interpretation
x is an integer
x is a read-only integer
y is a read-only integer with initial value of 5
z is an integer with initial value of 10
x and y are integers
z is an integer with an initial value of 20
2-35
Arithmetic operators
Reference: Brooks, Chapter 3 (3.2 - 3.4)
int
double
i, j;
x, y, z;
operator
+
semantics
addition
subtraction
*
/
multiplication
integer division
real division
integer modulus
examples
i + j
+ x
i - j
- x
i * j
both arguments are integers
i / j
at least one arg is floating point
i / x
x / j
x / y
i % j
both arguments must be integers
2-36
2-37
if ( expression )
statement-1
else
statement-2
Semantics
1. The expression is evaluated
2. If true (non-zero), statement-1 is executed.
3. If false (zero), then if there is an else part, then statement-2 is executed
Basic Axiom
FALSE IS ZERO
TRUE IS NOT FALSE
FALSE
TRUE
ZERO
NULL
'\0'
NOT FALSE
NOT 0
NOT NULL
NOT '\0'
2-38
if
conditi
on
true
statement1
statement2
...
statementN
fals
e
2-39
example
if (x > 5)
x = 5;
else
x++;
/* semicolon is required */
/* but not allowed in Pascal */
Braces { and } are used to group declarations and statements together into a
compound statement (no declarations), or block, so that they are syntactically
equivalent to a single statement.
Null statement
example
;
;
3;
Here we have two null statements followed by a expression ; form statement
The latter is a statement because 3 is the simplest type of expression
2-40
2-41
>=
value
8
1
2.5
0
1
2
3
3
-3
0
-2
2
2-42
type
int
int
double
int
int
int
int
int
int
int
int
int
::=
|
|
|
valid examples
invalid examples
a < 3
a =< b
/* out of order */
a < = b
/* space not allowed */
a >> b
/* shift expression */
/*syntactically correct, but
confusing*/
a > b
-1.3 >= (2.0*x + 3.3)
a < b < c
In the first invalid example, the = and < signs are out of order
In the second invalid example, the space between < and = causes these to be
treated as two separate tokens, i.e. LESS and ASSIGN, instead of
LESS_EQUAL
In the third invalid example, using >> yields an expression which will compile,
but it is not a relational expression as this section is trying to illustrate
Values of e1-e2
positive
zero
negative
e1 < e2
0
0
1
e1 > e2
1
0
0
2-43
e1 <= e2
0
1
1
e1 >= e2
1
1
0
invalid examples
c == 'A'
a = b
/*assignment statement*/
a =
= b - 1
/*space not allowed*/
(x + y) =! 44
/* equivalent to (x + y) = (!44) */
k != -2
x + y == 3 * z - 7
Values of
expr1 - expr2
zero
nonzero
expr1 == expr2
expr1 != expr2
1
0
0
1
2-44
a && b
a || b
! a
! b
nonzero
nonzero
nonzero
nonzero
2-45
invalid/misleading examples
if b == a
/* parentheses missing */
area = a * a;
if ( i < j )
min = i;
printf("i is smaller than j\n");
/*second statement not part of if*/
if ( i !=
{
i = i +
j = j +
};
else
i = i -
j )
1;
2;
/*syntax error*/
j;
2-46
2-47
2-48
*
+
x
*
y
The answer is (b) because multiplicative operators have higher precedence than
additive operators and thus bind onto their arguments quicker than the lower
precedence operators.
That is, operators of higher precedence are grouped together first.
The answer is (a) because operators of equal precedence (in this case the
subtraction operator) follow associativity rules.
Additive operators associate from left to right.
2-49
The following table lists the operators we have seen thus far.
The operators of highest precedence are at the top of the table.
Operators of lower precedence are listed below those of higher precedence
Operators in the same row are of equal precedence
Operator
()
+ (unary) - (unary)
* / %
+ < <= > >=
== !=
&&
||
Associativity
left to right
right to left
left to right
left to right
left to right
left to right
left to right
left to right
(Reference: p. 53 of K&R)
2-50
2-51
2-52
This will compile and run, but it will not give the desired result.
The first part of the if-else will always execute because the expression is always
true.
The reason is that the expression 10 <= x <= 20 is really equivalent to the
expression (10 <= x) <= 20 and the first subexpression evaluates to either
0 or 1.
In strongly typed languages such as Pascal, the first subexpression would yield a
BOOLEAN type which in turn could not be compared to an integer.
2-53
A year is a leap year if it is divisible by 4, but not by 100, except that years
divisible by 400 are leap years.
if (leap_flag)
printf("%d is a leap year\n", year);
else
printf("%d is not a leap year\n", year);
2-54
Example
#include <stdio.h>
int
{
int
{
int
{
foo()
printf("foo\n"); return(1); }
bar()
printf("bar\n"); return(0); }
fubar()
printf("fubar\n"); return( foo() || bar(); ) }
main()
{
if ( foo() && bar() && fubar() )
return( foo() );
else
return( fubar() && foo() );
}
What gets printed? (exercise)
2-55