Lawrence Technological University
College of Arts and Science
Department of Mathematics and Computer Sciences

Introduction to Programming in C, MCS 1142 Sec. 06, Fall 2004

A recap of the important points in the lectures. Please check this page frequently and be sure you understand the major points. If you do, you should be ready for the coming material and ready for tests on covered material. If you do not, then see me after class.

Tuesday, August 31st The Fall semester begins. Welcome! Some introductions

• This is a course in learning to program. The computer language of instruction is C.
• A look at the syllabus and its links.
• What is programming?
• Why program?
• The compilation process.
• Resources today at LTU
1. Your laptop
2. S115 ==> M138 in transition
3. VAX
• Housekeeping
• Join the Blackboard Discussion Topic on your programming preferences.
• All correspondence will be in plain text. Attachments will be ignored.
• Some class sessions will be on-line. I need your feedback.
• Your task for the next week: Homework Assignment 0 and getting the "Hello, World" program to compile and run on some platform.
• Homework Assignment 0 is quite similar to Program 1-4 on page 15.

Tuesday, September 7th

• If at all possible bring the computer and compiler you intend to practice on to class today!
• Programs = Algorithms + Data Structures (Nicholas Wirth)
• Programs
• Copy
• Compare
• Calculate
• Control
• Save and Retrieve
• Where is the division between operating system and application programs? Just ask Microsoft.
• For C some understanding of the binary and octal and hexadecimal number systems is important. If this is new to you, take a look at appendix D in the text and the binary numbers class handout.
• Numbers can represent quantities, but they can also represent characters. Be familiar with appendix A, the ASCII codes. Also look at the class handout on ASCII codes.
• Each student needs a set of steps from identifying the need for a program to completing a useful program.
• Writing a program should always consist of these steps. Loop back through the steps until all are completed successfully.
1. Understand the problem and formulate a plan.
2. Outline the solution using pseudo code and/or flowcharts.
3. Translate the pseudo code into C. Type the program in a text editor like Notepad or Emacs or a code editor that comes with your IDE.
4. Translate the C into machine, or binary code. i.e. compile, link and run the program
5. Debug and test the program
6. Ask the user if the result is satisfactory
• Problems, Chapter 1: 5, 8, 10, 11, 13, 27, 29 and 30
• Hello, World in detail.
• Laying out an Olympic course on your local high school track.
• Getting your computer working.
• Homework Assignments 1 and 2 should look a lot like Program 2-6 in the textbook. Assignment 1 is to use constant data, so where you might say something like
```float diameter;
printf("Please enter the diameter of the gas can in centimeters ==> ");
scanf("%f",&diameter);
printf("You entered %.2f cm as the diameter\n",diameter);
/* ask for the can height */
/* calculate the volume */
/* calculate the hours */
/* print the hours */
```
for Assignment 2; for Assignment 1 you would just
```float diameter = 30.0;
printf("The can diameter is %.2f cm\n",diameter);
/* set the can height */
/* calculate the volume */
/* calculate the hours */
/* print the hours */
```

Tuesday, September 14th

• You need a compiler for this course! A review of your options
1. If you have an LTU laptop or use the computers in M138, the Visual Studio Command Prompt Window may not appear on your Start Menu. To get started run vcvars32.bat. That file is the bin folder of the visual C folder(vc7) of the Visual Studio folder. To run it just double click it in the My Computer view. For more information see MSDN-Building on the Command Line To check your work create a file hello.c in NotePad or Emacs and save it in c:\mcs1142\hello.c and then open the Visual Studio Command Prompt Window. At the command prompt
```cd \mcs1142
cl hello.c
```
2. If you do not have an LTU laptop and still want to use cl, it is available for free at msdn.microsoft.com/visualc/vctoolkit2003
3. gcc is best used on a windows machine by installing it along with cygwin
4. bcc32 is available on any computers with C++Builder installed.
5. djgpp is a version of gcc for making DOS programs from www.delorie.com/djgpp
6. Macs or other unix machines come with cc or gcc already installed
7. VAX-OpenVMS comes with a C compiler. To use it and get the libraries like stdio to link properly see the online help or the course handouts or see me after class.
• You might enjoy a very nice C tutorial by John Kopp cplus.about.com/library/blctut.htm
• A sample situation where a little programming might help. My email program (Eudora) choked on a huge download. I could not just erase the inbox because it had some important emails that I had not finished with from the day before. I needed to repair the file in.mbx. There are usually problems loading a file bigger than 128 megabytes in any 32 bit system like Windows 2000. There are several options
1. Transfer the file to a better computer
2. Open the file in Word (12 minutes) and move to the end of the good area (20 minutes and not done yet) ...
3. Assign the problem as homework
4. Write a short program. Go to the Web mail portal and copy the header from the start of the bad email (4 minutes). Use Emacs to type the program (1 minute). Run the program (less than 1 second).
• Although option 3 seemed good, I used option 4, with some slightly idiomatic Perl
```c:\mcs1142>perl -c fix.pl
fix.pl syntax OK

c:\mcs1142>type fix.pl
while (<>) {
# copy everything until the header of the offending message
last if /From \?\?\?@\?\?\? Tue Sep 02 22:21:18 2003/;
print;
}

c:\mcs1142>perl fix.pl <in.mbx >infixed.mbx

c:\mcs1142>dir *.mbx
Volume in drive C has no label.
Volume Serial Number is 5C40-43DF

Directory of c:\mcs1142

09/02/2003  10:23p         294,603,235 in.mbx
09/03/2003  04:21p             517,314 infixed.mbx
2 File(s)    295,120,549 bytes
0 Dir(s)  23,686,516,736 bytes free
```
• Chapter 2. Last week we looked at the parts of the "Hello, World" program. Today we will look at the structure of a more general program
1. Initialize the constants
2. Accept the variable input
3. Do the calculation
4. Print the result
As in the book, we will consider output before input.
• What is a block?
• A few words about the assignment operator ("=" in C).
• In section 2-3, to the hard rules for identifiers in table 2-2, we add soft rules
1. Avoid using a leading underscore in your programs to avoid confusion with system and compiler identifiers.
2. For clarity, use full English words for global symbols, and abbreviations for symbols in local, complex expressions.
• We begin the discussion of Section 2-4, Types, by saying again that is important to remember the difference between the address of a memory location and the value stored at that location. Most of the identifiers that we will use, that occur to the left of the = (assignment operator), will refer to the value in the memory location.
• Exercises 1-7, 21, 27-29
• Of the 4 basic data types, consider the strange case of void. No variable can be of type void. But, a variable identifier can be an address of a memory location. If the data type of the value in that memory location is not defined, then that identifier is said to be a pointer to type void, or a pointer of type void.
• There is discussion in our text about when to initialize a variable. To say that C is a descendant of ALGOL is to say that it reuses or "dynamically allocates" memory. Breaking the program into blocks makes this possible. In C a block is the statements between a { and a }. For a local variable (one defined inside a block) the association of the variable identifier and a specific memory space is only valid while the block is executing. More on variable scope and initialization when we study functions in chapter 4.
• Constants
• String constants
• NULL
• literal, defined and memory constants
• More on data types next week.
• Simple output, copying a series of characters to an output device like the LCD laptop screen.
• What does printf("MCS%d",1142); actually do?
• Exercises 9 - 11 and 30 - 34.
• In a footnote to 11(e), we noted that the purpose of the "const" keyword is to help the compiler remind you not to change a constant. It certainly is bad programming practice to change a constant. However, the power of C to do address arithmetic also presents the danger that you can change a constant accidentally.
• Assignment 1 is due Thursday. Get started today if you have not already. Take a good look at Programs 2-2 through 2-6.
• printf() is an essential part of your reading and writing vocabulary in C. Section 8 of chapter 2.
• printf and scanf are functions with a variable number of arguments. That is, they are powerful features of C that can cause difficult to find bugs if they are not used carefully.
• The syntax for using printf is useful in C, but also in all the derivatives of C. Learn it now by doing the examples.
• Do all the Output Examples on pages 46-48.
• Understand each of the the 3 Common Output Errors. #3, omitting the "l" in %ld or %lf is not usually a problem, because of implicit type conversion (which we will study next week). The inverse situation with scanf on input is often a disaster.
• Program 2-5 has a lot of excellent examples.
• Review questions 13-14 and exercise 26.
• scanf() and the & (address of operator). Remember we said most of the identifiers or symbols we would use represent values stored at a computer memory address and not the address. (The main exceptions being identifiers which are names of arrays and not single variables -- a topic for later.) scanf needs to have an address to work with. For example in our first assignments we might have the symbol "height" to represent the value of the height measurement of our gas can. By
```double height;
```
we reserve 8 memory bytes to store that value. By
```scanf("%lf",&height);
```
we ask the function scanf to take the number typed at the keyboard and put it at that place in memory. Read "&height" as "the address of the variable height."
• Consider the work scanf does if a user types "1142[Enter Key]" in response to this program fragment
```int course_number;
printf("Please enter your course number ==> ");
scanf("%d",&course_number);
```
1. get 1st character, a '1'
2. decide 1st character is a digit
3. convert 1st character to number (perhaps by subtracting '0'?)
4. set Number to 1
5. get next character, a '1', decide is a digit and convert to a number
6. multiply Number by 10 and then add 1
7. get next character, a '4', decide is a digit and convert to a number
8. multiply Number by 10 and then add 4
9. get next character, a '2', decide is a digit and convert to a number
10. multiply Number by 10 and then add 2
11. get next character, an Enter key ('\n'), decide is not a digit
12. copy Number to &course_number
• Read page 49 carefully to understand "whitespace" and scanf.
• Study Table 2-16 on page 51, "scanf rules". The Input examples illustrate these rules. Do them all. consider an additional example pertaining to Rule 3:
```/* error.c
a program to see what happens with a mismatch
in data types in a scanf statement
*/
#include <stdio.h>
int main()
{
char yourGrade = 'A';
char a;
scanf("%d",&a);
printf("The result is %d, your grade is %c\n",a,yourGrade);
fflush(stdin);
getchar();
return 0;
}
```
• While going over the 5 rules for using scanf in the box on page 51, we add 2 more admonitions
1. Don't use elaborate scanf statements. scanf is only good for reading numbers, with or without decimals, separated by whitespace. scanf is not good for text processing.
2. As stated on page 49, Don't put delimiters in the input stream or in the input specification. They just confuse the user and lead to errors. Note Input Example 4 (p.51).
• Notice in Common Input Errors (p.52), there are more ways to get in trouble with scanf than printf.
• The pattern in our phrase book that is entitled "ask the user for x", would be a good one to follow.
• Review Question 16.
• Problem 41 (p.66)
```// p2_41.c
#include <stdio.h>
int main()
{
int num;
float fnum;
printf("Enter an integer ==> ");
scanf("%d",&num);
printf("The number as a character: %c\n",num);
printf("The number as a decimal: %d\n",num);
fnum = num;
printf("The number as a float: %f\n",fnum);
// patch to hold the output window open
printf("Press Enter to continue ...");
fflush(stdin);
getchar();
return 0;
}
```
• For a good review of the course so far, read pages 56 and 57 that present specifications for a program, the program and an analysis of the program considering those specifications.
• As with each quiz or test, you will have to write a complete program for part of next week's quiz. You should be able to write one like Homework Assignment 1 or 2, or like Problems 36, 37 or 42 on page 66.

Tuesday, September 21st

• Often I will make a comment that has nothing to do with the grade on your work. These comments are intended as suggestions for future improvement.
• In the beginning of Chapter 3 on expressions, we find a lot of needlessly picky definitions. You may ignore them.
• Consider this hierarchy
1. A C program has at least 1 function (called main).
2. A function has at least 1 block (stuff between { and }).
3. A block has at least 1 statement (line terminated by a ;).
4. A statement has at least 1 expression.
5. A non-trivial expression has at least 1 operand and 1 or more operators.
• One definition worth remembering is on page 93: "An expression is turned into a statement by placing a semicolon (;) after it."
• Back to Problems 38 and 40 in Chapter 2, to practice making a complete program
```// prob2_38.c
#include <stdio.h>
#define A 'a'
#define E 'e'
#define I 'i'
#define O 'o'
#define U 'u'
int main()
{
const int zero = 0;
const int two = 2;
const int four = 4;
const int six = 6;
const int eight = 8;
printf("%c%3c%3c%3c%3c\n",A,E,I,O,U); // experiment in columns
printf("%d\t%d\t%d\t%d\t%d\n",zero,two,four,six,eight);
printf("%c\t%c\t%c\t%c\t%c\n",'1','3','5','7','9');
printf("\nPress enter to continue... ");
getchar();
return 0;
}
```
and
```// prob2_40.c
#include <stdio.h>
int main()
{
int quantity;
float unitPrice;

printf(
"Enter a quantity (as an whole number) followed by a unit price\n==> ");
fflush(stdin);
scanf("%d%f",&quantity,&unitPrice);
printf("\n\nQuantity %8d",quantity);
printf("\nUnit Price %6.2f",unitPrice);
fflush(stdin);
printf("\nPress enter to continue... ");
getchar();
return 0;
}
```
• The terms unary, binary and ternary only refer to the number of operands. The "unary minus" is the only example where one of those terms is a part of the descriptive name of a C operator.
• What do the operators do?
• Unary minus, +, -, *, / are the same as always except when both operands of the / operator are integers
• % gives the remainder in integer division
• = is the assignment operator
• +=, -=, *=, /=, %= are shorthand and never necessary
• ++, -- are further contractions and are also never necessary
• Logical operators !, ==, >, ?: etc will be considered in chapter 5
• &, *, ., -> will be briefly considered later in the course
• The bitwise operators will be considered toward the end of the course
• () and , affect the order of expression evaluation and will be considered next week
• Quiz 1

Tuesday, September 28th

• Review of Quiz 1.
• Continuing about expressions (Chapter 3)...
• Neither
```a = b++;
```
nor
```a = ++b;
```
is ever good programming. Occasionally, but not at the level of this course,
```a = *b++;
```
is acceptable idiom used sparingly.
• Remember that the assignment operator, = , is unusual in that it changes the operand to its left. Most of the operators do not change any operand.
• The expression x + 2/6 + y and the rest of Problem 26.
• Expression evaluation based on operator precedence and associativity. Associativity applies only if the precedence is the same. When in doubt use parentheses.
• Problem 24c (page 111)
```x = y = 50;
```
just to remember that the assignment operator also returns a value.
• Problem 25a-e only to deprecate ever using constructions like those in your programs.
• Examine and understand Problem 27c.
• Making readable expresions.
• Type conversions, casts and rounding.
• The binary operators in C work on 2 operands of the same type. If the types do not match, the lower type on the ladder in figure 3-12 is converted to the higher type. Note that in this ladder, all the floating point types are higher than any integral types.
• This implicit type conversion also happens with function arguments.
• Implicit type conversion is why
```float f = 4.0;
double d = 5.0;
printf("%f %f",f,d);
```
works and
```float f;
double d;
scanf("%f %f",&f,&d);
```
does not.
• ```char x;
int y;
x = y;
```
may produce a warning that the type conversion might loose data. This warning can be removed by a cast
```x = (char)y;
```
• Similar warnings can come with function argument or function return value type conversions.
• Only use a cast to reassure the compiler that you see the problem. Never use a cast to try and fool the compiler.
• For homework assignment 2, and looking ahead to assignment 3, pay attention to displaying a reasonable number of decimal places. For example, the hours run depends on 0.3 gallons per hour, a number which is known only to 1 significant digit. The result in hours should have at most 1 decimal place (%.1f).
• Usually we want the rounded number from printf rather than the truncated value from a type conversion.
```float f_bmi = 20.56;
int BMI;
printf("%.0f",f_bmi);  // prints 21
BMI = f_bmi;
printf("%d",BMI);      // prints 20
BMI = f_bmi + .5;
printf("%d",BMI);      // prints 21
```
• Note the admonition on page 107 to use a prompt to let the user know what is going on. We note that program 3-11 forgets to do this. The comments say that the numbers are integers. The user does not know that and may use a decimal point in their number. First tell the user to enter whole numbers. Second use
```fflush(stdin);
```
after each prompt and before the scanf to discard any inadvertent decimals etc.
• Problem 31, to extract and print the rightmost digit of an integral portion of a float
```float f = 54.0;
int i;
i = f;      // truncates the float and just keeps the integer part
i = i % 10; // returns the remainder of a divide by 10, which is 4
printf("%d",i);
```
Be prepared to do problem 32, the second rightmost digit.
• Writing out the next term in a series like in problem 37 on page 112. For these series, the next term depends only on the term before
```next_x = x + 5; // 37a
```
• Monday, or perhaps a week from Monday as we try functions, we will look at the Fibonacci series (problem 39).

Tuesday, October 5th

• Assignment 3
1. BMI should be a whole number.
2. As with our example from last week, use floating point types for real numbers.
3. Liberal use of fflush(stdin) helps forgive simple mistakes by the user.
4. Do not use delimiters in the input stream
```// delimit.c
// a bad example
#include <stdio.h>
int main()
{
double heightInFeet, heightInInches;
printf("Enter your height in feet and inches,\n");
printf("such as 5\'7\", separated by a space: ");
fflush(stdin);  // discard any left over keystrokes
scanf("%lf %lf", &heightInFeet, &heightInInches);  //user enters two values
printf("Feet: %.2lf, Inches: %.2lf\n", heightInFeet,heightInInches);
return 0;
}
```
Why does this not work as the user might expect?
```Enter your height in feet and inches,
such as 5'7", separated by a space: 5, 7
Feet: 5.00, Inches: 0.00
```
• Functions are used to break up long complicated blocks of code. Long in modern terms could be any block that is longer than 1 computer screen.
• Functions are also used to compact repeating sections of code.
• Our current programming projects are not long nor repetitious. We will consider functions in more depth when we can use their power.
• Chapter 5, if statements.
• Decision making is fundamental to the concept of computing.
• All computer decisions are binary or two-way. More complex, or what the text calls multi-way, decisions are just combinations of binary decisions.
• Decision making on the LTU2002. In machine language the decision is to branch or jump to a piece of code or not.
• What is truth in C? What is NULL in C?
• In C, if statements have the form
```if (condition-expression)
block
else
block
```
• condition-expressions are just expressions that are considered true if non-zero and false if zero.
• A block can be a single statement or more than 1 statement surrounded by {}'s.
• When the condition_expression is true the first block is executed
• When the condition_expression is false the second block is executed.
• The else clause and its block are optional.
• Some new operators which can be used in any expression.
• The relation operators !=, ==, >, >=, etc. work like they do in algebra. In C expressions they return only one of the two values 1 (if the relation is true) or 0 (if the relation is false).
• The logical operators ! (not), && (and), || (or) also only return 1 or 0. Be sure you understand the truth tables in Figure 5-2 on page 175.
• The idea of && and || being "shortcut" operators as mentioned on page 175. This feature of C is to be used very sparingly.
```// see if a word is listed
// assume there are 2 dictionary files, a short one of frequent words and
// a loooong one of all the words
if (in_short(word) || in_long(word))
// if the word is in the short dictionary you never have to search the
// long one
```
• A small test program to study the expressions in exercise 15
```/* test program */
#include <stdio.h>
main()
{
if (exp) {
printf("true");
} else {
printf("false");
}
return 0;
}
```
• Review questions 6 and 7.
• More complex if statements.
• If statements do not have semicolons at the end.
```if (a == b) ;
printf("true");
```
always prints "true", because the indentation is ignored by the compiler. The compiler reads that as
```if (a == b)
;          // a blank or do nothing statement
printf("true"); // a completely separate statement not part of the if
```
• Nested if statements are simply if statements
```if (condition)
block1
else
block2
```
where block1 or block2 or both contain an if statement
• if else if structures are just a series of nested if statements.
```
if (condition1)
block1
else
if (condition2)
block2
else
if (condition3)
block3
else
block4
```
if condition1 and condition2 and condition3 are mutually exclusive then adjusting the spacing and indentation, without changing the program flow, makes the logic clearer
```
if (condition1)
block1
else if (condition2)
block2
else if (condition3)
block3
else
block4
```
for example
```if (x == 1)
func1();  // an arbitrary function
else if (x == 2)
func2();   // a different function
else if (x == 3)
func3();   // yet another function
```
• The above examples show the importance of indentation and braces in making the intent of complex if statements clear and preventing bugs. After each chapter, remember to review the programming style page.
• When testing always check both branches of your if statements.
• A switch statement is just shorthand for a if-else-if structure. It may be clearer when there are many mutually exclusive integral choices, but it is never required. If the choices are not mutually exclusive, the break; statements and goto labels can cause problems. We will talk about these problems more in coming weeks as we consider looping.
• The ?: operator is a shorthand operator. Like += and other shorthand assignment operators it is never required and should be used sparingly. Example
```if (b < c)
a = d;
else
a = e;
```
could be abbreviated
```a = b < c ? d : e;
```
or
```if (testing == 1)
printf("testing");
else
printf("normal");
```
could be abbreviated
```printf("%s", (testing == 1) ? "testing" : "normal");
```
• We emphasize tips 4, 5 and 8 on page 217. Tip 9 is similar to the example we did earlier.
• If you have to use De Morgan's rule to simplify your logic, go back and redesign your program flow on paper.
• We can do some of the problems, and check our work using a small test program
```#include <stdio.h>
// test bed for problems 20-29 pp.220-221
int main()
{
// the initial values
int x=4,y=0,z=2;
// the if statement from problem 23
if (x || y || z)
y=1;
else
z=3;
// print the final values
printf("x is %d, y is %d , z is %d\n",x,y,z);
return 0;
}
```
• You will certainly see if's like those in problems 20-29 on October 12th.
• Miscellaneous points about Chapter 5 and Assignment 4
• The else clause is optional.
• Homework Assignment 4 is an exercise in if statements. Issue the warnings only if they apply.
• When you tell someone they are out of the range of normal, it is only fair and friendly to tell them what the range of normal is!
• Games programming is another matter. Still you may wish to provide different levels of feedback for different skill levels
• Switch statements, Problems 30, 31 and 32. These are examples of switch statement with missing or misplaced break; statements. Notice, like the if, switch statements do not end in a semicolon. The symbols like "case 0:" are statement labels and represent neither a variable's value nor a variable's address in memory. case 0: is a named label of the place in the program code where execution is to GO TO next. The break; statement means exit the current { block } now and start with the code right after the current block. Switch statements like
```switch (x) {
case 0: thing1();
case 1: thing2();
break;
case 2: thing3();
break;
default: default_thing();
}
```
are either a mistake or an arcane structure that makes sense to an assembly language programmer. They will not make your program easier to maintain.

Tuesday, October 12th

• More practice with complex if statements. Problems 31, 32, 41-45.
• Look at Problem 56, page 224:
How many values of the variable "num" must be used to completely test all branches of the following code fragment?
```if (num > 0)
if (value < 25) {
value = 10 * num;
if (num < 12)
value = value / 10;
} else
value = 20 * num;
else
value = 30 * num;
```
1. Consider that question. Observe that no matter how many instances of the variable "num" we use, the ifs are not completely tested unless we use 2 different values for the variable "value" as well.
2. Suggest ways to simplify this fragment and make it more readable. We can improved the fragment by using a series of if-else-if statements that were ordered from low values to high values. The ordering is an important part of the simplification process. It can be either low to high or high to low, but should be consistent. You could use something like this for Assignment 5. Notice that keeping the values in strict ascending order avoids having to use compound logical clauses like num > 0 && num < 12 and makes the program easier to read
```if (num <= 0)
value = 30 * num;
else if (num < 12)
if (value > 25)
value = num;
else
value = 20 * num;
else
if (value > 25)
value = 10 * num;
else
value = 20 * num;
```
3. Decide if improving the fragment makes testing easier
• Quiz 2

Tuesday, October 19th

• Review of Quiz 2
• Chapter 4, Functions, briefly...
• We have used a few library functions already scanf, printf and fflush. The function prototypes for these are in stdio.h
• math.h has the prototypes for fabs, pow, sqrt and the trig functions.
• Remember these functions are parts of the C Runtime Library in help files.
• "User" functions refers to the user of the compiler -- you the programmer -- and not the end user of your program.
• The arguments to functions are passed by value in C. That means that a copy of the variable is passed to the function for its use. In the case
```// byvalue.c
#include <stdio.h>
void func(int a);
main()
{
int a = 1;
func(a);
printf("%d",a);
return 0;
}
void func(int a)
{
a = 2;
return;
}
```
the program prints "1".
• User functions usually return a value
```// fib_3_39.c
#include <stdio.h>
int next_fib(int a,int b);
main()
{
int x = 3,y = 5;
printf("The Fibonacci number after %d and %d is %d\n",x,y,next_fib(x,y));
return(0);
}
int next_fib(int a,int b)
{
return a + b;
}
```
• Making our greeting code into a function
```// hello2.c
#include <stdio.h>
void say_hello(void);

int main()
{
/* your program starts here */
say_hello();
/* your program ends here */
return 0;
}

void hold_open(void)
{
printf("hello, world");
return; // optional
}
```
• General review points
1. Why are we here?
2. Keep the user informed. They can't ead your code or your comments.
3. Comments are not optional.
4. Let the compiler be your calculator for constants.
• We will consider any questions you have from the first 5 chapters, the front and back inside book covers, Appendices A and D, and the following problems
1. Chapter 3, Problem 35, Page 112
```// temp.c
// prob 35, page 112
// an example of directly translating a formula
#include <stdio.h>

int main()
{
double F,C;
printf("Please enter the temperature in Centigrade  ==> ");
scanf("%lf",&C);
F = 32.0 + C * 180.0 /100.0;
printf("%.1lf Centigrade is %.1lf degrees Fahrenheit\n", C,F);
return 0;
}
/* output
Please enter the temperature in Centigrade  ==> 100
100.0 Centigrade is 212.0 degrees Fahrenheit
Press Enter to continue..
*/
```
2. Chapter 3, Problem 41, Page 112-113, Left as an exercise for the student.
3. Chapter 5, Problem 57, Page 224
```// age.c
// prob 57, page 224
// this time without a user function and without the time() library function
#include <stdio.h>

int main()
{
int month,day,year,age;
int cmonth,cday,cyear;
// Ask for Birth Date first
printf("Enter the Year of your birth ==> ");
fflush(stdin);
scanf("%d",&year);
printf("Enter the Month of your birth ==> ");
fflush(stdin);
scanf("%d",&month);
printf("Enter the Day of your birth ==> ");
fflush(stdin);
scanf("%d",&day);
// Ask for today's Date next
printf("Enter the Year now ==> ");
fflush(stdin);
scanf("%d",&cyear);
printf("Enter the Month now ==> ");
fflush(stdin);
scanf("%d",&cmonth);
printf("Enter the Day now ==> ");
fflush(stdin);
scanf("%d",&cday);
// calculate the difference in whole years
age = cyear - year;
if (cmonth == month)
if (cday < day) month++; // before debugging was month--;
if (cmonth < month) age--;
printf("Now you are %d years old\n",age);
printf("Press Enter to continue..");
fflush(stdin);
getchar();
return 0;
}
/* test 1
Enter the Year of your birth ==> 2000
Enter the Month of your birth ==> 3
Enter the Day of your birth ==> 4
Enter the Year now ==> 2003
Enter the Month now ==> 3
Enter the Day now ==> 3
Now you are 3 years old
*/
/* test 2
Enter the Year of your birth ==> 2000
Enter the Month of your birth ==> 3
Enter the Day of your birth ==> 2
Enter the Year now ==> 2003
Enter the Month now ==> 3
Enter the Day now ==> 3
Now you are 3 years old
*/
/* test 1 after debugging
Enter the Year of your birth ==> 2000
Enter the Month of your birth ==> 3
Enter the Day of your birth ==> 4
Enter the Year now ==> 2003
Enter the Month now ==> 3
Enter the Day now ==> 3
Now you are 2 years old
*/
/* test 2 after debugging
Enter the Year of your birth ==> 2000
Enter the Month of your birth ==> 3
Enter the Day of your birth ==> 2
Enter the Year now ==> 2003
Enter the Month now ==> 3
Enter the Day now ==> 3
Now you are 3 years old
*/
```
• Midterm course survey
• Midterm

Tuesday, October 26th

• Review of Midterm.
• Today Chapter 6, repetition. Repeating the same code steps over again is referred to as looping, and the fragment of code that is repeated is called the loop. The machine or assembly language translation of a basic loop into C would be
```Loop:
loop-block
if (condition) goto Loop;
```
This is like the post test loop in figure 6-2.
• On the LTU2002, consider Exercise 4.
• The C shorthand for this arrangement of if and goto and statement label is a do-while loop
```do
loop-block
while (condition);
```
• With if's the pretest loop looks like this
```Loop:
if (condition) {
loop-block;
goto Loop;
}
```
This is better written in C as as
```while (condition)
loop-block
```
In general while and do-while are more clear and much preferred over the if-goto construction.
• Later we will discuss loops with counters, "for" loops.
• Clarity is an important consideration when choosing which type of loop to use
• The logic of always doing at least 1 pass in the do-while loop is seldom more clear to anybody other than old assembly language programmers.
• For a known number of iterations the for loop is more clear.
• For an unknown number of iterations the while loop is more clear.
• We look at exercises 16a and 17a on page 292 because they illustrate the cardinal sin of looping ... making the infinite loop because you forgot to change the loop variable.
• Exercise 19 demonstrates the difference between while and do-while loops.
• When constructing a loop always check what happens the first and last time through the loop.
• We will defer the discussion of recursion until we return to working with functions a bit later.
• For loops and more or repetition, repetition.
• The next homework program will use a while loop and the gas can problem will use a for loop. This is so we can start thinking about game programming... the one request from the midterm class survey.
• The conversion from a while loop with a counter to a for loop.
• Flags and continues and breaks are tools for stopping loops.
• Approaching the gas can problem for more than 1 can with a while loop and a flag variable
```int more = 1;
while (totalGallons < 55 && more) {
do-another-can
ask-if-more-cans
if (answer == 'N')
more = 0;
}
```
or using a break; statement
```while (totalGallons < 55) {
do-another-can
ask-if-more-cans
if (answer == 'N')
break;
}
```
• Using the continue statement to skip cans that are larger than the capacity left in the barrel.
• Notice that figure 6-22 reminds us that the 3rd part of a for statement where the loop variables are incremented is done after a continue statement.
• Again we note that the for loop really only improves the readability of your program when there are a known or calculable number of loop iterations.
• Exercises 16b and 17b and 20a and 26 and 27.
• Although 20b can be converted to a for loop, it would not be good C programming style.
• While converting 20a to a for loop we experiment with putting
```if (x == 5) continue;
```
in the for loop to skip printing the 5. Observe that this same statement would cause an infinite loop in the original while loop, because the x++; line is skipped.
• How to approach and implement and check a problem like 6.42
```// class exercise chapter 6, problem 42
#include <stdio.h>
int main()
{
int height;
int stars;
printf("enter the number of lines ==> ");
fflush(stdin);
scanf("%d", &height);
while (height > 0) {  // for homework change this to a for loop
stars = height * 2 - 1;
while (stars > 0) {
printf("*");
stars--;
}
printf("\n");
height--;
}
return 0;
}
```
You should be able to do problems similar to these.
• Think about Exercise 32, page 293 for next class
```for ( ; ; ) {
...
}
```
• A little about the library function rand() and Assignment 6. The storage for the next number to be returned by rand() is an example of a static rather than an automatic variable in a function. It is allocated and initialized, just one time at the beginning of program execution and not each time the function runs.

Tuesday, November 2nd

• The notions of arrays, pointers and address arithmetic form a braid rather than separate threads in C. Our text covers them in Chapters 8, 9 and 10. In our introductory course we will only be looking at the first 2 sections of each of those chapters.
• Consider the first 2 sections of Chapter 10 by looking at the folowing example
```int a = 7;               // 1 integer
int b = {2,4,6,8,10}; // an array of 5 integers
int *p = b;              // an address of, or pointer to, an integer
```
These statements reserve space for 6 integers • Several important points about this example
1. It is important to remember when a symbol represents a value and when it represents an address.
2. a is a symbol for the value stored there, which is 7.
3. &a is the address of the memory space that contains the integer 7.
4. *(&a) is again the value 7.
5. b is not a value but an address of the first of 5 integers.
6. b is a constant and cannot appear to the left of an "=".
7. p is an address that is a variable, in other words a pointer.
8. b is the value of the first integer.
9. b is equivalent to &b
10. b + 0 is equivalent to &b
11. b + 1 is equivalent to &b
12. *(b + 0) is equivalent to b
13. *(b + 1) is equivalent to b
14. *(p + 1) is equivalent to b
15. *p + 1 is equivalent to b + 1 because * is of higher precedence than +
16. after p++; then *(p + 1) is equivalent to b
17. Pointer notation should be part of your reading C vocabulary, but is not necessary for your writing C vocabulary.
• Think about what the following lines would do
```int a = 7,i;               // 1 integer
int b = {2,4,6,8,10}; // an array of 5 integers
int *p = b;              // an address of, or pointer to, an integer
for (i = 0;i < 5;i++,p++) {
b[i] = a + *(b + i) / 2;
printf("%d ",p);
}
```
• Translating the mathematics notation of sigma to a for loop
```/* ex6_51.c
estimating pi from a series
*/
#include <stdio.h>
#include <math.h>
main()
{
double pi;
int i;
double sigma = 0.0;
int n = 5;
for (i = 1;i <= n;i++) {
sigma = sigma + 1.0 / pow(i,2);
}
pi = sqrt(6 * sigma);
printf("After %d terms pi is %lf\n",n,pi);
return 0;
}
```
running this loop, we find the series converges slowly so that n = 1000 is reasonable.
• One dimensional arrays. Consider the symbol a
DeclarationMeaning
int a;The symbol a is an integer
int a();The symbol a is a function that returns an integer
int a[];The symbol a is the address of the first integer in an array of integers
int *a;The symbol a is an address of an integer (often termed a pointer to an integer)
• The key sections of chapter 8 are 1 and 2. Understand them. Some of the exercises to illustrate the points in these important sections
• Question 1 page 413 is true by the definition of a C array.
• Question 2 is true, consider
```int days_in_year,year;
int days = {365,366};

days_in_year =
days[year % 400 == 0 || year % 100 != 0 && year % 4 == 0];
```
• With Question 3, why not to initialize arrays like
```int stuff = {0}; // not portable with automatic variables
```
• Try 8 and 9.
• You should be able to answer Questions 16 to 18.
• Now retry problem 6-51 with an array, in a manner similar to problem 8-16
```/* ex6_51.c
estimating pi from a series
*/
#include <stdio.h>
#include <math.h>
#define TERMS 1000
main()
{
double pi;
int i;
double term[TERMS];
double sigma = 0.0;
for (i = 0;i < TERMS;i++) {
term[i] = 1.0 / pow(i + 1,2);
}
for (i = 0;i < TERMS;i++) {
sigma = sigma + term[i];
}
pi = sqrt(6 * sigma);
printf("After %d terms pi is %lf\n",TERMS,pi);
return 0;
}
```
This approach might be helpful in Homework Assignment 8.
• The for-each-member-of-an-array concept in C.

Tuesday, November 9th

• Thoughts on Homework Assignment 8
1. For an understanding of the Golden Ratio as found in nature and often imitated in engineering, Natural History, March 2003, by Mario Livio, pages 64-69.
2. The library function fabs() is helpful when a series is not either always increasing or always decreasing. Why not abs()?
```while (fabs(this_ratio - last_ratio) > precision) {
last_ratio = this_ratio
calculate this_ratio
}
```
3. To exchange 2 values use an intermediate value
```temp = val1;
val1 = val2;
val2 = temp;
```
To shift a series without using arrays, when shifting toward the left start from the left end
```second_last = last;
last = current;
calculate-current
```
not
```calculate-current
last = current;
second_last = last;
```
• This weeks topic is strings, Chapter 11. We discuss sections 11-1 and 11-2. We go over the examples in the text, but often use the common terms "counted string" for length-controlled string and "null terminated" for delimited string with a zero as the delimiter.
• Later, we will consider string related library functions.
• Be sure you understand what is happening in figure 11-10.
• Review Questions 1, 2 and 7a-e. For 7c we again note the difference between an array address and a pointer. Only the pointer can appear to the left of "=".
• Three lines of C that do exactly the same thing
1. `char greeting[] = "Hello";`
2. `char greeting[] = {'H','e','l','l','o','\0'};`
3. `char greeting[] = {72,101,108,108,111,0};`
4. and one slightly different
`char *greeting = "Hello";`
• An example of filling 2 arrays and using them with loops
```// arrays.c
// a class example of array intialization and use.
#include <stdio.h>
main()
{
int num;
char str[] = "hdjik";
int i;
for (i=0;i < 5;i++)
num[i] = i;
for (i=0;i < 5;i++)
str[i] += num[i];
printf("%s\n",str);
return 0;
}
```
• Consider two implementations of the library function strlen("hello")
 ```// with array notation int str_len(char *s) { int count = 0; while (s[count]) { count++; } return count; } ``` ```// with pointer notation int str_len(char *s) { int count = 0; while (*(s + count)) { count++; } return count; } ```
• The string.h library functions used to manipulate null terminated strings in C. This short discussion is not so much about how to use these functions, but how to avoid trouble when you have to use them.
• Some general points about sections 11-3 to 11-5
• When looking for help with the string manipulation (and other library functions), remember they are part of the C Runtime Library.
• To keep from making fatal mistakes when manipulating null terminated strings, you must keep in mind how the strings are physically stored in memory. As an example consider the array of string pointers in program 11-9 and the memory diagram in Figure 11-13.
• If you want to do extensive text processing don't use C. Use a language with counted strings.
• As we said earlier, strings are not data types in C and thus cannot be manipulated with the standard operators. In particular a = b (assignment) and a == b (equality) are not meaningful if a and b are strings.
• Consider the + operator. It does what you would expect with a + b if a and b are of type int or type double. It does not do what you want if a and b are null terminated strings. (In Python it will however.) So
```char a[] = "Hello, ";
char b[] = "World";
char buffer = "";
printf("%s\n",a + b); // will not work
printf("%s\n",strcat(a,b)); // may work and may crash your program
printf("%s\n",strcat(strcat(buffer,a),b)); // will work
sprintf(buffer,"%s%s Ver. %d",a,b,2);
printf("%s\n",buffer); // will also work and is more clear
```
• A buffer overflow is a malicious hacker's favorite tool.
• And some points about specific functions
• Use your old friends printf and scanf if at all possible.
• Occasionally, you will need sprintf or sscanf
• Never read in a string without a length limiter. You can do this with
```#define S_LEN 10
char str[S_LEN + 1];
scanf("%S_LENs",str);
```
or
```char str;
fgets(str,sizeof(str),stdin);
```
For this reason never use gets().
• fgets reads a line including embedded spaces and tabs and end of line characters. Remember it always leaves room for the terminating null character, so if you tried to read "0123456789\n" with the above example, the "\n" would be lost.
• Note strcmp is for sorts and therefore has a ternary not binary result of -1, 0 or 1.
• strcpy is only really helpful with dynamic memory allocation (in the next course)
```char *p;
p = (char *)malloc(strlen(str) + 1);
strcpy(p,str);
```
• strstr(string1,string2) is a function that tests if string2 is contained in string1. If true it returns a pointer to the place where string2 starts. If false it returns a null pointer. This is common, but idiomatic C that you should be aware of.
• More versions of strlen. For a program like
```int str_len(char *s);
int main()
{
char str[] = "hello";
printf("hello is %d characters long\n",str_len(str));
return 0;
}
```
we consider 3 versions of str_len (avoiding using the same name as the library function)
```int str_len(char *s)
{
int i = 0;
while(s[i++]) ;  // array subscript notation, like before
return i;
}

int str_len(char *s)
{
char *end = s;
while(*end++) ;  // pointer notation, a variation
return end - s;
}

int str_len(char *s)
{
if (*s)
return 1 + str_len(s + 1); // by recursion, a new method
else                        // mentioned in the chapter on
return 0;                  // loops as another form of repetition
}
```
• We will consider this recursion example next week.
• Quiz 3
• Some ideas about converting decimals to fractions in Assignment 7
```// eighths.c
#include <stdio.h>
#include <math.h>
main()
{
double measurement,fraction;
int whole,numerator,denominator = 8;
char buffer;
while (1) {
printf("Enter a measurement as a decimal fraction for conversion\n");
printf("                         (or 0 to quit this program) ==> ");
scanf("%lf",&measurement);
if (measurement == 0.0) {
printf("Goodbye\n");
break;
}
whole = measurement;
// what about negative measurements ?
fraction = fabs(measurement - whole);
// round to nearest something by adding half a something first
fraction += 1.0 / 8 / 2;
numerator = fraction / (1.0 / 8);
// reduce the fractions
if (numerator % 4 == 0) {
numerator /= 4;
denominator /= 4;
}
if (numerator % 2 == 0) {
numerator /= 2;
denominator /= 2;
}
// using sprintf for nicer printing
if (numerator)
sprintf(buffer,"%d/%d",numerator,denominator);
else
sprintf(buffer,"even");
printf("The number to the nearest eighth is %d %s\n",whole,buffer);
}
return 0;
}
```

Tuesday, November 16th

• Review of Quiz 3
• To see what a loop does, look at the first and last time through the loop.
• The technique of using a loop to do something to each member of an array is very important.
• The difference between integer and floating point division, from the first few weeks, is still important.
• This course, and programming in general, is not about learning a set of separate tricks, but about developing a cumulative skill.
• ASCII and arrays, yet again
```char c,carray;
char *p;
int i;
```
let us consider this loop
```for (c = 'a';c <= 'z';c++) printf("%c",c);
```
and then
```for (i = 0;i < 26;i++) carray[i] = i + 'a';
```
or
```for (p = carray,c = 'a';c <= 'z';p++,c++) *p = c;
```
and then
```for (i = 0;i < 26;i++) printf("%c",carray[i]);
```
and then
```carray = 0;
printf("%s",carray);
```
• Choosing arrays or discrete variables for a series problem like Homework Assignment 8?
Without ArraysWith Arrays
uses less memoryuses more memory
shifting to reuse memoryno shifting
code interdependentcode more modular
no array boundariesarray boundaries need checking
```int n = 20;
int prev_term = 1;
int curr_term = 1;
int next_term;
int terms = 3; // term 1 and term 2 are given
printf("%d %d ",prev_term,curr_term);
while (terms <= n) {
next_term = prev_term + curr_term;
printf("%d ",next_term);
// advance to next term in series
terms++;
prev_term = curr_term;  // to shift left,
curr_term = next_term;  // start from the left
}
```
```int n = 20;
int term,terms=0;
term[terms] = 1;
terms++;
term[terms] = 1;
terms++;
// added safety clause to condition
while (terms < n && terms < 1000) {
term[terms] = term[terms - 2] + term[terms - 1];
terms++;
}
for (terms = 0;terms < n;terms++) {
printf("%d ",term[terms]);
}
```
• Other thoughts about Homework Assignment 8
1. ```/* precision.c
exercise 51 from chapter 6 revisited
calculating pi
*/
#include <stdio.h>
#include <math.h>
main()
{
double pi, old_pi;
int i = 1;
double sigma = 0.0;
double delta = 1.0;
double precision = 0.0001;
// a while loop this time since we don't know how
// many terms it will take
while (delta > precision) {
sigma = sigma + 1.0 / pow(i,2);
pi = sqrt(6 * sigma);
// many series do not continually increase
// abs() returns an integer
// you also could say:
// delta = pi - old_pi;
// delta = (delta < 0) ? delta * -1.0 : delta;
delta = fabs(pi - old_pi);
old_pi = pi;
i++;
}
printf("After %d terms pi is %lf\n",i,pi);
// this time measure against the constant M_PI
sigma = 0.0;
delta = 1.0;
i = 1;
while (delta > precision) {
sigma = sigma + 1.0 / pow(i,2);
pi = sqrt(6 * sigma);
delta = fabs(pi - M_PI);
i++;
}
printf("After %d terms pi is %lf\n",i,pi);
getchar();
return 0;
}
```
2. float will not give 10 decimal places. Use double
3. The default %lf usually gives .dddddd Use %.10lf
4. Do not use a for loop and do not use the number the user enters for the precision as the number of terms in the series
• Text files, Chapter 7
• This week we look more closely at text files. We have used files all along with printf and scanf. printf("format",... is shorthand for fprintf(stdout,"format",... and scanf("format",... is shorthand for fscanf(stdin,"format",...
• stdin and stdout are pointers to FILE structures that keep track of your place in input and output streams of characters. We have manipulated them before with fflush(stdin).
• All stream variables, like all variables in C, have to be declared. For stdin and stdout (and stderr) this is done in stdio.h.
• All streams need to be initialized or opened. stdin and stdout are opened automatically.
• Refer to the C Phrase Book handout for help in getting started using files.
• To work with a disk file you need a FILE type of variable. The FILE variable is a complex data structure with many items of information, including the location of the file on the disk and a bookmark showing your current place in the file. The notation FILE *infile means that infile is an address and the * operator says that the contents of that address is a FILE variable. Usually, in the idiom of C and similar languages, you would say that infile is a "pointer" to a FILE type variable.
• Before you can use a file you must open it
```infile = fopen("c:\\mcs1142\\numbers.txt","r");
```
Notice we needed to use \\ to mean \ between quotes.
• If the file opening fails, it's user friendly to say why. For this you can use the perror function.
• To abort in case of an error, you can simply use
```return 1; // return 0 in main() means there were 0 errors
```
But this is more complicated when we start using our own functions. So we will get used to using
```#include <stdlib.h>
exit(1);
```
• The stdio.h functions usually return a value. We have not used this much before. Consider a case where it is important to test that the number of integers we are reading in is not more than we have saved space for.
• Remember scanf and fscanf can return a 0 if no valid items are found (e.g. if a comma was placed between the numbers in our text file). You can try scanning as long as fscanf != EOF. It is probably safer to read as long as fscanf > 0, in case your input file is not perfect.
• A reminder of these points is on the C Style Web page.
• Problem 7-20, page 346
```// prob7_20.c
#include <stdio.h>
main()
{
FILE *fp;
int i;
char ch;
fp = fopen("c:\\mcs1142\\test.dat","w");
for (i = 2;i < 20;i += 2)
fprintf(fp,"%3d",i);
fclose(fp);
fp = fopen("c:\\mcs1142\\test.dat","r");
while ((ch = fgetc(fp)) != EOF)
if (ch == ' ')
fputc('*',stdout);
else if (ch != '1')
fputc(ch,stdout);
else {
putchar('\n');
putchar(ch);
}
return 0;
}
```
• Thinking about the extra credit problems
• A LTU2002 program to put the first 10 integers into memory, as a start on the extra credit LTU2002 Fibonacci problem
```  loadai 1
stora num
loadbi array
loop:
loada num
storax 0
addai 1
stora num
addbi 1
suba max
brnz loop
halt
num: 0
max: 11
array: 0
```
• Few tried a user function on Homework Assignment 6, so we try Problem 26 (page 584), a user function to chop the last character from a string
```char * our_chop(char *p)
{
int i = 0;
while (p[i])i++; // first go to the end of the string
if (i > 0) i--;  // go back 1 if p was not an empty string
p[i] = 0;
return p;
}

char * our_chop_v2(char *p)
{
// a version using the library function strlen
if (strlen(p)) p[strlen(p) - 1] = 0;
return p;
}
```
This later version might be a template for the extra credit problem on centering a string.

Tuesday, November 23rd

• Bitwise operators, Chapter 15
• To this point we have considered all input to come from the keyboard or from a file, and all output to be to the screen or to a file. The smallest unit in these transactions has been the byte, a group of 8 bits.
• A large number of programs have their input from an analog reference voltage or output an analog voltage or both. The smallest unit in these transactions is a single bit. With 1 bit we can represent or control either the full reference voltage or 0. With a group of 4 bits we can control or represent 16 different portions of the full reference voltage.
• There are really only 4 things to do with a single bit
1. Read it, see if it is 1 or 0
2. Set it, make it 1
3. Clear it, make it 0
4. Toggle it, if 1 make it 0, if 0 make it 1
• Each of these tasks on a single bit, or on a group of bits, is done by creating a mask and then using that mask to select the bits for reading or altering by the bitwise operators |, &, ^, >>, << and ~.
• The bitwise operators are like their corresponding logical operators in that they return either 1 or 0. The bitwise operators are like their corresponding arithmetic operators but there is no carry or borrow from the bit on the left.
Bitwise operatorLogical OperatorArithmetic Operator
|||+
&&&*
^

~!-(unary)
• A table of the values returned by |, &, ^ and ~  0 | 0 = 0 0 | 1 = 1 1 | 0 = 1 1 | 1 = 1 0 & 0 = 0 0 & 1 = 0 1 & 0 = 0 1 & 1 = 1 0 ^ 0 = 0 0 ^ 1 = 1 1 ^ 0 = 1 1 ^ 1 = 0 ~0 = 1 ~1 = 0
• The technique of masking, or selecting specific bits and leaving the rest alone:
1. The mask to Read bits has 1 in the corresponding bits and the rest 0. It is applied with the & operator.
2. The mask to Set bits has 1 in the corresponding bits and the rest 0. It is applied with the | operator.
3. The mask to Clear bits has 0 in the corresponding bits and the rest 1. It is applied with the & operator. The mask is made by applying the ~ operator to a mask that has 1 in the corresponding bits and the rest 0.
4. The mask to Toggle bits has 1 in the corresponding bits and the rest 0. It is applied with the ^ operator.
• >> is a logical shift, not an arithmetic shift. That is, the leftmost bits are filled in with 0 and not with the sign bit.
• << is a logical shift, not a logical rotation. That is, the rightmost bits are filled with 0 and not with the bit rotated or shifted out at the left.
• Section 15-2 mentions the uses of the shift operators to do arithmetic operations. This should generally be avoided. At least wait until you take further classes, like Dr. Bindschadler's assembly language class. Dividing a negative integer by 2 using a right shift is an example of a potentially bad idea in C.
• Section 15-3 has a non-portable example of converting to upper case letters. Perhaps we could do better?
```lc_letter & ~('A' ^ 'a') // more portable way to force uppercase
```
• Try evaluating 'b' & ~('A' ^ 'a'). Is it 'B' as expected. What would 'B' | ('A' ^ 'a') evaluate to?
• The bitwise operations in NotQuiteC on the Mindstorms Robot platform
```task main()
{
/*
this is for a 4 wheel autonomous robot with
motor A driving the left rear wheel and
motor C driving the right rear wheel
*/
SetPower(OUT_A+OUT_C,2);  // power or speed 2 / 7 or slow
OnFwd(OUT_A+OUT_C);       // start going forward
Wait(400);                // wait 4 seconds
OnRev(OUT_A+OUT_C);       // start going backwards
Wait(400);                // wait 4 seconds
Off(OUT_A+OUT_C);         // stop
}
```
Motors A, B and C are each controlled by a separate bit. The symbolic constants OUT_A, OUT_B and OUT_C are separate powers of 2 so that they can be combined by using + or |.
• Problems 15.7 to 15.15 pages 778-779.
• Problems 15.16 and 15.17 on page 779. We can do any of these by using the same stepwise approach
1. Decide which operations are done first by referring to the precedence table inside the front cover.
2. If precedences are the same decide using the direction of associativity from the same table.
3. Convert from decimal to hexadecimal using the ASCII table in Appendix A.
4. Convert from hexadecimal to binary using Table D-1 on page 801.
5. Do the bitwise operations.
6. Convert back to hexadecimal and then to decimal.
• Problem 15.17b as an 8 bit number and as a 16 bit number.
• Problem 15.17c.
• Problems 15.19 and 15.24.
• There will be a problem like those from 15.18 to 15.28 (page 779) for Quiz 4 or the final exam.
• The arithmetic of 15a
```24        to hexadecimal by the ASCII table
18 to binary from table D-1
0001 1000 1's complement with ~
1110 0111 to hexadecimal with ASCII table
E7        by subtraction
77 + 70   to decimal from the ASCII table
119 + 112 by addition
231
or converting by positional values
E7  = 14 * 16^1 + 7 * 16^0
231 = 224 + 7
```
Because printf uses long signed integers, a cast is needed to demonstrate this in C
```\$ cat p15abcd.c
// p15abcd.c
#include <stdio.h>
main()
{
unsigned char a=24,b=123,c=67,d=4;
printf("%d is ~%d, %d is ~%d, %d is ~%d, %d is ~%d\n",
(unsigned char)~a,a,
(unsigned char)~b,b,
(unsigned char)~c,c,
(unsigned char)~d,d);
return 0;
}
\$ ./p15abcd.exe
231 is ~24, 132 is ~123, 188 is ~67, 251 is ~4
```

Tuesday, November 30th

• Two thoughts about Homework Assignment 9
1. Sometimes it is easier to write and test the second part of a program before writing the first part. Suppose we already had a file of numbers (or could quickly make one in NotePad) and we wanted to find the average of those numbers.
```// a9part2.c
#include <stdio.h>
#include <stdlib.h>
main()
{
double sum,avg;
int i,n,array;
FILE *infile;
infile = fopen("c:\\mcs1142\\numbers.txt","r");
if (!infile) {
perror("The input file was not opened because");
exit(1);
}
i = 0;
while(i < 1000 && fscanf(infile,"%lf",&array[i]) > 0)
i++;
n = i;
for (i = 0,sum = 0.0;i < n;i++) sum += array[i];
avg = sum / n;
printf("The average of %d numbers is %.2lf\n",n,avg);
return(0);
}
```
2. Perl, Python and Ruby handle text files easily. Consider both halves of this assignment in Perl
```# a9.pl Somewhat idiomatic Perl answer to Homework Assignemt 9
sub rand_1_10 { # a user function
return int(rand(10)) + 1;  # in Perl srand is automatically called
}
print 'How many random integers? (1-1000) ==> '; # ask for N
chop(\$n = <>); # discard newline from pressing "Enter"
die "\$n is not between 1 and 1000" if (\$n < 1 or \$n > 1000);
for (1..\$n) { push @r,&rand_1_10; } # foreach loop on a range
open TEXTFILE, ">numbers.txt" or die "Can't open intermediate file";
print TEXTFILE join " ",@r;
close TEXTFILE;
open TEXTFILE, "numbers.txt" or die "Can't re-open intermediate file";
(\$lines) = <TEXTFILE>; # read all the lines into a list of 1 line
@nums = split " ",\$lines; # reparse file as numbers separated by whitespace
\$sum = 0;
for \$r (@nums) { \$sum += \$r; } # another foreach loop
\$n = scalar @nums; # scalar @array is the length of the array
printf "\nFile contains %d numbers with an average of %.2f",\$n,\$sum/\$n;
```
• A general discussion of platforms beyond the command line
• The Web and the CGI interface. Learn a little HTML! Assignment 6 as a Perl backed Web site.
• Windows and the message loop. The "Hello, World" program in C is a little over 75 lines. Frameworks are groups of structures and functions that make repetitive tasks like Windows programming easier. Visual C++ has MFC and C++ Builder has VCL. Tk is another framework but is easier to use than MFC or VCL. Tk works with C, Perl, Python, Ruby and many others. Tk works on Windows and on Unix and Mac windows as well. An example with Python in interactive mode.
```from Tkinter import *
mainWindow = Tk()
mainWindow.title('Hello from Tk')
widget = Label(text='Hello, World')
widget.pack(side=TOP,expand=YES,fill=BOTH)
mainWindow.mainloop()
```
• Robotics and a "realtime" OS.
• Quiz 4.

Tuesday, December 7th

• Review of Quiz 4. Sample answers
1. ```char str1 = "#Ifmmp-!Xpsme\"#";
int i;
for (i = 0;str1[i];i++)
fprintf(stdout,"%c",str1[i] - 1);
```
2. ```FILE *quiz4;
float sum = 0.0;
float num;
int i;
quiz4 = fopen("c:\\mcs1142\\quiz4_2.txt","r");
for (i = 0;i < 5;i++)
fscanf(quiz4,"%f",&num[i]);
for (i = 0;i < 5;i++)
sum += num[i];
printf("\n%.2f is the average\n",sum / 5.0);
```
3. ```/*Array.c*/
#include<stdio.h>
main()
{

int i;
char alpha;
/*alpha-alpha*/

for (i=0; i < 26;i++)
alpha[i] ='a' + i;

for (i=0; i < 26;i++)
printf("%c",alpha [i]);

printf("\n");

for (i=25; i >= 0;i--)
printf("%c",alpha [i]);
for (i=0; i < 26;i++)
alpha[i] = alpha[i] &~('a' ^ 'A');

alpha = 0;
printf("\n%s\n",alpha);
return 0;
}

C:\mcs1142>edit array.c

C:\mcs1142>cl array.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

array.c
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:array.exe
array.obj

C:\mcs1142>array.exe
abcdefghijklmnopqrstuvwxyz
zyxwvutsrqponmlkjihgfedcba
ABCDEFGHIJKLMNOPQRSTUVWXYZ
```
• General review
• Leveraging your C knowledge after Intro to C
• Your own library of subroutines.
• Your own data types.
• On to C++ in CS1,2,3.
• The GNU compiler suite.
• Scripting languages descended from C.
• For the final be sure you understand Quizes 1 through 4 and can do the Homework Assignments through Assignment 9.

Final Exam, Tuesday December 14th

Revised December 8, 2004