WHAT IS AN IDENTIFIER? Before you can do anything in any language, you must know how to name an identifier. An identifier is used for any variable, function, data definition, etc. In the C programming language, an identifier is a combination of alphanumeric characters, the first being a letter of the alphabet or an Two rules must be kept in mind when naming identifiers.
WHAT ABOUT THE UNDERLINE? The underline can be used as part of a variable name, and adds greatly to the readability of the resulting code. It is used by some, but not all, experienced C programmers. A few underlines are used for illustration in this It adds greatly to the readability of a program to use descriptive names for variables and it would be to your advantage to do so. Pascal and Ada programmers tend to use long descriptive names, but most C programmers tend to use short cryptic names. Most of the example programs in this tutorial use very short names for that reason, but a few longer names are used for illustrative purposes. KEYWORDS There are 32 words defined as keywords in C. These have predefined uses and cannot be used for any other purpose in a C program. They are used by the compiler as an aid to compiling the program. They are always written in lower case. A complete list follows; auto double int struct break else long case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do if static while In addition to this list of keywords, your compiler may define a few more. If it does, they will be listed in the documentation that came with your compiler. Each of the above keywords will be defined, illustrated, and used in this tutorial. WE NEED DATA AND A PROGRAM Any computer program has two entities to consider, the data, and the program. They are highly dependent on one another and careful planning of both will lead to a well planned and well written program. Unfortunately, it is not possible to study either completely without a good working knowledge of the other. For that reason, this tutorial will jump back and forth between teaching methods of program writing and methods of data definition. Simply follow along and you will have a good understanding of both. Keep in mind that, even though it seems expedient to sometimes jump right into coding the program, time spent planning the data structures will be well spent and the quality of the final program will reflect the original planning. HOW THIS TUTORIAL IS WRITTEN As you go through the example programs, you will find that every program is complete. There are no program fragments that could be confusing. This allows you to see every requirement that is needed to use any of the features of C as they are presented. Some tutorials I have seen give very few, and very complex examples. They really serve more to confuse the student. This tutorial is the complete opposite because it strives to cover each new aspect of programming in as simple a context as possible. Throughout this tutorial, keywords, variable names, and function names will be given in boldface as an aid to clarity. These terms will be completely defined throughout the tutorial. HOW THIS TUTORIAL IS WRITTEN As you go through the example programs, you will find that every program is complete. There are no program fragments that could be confusing. This allows you to see every requirement that is needed to use any of the features of C as they are presented. Some tutorials I have seen give very few, and very complex examples. They really serve more to confuse the student. This tutorial is the complete opposite because it strives to cover each new aspect of programming in as simple a context as possible. Throughout this tutorial, keywords, variable names, and function names will be given in boldface as an aid to clarity. These terms will be completely defined throughout the tutorial. RESULT OF The result of executing each program will be given in comments at the end of the program listing after the comment is defined in about the fourth program of chapter 2. If you feel confident that you completely understand the program, you can simply refer to the result of execution to see if you understand the result. In this case, it will not be necessary for you to compile and execute every program. It would be a good exercise for you to compile and execute some of them however, because all C compilers will not generate exactly the same results and you need to get familiar with your own compiler. Example program ------> FIRSTEX.C At this point, you should compile and execute FIRSTEX.C if you have not yet done so, to see that your C compiler is properly loaded and operating. Don't worry about what the program does yet. In due time you will understand it completely. Note that this program will compile and execute properly with any good compiler. A WORD ABOUT COMPILERS All of the example programs in this tutorial will compile and execute correctly with any good ANSI compatible C compiler. Some compilers have gotten extremely complex and hard to use for a beginning C programmer, and some only compile and build Microsoft Windows programs. Fortunately, most of the C compilers available have a means of compiling a standard C program which is written for the DOS environment and includes none of the Windows extensions. You should check your documentation for the capabilities and limitations of your compiler. If you have not yet purchased a C compiler, you should find one that is ANSI-C compliant, and that also has the ability to generate a DOS executable if you are planning to use the DOS operating system. ANSWERS TO PROGRAMMING EXERCISES There are programming exercises at the end of most of the chapters. You should attempt to do original work on each of the exercises before referring to the answers in order to gain your own programming experience. These answers are given for your information in case you are completely stuck on how to solve a particular problem. These answers are not meant to be the only answer, since there are many ways to program anything, but they are meant to illustrate one way to solve the suggested programming problem. The answers are all in source files named in the format CHnn_m.C where nn is the chapter number, and m is the exercise number. If more than one answer is required, an A, B, or C is included following the exercise number. PROGRAM YOUR FIRST C PROGRAM Example program ------> TRIVIAL.C The best way to get started with C is to actually study a program, so load the file named TRIVIAL.C and display it on the The word main is very important, and must appear once, and only once in every C program. This is the point where execution is begun when the program is run. We will see later that this does not have to be the first statement in the program but it must exist as the entry point. Following the main program name is a pair of parentheses which are an indication to the compiler that this is a function. We will cover exactly what a function is in due time. For now, I suggest that you simply include the pair of parentheses. The two curly brackets in lines 2 and 3, properly called braces, are used to define the limits of the program itself. The actual program statements go between the two braces and in this case, there are no statements because the program does absolutely nothing. You can compile and run this program, but since it has no executable statements, it does nothing. Keep in mind, however, that it is a valid C program. When you compile this program, you may get a warning. You can ignore the warning and we will discuss it later in this tutorial, or you can modify the program so that it appears as follows; int main() { return 0; } This modified program must compile on any good C compiler since it conforms to the ANSI-C standard. We will explain the difference in these two programs later in this tutorial. A PROGRAM THAT DOES SOMETHING Example program ------> WRTSOME.C For a much more interesting program, load the program named WRTSOME.C and display it on your monitor. It is the same as the previous program except that it has one executable statement between the braces plus the obligatory return statement. The executable statement is a call to a function supplied as a part of your C library. Once again, we will not worry about what a function is, but only how to use this one named printf(). In order to output text to the monitor, the desired text is put within the function parentheses and bounded by quotation marks. The end result is that whatever text is included between the quotation marks will be displayed on the monitor when the program is run. Notice the semi-colon at the end of line 5. C uses a semi-colon as a statement terminator, so the semi-colon is required as a signal to the compiler that this line is complete. This program is also executable, so you can compile and run it to see if it does what you think it should. It should cause the text between the quotation marks to appear on the monitor when you execute it. You can ignore the statements in lines 1 and 7 in this program and similar statements in each of the remaining programs in this chapter. These will be fully described later in this tutorial. We will also define why the word int is used at the begining of line 3. We have a few preliminary topics to cover before we get to these items. ANOTHER PROGRAM WITH MORE OUTPUT Example program ------> WRTMORE.C Load the program WRTMORE.C and display it on your monitor for an example with more output and another small but important concept. You will see that there are four executable statements in this program, each one being a call to the function printf(). The top line will be executed first, then the next, and so on, until the fourth line is complete. The statements are executed sequentially from top to bottom. Notice the funny character near the end of the first line, namely the backslash. The backslash is used in the printf() statement to indicate that a special control character is following. In this case, the "n" indicates that a newline is requested. This is an indication to return the cursor to the left side of the monitor and move down one line. Any place within printed text that you desire, you can put a newline character to start a new line. You could even put it in the middle of a word and split the word between two lines. A complete description of this program is now possible. The first printf() outputs a line of text and returns the carriage. (Of course, there is no carriage, but the cursor is moved to the next line on the monitor. The terminology carries over from the days of teletypes.) The second printf() outputs a line of text but does not return the carriage so that the third line is appended to the end of the second, then followed by two carriage returns, resulting in a blank line. Finally the fourth printf() outputs a line followed by a carriage return and the program is complete. After compiling and executing WRTMORE.C, the following text should be displayed on your monitor; This is a line of text to output. And this is another line of text. This is a third line. Compile and execute this program to see if it gives you this output. It would be a good idea at this time for you to experiment by adding additional lines of printout to see if you understand how the statements really work. Add a few carriage returns in the middle of a line to prove to yourself that it works as stated, then compile and execute the modified program. The more you modify and compile the example programs included with this tutorial, the more you will learn as you work your way through it. LET'S PRINT SOME NUMBERS Example program ------> ONEINT.C Load the file named ONEINT.C and display it on the monitor for our first example of how to work with data in a C program. The entry point main() should be clear to you by now as well as the beginning brace. The first new thing we encounter is line 5 containing int index; which is used to define an integer variable named index. The word int is a keyword in C, and can not be used for anything else. It defines a variable that can store a whole number within a predefined range of values. We will define an actual range later. The variable name, index, can be any name that follows the rules for an identifier and is not one of the keywords for C. The final character on the line, the semi-colon, is the statement terminator as discussed earlier. Note that, even though we have defined a variable, we have not yet assigned a value to it, so it contains an undefined value. We will see in a later chapter that additional integers could also be defined on the same line, but we will not complicate the present situation. Observing the main body of the program, you will notice that there are three statements that assign a value to the variable index, but only one at a time. The statement in line 7 assigns the value of 13 to index, and its value is printed out by line 8. (We will see how shortly. Trust me for the time being.) Later, the value of 27 is assigned to index, and finally 10 is assigned to it, each value being printed out. It should be intuitively clear that index is indeed a variable and can store many different values but only one value at a time of course. Please note that many times the words "printed out" are used to mean "displayed on the monitor". You will find that in many cases experienced programmers take this liberty, probably due to the printf() function being used for monitor display. HOW DO WE PRINT NUMBERS? To keep our promise, let's return to the printf() statements for a definition of how they work. Notice that they are all identical and that they all begin just like the printf() statements we have seen before. The first difference occurs when we come to the % character. This is a special character that signals the output routine to stop copying characters to the output and do something different, usually to output the value of a variable. The % sign is used to signal the output of many different types of variables, but we will restrict ourselves to only one for this example. The character following the % sign is a d, which signals the output routine to get a decimal value and output it. Where the decimal value comes from will be covered shortly. After the d, we find the familiar \n, which is a signal to return the video "carriage", and the closing quotation mark. All of the characters between the quotation marks define the pattern of data to be output by this statement. Following the output pattern, there is a comma followed by the variable name index. This is where the printf() statement gets the decimal value which it will output because of the %d we saw earlier. The system substitutes the current value of the variable named index for the %d and copies it to the monitor. We could add more %d output field descriptors anywhere within the brackets and more variables following the description to cause more data to be printed with one statement. Keep in mind however, that the number of field descriptors and the number of variable definitions must be the same or the runtime system will generate something we are not expecting. Much more will be covered at a later time on all aspects of input and output formatting. A reasonably good grasp of these fundamentals are necessary in order to understand the following lessons. It is not necessary to understand everything about output formatting at this time, only a fair understanding of the basics. Compile and run ONEINT.C and observe the output. Two programming exercises at the end of this chapter are based on this program. HOW DO WE ADD COMMENTS IN C? Example program ------> COMMENTS.C Load the file named COMMENTS.C and observe it on your monitor for an example of how comments can be added to a C program. Comments are added to make a program more readable to you but represent nonsense to the compiler, so we must tell the compiler to ignore the comments completely by bracketing them with special characters. The slash star combination is used in C for comment delimiters, and are illustrated in the program at hand. Please note that the program does not illustrate good commenting practice, but is intended to illustrate where comments can go in a program. It is a very sloppy looking program. The slash star combination in line 3 introduces the first comment and the star slash at the end of that line terminates this comment. Note that this comment is prior to the beginning of the program illustrating that a comment can precede the program itself. Good programming practice would include a comment prior to the program with a short introductory description of the program. The comment in line 5 is after the main program entry point and prior to the opening brace for the program code itself. The third comment starts after the first executable statement in line 7 and continues for four lines. This is perfectly legal because a comment can continue for as many lines as desired until it is terminated. Note carefully that if anything were included in the blank spaces to the left of the three continuation lines of the comment, it would be part of the comment and would not be compiled, but totally ignored by the compiler. The last comment, in line 15, is located following the completion of the program, illustrating that comments can go nearly anywhere in a C program. Experiment with this program by adding comments in other places to see what will happen. Comment out one of the printf() statements by putting comment delimiters both before and after it and see that it does not get executed and therefore does not produce a line of printout. Comments are very important in any programming language because you will soon forget what you did and why you did it. It will be much easier to modify or fix a well commented program a year from now than one with few or no comments. You will very quickly develop your own personal style of commenting. Some C compilers will allow you to "nest" comments which can be very handy if you need to "comment out" a section of code during debugging. Since nested comments are not a part of the ANSI-C standard, none will be used in this tutorial. Check the documentation for your compiler to see if they are permitted with your implementation of C. Even though they may be allowed, it is a good idea to refrain from their use, since they are rarely used by experienced C programmers, and using them may make it difficult to port your code to another compiler if the need should arise. GOOD FORMATTING STYLE Example program ------> GOODFORM.C Load the file GOODFORM.C and observe it on your monitor. It is an example of a well formatted program. Even though it is very short and therefore does very little, it is very easy to see at a glance what it does. With the experience you have already gained in this tutorial, you should be able to very quickly grasp the meaning of the program in it's entirety. Your C compiler ignores all extra spaces and all carriage returns giving you considerable freedom in formatting your program. Indenting and adding spaces is entirely up to you and is a matter of personal taste. Compile and run the program to see if it does what you expect it to do. Example program ------> UGLYFORM.C Now load and display the program UGLYFORM.C and observe it. How long will it take you to figure out what this program will do? It doesn't matter to the compiler which format style you use, but it will matter to you when you try to debug your program. Compile this program and run it. You may be surprised to find that it is the same program as the last one, except for the formatting. Don't get too worried about formatting style yet. You will have plenty of time to develop a style of your own as you learn the C language. Be observant of styles as you see C programs in magazines and books. This covers some of the basic concepts of programming in C, but as there are many other things to learn, we will forge ahead to additional program structure. It will definitely be to your advantage to do the programming exercises at the end of each chapter. They are designed to augment your studies and teach you to use your compiler. PROGRAMMING EXERCISES
printf("Index is %d\n it still is %d\n it is %d", index, index, index); PROGRAM CONTROL THE WHILE LOOP The C programming language has several structures for looping and conditional branching. We will cover them all in this chapter and we will begin with the while loop. The while loop continues to loop while some condition is true. When the condition becomes false, the looping is discontinued. It therefore does just what it says it does, the name of the loop being very descriptive. Example program ------> WHILE.C Load the program WHILE.C and display it for an example of a while loop. We begin with a comment and the program entry point main(), then go on to define an integer variable named count within the body of the program. The variable is set to zero and we come to the while loop itself. The syntax of a while loop is just as shown here. The keyword while is followed by an expression of something in parentheses, followed by a compound statement bracketed by braces. As long as the expression in the parenthesis is true, all statements within the braces will be repeatedly executed. In this case, since the variable count is incremented by one every time the statements are executed, it will eventually reach 6. At that time the statement will not be executed because count is not less than 6, and the loop will be terminated. The program control will resume at the statement following the statements in braces. We will cover the compare expression, the one in parentheses, in the next chapter. Until then, simply accept the expressions for what you think they should do and you will be correct for these simple cases. Several things must be pointed out regarding the while loop. First, if the variable count were initially set to any number greater than 5, the statements within the loop would not be executed at all, so it is possible to have a while loop that never is executed. Secondly, if the variable were not incremented in the loop, then in this case, the loop would never terminate, and the program would never complete. Finally, if there is only one statement to be executed within the loop, it does not need delimiting braces but can stand alone. Compile and run this program after you have studied it enough to assure yourself that you understand its operation completely. Note that the result of execution is given for this program, (and will be given for all of the remaining example programs in this tutorial) so you do not need to compile and execute every program to see the results. Be sure to compile and execute some of the programs however, to gain experience with your compiler. You should make some modifications to any programs that are not completely clear to you and compile them until you understand them completely. The best way to learn is to try various modifications yourself. We will continue to ignore the #include statement and the return statement in the example programs in this chapter. We will define them completely later in this tutorial. THE DO-WHILE LOOP Example program ------> DOWHILE.C A variation of the while loop is illustrated in the program DOWHILE.C, which you should load and display. This program is nearly identical to the last one except that the loop begins with the keyword do, followed by a compound statement in braces, then the keyword while, and finally an expression in parentheses. The statements in the braces are executed repeatedly as long as the expression in the parentheses is true. When the expression in parentheses becomes false, execution is terminated, and control passes to the statements following this statement. Several things must be pointed out regarding the do-while loop. Since the test is done at the end of the loop, the statements in the braces will always be executed at least once. Secondly, if the variable i were not changed within the loop, the loop would never terminate, and hence the program would never terminate. It should come as no surprise to you that these loops can be nested. That is, one loop can be included within the compound statement of another loop, and the nesting level has no limit. This will be illustrated later. Compile and run this program to see if it does what you think it should do. THE FOR LOOP Example program ------> FORLOOP.C Load and display the file named FORLOOP.C on your monitor for an example of a program with a for loop. The for loop consists of the keyword for followed by a rather large expression in parentheses. This expression is really composed of three fields separated by semi-colons. The first field contains the expression "index = 0" and is an initializing field. Any expressions in this field are executed prior to the first pass through the loop. There is essentially no limit as to what can go here, but good programming practice would require it to be kept simple. Several initializing statements can be placed in this field, separated by commas. The second field, in this case containing "index < 6", is the test which is done at the beginning of each pass through the loop. It can be any expression which will evaluate to a true or false. (More will be said about the actual value of true and false in the next chapter.) The expression contained in the third field is executed each time the loop is exercised but it is not executed until after those statements in the main body of the loop are executed. This field, like the first, can also be composed of several operations separated by commas. Following the for() expression is any single or compound statement which will be executed as the body of the loop. A compound statement is any group of valid C statements enclosed in braces. In nearly any context in C, a simple statement can be replaced by a compound statement that will be treated as if it were a single statement as far as program control goes. Compile and run this program. The while is convenient to use for a loop when you don't have any idea how many times the loop will be executed, and the for loop is usually used in those cases when you are doing a fixed number of iterations. The for loop is also convenient because it moves all of the control information for a loop into one place, between the parentheses, rather than at both ends of the code. It is your choice as to which you would rather use. Depending on how they are used, it is possible with each of these two loops to never execute the code within the loop at all. This is because the test is done at the beginning of the loop, and the test may fail during the first iteration. The do-while loop however, due to the fact that the code within the loop is executed prior to the test, will always execute the code at least once. THE IF STATEMENT Example program ------> IFELSE.C Load and display the file IFELSE.C for an example of our first conditional branching statement, the if. Notice first, that there is a for loop with a compound statement as its executable part containing two if statements. This is an example of how statements can be nested. It should be clear to you that each of the if statements will be executed 10 times. Consider the first if statement. It starts with the keyword if followed by an expression in parentheses. If the expression is evaluated and found to be true, the single statement following the if is executed, and if false, the following statement is skipped. Here too, the single statement can be replaced by a compound statement composed of several statements bounded by braces. The expression "data == 2" is simply asking if the value of data is equal to 2. This will be explained in detail in the next chapter. (Simply suffice for now that if "data = 2" were used in this context, it would mean a completely different thing. You must use the double equal sign for comparing values.) NOW FOR THE IF-ELSE The second if is similar to the first with the addition of a new keyword, the else in line 17. This simply says that if the expression in the parentheses evaluates as true, the first expression is executed, otherwise the expression following the else is executed. Thus, one of the two expressions will always be executed, whereas in the first example the single expression was either executed or skipped. Both will find many uses in your C programming efforts. Compile and run this program to see if it does what you expect. THE BREAK AND CONTINUE Example program ------> BREAKCON.C Load the file named BREAKCON.C for an example of two new statements. Notice that in the first for loop, there is an if statement that calls a break if xx equals 8. The break will jump out of the loop you are in and begin executing statements immediately following the loop, effectively terminating the loop. This is a valuable statement when you need to jump out of a loop depending on the value of some results calculated in the loop. In this case, when xx reaches the value of 8, the loop is terminated and the last value printed will be the previous value, namely 7. The break always jumps out of the loop just past the terminating brace. The next for loop starting in line 15, contains a continue statement which does not cause termination of the loop but jumps out of the present iteration. When the value of xx reaches 8 in this case, the program will jump to the end of the loop and continue executing the loop, effectively eliminating the printf() statement during the pass through the loop when xx is eight. The continue statement always jumps to the end of the loop just prior to the terminating brace. At that time the loop is terminated or continues based on the result of the loop test. Be sure to compile and execute this program. THE SWITCH STATEMENT Example program ------> SWITCH.C Load and display the file SWITCH.C for an example of the biggest construct yet in the C language, the switch. The switch is not difficult, so don't let it intimidate you. It begins with the keyword switch followed by a variable in parentheses which is the switching variable, in this case truck. As many cases as needed are then enclosed within a pair of braces. The reserved word case is used to begin each case, followed by the value of the variable for that case, then a colon, and the statements to be executed. In this example, if the variable named truck contains the value 3 during this pass of the switch statement, the printf() in line 13 will cause "The value is three\n" to be displayed, and the break statement will cause us to jump out of the switch. The break statement here works in much the same manner as the loop, it jumps out just past the closing brace. Once an entry point is found, statements will be executed until a break is found or until the program drops through the bottom of the switch braces. If the variable truck has the value 5, the statements will begin executing at line 17 where "case 5 :" is found, but the first statements found are where the case 8 statements are. These are executed and the break statement in line 21 will direct the execution out of the bottom of the switch just past the closing brace. The various case values can be in any order and if a value is not found, the default portion of the switch will be executed. It should be clear that any of the above constructs can be nested within each other or placed in succession, depending on the needs of the particular programming project at hand. Note that the switch is not used as frequently as the loop and the if statements. In fact, the switch is used infrequently but should be completely understood by the serious C programmer. Be sure to compile and run SWITCH.C and examine the results. THE EVIL GOTO STATEMENT Example program ------> GOTOEX.C Load and display the file GOTOEX.C for an example of a file with some goto statements in it. To use a goto statement, you simply use the reserved word goto followed by the symbolic name to which you wish to jump. The name is then placed anywhere in the program followed by a colon. You can jump nearly anywhere within a function, but you are not permitted to jump into a loop, although you are allowed to jump out of a loop. This particular program is really a mess but it is a good example of why software writers are trying to eliminate the use of the goto statement as much as possible. The only place in this program where it is reasonable to use the goto is the one in line 23 where the program jumps out of the three nested loops in one jump. In this case it would be rather messy to set up a variable and jump successively out of each of the three nested loops but one goto statement gets you out of all three in a very concise manner. Some persons say the goto statement should never be used under any circumstances, but this is narrow minded thinking. If there is a place where a goto will clearly do a neater control flow than some other construct, feel free to use PARAMETER PASSING After teaching C programming for several years, I found that there are certain concepts that are difficult to understand and are often misunderstood by new programmers. This is even true of some programmers that have been using C for several years. This document will define how parameters are passed to functions. A detailed knowledge of how this is done in C and C++ will allow you to write more efficient and more robust programs. HOW IS DATA PASSED TO A FUNCTION? Consider the very simple program given in the listing immediately below. This program makes a single call to the function named product(), and it passes two parameters to that function. We can also see that the function returns a single value which is of type int. Because this is a trivial program, and we wish to keep it simple, a prototype for the function is not included. A real program should also do something with the returned result named area which we simply ignore in this example. int length = 12; int width = 5; int main() { int area; area = product(length, width); /* The call to the function */ } int product(int side1, int side2) /* The function header */ { return side1 * side2; } This is a trivial program, but it will be the starting point for our study of how parameters are passed to a function. If we consider the two lines that are commented on in the example code, we can extract the following two statements, which are executed each time the function named product() is called. int side1 = length; int side2 = width; Even though these two statements are not explicitly given in the code, they are nevertheless executed with each call to product() because of the way C is defined. The first statement is saying, "create a variable for use within the function that is of type int, named side1, and initialize it to the value of length from the calling program". Anytime we refer to the variable named side1 within the function, we are referring to the local copy of the variable, and if we change the value stored in side1, we do not affect the value of length back in the calling program because we are working only with side1. The same is true of the second parameter. We are telling the system to create a variable named side2 which is of type int, and initialize it to the value of width from the main program. When we return from the function, the two new variables are no longer needed so they are deleted. When we say they are deleted, they are not set equal to zero, or any other value, they actually cease to exist. They are deallocated by the C runtime system. A GRAPHICAL REPRESENTATION OF THIS OPERATION If you have not already done so, read the Memory Diagram document which defines some of the terms given below including the graphical diagramming conventions used by this author A picture is said to be worth a thousand words, so let's draw a picture. Figure 1 is a diagram of the memory space of the computer just prior to making the call to the function. (This is actually a greatly simplified diagram, but it will help us get started in understanding just what is happening. We will fill in more details later.) The function main() and the function product() are stored somewhere in the global memory space of the computer, and the stack is allocated by the C runtime system for use by our program. The two boxes represent storage for each of the two global variables named length and width. The storage for each of these two variables will be created just large enough to store an int type variable on our system. The stack is currently empty. You will notice that each of the variables has a value as a result of the initialization in the code. (I am purposely ignoring the variable named area for the time being. We will explain where it is stored later in this document.) When the call to the function is made, the system creates a variable named side1 of type int and copies the value of length from the main program into it. This variable is created on the stack and can be used within the function. Likewise, another variable is created on the stack named side2 of type int and the value of width is copied into it. Neither of these two variables is available for use within the calling program, but are only available to the function named product(). The memory space now looks like figure 2, and the code in the function named product() is executed with full access to the two parameters on the stack. Because the variables named length and width are global, they are also available for use or modification within the function named product(). When execution of the function code is complete, the value of the product of the two variables is returned to the calling program, which can do whatever it wishes to do with it. The two variables are removed from the stack and discarded or, to be a little more proper, they are deallocated. We will say more about the returned value later in this document. When we return to the calling program, the memory space can be diagrammed as shown in figure 3. You will notice that figure 3 is identical to figure 1. Based on what we have said so far, the following facts should be clear to you;
We can define a generalized assignment for each parameter that is passed to a function, formal_type formal_parameter = actual_parameter; We are still not worried about the return value or the variable named area. We will define them completely later, but I am more interested in defining the parameter passing scheme at this time. LET'S REFINE THE MODEL SOME We will repeat the first program with a slight modification and we will be a little more correct since we will not ignore any of the variables. We will move the two global variables into the main program so that they are local variables, and if you studied C diligently, you will recall that they are also called automatic variables. They are called automatic variables because they are automatically allocated when they are needed. If you guess that they are allocated on the stack, you are right. The new code is given as follows; int main() { int length = 12; int width = 5; int area; area = product(length, width); /* The call to the function */ } int product(int side1, int side2) /* The function header */ { return side1 * side2; } Now we have a slightly different memory layout. The automatic variables are all allocated on the stack as they are encountered in the main program, so that when we arrive at the function call in the main program, the memory layout is as depicted in figure 4. The three variables on the stack can be accessed by the main() program. I promised earlier that I would show you where the variable area is stored, and you can see that it is on the stack because it is an automatic variable. It is a little different from the other two variables however, because it has not been initialized. Local variables are not automatically initialized by the system, but contain whatever bit pattern happened to be in that memory location. At this time therefore, the variable named area contains any value imaginable that is legal for an int type variable. The variables named width and length are explicitly initialized in the code. During the call to the function, the system allocates the two parameters on the stack as it did in the last program, initializes them to the required values as illustrated above, and we have the resulting memory layout given in figure 5 just prior to executing the return statement. The stack now contains 5 variables. Three are available exclusively to the main() function, and two are available exclusively to the product() function. The word exclusively is essential in the preceding statement. The variables cannot be seen by any address space within the memory other than where they are defined because of the way C is defined. Since we moved the two global variables into the main() function, they are no longer visible when we are executing code within the product() function. Execution of the return statement in the function, causes the two variables for the function to be deallocated from the stack, and control returns to the main() function. At this time, the memory space will look very much like figure 4 again but with a meaningful value stored in area. We can make up two more rules of argument passing and stack operations;
|
Or If You Wanted The Complete C Language Guide
Download this "Let Us C" Book..
0 comments:
Post a Comment