CMPE-13/L: COMPUTER SYSTEMS AND C PROGRAMMING WINTER 2015

Size: px
Start display at page:

Download "CMPE-13/L: COMPUTER SYSTEMS AND C PROGRAMMING WINTER 2015"

Transcription

1 UNIVERSITY OF CALIFORNIA, SANTA CRUZ BOARD OF STUDIES IN COMPUTER ENGINEERING CMPE-13/L: COMPUTER SYSTEMS AND C PROGRAMMING WINTER 2015 NOTES TO ACCOMPANY THE C PROGRAMMING LANGUAGE, BY KERNIGHAN AND RITCHIE ( K&R ) Chapter 4: Functions and Program Structure BY STEVE SUMMIT Page 67: Deep sentence: Functions break large computing tasks into smaller ones, and enable people to build on what others have done instead of starting over from scratch. Appropriate functions hide details of operation from parts of the program that don t need to know about them, thus clarifying the whole, and easing the pain of making changes. Functions are probably the most import weapon in our battle against software complexity. You ll want to learn when it s appropriate to break processing out into functions (and also when it s not), and how to set up function interfaces to best achieve the qualities mentioned above: reuseability, information hiding, clarity, and maintainability. The quoted sentences above show that a function does more than just save typing: a well-defined function can be re-used later, and eases the mental burden of thinking about a complex program by freeing us from having to worry about all of it at once. For a well-designed function, at any one time, we should either have to think about: 1. that function s internal implementation (when we re writing or maintaining it); or 2. a particular call to the function (when we re working with code which uses it). But we should not have to think about the internals when we re calling it, or about the callers when we re implementing the internals. (We should perhaps think about the callers just enough to ensure that the function we re designing will be easy to call, and that we aren t accidentally setting up so that callers will have to think about any internal details.) Sometimes, we ll write a function which we only call once, just because breaking it out into a function makes things clearer and easier. Deep sentence: C has been designed to make functions efficient and easy to use; C programs generally consist of many small functions rather than a few big ones. Some people worry about function call overhead, that is, the work that a computer has to do to set up and return from a function call, as opposed to simply doing the function s statements in-line. It s a risky thing to worry about, though, because as soon as you start worrying about it, you have a bit of a disincentive to use functions. If you re reluctant to use functions, your programs will probably be bigger and more complicated and harder to maintain (and perhaps, for various reasons, actually less efficient).

2 The authors choose not to get involved with the system-specific aspects of separate compilation, but we ll take a stab at it here. We ll cover two possibilities, depending on whether you re using a traditional command-line compiler or a newer integrated development environment (IDE) or other graphical user interface (GUI) compiler. When using a command-line compiler, there are usually two main steps involved in building an executable program from one or more source files. First, each source file is compiled, resulting in an object file containing the machine instructions (generated by the compiler) corresponding to the code in that source file. Second, the various object files are linked together, with each other and with libraries containing code for functions which you did not write (such as printf), to produce a final, executable program. Under Unix, the cc command can perform one or both steps. So far, we ve been using extremely simple invocations of cc such as cc hello.c (section 1.1, page 6). This invocation compiles a single source file, links it, and places the executable (somewhat inconveniently) in a file named a.out. Suppose we have a program which we re trying to build from three separate source files, x.c, y.c, and z.c. We could compile all three of them, and link them together, all at once, with the command cc x.c y.c z.c (see also page 70). Alternatively, we could compile them separately: the -c option to cc tells it to compile only, but not to link. Instead of building an executable, it merely creates an object file, with a name ending in.o, for each source file compiled. So the three commands cc -c x.c cc -c y.c cc -c y.c would compile x.c, y.c, and z.c and create object files x.o, y.o, and z.o. Then, the three object files could be linked together using cc x.o y.o z.o When the cc command is given an.o file, it knows that it does not have to compile it (it s an object file, already compiled); it just sends it through to the link process. Here we begin to see one of the advantages of separate compilation: if we later make a change to y.c, only it will need recompiling. (At some point you may want to learn about a program called make, which keeps track of which parts need recompiling and issues the appropriate commands for you.) Above we mentioned that the second, linking step also involves pulling in library functions. Normally, the functions from the Standard C library are linked in automatically. Occasionally, you must request a library manually; one common situation under Unix is that certain math routines are in a separate math library, which is requested by using -lm on the command line. Since the libraries must

3 typically be searched after your program s own object files are linked (so that the linker knows which library functions your program uses), any -l option must appear after the names of your files on the command line. For example, to link the object file mymath.o (previously compiled with cc -c mymath.c) together with the math library, you might use cc mymath.o lm Two final notes on the Unix cc command: if you re tired of using the nonsense name a.out for all of your programs, you can use -o to give another name to the output (executable) file: cc -o hello hello.c would create an executable file named hello, not a.out. Finally, everything we ve said about cc also applies to most other Unix C compilers. Many of you will be using acc (a semistandard name for a version of cc which does accept ANSI Standard C) or gcc (the FSF s GNU C Compiler, which also accepts ANSI C and is free). There are command-line compilers for MS-DOS systems which work similarly. For example, the Microsoft C compiler comes with a CL ( compile and link ) command, which works almost the same as Unix cc. You can compile and link in one step: cl hello.c or you can compile only: cl /c hello.c creating an object file named hello.obj which you can link later. The preceding has all been about command-line compilers. If you re using some kind of integrated development environment, such as Turbo C or the Microsoft Programmer s Workbench or Think C, most of the mechanical details are taken care of for you. (There s also less I can say here about these environments, because they re all different.) Typically there s a way to specify the list of files (modules) which make up your project, and a single build button which does whatever s required to build (and perhaps even execute) your program. Section 4.1: Basics of Functions Page 68: Once again, notice how a clear, simple description of the problem we re trying to solve leads to an (almost) equally clear program implementing it. Here are some more nice statements about the virtues of a clean, modular design: Although it s certainly possible to put the code for all of this in main, a better way is to use the structure to advantage by making each part a separate function. Three small pieces are easier to deal with than one big one, because irrelevant details can be buried in the functions, and the chance of unwanted interactions is minimized. And the pieces may even be useful in other programs.

4 Let s say a bit more about how and why functions can be useful. First, we can see that, having chosen to use a separate function for each part of the print-matching-lines program, the top-level main routine on page 69 is particularly simple and straightforward; it s little more than a transcription into C of the pseudocode on page 68. The authors don t tend to use too many comments in their code, anyway, but this code hardly needs any: the names of the functions called speak for themselves. (The only thing that might not be obvious at first is that strindex is being used not so much to find the index of a substring but just to determine whether a substring is present at all.) Second, we may be pleased to notice that we re already having a chance to re-use the getline function we first wrote in Chapter 1. Third, we note that the two functions which we ve chosen to use (getline and strindex) are themselves reasonably simple and straightforward to write. Finally, note that sometimes what you re-use is not so much a function as a function interface. The code on page 69 uses a new implementation of getline, but the interface (the argument list, return value, and functionality) is the same as for the versions of getline in section 1.9 on page 29. We could have used that version here, or this new version there. Later, if we think of some even better way of reading lines, we can write yet another version of getline, and as long as it has the same interface, these programs can call it without their having to be rewritten. The ease with which a program like this comes together may be mildly deceptive, because nowhere have we discussed the the motivations which led to the particular pseudocode description on page 68 or the particular definitions of the functions which were chosen to break the problem down into. Choosing a design for a program, and defining subfunctions (their interfaces and their behavior) are both arts, and of course the tasks are not unrelated. A good design leads to the invention of functions which might well be useful later, and an existing body of good, general-purpose functions (all crying out to be re-used) can help to guide the design of the next program. What makes a good building block, either an abstract one that we use in a pseudocode description, or a concrete one in the form of a general-purpose function? The most important aspect of a good building block is that have a single, well-defined task to perform. Two of the three functions used in the line-matching program fill this role very well: getline s job is to read one line, and strindex es job is to find one string in another string. printf s specification is considerably broader: its job is to print stuff. (It s not surprising that printf can therefore be the harder routine to call, and is certainly much harder to implement. Its saving virtue is that it is nonetheless broadly applicable and infinitely reusable.) When you find that a program is hard to manage, it s often because if has not been designed and broken up into functions cleanly. Two obvious reasons for moving code down into a function are because: 1. It appeared in the main program several times, such that by making it a function, it can be written just once, and the several places where it used to appear can be replaced with calls to the new function. 2. The main program was getting too big, so it could be made (presumably) smaller and more manageable by lopping part of it off and making it a function. These two reasons are important, and they represent significant benefits of well-chosen functions, but they are not sufficient to automatically identify a good function. A good function has at least these two additional attributes: 3. It does just one well-defined task, and does it well.

5 4. Its interface to the rest of the program is clean and narrow. Attribute 3 is just a restatement of something we said above. Attribute 4 says that you shouldn t have to keep track of too many things when calling a function. If you know what a function is supposed to do, and if its task is simple and well-defined, there should be just a few pieces of information you have to give it to act upon, and one or just a few pieces of information which it returns to you when it s done. If you find yourself having to pass lots and lots of information to a function, or remember details of its internal implementation to make sure that it will work properly this time, it s often a sign that the function is not sufficiently well-defined. (It may be an arbitrary chunk of code that was ripped out of a main program that was getting too big, such that it essentially has to have access to all of that main function s variables.) The whole point of breaking a program up into functions is so that you don t have to think about the entire program at once; ideally, you can think about just one function at a time. A good function is a black box : when you call it, you only have to know what it does (not how it does it); and when you re writing it, you only have to know what it s supposed to do (and you don t have to know why or under what circumstances its caller will be calling it). Some functions may be hard to write (if they have a hard job to do, or if it s hard to make them do it truly well), but that difficulty should be compartmentalized along with the function itself. Once you ve written a hard function, you should be able to sit back and relax and watch it do that hard work on call from the rest of your program. If you find that difficulties pervade a program, that the hard parts can t be buried inside black-box functions and then forgotten about, if you find that there are hard parts which involve complicated interactions among multiple functions, then the program probably needs redesigning. For the purposes of explanation, we ve been seeming to talk so far only about main programs and the functions they call and the rationale behind moving some piece of code down out of a main program into a function. But in reality, there s obviously no need to restrict ourselves to a two-tier scheme. The main program, main(), is itself just a function, and any function we find ourself writing will often be appropriately written in terms of sub-functions, sub-sub-functions, etc. That s probably enough for now about functions in general. Here are a few more notes about the line-matching program. The authors mention that The standard library provides a function strstr that is similar to strindex, except that it returns a pointer instead of an index. We haven t met pointers yet (they re in chapter 5), so we aren t quite in a position to appreciate the difference between an index and a pointer. Generally, an index is a small number referring to some element of an array. A pointer is more general: it can point to any data object of a particular type, whether it s one element of an array, or some other object anywhere in memory. (Don t worry too much about the distinction yet, but bear in mind that there is a distinction. Note, too, that the distinction is not absolute; in fact, the word index seems to derive from the concept of pointing, as you can see if you think about what you use your index finger for, or if you notice that the entries in a book s index point at the referenced parts of the book. We frequently speak casually of an index variable pointing at some cell of an array, even though it s not a true pointer variable.) One facet of the getline function s interface might bear mentioning: its first argument, the character array s, is being used to return the line that it reads. This may seem to contradict the rule that a function

6 can never modify the value of a variable in its caller. As was briefly mentioned on page 28, there s an exception for arrays, which well be learning about in chapter 5; for now, we ll gloss over the point. (Actually, we re glossing over two points: not only is getline able to return a value via an argument, but the argument isn t really an array, although it s declared as and looks like one. Please forgive these gentle fictions; explaining them completely would really be premature at this point. Perhaps they weren t worth mentioning yet, after all.) For comparison, here is yet another version of getline: int getline(char s[], int lim) { int c, i = 0; while(--lim > 0 && (c=getchar())!= EOF) { s[i++] = c; if(c == \n ) break; } s[i] = \0 ; } return i; Note that by using break, we avoid having to test for \n in two different places. If you re having trouble seeing how the strindex function works, its algorithm is for (each position i in s) if (t occurs at position i in s) return i; (else) return -1; Filling in the details of if (t occurs at position i in s), we have: for (each position i in s) for (each character in t) if (it matches the corresponding character in s) if (it s \0 ) return i; else keep going else no match at position i (else) return -1; A slightly less compressed implementation than the one on page 69 would be: int strindex(char s[], char t[]) { int i, j, k; for (i = 0; s[i]!= \0 ; i++) { for(j = i, k = 0; t[k]!= \0 ; j++, k++) if(s[j]!= t[k]) break; } if(t[k] == \0 ) return i;

7 } return -1; Note that we have to check for the end of the string t twice: once to see if we re at the end of it in the innermost loop, and again to see why we terminated the innermost loop. (If we terminated the innermost loop because we reached the end of t, we found a match; otherwise, we didn t.) We could rearrange things to remove the duplicated test: int strindex(char s[], char t[]) { int i, j, k; for (i = 0; s[i]!= \0 ; i++) { j = i; k = 0; } do { if(t[k] == \0 ) return i; } while(s[j++] == t[k++]); } return -1; It s a matter of style which implementation of strindex is preferable; it s impossible to say which is best. (Can you see a slight difference in the behavior of the version on page 69 versus the two here? Under what circumstance(s) would this difference be significant? How would the version on page 69 behave under those circumstances, and how would the two routines here behave?) Page 70: Deep sentence: A program is just a set of definitions of variables and functions. This sentence may or may not seem deep, and it may or may not be deep, but it s a fundamental definition of what a C program is. Note that a function s return value is automatically converted to the return type of the function, if necessary, just as in assignments like f = i; where f is float and i is int. Most programmers do use parentheses around the expression in a return statement, because that way it looks more like while(), for(), etc. The reason the parentheses are optional is that the formal syntax is return expression ; and, as we know, any expression surrounded by parentheses is another expression. It s debatable whether it s not illegal for a function to have return statements with and without values. It s a sign of trouble at best, and undefined at worst. Another clear sign of trouble (which is

8 equally undefined) is when a function returns no value, or is declared as void, but a caller attempts to use the return value. The main program on page 69 returns the number of matching lines found. This is probably better than returning nothing, but the convention is usually that a C program returns 0 when it succeeds and a positive number when it fails. Section 4.2: Functions Returning Non-Integers Page 71: Actually, we may have seen at least one function returning a non-integer, in the Fahrenheit- Celsius conversion program in exercise 1-15 on page 27 in Section 1.7. The type name which precedes the name of a function (and which sets its return type) looks just like (i.e. is syntactically the same as) the void keyword we ve been using to identify functions which don t return a value. Note that the version of atof on page 71 does not handle exponential notation like 1.23e45; handling exponents is left for exercise 4-2 on page 73. The standard library includes an atof means that we re reimplementing something which would otherwise be provided for us anyway (i.e. just like printf). In general, it s a bad idea to rewrite standard library routines, because by doing so you negate the advantage of having someone else write them for you, and also because the compiler or linker are allowed to complain if you redefine a standard routine. (On the other hand, seeing how the standard library routines are implemented can be a good learning experience.) Page 72: In the primitive calculator code at the top of page 72, note that the call to atof is buried in the argument list of the call to printf. Deep sentences: The function atof must be declared and defined consistently. If atof itself and the call to it in main have inconsistent types in the same source file, the error will be detected by the compiler. But if (as is more likely) atof were compiled separately, the mismatch would not be detected, atof would return a double that main would treat as an int, and meaningless answers would result. The problems of mismatched function declarations are somewhat reduced today by the widespread use of ANSI function prototypes, but they re still important to be aware of. The implicit function declarations mentioned at the bottom of page 72 are an older feature of the language. They were handy back in the days when most functions returned int and function prototypes hadn t been invented yet, but today, if you want to use prototypes, you won t want to rely on implicit declarations. If you don t like depending on defaults and implicit declarations, or if you do want to use function prototypes religiously, you re under no compunction to make use of (or even learn about) implicit function declarations, and you ll want to configure your compiler so that it will warn you if you call a function which does not have an explicit, prototyped declaration in scope. You may wonder why the compiler is able to get some things right (such as implicit conversions between integers and floating-point within expressions) whether or not you re explicit about your

9 intentions, while in other circumstances (such as while calling functions returning non-integers) you must be explicit. The question of when to be explicit and when to rely on the compiler hinges on several questions: 1. How much information does the compiler have available to it? 2. How likely is it that the compiler will infer the right action? 3. How likely is it that a mistake which you the programmer might make will be caught by the compiler, or silently compiled into incorrect code? It s fine to depend on things like implicit conversions as long as the compiler has all the information it needs to get them right, unambiguously. (Relying on implicit conversions can make code cleaner, clearer, and easier to maintain.) Relying on implicit declarations, however, is discouraged, for several reasons. First, there are generally fewer declarations than expressions in a program, so the impact (i.e. work) of making them all explicit is less. Second, thinking about declarations is good discipline, and requiring that everything normally be declared explicitly can let the compiler catch a number of errors for you (such as misspelled functions or variables). Finally, since the compiler only compiles one source file at a time, it is never able to detect inconsistencies between files (such as a function or variable declared one way in once source file and some other way in another), so it s important that cross-file declarations be explicit and consistent. (Various strategies, such as placing common declarations in header files so that they can be #included wherever they re needed, and requesting that the compiler warn about function calls without prototypes in scope, can help to reduce the number of errors having to do with improper declarations.) For the most part, you can also ignore the old style function syntax, which hardly anyone is using any more. The only thing to watch out for is that an empty set of parentheses in a function declaration is an old-style declaration and means unspecified arguments, not no arguments. To declare a newstyle function taking no arguments, you must include the keyword void between the parentheses, which makes the lack of arguments explicit. (A declaration like int f(void); does not declare a function accepting one argument of type void, which would be meaningless, since the definition of type void is that it is a type with no values. Instead, as a special case, a single, unnamed parameter of type void indicates that a function takes no arguments.) For example, the definition of the getchar function might look like int getchar(void) { int c; } read next character into c somehow if (no next character) return EOF; return c; Page 73: Note that this version of atoi, written in terms of atof, has very slightly different behavior: it reads past a. (and, assuming a fully-functional version of atof, an e ).

10 The use of an explicit cast when returning a floating-point expression from a routine declared as returning int represents another point on the spectrum of what you should worry about explicitly versus what you should feel comfortable making use of implicitly. This is a case where the compiler can do the right thing safely and unambiguously, as long as what you said (in this case, to return a floating-point expression from a routine declared as returning int) is in fact what you meant. But since the real possibility exists that discarding the fractional part is not what you meant, some compilers will warn you about it. Typically, compilers which warn about such things can be quieted by using an explicit cast; the explicit cast (even though it appears to ask for the same conversion that would have happened implicitly) serves to silence the warning. (In general, it s best to silence spurious warnings rather than just ignoring them. If you get in the habit of ignoring them, sooner or later you ll overlook a significant one that you would have cared about.) Section 4.3: External Variables The word external is, roughly speaking, equivalent to global. Page 74: A program with too many data connections between functions hasn t managed to achieve the desirable attributes we were talking about earlier, in particular that a function s interface to the rest of the program is clean and narrow. Another bit of jargon you may hear is the word coupling, which refers to how much one piece of a program has to know about another. In general, as we have mentioned, the connections between functions should generally be few and well-defined, in which case they will be amenable to regular old function arguments, and you won t be tempted to pass lots of data around in global variables. (On the other hand, global variables are fine for some things, such as configuration information which the whole program cares about and which is set just once at program startup and then doesn t change.) The word lifetime refers to how long a variable and its value stick around. (The jargon term is duration. ) So far, we ve seen that global variables persist for the life of the program, while local variables last only as long as the functions defining them are active. However, lifetime (duration) is a separate and orthogonal concept from scope; we ll soon be meeting local variables which persist for the life of the program. Deep sentence: Thus if two functions must share some data, yet neither calls the other, it is often most convenient if the shared data is kept in external variables rather than passed in and out via arguments. (Later, though, we ll learn about data structures which can make it more convenient to pass certain data around via function arguments, so we ll have less reason for using external variables for these sorts of purposes.) Reverse Polish is used by some (earlier, all) Hewlett-Packard calculators. (The name is based on the nationality of the mathematician who studied and formalized this notation.) It may seem strange at first, but it s natural if you observe that you need both numbers (operands) before you can carry out an operation on them. (This fact is one of the reasons that reverse Polish notation is easier to implement. )

11 The calculator example is a bit long and a bit involved, but I urge you to work through and understand it. A calculator is something that everyone s likely to be familiar with; it s interesting to see how one might work inside; and the techniques used here are generally useful in all sorts of programs. A stack is simply a last-in, first-out list. You push data items onto a stack, and whenever you pop an item from the stack, you get the one most recently pushed. Pages 76-79: The code for the calculator may seem daunting at first, but it s much easier to follow if you look at each part in isolation (as good functions are meant to be looked at), and notice that the routines fall into three levels. At the top level is the calculator itself, which resides in the function main. The main function calls three lower-level functions: push, pop, and getop. getop, in turn, is written in terms of the still lower-level functions getch and ungetch. A few details of the communication among these functions deserve mention. The getop routine actually returns two values. Its formal return value is a character representing the next operation to be performed. Usually, that character is just the character the user typed, that is, +, -, *, or /. In the case of a number typed by the user, the special code NUMBER is returned (which happens to be #defined to be the character 0, but that s arbitrary). A return value of NUMBER indicates that an entire string of digits has been typed, and the string itself is copied into the array s passed to getop. In this case, therefore, the array s is the second return value. In some printings, the second line on page 76 reads #include <math.h> /* for atof() */ which is incorrect; it should be #include <stdlib.h> /* for atof() */ Page 77: Make sure you understand why the code push(pop() - pop()); /* WRONG */ might not work correctly. The representation can be hidden means that the declarations of these variables can follow main in the file, such that main can t see them (that is, can t attempt to refer to them). Furthermore, as we ll see, the declarations might be moved to a separate source file, and main won t care. Pages 77-78: Note that getop does not incorporate the functionality of atoi or atof--it collects and returns the digits as a string, and main calls atof to convert the string to a floating-point number (prior to pushing it on the stack). (There s nothing profound about this arrangement; there s no particular reason why getop couldn t have been set up to do the conversion itself.) The reasons for using a routine like ungetch are good and sufficient, but they may not be obvious at first. The essential motivation, as the authors explain, is that when we re reading a string of digits, we don t know when we ve reached the end of the string of digits until we ve read a non-digit, and that non-digit is not part of the string of digits, so we really shouldn t have read it yet, after all. The rest of

12 the program is set up based on the assumption that one call to getop will return the string of digits, and the next call will return whatever operator followed the string of digits. To understand why the surprising and perhaps kludgey-sounding getch/ungetch approach is in fact a good one, let s consider the alternatives. getop could keep track of the one-too-far character somehow, and remember to use it next time instead of reading a new character. (Exercise 4-11 asks you to implement exactly this.) But this arrangement of getop is considerably less clean from the standpoint of the invariants we were discussing earlier. getop can be written relatively cleanly if one of its invariants is that the operator it s getting is always formed by reading the next character(s) from the input stream. getop would be considerably messier if it always had to remember to use an old character if it had one, or read a new character otherwise. If getop were modified later to read new kinds of operators, and if reading them involved reading more characters, it would be easy to forget to take into account the possibility of an old character each time a new character was needed. In other words, everywhere that getop wanted to do the operation read the next character it would instead have to do if (there s an old character) use it else read the next character It s much cleaner to push the checking for an old character down into the getch routine. Devising a pair of routines like getch and ungetch is an excellent example of the process of abstraction. We had a problem: while reading a string of digits, we always read one character too far. The obvious solution--remembering the one-too-far character and using it later--would have been clumsy if we d implemented it directly within getop. So we invented some new functions to centralize and encapsulate the functionality of remembering accidentally-read characters, so that getop could be written cleanly in terms of a simple get next character operation. By centralizing the functionality, we make it easy for getop to use it consistently, and by encapsulating it, we hide the (potentially ugly) details from the rest of the program. getch and ungetch may be tricky to write, but once we ve written them, we can seal up the little black boxes they re in and not worry about them any more, and the rest of the program (especially getop) is cleaner. Page 79: If you re not used to the conditional operator?: yet, here s how getch would look without it: int getch(void) { if (bufp > 0) return buf[--bufp]; else return getchar(); } Also, the extra generality of these two routines (namely, that they can push back and remember several characters, a feature which the calculator program doesn t even use) makes them a bit harder to follow. Exercise 4-8 asks you two write simpler versions which allow only one character of pushback.

13 (Also, as the text notes, we don t really have to be writing ungetch at all, because the standard library already provides an ungetc which can provide one character of pushback for getchar.) When we defined a stack, we said that it was last-in, first-out. Are the versions of getch and ungetch on page 79 last-in, first-out or first-in, first out? Do you agree with this choice? One last note: the name of the variable bufp suggests that it is a pointer, but it s actually an index into the buf array. Section 4.4: Scope Rules Page 80: With respect to the practical matter of splitting the calculator program up into multiple source files, though it s certainly small enough to fit comfortably into a single source file, it s not so small that there s anything wrong with splitting it up into multiple source files, especially if we start adding functionality to it. The scope of a name is what we have been calling its visibility. When we say things like calling a function with a prototype in scope we mean that a prototype is visible, that a declaration is in effect. The variables sp and val can be used by the push and pop routines because they re defined in the same file (and the definitions appear before push and pop). They can t be used in main because no declaration for them appears in main.c (nor in calc.h, which main.c #includes). If main attempted to refer to sp or val, they d be flagged as undefined. (Don t worry about the visibility of push and pop themselves. ) The paragraph beginning On the other hand is explaining how global ( external ) variables like sp and val could be accessed in a file other than the file where they are defined. In the examples we ve been looking at, as we ve said, sp and val can be used in push and pop because the variables are defined above the functions. If the variables were defined elsewhere (i.e. in some other file), we d need a declaration above--and that s exactly what extern is for. (See page 81 for an example.) Page 81: A definition creates a variable, and for any given global variable, you only want to do that once. Anywhere else, you want to refer to an existing variable, created elsewhere, without creating a new, conflicting one. Referring to an existing variable or function is exactly what a declaration is for. Note also that the definition may optionally initialize the variable. (Don t worry about why a declaration may optionally include an array dimension.) This same organization would also be needed if the definitions of sp and val followed their use in one file means that we could conceivably have, in one file, extern int sp; extern double val[]; void push(double f) {... } double pop(void) {... } int sp = 0; double val[maxval];

14 So extern just means somewhere else ; it doesn t have to mean in a different file, though usually it does. Section 4.5: Header Files Page 82: By the way, the.h traditionally used in header file names simply stands for header. We can imagine several strategies for using header files. At one extreme would be to use zero header files, and to repeat declarations in each file which needed them. This would clearly be a poor strategy, because whenever a declaration changed, we would have to remember to change it in several places, and it would be easy to miss one of them, leading to stubborn bugs. At the other extreme would be to use one header file for each source file (declaring just the things defined in that source file, to be #included by files using those things), but such a proliferation of header files would usually be unwieldy. For small projects (such as the calculator example), it s a reasonable strategy to use one header file for the entire project. For larger projects, you ll usually have several header files for sets of related declarations. Section 4.6: Static Variables Page 83: Deep sentence: The static declaration, applied to an external variable or function, limits the scope of that object to the rest of the source file being compiled. External static thus provides a way to hide names like buf and bufp in the getch-ungetch combination, which must be external so they can be shared, yet which should not be visible to users of getch and ungetch. So we can have three kinds of declarations: local to one function, restricted to one source file, or global across potentially many source files. We can imagine other possibilities, but these three cover most needs. Notice that the static keyword does two completely different things. Applied to a local variable (one inside of a function), it modifies the lifetime ( duration ) of the variable so that it persists for as long as the program does, and does not disappear between invocations of the function. Applied to a variable outside of a function (or to a function) static limits the scope to the current file. To summarize the scope of external and static functions and variables: when a function or global variable is defined without static, its scope is potentially the entire program, although any file which wishes to use it will generally need an extern declaration. A definition with static limits the scope by prohibiting other files from accessing a variable or function; even if they try to use an extern declaration, they ll get errors about undefined externals. The rules for declaring and defining functions and global variables, and using the extern and static keywords, are admittedly complicated and somewhat confusing. You don t need to memorize all of the rules right away: just use simple declarations and definitions at first, and as you find yourself needing some of the more complicated possibilities such as static variables, the rules will begin to make more sense. Section 4.7: Register Variables

15 Page 83: The register keyword is only a hint. The compiler might not put something in a register even though you ask it to, and it might put something in a register even though you don t ask it to. Most modern compilers do a good job of deciding when to put things in registers, so most of the time, you don t need to worry about it, and you don t have to use the register keyword at all. (A note to assembly language programmers: there s no way to specify which register a register variable gets assigned to. Also, when you specify a function parameter as register, it just means that the local copy of the parameter should be copied to a register if possible; it does not necessarily indicate that the parameter is going to be passed in a register.) Section 4.8: Block Structure Pages 84-85: You ve probably heard that global variables are bad because they exist everywhere and it can be hard to keep track of who s using them. In the same way, it can be useful to limit the scope of a local variable to just the bit of the function that uses it, which is exactly what happens if we declare a variable in an inner block. Section 4.9: Initialization Page 85: These are some of the rules on initialization; we ll learn a few more later as we learn about a few more data types. If you don t feel like memorizing the rules for default initialization, just go ahead and explicitly initialize everything you care about. Earlier we said that C is quite general in its treatment of expressions: anywhere you can use an expression, you can use any expression. Here s an exception to that rule: in an initialization of an external or static variable (strictly speaking, any variable of static duration; generally speaking, any global variable or local static variable), the initializer must be a constant expression, with value determinable at compile time, without calling any functions. (This rule is easy to understand: since these initializations happen conceptually at compile time, before the program starts running, there s no way for a function call--that is, some run-time action--to be involved.) Page 86: It probably won t concern you right away, but it turns out that there s another exception about the allowable expressions in initializers: in the brace-enclosed list of initializers for an array, all of the expressions must be constant expressions (even for local arrays). There is an error in some printings: if there are fewer explicit initializers than required for an array, the others will be initialized to zero, for external, static, and automatic (local) arrays. (When an automatic array has no initializers at all, then it contains garbage, just as simple automatic variables do.) If the initialization char pattern[] = "ould"; makes sense to you, you re fine. But if the statement that char pattern[] = "ould";

16 is equivalent to char pattern[] = { o, u, l, d, \0 }; bothers you at all, study it until it makes sense. Also, note that a character array which seems to contain (for example) four characters actually contains five, because of the terminating \0. Section 4.10: Recursion Page 86: Recursion is a simple but deep concept which is occasionally presented somewhat bewilderingly. Please don t be put off by it. If this section stops making sense, don t worry about it; we ll revisit recursion in chapter 6. Earlier we said that a function is (or ought to be) a black box which does some job and does it well. Whenever you need to get that job done, you re supposed to be able to call that function. You re not supposed to have to worry about any reasons why the function might not be able to do that job for you just now. It turns out that some functions are naturally written in such a way that they can do their job by calling themselves to do part of their job. This seems like a crazy idea at first, but based on a strict interpretation of our observation about functions--that we ought to be able to call them whenever we need their job done--calling a function from within itself ought not to be illegal, and in fact in C it is legal. Such a call is called a recursive call, and it works because it s possible to have several instances of a function active simultaneously. They don t interfere with each other, because each instance has its own copies of its parameters and local variables. (However, if a function accesses any static or global data, it must be written carefully if it is to be called recursively, because then different instances of it could interfere with each other.) Let s consider the printd example rather carefully. First, remind yourself about the reverse-order problem from the itoa example on page 64 in section 3.6. The obvious algorithm for determining the digits in a number, which involves successively dividing it by 10 and looking at the remainders, generates digits in right-to-left order, but we d usually like them in left-to-right order, especially if we re printing them out as we go. Let s see if we can figure out another way to do it. It s easy to find the lowest (rightmost) digit; that s n % 10. It s easy to compute all but the lowest digit; that s n / 10. So we could print a number left-to-right, directly, without any explicit reversal step, if we had a routine to print all but the last digit. We could call that routine, then print the last digit ourselves. But--here s the surprise--the routine to print all but the last digit is printd, the routine we re writing, if we call it with an argument of n / 10. Recursion seems like cheating--it seems that if you re writing a routine to do something (in this case, to print digits) and instead of writing code to print digits you just punt and call a routine for printing digits and which is in fact the very routine you re supposed to write--it seems like you haven t done the job you came to do. A recursive function seems like circular reasoning; it seems to beg the question of how it does its job.

17 But if you re writing a recursive function, as long as you do a little bit of work yourself, and only pass on a portion of the job to another instance of yourself, you haven t completely reneged on your responsibilities. Furthermore, if you re ever called with such a small job to do that the little bit you re willing to do encompasses the whole job, you don t have to call yourself again (there s no remaining portion that you can t do). Finally, since each recursive call does some work, passing on smaller and smaller portions to succeeding recursive calls, and since the last call (where the remaining portion is empty) doesn t generate any more recursive calls, the recursion is broken and doesn t constitute an infinite loop. Don t worry about the quicksort example if it seems impenetrable--quicksort is an important algorithm, but it is not easy to understand completely at first. Note that the qsort routine described here is very different from the standard library qsort (in fact, it probably shouldn t even have the same name). Section 4.11: The C Preprocessor Page 88: We ve been using #include and #define already, but now we ll describe them more completely. Section : File Inclusion The two syntaxes for #include lines can be used in various ways, but very simply speaking, "" is for header files you ve written, and <> is for headers which are provided for you (which someone else has written). Page 89: Deep sentences: #include is the preferred way to tie the declarations together for a large program. It guarantees that all the source files will be supplied with the same definitions and variable declarations, and thus eliminates a particularly nasty kind of bug. Naturally, when an included file is changed, all files that depend on it must be recompiled. That s the story on #include, in a nutshell. Section : Macro Substitution #defines last for the whole file; you can t have local ones like you can for local variables. Substitutions are made only for tokens means that a substitutable macro name is only recognized when it stands alone. Also, substitution never happens in quoted strings, because it turns out that you usually don t want it to. Strings are generally used for communication with the user, while you want substitutions to happen where you re talking to the compiler. The point of the forever example is to demonstrate that the replacement text doesn t have to be a simple number or string constant. You d use the forever macro like this: forever {... }

18 which the preprocessor would expand to for (;;) {... } which, as we learned in section 3.5 on page 60, is an infinite loop. (Presumably there s a break; see section 3.7 p. 64.) Another popular trick is #define ever ;; so that you can say for(ever) {... } But preprocessor tricks like these tend to get out of hand very quickly; if you use too many of them you re not writing in C anymore but rather in your own peculiar dialect, and no one will be able to read your code without understanding all of your silly little macros. It is best if simple macros expand to simple constants (or expressions). Macros with arguments are also called function-like macros because they act almost like miniature functions. There are some important differences, however: no call-by-value copying semantics no space saving hard to have local variables or block structure have to parenthesize carefully (see below) Page 90: The correct way to write the square() macro is #define square(x) ((x) * (x)) There are three rules to remember when defining function-like macros: 1. The macro expansion must always be parenthesized so that any low-precedence operators it contains will still be evaluated first. If we didn t write the square() macro carefully, the invocation: 1 / square(n) might expand to 1 / n * n while it should expand to

19 1 / (n * n) 2. Within the macro definition, all occurrences of the parameters must be parenthesized so that any low-precedence operators the actual arguments contain will be evaluated first. If we didn t write the square() macro carefully, the invocation: square(n + 1) might expand to n + 1 * n + 1 while it should expand to (n + 1) * (n + 1) 3. If a parameter appears several times in the expansion, the macro may not work properly if the actual argument is an expression with side effects. No matter how we parenthesize the square() macro, the invocation: square(i++) would result in i++ * i++ (perhaps with some parentheses), but this expression is undefined, because we don t know when the two increments will happen with respect to each other or the multiplication. Since the square() macro can t be written perfectly safely, (arguments with side effects will always be troublesome), its callers will always have to be careful (i.e. not to call it with arguments with side effects). One convention is to capitalize the names of macros which can t be treated exactly as if they were functions: #define Square(x) ((x) * (x)) Page 90 continued: #undef can be used when you want to give a macro restricted scope, if you can remember to undefine it when you want it to go out of scope. Don t worry about [ensuring] that a routine is really a function, not a macro or the getchar example. Also, don t worry about the # and ## operators. These are new ANSI features which aren t needed except in relatively special circumstances. Section : Conditional Inclusion Page 91: The #if!defined(hdr) trick is a bit esoteric to start out with. Let s look at a simpler example: in ANSI C, the remove function deletes a file. On some older Unix systems, however, the function to delete a file is instead named unlink. Therefore, when deleting a file, we might use code like this: #if defined(unix)

6.001 Notes: Section 6.1

6.001 Notes: Section 6.1 6.001 Notes: Section 6.1 Slide 6.1.1 When we first starting talking about Scheme expressions, you may recall we said that (almost) every Scheme expression had three components, a syntax (legal ways of

More information

Intro. Scheme Basics. scm> 5 5. scm>

Intro. Scheme Basics. scm> 5 5. scm> Intro Let s take some time to talk about LISP. It stands for LISt Processing a way of coding using only lists! It sounds pretty radical, and it is. There are lots of cool things to know about LISP; if

More information

QUIZ. What is wrong with this code that uses default arguments?

QUIZ. What is wrong with this code that uses default arguments? QUIZ What is wrong with this code that uses default arguments? Solution The value of the default argument should be placed in either declaration or definition, not both! QUIZ What is wrong with this code

More information

COSC 2P95. Procedural Abstraction. Week 3. Brock University. Brock University (Week 3) Procedural Abstraction 1 / 26

COSC 2P95. Procedural Abstraction. Week 3. Brock University. Brock University (Week 3) Procedural Abstraction 1 / 26 COSC 2P95 Procedural Abstraction Week 3 Brock University Brock University (Week 3) Procedural Abstraction 1 / 26 Procedural Abstraction We ve already discussed how to arrange complex sets of actions (e.g.

More information

These are notes for the third lecture; if statements and loops.

These are notes for the third lecture; if statements and loops. These are notes for the third lecture; if statements and loops. 1 Yeah, this is going to be the second slide in a lot of lectures. 2 - Dominant language for desktop application development - Most modern

More information

Module 10A Lecture - 20 What is a function? Why use functions Example: power (base, n)

Module 10A Lecture - 20 What is a function? Why use functions Example: power (base, n) Programming, Data Structures and Algorithms Prof. Shankar Balachandran Department of Computer Science and Engineering Indian Institute of Technology, Madras Module 10A Lecture - 20 What is a function?

More information

Have examined process Creating program Have developed program Written in C Source code

Have examined process Creating program Have developed program Written in C Source code Preprocessing, Compiling, Assembling, and Linking Introduction In this lesson will examine Architecture of C program Introduce C preprocessor and preprocessor directives How to use preprocessor s directives

More information

Type Checking and Type Equality

Type Checking and Type Equality Type Checking and Type Equality Type systems are the biggest point of variation across programming languages. Even languages that look similar are often greatly different when it comes to their type systems.

More information

6.001 Notes: Section 15.1

6.001 Notes: Section 15.1 6.001 Notes: Section 15.1 Slide 15.1.1 Our goal over the next few lectures is to build an interpreter, which in a very basic sense is the ultimate in programming, since doing so will allow us to define

More information

This section provides some reminders and some terminology with which you might not be familiar.

This section provides some reminders and some terminology with which you might not be familiar. Chapter 3: Functions 3.1 Introduction The previous chapter assumed that all of your Bali code would be written inside a sole main function. But, as you have learned from previous programming courses, modularizing

More information

Lecture 4 CSE July 1992

Lecture 4 CSE July 1992 Lecture 4 CSE 110 6 July 1992 1 More Operators C has many operators. Some of them, like +, are binary, which means that they require two operands, as in 4 + 5. Others are unary, which means they require

More information

The compiler is spewing error messages.

The compiler is spewing error messages. Appendix B Debugging There are a few different kinds of errors that can occur in a program, and it is useful to distinguish between them in order to track them down more quickly. Compile-time errors are

More information

Documentation Nick Parlante, 1996.Free for non-commerical use.

Documentation Nick Parlante, 1996.Free for non-commerical use. Documentation Nick Parlante, 1996.Free for non-commerical use. A program expresses an algorithm to the computer. A program is clear or "readable" if it also does a good job of communicating the algorithm

More information

UNIVERSITY OF CALIFORNIA, SANTA CRUZ BOARD OF STUDIES IN COMPUTER ENGINEERING

UNIVERSITY OF CALIFORNIA, SANTA CRUZ BOARD OF STUDIES IN COMPUTER ENGINEERING UNIVERSITY OF CALIFORNIA, SANTA CRUZ BOARD OF STUDIES IN COMPUTER ENGINEERING CMPE13/L: INTRODUCTION TO PROGRAMMING IN C SPRING 2012 Lab 3 Matrix Math Introduction Reading In this lab you will write a

More information

6.001 Notes: Section 8.1

6.001 Notes: Section 8.1 6.001 Notes: Section 8.1 Slide 8.1.1 In this lecture we are going to introduce a new data type, specifically to deal with symbols. This may sound a bit odd, but if you step back, you may realize that everything

More information

3 Nonlocal Exit. Quiz Program Revisited

3 Nonlocal Exit. Quiz Program Revisited 3 Nonlocal Exit This chapter is about the commands catch and throw. These commands work together as a kind of super-stop command, which you can use to stop several levels of procedure invocation at once.

More information

The Dynamic Typing Interlude

The Dynamic Typing Interlude CHAPTER 6 The Dynamic Typing Interlude In the prior chapter, we began exploring Python s core object types in depth with a look at Python numbers. We ll resume our object type tour in the next chapter,

More information

COSC 2P91. Bringing it all together... Week 4b. Brock University. Brock University (Week 4b) Bringing it all together... 1 / 22

COSC 2P91. Bringing it all together... Week 4b. Brock University. Brock University (Week 4b) Bringing it all together... 1 / 22 COSC 2P91 Bringing it all together... Week 4b Brock University Brock University (Week 4b) Bringing it all together... 1 / 22 A note on practicality and program design... Writing a single, monolithic source

More information

Starting to Program in C++ (Basics & I/O)

Starting to Program in C++ (Basics & I/O) Copyright by Bruce A. Draper. 2017, All Rights Reserved. Starting to Program in C++ (Basics & I/O) On Tuesday of this week, we started learning C++ by example. We gave you both the Complex class code and

More information

Course organization. Course introduction ( Week 1)

Course organization. Course introduction ( Week 1) Course organization Course introduction ( Week 1) Code editor: Emacs Part I: Introduction to C programming language (Week 2-9) Chapter 1: Overall Introduction (Week 1-3) Chapter 2: Types, operators and

More information

CS125 : Introduction to Computer Science. Lecture Notes #4 Type Checking, Input/Output, and Programming Style

CS125 : Introduction to Computer Science. Lecture Notes #4 Type Checking, Input/Output, and Programming Style CS125 : Introduction to Computer Science Lecture Notes #4 Type Checking, Input/Output, and Programming Style c 2005, 2004, 2002, 2001, 2000 Jason Zych 1 Lecture 4 : Type Checking, Input/Output, and Programming

More information

APPENDIX B. Fortran Hints

APPENDIX B. Fortran Hints APPENDIX B Fortran Hints This appix contains hints on how to find errors in your programs, and how to avoid some common Fortran errors in the first place. The basics on how to invoke the Fortran compiler

More information

The name of our class will be Yo. Type that in where it says Class Name. Don t hit the OK button yet.

The name of our class will be Yo. Type that in where it says Class Name. Don t hit the OK button yet. Mr G s Java Jive #2: Yo! Our First Program With this handout you ll write your first program, which we ll call Yo. Programs, Classes, and Objects, Oh My! People regularly refer to Java as a language that

More information

Chapter 6: The C Preprocessor

Chapter 6: The C Preprocessor C: Chapter6 Page 1 of 5 C Tutorial.......... The C preprocessor Chapter 6: The C Preprocessor AIDS TO CLEAR PROGRAMMING The preprocessor is a program that is executed just prior to the execution of the

More information

How to approach a computational problem

How to approach a computational problem How to approach a computational problem A lot of people find computer programming difficult, especially when they first get started with it. Sometimes the problems are problems specifically related to

More information

Introduction to Programming

Introduction to Programming CHAPTER 1 Introduction to Programming Begin at the beginning, and go on till you come to the end: then stop. This method of telling a story is as good today as it was when the King of Hearts prescribed

More information

EXAMINING THE CODE. 1. Examining the Design and Code 2. Formal Review: 3. Coding Standards and Guidelines: 4. Generic Code Review Checklist:

EXAMINING THE CODE. 1. Examining the Design and Code 2. Formal Review: 3. Coding Standards and Guidelines: 4. Generic Code Review Checklist: EXAMINING THE CODE CONTENTS I. Static White Box Testing II. 1. Examining the Design and Code 2. Formal Review: 3. Coding Standards and Guidelines: 4. Generic Code Review Checklist: Dynamic White Box Testing

More information

Lecture 19 CSE August You taught me Language, and my profit on t is I know how to curse. William Shakspere, The Tempest, I, ii.

Lecture 19 CSE August You taught me Language, and my profit on t is I know how to curse. William Shakspere, The Tempest, I, ii. Lecture 19 CSE 110 5 August 1992 You taught me Language, and my profit on t is I know how to curse. William Shakspere, The Tempest, I, ii. 1 Left-Over Language Features Today was the day we saw the last

More information

14.1 Encoding for different models of computation

14.1 Encoding for different models of computation Lecture 14 Decidable languages In the previous lecture we discussed some examples of encoding schemes, through which various objects can be represented by strings over a given alphabet. We will begin this

More information

Divisibility Rules and Their Explanations

Divisibility Rules and Their Explanations Divisibility Rules and Their Explanations Increase Your Number Sense These divisibility rules apply to determining the divisibility of a positive integer (1, 2, 3, ) by another positive integer or 0 (although

More information

Trombone players produce different pitches partly by varying the length of a tube.

Trombone players produce different pitches partly by varying the length of a tube. Trombone players produce different pitches partly by varying the length of a tube. 7 Variables A variable is a connection between a name and a value.* That sounds simple enough, but some complexities arise

More information

CSCI 1100L: Topics in Computing Lab Lab 11: Programming with Scratch

CSCI 1100L: Topics in Computing Lab Lab 11: Programming with Scratch CSCI 1100L: Topics in Computing Lab Lab 11: Programming with Scratch Purpose: We will take a look at programming this week using a language called Scratch. Scratch is a programming language that was developed

More information

6.001 Notes: Section 17.5

6.001 Notes: Section 17.5 6.001 Notes: Section 17.5 Slide 17.5.1 Now, let's look at one example in which changing the evaluation model allows us to explore a very different kind of computational problem. Our goal is to show how

More information

CS Introduction to Data Structures How to Parse Arithmetic Expressions

CS Introduction to Data Structures How to Parse Arithmetic Expressions CS3901 - Introduction to Data Structures How to Parse Arithmetic Expressions Lt Col Joel Young One of the common task required in implementing programming languages, calculators, simulation systems, and

More information

QUIZ. What are 3 differences between C and C++ const variables?

QUIZ. What are 3 differences between C and C++ const variables? QUIZ What are 3 differences between C and C++ const variables? Solution QUIZ Source: http://stackoverflow.com/questions/17349387/scope-of-macros-in-c Solution The C/C++ preprocessor substitutes mechanically,

More information

CSCI S-Q Lecture #12 7/29/98 Data Structures and I/O

CSCI S-Q Lecture #12 7/29/98 Data Structures and I/O CSCI S-Q Lecture #12 7/29/98 Data Structures and I/O Introduction The WRITE and READ ADT Operations Case Studies: Arrays Strings Binary Trees Binary Search Trees Unordered Search Trees Page 1 Introduction

More information

CS Programming In C

CS Programming In C CS 24000 - Programming In C Week Two: Basic C Program Organization and Data Types Zhiyuan Li Department of Computer Science Purdue University, USA 2 int main() { } return 0; The Simplest C Program C programs

More information

PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between

PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between MITOCW Lecture 10A [MUSIC PLAYING] PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between all these high-level languages like Lisp and the query

More information

printf( Please enter another number: ); scanf( %d, &num2);

printf( Please enter another number: ); scanf( %d, &num2); CIT 593 Intro to Computer Systems Lecture #13 (11/1/12) Now that we've looked at how an assembly language program runs on a computer, we're ready to move up a level and start working with more powerful

More information

CSE 374 Programming Concepts & Tools

CSE 374 Programming Concepts & Tools CSE 374 Programming Concepts & Tools Hal Perkins Fall 2017 Lecture 8 C: Miscellanea Control, Declarations, Preprocessor, printf/scanf 1 The story so far The low-level execution model of a process (one

More information

QUIZ Friends class Y;

QUIZ Friends class Y; QUIZ Friends class Y; Is a forward declaration neeed here? QUIZ Friends QUIZ Friends - CONCLUSION Forward (a.k.a. incomplete) declarations are needed only when we declare member functions as friends. They

More information

Lecture 1: Overview

Lecture 1: Overview 15-150 Lecture 1: Overview Lecture by Stefan Muller May 21, 2018 Welcome to 15-150! Today s lecture was an overview that showed the highlights of everything you re learning this semester, which also meant

More information

CS 161 Computer Security

CS 161 Computer Security Wagner Spring 2014 CS 161 Computer Security 1/27 Reasoning About Code Often functions make certain assumptions about their arguments, and it is the caller s responsibility to make sure those assumptions

More information

Course organization. Part I: Introduction to C programming language (Week 1-12) Chapter 1: Overall Introduction (Week 1-4)

Course organization. Part I: Introduction to C programming language (Week 1-12) Chapter 1: Overall Introduction (Week 1-4) Course organization 1 Course introduction ( Week 1) Code editor: Emacs Part I: Introduction to C programming language (Week 1-12) Chapter 1: Overall Introduction (Week 1-4) C Unix/Linux Chapter 2: Types,

More information

Foundations, Reasoning About Algorithms, and Design By Contract CMPSC 122

Foundations, Reasoning About Algorithms, and Design By Contract CMPSC 122 Foundations, Reasoning About Algorithms, and Design By Contract CMPSC 122 I. Logic 101 In logic, a statement or proposition is a sentence that can either be true or false. A predicate is a sentence in

More information

Course organization Course introduction ( Week 1) Part I: Introduction to C programming language (Week 3-12)

Course organization Course introduction ( Week 1) Part I: Introduction to C programming language (Week 3-12) 1 Course organization Course introduction ( Week 1) Code editor: Emacs (Week 2) Part I: Introduction to C programming language (Week 3-12) Chapter 1: Overall Introduction (Week 3-4) Chapter 2: Types, operators

More information

QUIZ. Source:

QUIZ. Source: QUIZ Source: http://stackoverflow.com/questions/17349387/scope-of-macros-in-c Ch. 4: Data Abstraction The only way to get massive increases in productivity is to leverage off other people s code. That

More information

FUNCTIONS. The Anatomy of a Function Definition. In its most basic form, a function definition looks like this: function square(x) { return x * x; }

FUNCTIONS. The Anatomy of a Function Definition. In its most basic form, a function definition looks like this: function square(x) { return x * x; } 2 FUNCTIONS We have already used several functions in the previous chapter things such as alert and print to order the machine to perform a specific operation. In this chapter, we will start creating our

More information

Lecture Notes on Memory Layout

Lecture Notes on Memory Layout Lecture Notes on Memory Layout 15-122: Principles of Imperative Computation Frank Pfenning André Platzer Lecture 11 1 Introduction In order to understand how programs work, we can consider the functions,

More information

First-Order Translation Checklist

First-Order Translation Checklist CS103 Winter 2019 First-Order Translation Checklist Cynthia Lee Keith Schwarz In this handout, we ve distilled five specific points that you should check in your first-order logic statements before submitting

More information

CPS122 Lecture: From Python to Java last revised January 4, Objectives:

CPS122 Lecture: From Python to Java last revised January 4, Objectives: Objectives: CPS122 Lecture: From Python to Java last revised January 4, 2017 1. To introduce the notion of a compiled language 2. To introduce the notions of data type and a statically typed language 3.

More information

VARIABLES. Aim Understanding how computer programs store values, and how they are accessed and used in computer programs.

VARIABLES. Aim Understanding how computer programs store values, and how they are accessed and used in computer programs. Lesson 2 VARIABLES Aim Understanding how computer programs store values, and how they are accessed and used in computer programs. WHAT ARE VARIABLES? When you input data (i.e. information) into a computer

More information

CPS122 Lecture: From Python to Java

CPS122 Lecture: From Python to Java Objectives: CPS122 Lecture: From Python to Java last revised January 7, 2013 1. To introduce the notion of a compiled language 2. To introduce the notions of data type and a statically typed language 3.

More information

Functions, Pointers, and the Basics of C++ Classes

Functions, Pointers, and the Basics of C++ Classes Functions, Pointers, and the Basics of C++ Classes William E. Skeith III Functions in C++ Vocabulary You should be familiar with all of the following terms already, but if not, you will be after today.

More information

Signed umbers. Sign/Magnitude otation

Signed umbers. Sign/Magnitude otation Signed umbers So far we have discussed unsigned number representations. In particular, we have looked at the binary number system and shorthand methods in representing binary codes. With m binary digits,

More information

PIC 10A Objects/Classes

PIC 10A Objects/Classes PIC 10A Objects/Classes Ernest Ryu UCLA Mathematics Last edited: November 13, 2017 User-defined types In C++, we can define our own custom types. Object is synonymous to variable, and class is synonymous

More information

Type Checking in COOL (II) Lecture 10

Type Checking in COOL (II) Lecture 10 Type Checking in COOL (II) Lecture 10 1 Lecture Outline Type systems and their expressiveness Type checking with SELF_TYPE in COOL Error recovery in semantic analysis 2 Expressiveness of Static Type Systems

More information

Chapter01.fm Page 1 Monday, August 23, :52 PM. Part I of Change. The Mechanics. of Change

Chapter01.fm Page 1 Monday, August 23, :52 PM. Part I of Change. The Mechanics. of Change Chapter01.fm Page 1 Monday, August 23, 2004 1:52 PM Part I The Mechanics of Change The Mechanics of Change Chapter01.fm Page 2 Monday, August 23, 2004 1:52 PM Chapter01.fm Page 3 Monday, August 23, 2004

More information

Full file at

Full file at Java Programming: From Problem Analysis to Program Design, 3 rd Edition 2-1 Chapter 2 Basic Elements of Java At a Glance Instructor s Manual Table of Contents Overview Objectives s Quick Quizzes Class

More information

CS125 : Introduction to Computer Science. Lecture Notes #38 and #39 Quicksort. c 2005, 2003, 2002, 2000 Jason Zych

CS125 : Introduction to Computer Science. Lecture Notes #38 and #39 Quicksort. c 2005, 2003, 2002, 2000 Jason Zych CS125 : Introduction to Computer Science Lecture Notes #38 and #39 Quicksort c 2005, 2003, 2002, 2000 Jason Zych 1 Lectures 38 and 39 : Quicksort Quicksort is the best sorting algorithm known which is

More information

CS103 Handout 29 Winter 2018 February 9, 2018 Inductive Proofwriting Checklist

CS103 Handout 29 Winter 2018 February 9, 2018 Inductive Proofwriting Checklist CS103 Handout 29 Winter 2018 February 9, 2018 Inductive Proofwriting Checklist In Handout 28, the Guide to Inductive Proofs, we outlined a number of specifc issues and concepts to be mindful about when

More information

Variables, expressions and statements

Variables, expressions and statements Variables, expressions and statements 2.1. Values and data types A value is one of the fundamental things like a letter or a number that a program manipulates. The values we have seen so far are 2 (the

More information

CMSC 201 Fall 2016 Lab 09 Advanced Debugging

CMSC 201 Fall 2016 Lab 09 Advanced Debugging CMSC 201 Fall 2016 Lab 09 Advanced Debugging Assignment: Lab 09 Advanced Debugging Due Date: During discussion Value: 10 points Part 1: Introduction to Errors Throughout this semester, we have been working

More information

1: Introduction to Object (1)

1: Introduction to Object (1) 1: Introduction to Object (1) 김동원 2003.01.20 Overview (1) The progress of abstraction Smalltalk Class & Object Interface The hidden implementation Reusing the implementation Inheritance: Reusing the interface

More information

Coding Workshop. Learning to Program with an Arduino. Lecture Notes. Programming Introduction Values Assignment Arithmetic.

Coding Workshop. Learning to Program with an Arduino. Lecture Notes. Programming Introduction Values Assignment Arithmetic. Coding Workshop Learning to Program with an Arduino Lecture Notes Table of Contents Programming ntroduction Values Assignment Arithmetic Control Tests f Blocks For Blocks Functions Arduino Main Functions

More information

Deep C (and C++) by Olve Maudal

Deep C (and C++) by Olve Maudal Deep C (and C++) by Olve Maudal http://www.noaanews.noaa.gov/stories2005/images/rov-hercules-titanic.jpg Programming is hard. Programming correct C and C++ is particularly hard. Indeed, it is uncommon

More information

Chamberlin and Boyce - SEQUEL: A Structured English Query Language

Chamberlin and Boyce - SEQUEL: A Structured English Query Language Programming Languages (CS302 2007S) Chamberlin and Boyce - SEQUEL: A Structured English Query Language Comments on: Chamberlin, D. D. and Boyce, R. F. (1974). SEQUEL: A Structured English Query Language.

More information

An Interesting Way to Combine Numbers

An Interesting Way to Combine Numbers An Interesting Way to Combine Numbers Joshua Zucker and Tom Davis October 12, 2016 Abstract This exercise can be used for middle school students and older. The original problem seems almost impossibly

More information

(Refer Slide Time: 4:00)

(Refer Slide Time: 4:00) Principles of Programming Languages Dr. S. Arun Kumar Department of Computer Science & Engineering Indian Institute of Technology, Delhi Lecture - 38 Meanings Let us look at abstracts namely functional

More information

6.001 Notes: Section 4.1

6.001 Notes: Section 4.1 6.001 Notes: Section 4.1 Slide 4.1.1 In this lecture, we are going to take a careful look at the kinds of procedures we can build. We will first go back to look very carefully at the substitution model,

More information

This is a book about using Visual Basic for Applications (VBA), which is a

This is a book about using Visual Basic for Applications (VBA), which is a 01b_574116 ch01.qxd 7/27/04 9:04 PM Page 9 Chapter 1 Where VBA Fits In In This Chapter Describing Access Discovering VBA Seeing where VBA lurks Understanding how VBA works This is a book about using Visual

More information

Proofwriting Checklist

Proofwriting Checklist CS103 Winter 2019 Proofwriting Checklist Cynthia Lee Keith Schwarz Over the years, we ve found many common proofwriting errors that can easily be spotted once you know how to look for them. In this handout,

More information

Functions and Decomposition

Functions and Decomposition Unit 4 Functions and Decomposition Learning Outcomes Design and implement functions to carry out a particular task. Begin to evaluate when it is necessary to split some work into functions. Locate the

More information

Annotation Annotation or block comments Provide high-level description and documentation of section of code More detail than simple comments

Annotation Annotation or block comments Provide high-level description and documentation of section of code More detail than simple comments Variables, Data Types, and More Introduction In this lesson will introduce and study C annotation and comments C variables Identifiers C data types First thoughts on good coding style Declarations vs.

More information

Lecture 12 CSE July Today we ll cover the things that you still don t know that you need to know in order to do the assignment.

Lecture 12 CSE July Today we ll cover the things that you still don t know that you need to know in order to do the assignment. Lecture 12 CSE 110 20 July 1992 Today we ll cover the things that you still don t know that you need to know in order to do the assignment. 1 The NULL Pointer For each pointer type, there is one special

More information

Excel Basics: Working with Spreadsheets

Excel Basics: Working with Spreadsheets Excel Basics: Working with Spreadsheets E 890 / 1 Unravel the Mysteries of Cells, Rows, Ranges, Formulas and More Spreadsheets are all about numbers: they help us keep track of figures and make calculations.

More information

Maciej Sobieraj. Lecture 1

Maciej Sobieraj. Lecture 1 Maciej Sobieraj Lecture 1 Outline 1. Introduction to computer programming 2. Advanced flow control and data aggregates Your first program First we need to define our expectations for the program. They

More information

Preprocessor Directives

Preprocessor Directives C++ By 6 EXAMPLE Preprocessor Directives As you might recall from Chapter 2, What Is a Program?, the C++ compiler routes your programs through a preprocessor before it compiles them. The preprocessor can

More information

Computer Programming & Problem Solving ( CPPS ) Turbo C Programming For The PC (Revised Edition ) By Robert Lafore

Computer Programming & Problem Solving ( CPPS ) Turbo C Programming For The PC (Revised Edition ) By Robert Lafore Sir Syed University of Engineering and Technology. Computer ming & Problem Solving ( CPPS ) Functions Chapter No 1 Compiled By: Sir Syed University of Engineering & Technology Computer Engineering Department

More information

C Pointers 2013 Author Riko H i

C Pointers 2013 Author Riko H i http:/cdorm.net/understanding C Pointers 2013 Author Riko H i Copyright 2013 CDorm.net All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form

More information

C++ Data Types. 1 Simple C++ Data Types 2. 3 Numeric Types Integers (whole numbers) Decimal Numbers... 5

C++ Data Types. 1 Simple C++ Data Types 2. 3 Numeric Types Integers (whole numbers) Decimal Numbers... 5 C++ Data Types Contents 1 Simple C++ Data Types 2 2 Quick Note About Representations 3 3 Numeric Types 4 3.1 Integers (whole numbers)............................................ 4 3.2 Decimal Numbers.................................................

More information

Notes on Turing s Theorem and Computability

Notes on Turing s Theorem and Computability Notes on Turing s Theorem and Computability Walter Neumann About 60 years ago there was a revolution in mathematics and philosophy. First Gödel and then Turing showed that there are impossible problems

More information

Test Requirement Catalog. Generic Clues, Developer Version

Test Requirement Catalog. Generic Clues, Developer Version Version 4..0 PART 1: DATA TYPES Test Requirement Catalog SIMPLE DATA TYPES... 4 BOOLEAN... 4 CASES... 4 COUNTS... 5 INTERVALS... 5 [LOW, HIGH] an interval that contains both LOW and HIGH... 6 [LOW, HIGH)

More information

Rapid Software Testing Guide to Making Good Bug Reports

Rapid Software Testing Guide to Making Good Bug Reports Rapid Software Testing Guide to Making Good Bug Reports By James Bach, Satisfice, Inc. v.1.0 Bug reporting is a very important part of testing. The bug report, whether oral or written, is the single most

More information

Part II Composition of Functions

Part II Composition of Functions Part II Composition of Functions The big idea in this part of the book is deceptively simple. It s that we can take the value returned by one function and use it as an argument to another function. By

More information

Week - 01 Lecture - 04 Downloading and installing Python

Week - 01 Lecture - 04 Downloading and installing Python Programming, Data Structures and Algorithms in Python Prof. Madhavan Mukund Department of Computer Science and Engineering Indian Institute of Technology, Madras Week - 01 Lecture - 04 Downloading and

More information

Chapter 1 Getting Started

Chapter 1 Getting Started Chapter 1 Getting Started The C# class Just like all object oriented programming languages, C# supports the concept of a class. A class is a little like a data structure in that it aggregates different

More information

Difference Between Dates Case Study 2002 M. J. Clancy and M. C. Linn

Difference Between Dates Case Study 2002 M. J. Clancy and M. C. Linn Difference Between Dates Case Study 2002 M. J. Clancy and M. C. Linn Problem Write and test a Scheme program to compute how many days are spanned by two given days. The program will include a procedure

More information

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #17. Loops: Break Statement

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #17. Loops: Break Statement Introduction to Programming in C Department of Computer Science and Engineering Lecture No. #17 Loops: Break Statement (Refer Slide Time: 00:07) In this session we will see one more feature that is present

More information

6.001 Notes: Section 1.1

6.001 Notes: Section 1.1 6.001 Notes: Section 1.1 Slide 1.1.1 This first thing we need to do is discuss the focus of 6.001. What is this course all about? This seems quite obvious -- this is a course about computer science. But

More information

Software Engineering /48

Software Engineering /48 Software Engineering 1 /48 Topics 1. The Compilation Process and You 2. Polymorphism and Composition 3. Small Functions 4. Comments 2 /48 The Compilation Process and You 3 / 48 1. Intro - How do you turn

More information

We do not teach programming

We do not teach programming We do not teach programming We do not teach C Take a course Read a book The C Programming Language, Kernighan, Richie Georgios Georgiadis Negin F.Nejad This is a brief tutorial on C s traps and pitfalls

More information

12. Pointers Address-of operator (&)

12. Pointers Address-of operator (&) 12. Pointers In earlier chapters, variables have been explained as locations in the computer's memory which can be accessed by their identifer (their name). This way, the program does not need to care

More information

Clean & Speed Up Windows with AWO

Clean & Speed Up Windows with AWO Clean & Speed Up Windows with AWO C 400 / 1 Manage Windows with this Powerful Collection of System Tools Every version of Windows comes with at least a few programs for managing different aspects of your

More information

Control Flow. COMS W1007 Introduction to Computer Science. Christopher Conway 3 June 2003

Control Flow. COMS W1007 Introduction to Computer Science. Christopher Conway 3 June 2003 Control Flow COMS W1007 Introduction to Computer Science Christopher Conway 3 June 2003 Overflow from Last Time: Why Types? Assembly code is typeless. You can take any 32 bits in memory, say this is an

More information

Formal Methods of Software Design, Eric Hehner, segment 1 page 1 out of 5

Formal Methods of Software Design, Eric Hehner, segment 1 page 1 out of 5 Formal Methods of Software Design, Eric Hehner, segment 1 page 1 out of 5 [talking head] Formal Methods of Software Engineering means the use of mathematics as an aid to writing programs. Before we can

More information

6.096 Introduction to C++

6.096 Introduction to C++ MIT OpenCourseWare http://ocw.mit.edu 6.096 Introduction to C++ January (IAP) 2009 For information about citing these materials or our Terms of Use, visit: http://ocw.mit.edu/terms. 6.096 Lecture 3 Notes

More information

COMP-202 Unit 2: Java Basics. CONTENTS: Using Expressions and Variables Types Strings Methods

COMP-202 Unit 2: Java Basics. CONTENTS: Using Expressions and Variables Types Strings Methods COMP-202 Unit 2: Java Basics CONTENTS: Using Expressions and Variables Types Strings Methods Assignment 1 Assignment 1 posted on WebCt and course website. It is due May 18th st at 23:30 Worth 6% Part programming,

More information

This book is about using Visual Basic for Applications (VBA), which is a

This book is about using Visual Basic for Applications (VBA), which is a In This Chapter Describing Access Discovering VBA Seeing where VBA lurks Understanding how VBA works Chapter 1 Where VBA Fits In This book is about using Visual Basic for Applications (VBA), which is a

More information

An Introduction to Subtyping

An Introduction to Subtyping An Introduction to Subtyping Type systems are to me the most interesting aspect of modern programming languages. Subtyping is an important notion that is helpful for describing and reasoning about type

More information