⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loopexit.txt

📁 c语言开发方面的经典问题,包括源代码.c语言开发所要注意的问题,以及在嵌入式等各方面的应用
💻 TXT
📖 第 1 页 / 共 2 页
字号:
                 Loop Exits and Structured Programming:                          Reopening the Debate                            Eric S. Roberts                     Department of Computer Science                          Stanford UniversityNOTEThis paper has been submitted to the Twenty-sixth SIGCSE TechnicalSymposium on Computer Science Education.  Copyright is retained by theauthors prior to publication release.ABSTRACTInternal exits from loops represent a critically important controlstructure that should be taught in the introductory CS1 curriculum.Without access to those facilities, students are often incapable ofsolving simple programming problems that occur frequently inapplications.  This paper reviews the existing evidence in support ofsuch facilities and argues that it is important to reconsider ourtraditional pedagogical approach as we adopt new languages ofinstruction.1.  INTRODUCTIONTwenty-five years ago, a fierce debate raged within the computer sciencecommunity over the issue of structured programming.  At its essence,structured programming represents a disciplined approach to softwaredevelopment based on abstraction, stepwise refinement, and a formalapproach to program correctness [Dahl72].  Unfortunately, as the debateprogressed, attention was focused less on the general issues raised bystructured programming than on a relatively small detail: whether or notit is ever appropriate to use the goto statement in a well-structuredprogram.  Launched by a letter from Edsger Dijkstra in 1968[Dijkstra68], the goto controversy raged back and forth over the nextseveral years, often resembling a religious war in emotional intensity.In the late 1970s, the debate died down, and a period of relative peaceensued.The underlying controversy, however, has not gone away, and the questionof which control structures are acceptable remains a source ofpassionate concern.  The intensity of that concern has been demonstratedby some of the reactions I have received to the new CS1/CS2 curriculumat Stanford and to my textbook, The Art and Science of C: A Library-Based Approach [Roberts95], which reflects the curricular revisions wehave undertaken at Stanford.  When we converted the curriculum fromPascal to C [Roberts93], I decided -- on the basis of many years ofclassroom experience -- that we should move beyond the limited controlstructures available in Pascal and allow students to exit from theinterior of a loop in the following two cases:  1.  When the structure of a loop requires some preparation (such      as reading an input value) before making the test for      termination, I encourage students to use the break statement      to force explicit exit from the interior of a loop.  This      strategy, which is discussed in Section 3, allows students to      solve what Dijkstra calls the loop-and-a-half problem in a way      that both appeals to the student's intuition and avoids      duplication of code.  2.  In the context of a function, I encourage students to use the      return statement as soon as the value of the function becomes      known, even if that return statement would force an early exit      from a loop within the function.  Allowing return to be used      in this way makes it much easier for students to solve a      variety of problems, as illustrated in Section 4.Although the response to my text has been quite favorable, the decisionto allow internal loop exits in these restricted cases has elicited somenegative response.  One reviewer, for example, wrote that using break"is akin to using the proverbial goto."  Another charged that myapproach violates the basic tenets of structured programming.  A thirddeclared that my use of break to exit from a while loop is simply"unacceptable," ruling out any further consideration.The negative reactions expressed in such reviews underscore thecontinued existence of controversy over what control structures areacceptable for academic use.  This paper summarizes the evidencesupporting the use of internal loop exits and embedded returnstatements, and examines the dangers associated with restrictingstudents to a more tightly constrained control model.For many years, it was easy to discount the evidence in favor ofinternal loop exits.  As long as Pascal was overwhelmingly accepted asthe best language for teaching introductory programming, the issue hadlittle practical relevance.  In Pascal, internal loop exits are simplynot available, and those who adhere to the standard version of thelanguage are therefore forced to accept the control structures thatPascal provides.In the last few years, however, many schools have abandoned Pascal formore modern languages.  For the most part, the new languages -- eventhose that follow directly in the Pascal tradition such as Modula-2 andAda -- include both a structured mechanism for exiting from the interiorof a loop and an active return statement.  The availability of thesefacilities gives new relevance to the underlying pedagogical question ofhow to teach control structures at the introductory level.  It is timeto reopen the debate.2.  SUFFICIENCY VERSUS PRACTICAL UTILITYBefore exploring the accumulated evidence that supports the use ofinternal loop exits, it is important to acknowledge that the controlstructures provided by Pascal have a sound theoretical basis.  In their1966 paper, Boehm and Jacopini proved that it is possible to code anyflowchart program using four control structures: atomic actions,sequential composition, if-then-else, and while-do.  These structuresbecame known as D structures, after Edsger Dijkstra, and were soonextended to form a larger set of control primitives called D' structures[Ledgard75] that also includes the if-then, repeat-until, and casestatements as they exist in Standard Pascal.  Thus, the statementsprovided by Pascal indeed constitute a sufficient set of controlprimitives, in the theoretical sense.The key point, however, is that theoretical sufficiency is not in itselfthe principal criterion for program language design.  After all, thearithmetic if and goto statements provided by Fortran II also constitutea sufficient set by this definition, but no one would seriously advocateusing those statements as the basis for control structures in this dayand age.  The discipline encouraged by the use of D structures leadsempirically to more reliable and more easily maintained programs thanFortran's primitives support.  Thus, although the evolution of Dstructures represented an important practical advance for programminglanguage design, theoretical sufficiency was not the primary reason forits success.  If it were, language designers would have seen no need toaugment the set of D structures with the extremely useful D' forms.A similar illustration can be drawn from the standard set of Booleanoperators.  Most languages define and, or, and not as the primitiveoperations on Boolean data.  If one's primary concern is linguisticeconomy, this set could easily be considered wasteful, because thesingle operator nand (or, equivalently, the operator nor) would besufficient in theoretical terms.  This theoretical result is criticalfor hardware designers, who are able to exploit the sufficiency of asingle operator to achieve greater regularity in the design ofintegrated circuits.  For programmers, on the other hand, the fact thatnand is by itself sufficient has little practical relevance.  Theaverage applications programmer has no intuition regarding the behaviorof nand and therefore would not know how to use it effectively.Programming problems tend to be phrased in terms of the traditionallogical connectives, and it is for this reason -- the admittedlysubjective criterion of "naturalness" in the sense of being consistentwith intuition -- that and, or, and not form the basis of Booleancalculation.The question of what set of control structures is appropriate istherefore larger than the question of whether a particular set ofprimitives is sufficient.  It is also important to consider whether thecontrol structures are suitable for the problems that tend to arise inpractical programming, or, perhaps more importantly, whether thestructures suit the ways in which programmers conceive of thoseproblems.  If they do not, and if empirical evidence indicates thattransforming a conceptual image of a problem into an approved controlframework tends to introduce error or unnecessary complexity, it isimportant to examine that framework to determine whether extensions arerequired.3.  THE LOOP-AND-A-HALF PROBLEMThe fact that some loop structures seem to have a natural exit in themiddle has long been recognized.  In his 1974 comments on the gotocontroversy [Knuth74], Don Knuth outlined his own perspective, asfollows:      The iteration statements most often proposed as alternatives      to goto statements have been "while B do S" and "repeat S      until B".  However, in practice the iterations I encounter      very often have the form                A:  S;                    if B then goto Z fi;                    T;                    goto A                Z:      where S and T both represent reasonably long sequences of      code.  If S is empty, we have a while loop, and if T is      empty we have a repeat loop, but in the general case it is a      nuisance to avoid the goto statements.  A typical example of      such an iteration occurs when S is the code to acquire or      generate a new piece of data, B is the test for end of data,      and T is the processing of that data.Loops of this sort, in which some processing must precede the test, comeup quite often in programming and constitute what Dijkstra has calledthe loop-and-a-half problem.  The canonical example of the loop-and-a-half problem is precisely the one that Knuth describes: reading a set ofinput values until some sentinel value appears.  If the basic strategyis expressed in pseudocode, the problem has the following solution:          loop            read in a value;            if value = Sentinel then exit;            process the value          endloop;In this example, the loop/exit/endloop statement is an extension to thePascal repertoire and represents a loop that is terminated only by theexecution of the exit statement in the interior of the loop body.  Theloop/exit/endloop extension makes it possible to express the algorithmso that the input value is read in from the user, tested against thesentinel, and then processed as necessary.The loop/exit/endloop approach, however, offends the sensibilities ofmany computer science instructors, who have learned through theirexperience with Pascal to "unwind" the loop so that the test appears atthe top of the while loop, as follows:          read in a value;          while value != Sentinel do begin            process the value;            read in a value          end;Unfortunately, this approach has two serious drawbacks.  First, itrequires two copies of the statements required to read the input value.Duplication of code presents a serious maintenance problem, becausesubsequent edits to one set of statements may not always be made to theother.  The second drawback is that the order of operations in the loopis not the one that most people would expect.  In any Englishexplanation of the solution strategy, the first step is to read in anumber, and the second is to process it by adding it to the total.  Thetraditional Pascal approach reverses the order of the statements withinthe loop and turns a read/process strategy into a process/read strategy.As the rest of this section indicates, there is strong evidence tosuggest that the read/process strategy is more intuitive, in the sensethat it corresponds more closely to the cognitive structures programmersuse to solve such problems.The problem of code duplication is in some sense objective.  Thestatements that read in an input value do in fact appear twice in theprogram, and it is easy to imagine that an edit in one copy might not bemade symmetrically in the other.  The second problem, however, isinherently more subjective because it hinges on the question of whichloop order is more "intuitive."  What is intuitive for some may not beintuitive for others, and it may be that a preference for one strategyover another represents nothing more than an individual bias.  For thatreason, it is important to rely on empirical measurement of the successthat students have in using the different strategies.The best known study of this form was conducted by Elliot Soloway,Jeffrey Bonar, and Kate Ehrlich at Yale University in the early 1980s.In their experiments, student programmers with varying levels ofexperience were divided into experimental and control groups.  Thestudents in each group were then asked to write a program to average alist of integers terminated by a sentinel value.  Those in the controlgroup were instructed to solve the problem using Standard Pascal.  Thosein the experimental group were asked to use a variant of Pascal (PascalL) in which the standard looping statements while and repeat werereplaced by a new loop construct having the following form:          loop            statements            if condition leave;            statements          againThe loop statement allows for a structured exit from the interior of theloop and therefore permits the use of a read/process strategy.  Theresults of the experiment appear in the abstract of the paper publishedin Communications of the ACM  [Soloway83]:      Subjects overwhelmingly preferred a read/process strategy      over a process/read strategy.  When writing a simple looping      program, those using the loop . . . leave . . . again      construct were more often correct than were those using the      standard Pascal loop constructs.The correctness argument is particularly compelling.  At all levels ofexperience, students using Pascal L were more likely to write correctprograms than were their counterparts in the control group.  The outcomeis all the more significant because the students in the experimentalgroup had little chance to become familiar with the new loop construct,as indicated by the following passage from the paper:      Given that students were exposed to the loop . . . leave      . . . again construct of Pascal for only a few minutes, and      given that they had much more familiarity and experience      with Pascal's standard loop constructs, we were quite      impressed with the high performance of the Pascal L users.      Thus, these data support the claim that people will write      correct programs more often if they use the language that      facilitates their preferred strategy.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -