CS计算机代考程序代写 Character IO, Expressions

Character IO, Expressions

Class 14

Character IO

• the simplest IO consists of a reading a single character from
the standard input stream with getchar
• and writing a single character to the standard output stream

with putchar
• all data is in chunks of one byte, which is the size of char
• a byte in a file could be any value from 0000 0000 to 1111
1111 which in hex is 0x00 to 0xff
• all 256 values are valid data
• but there must also be the ability to detect end-of-file
• thus the return type of getchar is not char but int

Program 1.5.1

1 /*
2 * echo input to output
3 * one character at a time
4 * K&R 1.5.1
5 */
6
7 #include
8
9 int main(void)

10 {
11 int c;
12 c = getchar();
13
14 while (c != EOF)
15 {
16 putchar(c);
17 c = getchar();
18 }
19 return 0;
20 }

• 2-space indents
• braces vertically aligned
• main function return type

and void argument list
• space after while, no space

after main, putchar,getchar
• return from main

• obviously, the argument to
putchar is also an int

Program 1.5.1 Version 2

1 /*
2 * echo input to output
3 * one character at a time
4 * K&R 1.5.1 version 2
5 */
6
7 #include
8
9 int main(void)

10 {
11 int c;
12
13 while ((c = getchar()) != EOF)
14 {
15 putchar(c);
16 }
17
18 return 0;
19 }

• assignment has a return
value

• more succinct
• classic C idiom
• extra parentheses needed for

operator precedence = vs !=

Running the Program

• $ ./prog1_5_1v2 (remember Ctrl-d to end keyboard input)
• $ echo $?

• can redirect input
$ ./prog1_5_1v2 < prog1_5_v2.c • can redirect input and output $ ./prog1_5_1v2 < prog1_5_v2.c > foo

One More Example
1 #include
2 #define IN 1
3 #define OUT 0
4
5 int main(void)
6 {
7 int c;
8 unsigned lines = 0;
9 unsigned words = 0;

10 unsigned characters = 0;
11 unsigned state = OUT;
12 while ((c = getchar()) != EOF)
13 {
14 ++characters;
15 if (c == ’\n’)
16 {
17 ++lines;
18 }
19 if (c == ’ ’ || c == ’\n’ || c == ’\t’)
20 {
21 state = OUT;
22 }
23 else if (state == OUT)
24 {
25 state = IN;
26 ++words;
27 }
28 }
29 printf(“%u %u %u\n”, lines, words, characters);
30 return 0;
31 }

• #define directive vs.
const
• no semicolons on

preprocessor lines
• one variable per

declaration

K & R Sections

you should know:
• chapter 2, all
• chapter 3, all except 3.7 and 3.8

• we NEVER use break
• continue is so sloppy you should be embarrassed to even

consider it
• we NEVER use goto

• 6.1 through 6.3

K & R Sections

we will cover:
• 2.9
• chapter 4
• chapter 5
• chapter 6
• chapter 7
• pieces of chapter 8 and appendix B

Overflow and Underflow

1 /* illustrate wrapping */
2 #include
3 #include
4
5 int main(void)
6 {
7 uint8_t uvalue = 0;
8 int8_t svalue = -128;
9

10 printf(“start: %u\n”, uvalue);
11 uvalue–;
12 printf(“minus 1: %u\n”, uvalue);
13 uvalue++;
14 printf(“plus 1: %u\n\n”, uvalue);
15
16 printf(“start: %d\n”, svalue);
17 svalue–;
18 printf(“minus 1: %d\n”, svalue);
19 svalue++;
20 printf(“plus 1: %d\n”, svalue);
21 return 0;
22 }

• C does not define
behavior — machine
dependent
• on Intel-based Unix,

everything simply wraps
around

$ ./wrap
start: 0
minus 1: 255
plus 1: 0

start: -128
minus 1: 127
plus 1: -128

Bitwise Operators

• C has six bitwise operators
• integer argument (but we don’t use them on char)
• mostly they only make sense with unsigned values

& bitwise and
| bitwise or
ˆ bitwise exclusive or

<< left shift >> right shift
∼ unary bitwise complement

and

• in artwork, a stencil is a thin sheet with a cutout pattern
• lay the sheet on a surface and spray with paint
• where the sheet is, paint is blocked
• where the cutouts are, paint is applied to the surface
• the sheet areas of the stencil mask the surface

• bitwise and is typically used as a stencil sheet
• zeroes are solid stencil sheet
• ones are cutouts that let the paint through

and

1 uint8_t value;
2 uint8_t mask = 0xa5; /* 1010 1001 */
3
4 /* lets through 4 bits, blocks the others */
5 uint8_t result = value & mask;

• value is like the spray paint
• mask is the stencil sheet

value -> 1101 1010
mask -> & 1010 1001

———–
result -> 1000 1000

or

1 uint8_t value;
2 uint8_t inkpad = 0xa5; /* 1010 1001 */
3
4 /* guarantees 4 bits, allows others */
5 uint8_t result = value | inkpad;

• in contrast, or is like an inkpad, or a stencil with ink on it
• value is still like spray paint
• image appears from paint or inked spots (inclusive or)

value -> 1101 1010
inkpad -> | 1010 1001

———–
result -> 1111 1011

xor

1 uint8_t value;
2 uint8_t inkpad = 0xa5; /* 1010 1001 */
3
4 /* allows only one through */
5 uint8_t result = value ^ inkpad;

• xor doesn’t allow too much of a good thing
• value is spray paint, inkpad is also
• image appears from paint or inkpad but not both

value -> 1101 1010
inkpad -> ^ 1010 1001

———–
result -> 0111 0011

Left Shift

• left shift is the equivalent of multiplying by a power of 2
• low-order bits are filled with zeroes

1 uint8_t value = 0x29; /* 0010 1001 = 41 */
2 value <<= 2; /* now 1010 0100 = 41 x 4 = 164 */ value -> 0010 1001
<<2 --------- result -> 1010 0100

• textbook error on page 49, lines 5–6
• says shift amount must be positive
• actually shift amount must be non-negative
• shift can be zero (no change)

Right Shift

• for an unsigned value, strictly equivalent to dividing by a
power of 2
• zeroes are shifted into the most significant positions

• for a signed value, machine dependent
• are zeroes or ones shifted into the most significant positions?
• on Intel-based Unix, equivalent to dividing by power of 2
• details later, when we study 2’s complement representation

int8_t svalue = -8;
svalue >>= 2; /* svalue is now -2 */

Example

• from K&R page 49
/* get n bits from x starting at position p */
/* lsb is position 0 */
/* p = 6, n = 2 means positions 6 and 5 */
unsigned getbits(unsigned x, unsigned p, unsigned n)
{

return (x >> (p + 1 – n)) & ~(~0 << n); }