home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 200_01 / prog.man < prev    next >
Text File  |  1979-12-31  |  153KB  |  4,789 lines

  1.  
  2.  
  3.  
  4.  
  5.        Introduction to SCI Programming                     1
  6.  
  7.  
  8.        1.  IIIInnnnttttrrrroooodddduuuuccccttttiiiioooonnnn    ttttoooo SSSSCCCCIIII PPPPrrrrooooggggrrrraaaammmmmmmmiiiinnnngggg
  9.  
  10.        This section of the manual is a tutorial    introduction to    the
  11.        C  language.   If  you  have a casual knowledge of BASIC    and
  12.        understand some of the fundamental concepts of  programming,
  13.        you  should  have  no  difficulty  in following along.  This
  14.        tutorial    is designed to be used along with SCI, so  get    out
  15.        your  working copy of the SCI distribution diskette. You    did
  16.        make a backup copy, didn't you? If not, DO NOT PASS  GO,     DO
  17.        NOT   COLLECT  $200  until  you've  read     and  followed    the
  18.        instructions in the Introduction    section    of the    SCI  User's
  19.        Manual!
  20.  
  21.        Now go ahead and    start up SCI.  The  interpreter     should     be
  22.        loading    the  default  "shell"  file,  SHELL.SCI.  This file
  23.        simply  contains     a  C  program    that  is  run  by  the    SCI
  24.        interpreter.   It  performs several functions (most of which
  25.        shall remain invisible to you for the moment), but the  most
  26.        important  is  to  allow     you to    write and test SCI programs
  27.        immediately.  After the    interpreter  has  started  up,    you
  28.        should    see  SCI's  program  identification  banner  and  a
  29.        greater-than symbol (>),    like this:
  30.  
  31.            A> SCI
  32.            Small C Interpreter, V1.5 20Oct86 Copyright (C) 1986 Bob    Brodt
  33.            SCI Shell V1.5 20Oct86 Copyright    (C) 1986 Bob Brodt
  34.            shell>
  35.  
  36.        The "shell>" tells you that SCI is now ready to accept input
  37.        from  you.  One of the nicest features of SCI is    its ability
  38.        to immediately perform any C statement that  you     type.     As
  39.        you  will learn later, every C statement    produces a value as
  40.        a side-effect.  One of the  functions  of  SHELL.SCI  is     to
  41.        print this value    as a decimal number after the statement    has
  42.        been  executed.     Thus,    you  could  enter  some     arithmetic
  43.        expression like the following:
  44.  
  45.            shell> 2+2;
  46.            4
  47.            shell>
  48.  
  49.        and have    the SCI    shell print the    result,    just like BASIC.
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.        2                       SCI Statement Structure
  69.  
  70.  
  71.        2.  SSSSCCCCIIII SSSSttttaaaatttteeeemmmmeeeennnntttt SSSSttttrrrruuuuccccttttuuuurrrreeee
  72.  
  73.        In the above example, notice the    semicolon at the end of    the
  74.        line.   The  C language allows you to write programs without
  75.        regard to "white    space" (spaces,    tabs and  ends    of  lines).
  76.        This  means that    the components of program statements can be
  77.        seperated by as many spaces or tabs  as    you  like;  program
  78.        lines can be grouped together seperated from the    rest of    the
  79.        program by blank    lines, to show the reader that they perform
  80.        a   discrete  function;    you  can  indent  groups  of  lines
  81.        following a program looping statement to    show where the loop
  82.        starts  and  ends.   By    allowing  you  to  "sculpture" your
  83.        program like this, C lets you write very    easy  to  read    and
  84.        understand programs.  This is very much in contrast to BASIC
  85.        which requires every program statement to start with a  line
  86.        number,    followed by a space and    then the statement all on a
  87.        single line.  Because C is  such     a  free-form  language     it
  88.        would  have  a  difficult  time    recognizing  the  end  of a
  89.        statement without some kind  of    "end-of-statement"  marker.
  90.        This is the purpose of the semicolon.
  91.  
  92.        Now we're going to confuse you even further by  telling    you
  93.        that SCI    doesn't    need a semicolon at the    end of a statement!
  94.        Because it's an interpreter, SCI    recognizes either  the    end
  95.        of  a line or a semicolon as an end-of-statement    marker.     In
  96.        fact, if    a statement spills over    onto another program  line,
  97.        SCI  will  complain  -  it  requires that every statement be
  98.        completely contained on    one  line.   This  restriction    was
  99.        imposed    by  the     fact  that SCI    is an interpreter and not a
  100.        compiler.  This is an important difference between  "SCI     C"
  101.        and  "standard  C"  (which  allows  a single statement to be
  102.        spread out over several lines).    So if you are an experience
  103.        "C hacker", please be aware of this fact.
  104.  
  105.  
  106.        3.  SSSSCCCCIIII PPPPrrrrooooggggrrrraaaammmm SSSSttttrrrruuuuccccttttuuuurrrreeee
  107.  
  108.        When  learning  a  new  programming  language,  it's  always
  109.        helpful to recall fundamentals and ask yourself the question
  110.        "what is    a program?".  Simply stated, a program is a list of
  111.        instructions  that  tell    the computer exactly what to do.  A
  112.        program written in the BASIC language is    an ideal example of
  113.        this  concept; a    list of    instructions.  The instructions    are
  114.        numbered    to make    it easy    to see the order in  which  they'll
  115.        be performed.  Let's examine a fragment from a BASIC program
  116.        and identify some of its    key components.
  117.  
  118.  
  119.  
  120.  
  121.  
  122.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.        SCI Program Structure                         3
  132.  
  133.  
  134.            100 REM *** sort    a list of numbers in ascending order ***
  135.            110 DIM NUM(100),RSP$(80)
  136.            120 REM get the unsorted    number list
  137.                .
  138.                .
  139.                .
  140.            220 REM got 'em,    now sort 'em then print    'em
  141.            230 GOSUB 500
  142.            240 FOR I=1 TO 100
  143.            250    PRINT NUM(I)
  144.            260 NEXT    I
  145.            270 PRINT "Got another list to sort?";
  146.            280 INPUT RSP$
  147.            290 IF RSP$="Y" THEN GOTO 120
  148.            300 END
  149.            500 REM *** bubble sort routine ***
  150.            510 REM sorts the numbers in the    array "NUM"
  151.                .
  152.                .
  153.                .
  154.            600 RETURN
  155.  
  156.        Even the    novice BASIC programmer    can glance at this  program
  157.        fragment    and tell what's    happening: it starts with line 100,
  158.        which is    a note to the (human) reader telling him  what    the
  159.        program intends to do - sort a bunch of numbers in ascending
  160.        order.  Line 110    tells the computer to reserve  some  memory
  161.        storage    we'll  need  later.   Remember    that  BASIC  allows
  162.        variables to be "known" to every    instruction in the program.
  163.        Thus,  you  (the    programmer) can    not effectively    control    and
  164.        limit access to variables.  This    makes it difficult at times
  165.        to  determine  where  in    the program a variable is being    set
  166.        when it shouldn't be.  This is a    very  important     difference
  167.        between BASIC and C, as you will    find out later.
  168.  
  169.        The word    "GOSUB"    at line    230 tells the computer to hold    its
  170.        place  at  the current location in the program, then jump to
  171.        instruction  number  500.   The     "RETURN"   at     line    600
  172.        corresponds  to    the  "GOSUB"  and  tells  the  computer     to
  173.        continue    with the instruction following the "GOSUB".  Notice
  174.        that  the  set  of  instructions     from  line  500 to 600    are
  175.        general-purpose in nature and  could  possibly  be  used     in
  176.        another     BASIC    program     that  required     a  number  sorting
  177.        function.  However, to interface    this sub-program to another
  178.        program    would  probably    require    modifications to either    the
  179.        other program or    the sub-program, or both.  This     makes    the
  180.        thought    of  extracting the number sorting function somewhat
  181.        less attractive.
  182.  
  183.  
  184.  
  185.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.        4                     SCI Program Structure
  195.  
  196.  
  197.        Now  look  at  the  instructions     from  line  270  to   290.
  198.        Essentially,  these  ask     the  program user if there are    any
  199.        more numbers to sort, and jump back to the beginning of    the
  200.        program    to  start the process all over again.  But, what if
  201.        the programmer decides at some  later  time  to    modify    the
  202.        program    and  accidentally  deletes line    120 - the target of
  203.        the "GOTO" instruction  at  290.      BASIC     would    be  totally
  204.        confused,  since     it  wouldn't  be  able     to  find  line    120
  205.        anymore.      Although  numbering  program    instructions,  like
  206.        BASIC  does,  is    very nice and neat and makes a program easy
  207.        for the human reader to follow, it can  become  unmanageable
  208.        as the program grows in complexity.
  209.  
  210.        Now let's take a    look at     the  comparable  program  fragment
  211.        written in C.  Please don't be concerned    with the details of
  212.        this program at the moment, but rather focus on the  overall
  213.        structure:
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.        SCI Program Structure                         5
  258.  
  259.  
  260.            # *** sort a list of numbers in ascending order ***
  261.            main()
  262.            {
  263.                char num[100], rsp[80];
  264.  
  265.                while ( 1 )
  266.                {
  267.                    # get the unsorted number list
  268.                        .
  269.                        .
  270.                        .
  271.                    # got 'em, now sort 'em then print 'em
  272.                    sort( num );
  273.                    i=0;
  274.                    while ( i<100 )
  275.                    {
  276.                        printf( "%d\n", num[i] );
  277.                        ++i;
  278.                    }
  279.                    puts( "Got another list to sort?" );
  280.                    gets( rsp )
  281.                    if ( rsp[0] != 'Y' )
  282.                        break;
  283.                }
  284.            }
  285.            sort( numlist )
  286.            char numlist[];
  287.            {
  288.                # bubble    sort routine
  289.                    .
  290.                    .
  291.                    .
  292.            }
  293.  
  294.        The first thing that strikes the    BASIC  programmer  when     he
  295.        looks  at  a C program is the absence of    line numbers! The C
  296.        language    relies purely on the location of statements  within
  297.        a program to determine the order    of program execution.
  298.  
  299.        In the above example, notice the    presence  of  the  matching
  300.        left  and right curly braces ({ and }).    These serve to bind
  301.        together    logical    sections of the     program.   In    particular,
  302.        notice  the  first  "{" (following "main()") and    its partner
  303.        towards the end of the program.    These  particular  matching
  304.        braces  are  used  to "bind" everything between them to make
  305.        one functional  unit.  This  functional    unit  is  called  a
  306.        "function"  in  C.   Each  function  can    be thought of as an
  307.        autonomous  entity  -  everything  within  the  function     is
  308.  
  309.  
  310.  
  311.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.        6                     SCI Program Structure
  321.  
  322.  
  323.        accessible  only     to  statements     within    that function.    The
  324.        name of the function can    be  found  immediately    before    the
  325.        first  "{",  in    this  case,  the function's name is "main".
  326.        Another function     can  be  found     towards  the  end  of    the
  327.        program,    its name is "sort".
  328.  
  329.        So, in contrast to BASIC, a C program  is  a  collection     of
  330.        these  modular  functions rather    than just a sequential list
  331.        of instructions.
  332.  
  333.  
  334.        4.  FFFFuuuunnnnccccttttiiiioooonnnnssss
  335.  
  336.        Think of    functions as a kind of    "black    box"  machine;    raw
  337.        materials,  in the form of information, goes into one end of
  338.        the machine and a final product comes out of the    other  end.
  339.        The  inner  workings  of    the machine are    hidden and we don't
  340.        really care to know how the machine works, as  long  as    the
  341.        final  product  is  what     we expected from the raw materials
  342.        supplied.
  343.  
  344.        In C, the "raw materials" passed    to a function are known     as
  345.        the function's "arguments" and the "final product" is called
  346.        the function's "return value".  C allows    you to pass as many
  347.        arguments  to  a    function as needed, but    the function always
  348.        returns one and only one    value.    In the section on Variables
  349.        we  will     see  how  a function can be made to _s_e_e_m to return
  350.        more than one value.
  351.  
  352.        To get SCI to execute the  statements  within  a     particular
  353.        function, all you have to do is mention the function's name.
  354.        In the program fragment shown above, you    would  type  either
  355.        "main()",  or  "sort()"    at the SCI prompt.  The    parentheses
  356.        following  a  function's     name  serve  two  purposes:   they
  357.        distinguish  the     entity     as being the name of a    function as
  358.        opposed    to  a  variable;  and  they  show  SCI    where    the
  359.        function's  arguments start and end.  If    a function does    not
  360.        require any arguments (as in "main()" above), you still need
  361.        to  supply  the    left  and right    parentheses.  If a function
  362.        requires    more than one argument,    each argument is  seperated
  363.        from the    preceding one with a comma (,) like so:
  364.  
  365.            func( 23, 15, 34    )
  366.  
  367.        Note that the spaces are    optional!
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.        Functions                             7
  384.  
  385.  
  386.        4.1  LLLLiiiibbbbrrrraaaarrrryyyy FFFFuuuunnnnccccttttiiiioooonnnnssss
  387.  
  388.        Beyond using it as a rather dumb    integer    calculator, you    can
  389.        use  the     SCI  shell  to    test out any valid C statement with
  390.        support from a large collection of built-in  functions.     As
  391.        you  work  through  this    tutorial, you will be introduced to
  392.        many of these, refered to hereafter as  "Library     Functions"
  393.        (see  the  section  on  Library Functions for more details).
  394.        You may,    if you like, think  of    the  Library  Functions     as
  395.        being  analogous     to  BASIC's built-in commands like "PRINT"
  396.        and "INPUT". Most of the    Library    Functions  are    similar     to
  397.        those  shipped  with  "industrial  strength" C compilers, so
  398.        many  of     the  programs    you  write  under  SCI    should     be
  399.        transportable with some minor changes.
  400.  
  401.        4.1.1  _p_u_t_d_(_)   The  Library  Function  "putd()"     prints      a
  402.        number,    or  the     results  of  a     calculation on    the console
  403.        screen.    Try entering the following commands from the shell:
  404.  
  405.            putd(123)
  406.            putd( 235 + 12370 )
  407.  
  408.        In the first example, the argument passed to "putd()" is    the
  409.        number  123.   The function should have printed "123" on    the
  410.        console screen.    In the second example, the argument is    the
  411.        sum  of    235  and  12370.   Note     that  this  calculation is
  412.        performed first,    then the result    is passed to  "putd()"    for
  413.        printing.
  414.  
  415.        Below the numbers that were printed by "putd()"    you  should
  416.        have  seen  a  zero printed as well.  This zero is the value
  417.        returned    by "putd()" and    was printed by the shell.  In  this
  418.        case,  the  return  value of a function was not particularly
  419.        useful.    We were    more interested    in the side-effect of  this
  420.        function, namely    the displaying of a number on the screen.
  421.  
  422.        4.1.2  _g_e_t_c_h_a_r_(_)     The Library Function "getchar()" waits    for
  423.        a  single keyboard key to be pressed, then returns the value
  424.        (in ASCII) of that key.    At the    shell  prompt,    try  typing
  425.        "getchar()",  hit  a carriage return and    then hit the letter
  426.        'a' key.     You should see    the number 97 printed by the shell,
  427.        the ASCII value in decimal of the character 'a'.
  428.  
  429.        Unlike "putd()",    this function  required     no  arguments    and
  430.        returned    a useful value.
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.        8                             Functions
  447.  
  448.  
  449.        4.1.3  _p_u_t_s_(_)  The function "puts()"  is     used  to  print  a
  450.        sequence     of characters (known in C jargon as a "string") on
  451.        the console.  A string is represented in    C  as  a  bunch     of
  452.        characters  enclosed  in     quotes    ("), just as in    BASIC.    Try
  453.        the following command, and be careful  to  type    the  string
  454.        exactly as it appears here:
  455.  
  456.            puts("hello world\n")
  457.  
  458.        Look closely at the string again    and  notice  the  backslash
  459.        (\)   just   before  the     letter     'n'.    This  two-character
  460.        combination (\n)    is standard  C    shorthand  notation  for  a
  461.        "newline" character.  Newlines have the effect of performing
  462.        a cariage return    plus  linefeed    on  the     console.   Had     we
  463.        omitted    the  "\n" from the string, "puts()" would have just
  464.        printed "hello, world" and left the cursor on the same line,
  465.        after  the  "d"    in  "world".   SCI  provides  other similar
  466.        shorthand notations, which will    be  explained  in  a  later
  467.        section.
  468.  
  469.  
  470.        5.  YYYYoooouuuurrrr    FFFFiiiirrrrsssstttt PPPPrrrrooooggggrrrraaaammmm
  471.  
  472.        Now it's    time to    write your first program.  If  you  haven't
  473.        already    done  so,  read     the  Editor  section of the User's
  474.        Manual and perform the installation  as    required  for  your
  475.        particular computer.  If    you are    unsuccessful in    getting    the
  476.        editor to work properly,    you can    create the sample  programs
  477.        with  your  favorite text editor, then start up SCI and load
  478.        the program file.  This will be tedious and time     consuming,
  479.        but  it    may  just  give     you  enough  understanding of C to
  480.        perform the editor installation properly. If all    else fails,
  481.        appeal to the author for    help!
  482.  
  483.        5.1  HHHHeeeelllllllloooo aaaaggggaaaaiiiinnnn,,,, wwwwoooorrrrlllldddd!!!!
  484.  
  485.        Either using the    built-in editor    or a seperate text  editor,
  486.        create the following program:
  487.  
  488.            hi()
  489.            {
  490.                puts("hello, world\n");
  491.            }
  492.  
  493.        Now, from the shell, type the name of the function,  "hi()".
  494.        You should see the following on your screen:
  495.  
  496.  
  497.  
  498.  
  499.  
  500.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.        Your First Program                         9
  510.  
  511.  
  512.            shell> hi()
  513.            hello world
  514.            0
  515.            shell>
  516.  
  517.        If instead you are rewarded with    an error  message  followed
  518.        by  a question mark, you    did something wrong! Hit a carriage
  519.        return or two to    get back to the    shell's    "shell>" prompt, go
  520.        back into the editor, fix the mistake and try it    again.
  521.  
  522.        Whether you realize it or not, this exercise is an important
  523.        first  step  for     learning  a  new programming language.     It
  524.        teaches you all of the routine motions  you  will  be  going
  525.        through    to  write  programs  and  gives     you  confidence to
  526.        continue    on.
  527.  
  528.        5.2  FFFFaaaahhhhrrrreeeennnnhhhheeeeiiiitttt ttttoooo CCCCeeeellllssssiiiiuuuussss
  529.  
  530.        Next, type in the following sample program:
  531.  
  532.            fahr(celsius)
  533.            {
  534.                return 9    * celsius / 5 +    32;
  535.            }
  536.  
  537.        This  is     a  simple  celsius   to   fahrenheit    temperature
  538.        conversion   function.     Notice      here     the   symbols    for
  539.        multiplication (*) and division (/) are the same    as in  most
  540.        other programming languages.
  541.  
  542.        Try executing this function with     a  few     different  celsius
  543.        values.     Each  time the    argument is converted to fahrenheit
  544.        and is returned to the shell to be printed.
  545.  
  546.        As an exercise, modify the program to print  the     fahrenheit
  547.        value and return    a value    of zero!
  548.  
  549.  
  550.        6.  SSSSttttaaaatttteeeemmmmeeeennnnttttssss:::: SSSSiiiimmmmpppplllleeee aaaannnndddd CCCCoooommmmppppoooouuuunnnndddd
  551.  
  552.        In C, a "statement"  is    just  what  you     might    expect;     an
  553.        imperative  instruction    to  the     computer  to  perform some
  554.        calculation.   Statements  are  generally   some      kind     of
  555.        arithmetic expression followed by a semicolon (or the end of
  556.        line in SCI) - we  have    encountered  them  before.   The  C
  557.        language     also allows you to group together several of these
  558.        "simple"    statements and treat them as  a     single     "compound"
  559.        statement.   This  is  done  by placing left and    right curly
  560.  
  561.  
  562.  
  563.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.        10                Statements: Simple and Compound
  573.  
  574.  
  575.        braces ({ and })    around the simple statements.    Let's  look
  576.        at the example below:
  577.  
  578.            {puts("hello ");puts("world\n");}
  579.  
  580.        Here, everything    within the left    and right  braces  and    the
  581.        braces  themselves  are    treated    as a single statement in C.
  582.        The C language also lets    us write the above  statement  like
  583.        this:
  584.  
  585.            {
  586.                puts( "hello " );
  587.                puts( "world\n" );
  588.            }
  589.  
  590.        Notice that the program becomes much  easier  to     read  when
  591.        each  statement    is written on a    seperate line.    Also notice
  592.        that we have indented the two  simple  statements  from    the
  593.        braces.     Indenting  is    the  accepted  way of conveying    the
  594.        intended    structure of a program.     We are     in  effect  saying
  595.        that these two lines "belong together" and should be treated
  596.        as a single unit.
  597.  
  598.        The compound statement in the above  example  was  obviously
  599.        created    for  demonstration  purposes  only.  If    it had been
  600.        encountered by itself in    a real program,     the  braces  would
  601.        have  been  superfluous    and  would  not     have  altered    the
  602.        behavior    of the program.     However, earlier we encountered an
  603.        instance     where    the  curly  braces  were  required,  namely
  604.        immediately following a function    definition.  Later on  when
  605.        we  discuss  program  flow  control,  we    will again sing    the
  606.        praises of compound statements.
  607.  
  608.        We will now make    just one  more    point  concerning  compound
  609.        statements  and    the  SCI  shell.   From    the shell, type    the
  610.        following two statements:
  611.  
  612.            shell> puts("hello "); puts(" world");
  613.            shell> {puts("hello "); puts(" world");}
  614.  
  615.        In the first instance, you saw that only     the  word  "hello"
  616.        was  printed  followed by the shell's "shell>" prompt.  This
  617.        is because the interpreter executes only    the first statement
  618.        it  finds  in  the  input line buffer.  Since a statement is
  619.        terminated by a semicolon, the second  call  to    "puts"    was
  620.        never  seen.  In    the second example, the    interpreter saw    the
  621.        left curly brace, recognized the    entire    line  as  a  single
  622.        statement, and executed both calls to "puts()".
  623.  
  624.  
  625.  
  626.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.        Statements: Simple and Compound                     11
  636.  
  637.  
  638.        6.1  CCCCoooommmmmmmmeeeennnntttt SSSSttttaaaatttteeeemmmmeeeennnnttttssss
  639.  
  640.        Comment statements are completely ignored by C  and  may     be
  641.        used  liberally    anywhere within    a program for documentation
  642.        purposes.  Standard C uses the two-character combinations /*
  643.        (pronounced  "slash-star")  and */ to mark the beginning    and
  644.        ending of comment statements:
  645.  
  646.            2 + /* this is a    comment    */ 2 + 2;
  647.  
  648.        The /* and */ need not necessarily be on     the  same  program
  649.        line, as    for example:
  650.  
  651.            2 + 2 + 2;
  652.            /*
  653.            this is a comment
  654.            */
  655.  
  656.        SCI  uses  the  number  symbol  (#)  to    introduce   comment
  657.        statements.   A    comment     in SCI    begins with a #    and ends at
  658.        the end of the line.  Being  an    interpreter,  SCI  required
  659.        that  comments  appear  on  a single line, so only a comment
  660.        start symbol was    required.  The above example  might  appear
  661.        in SCI like this:
  662.  
  663.            2 + 2 + 2;
  664.            #
  665.            # this is a comment
  666.            #
  667.  
  668.        Be careful when placing comments    because    everything  to    the
  669.        right  of  the first # symbol on    the line is ignored by SCI.
  670.        For  example,  the  following  comment  would  not  work     as
  671.        expected:
  672.  
  673.            2 + # this is a comment # 2 + 2;
  674.  
  675.  
  676.        7.  EEEExxxxpppprrrreeeessssssssiiiioooonnnnssss
  677.  
  678.        Expressions can be thought of as    components of a    C statement
  679.        -  the  values  and  operators that, when evaluated, yield a
  680.        result.    The most common    example     that  comes  to  mind    are
  681.        arithmetic expressions:
  682.  
  683.            2 + 3 - 5
  684.  
  685.  
  686.  
  687.  
  688.  
  689.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.        12                            Expressions
  699.  
  700.  
  701.        An expression becomes  a     statement  if    we  simply  tack  a
  702.        semicolon at the    end of it, thus:
  703.  
  704.            2 + 3 - 5;
  705.  
  706.        7.1  OOOOppppeeeerrrraaaattttoooorrrrssss
  707.  
  708.        Since C provides     a  plethora  of  operators,  we  will    not
  709.        discuss    them  all in this section but rather introduce them
  710.        as they become relavent to  the    discussion.   If  you  have
  711.        burning    desire    to  discover  all of C's operators, see    the
  712.        Appendix.  First, we will define    some commonly used terms.
  713.  
  714.        7.1.1  _B_i_n_a_r_y__O_p_e_r_a_t_o_r_s    The term "binary operator" does    not
  715.        refer to    bits and bytes but rather to the class of operators
  716.        that require two    (hence "binary") operands.  Some  of  these
  717.        you  have  probably  already  seen  if you are familiar with
  718.        other  programming  languages,  like   the   addition   (+),
  719.        subtraction   (-),   multiplication  (*)     and  division    (/)
  720.        operators.
  721.  
  722.        7.1.2  _U_n_a_r_y__O_p_e_r_a_t_o_r_s    Unary    operators   perform   their
  723.        functions  on  only one operand.     The subtraction symbol    (-)
  724.        is used as a unary operator when    it stands  in  front  of  a
  725.        number or a variable, like so:
  726.  
  727.            -45
  728.  
  729.        You may also use    the plus sign  (+)  as    a  unary  operator,
  730.        although     it  would  be    superfluous  since  all    numbers    are
  731.        assumed to be positive unless preceeded by a minus sign.      C
  732.        also  provides  other unary operators that will be discussed
  733.        later.
  734.  
  735.        7.2  PPPPrrrreeeecccceeeeddddeeeennnncccceeee
  736.  
  737.        If you will recall, in your high    school    algebra     class    you
  738.        learned    that  in  an  arithmetic  expression  containing  a
  739.        combination   of      addition,   subtraction,   division    and
  740.        multiplication,    the  division and multiplication are always
  741.        done before addition and    subtraction.  That is to  say  that
  742.        division     and multiplication "take precedence" over addition
  743.        and subtraction.     This property of precedence extends to    all
  744.        operators  in  the  C  language,     not  just  the     arithmetic
  745.        operators.
  746.  
  747.        You  may     defeat     the  normal  order  of     evaluation  of     an
  748.        expression by using parentheses,    just as    in modern algebra:
  749.  
  750.  
  751.  
  752.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  753.  
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.        Expressions                             13
  762.  
  763.  
  764.            (2 + 3) * 5
  765.  
  766.        This   will   perform   the   addition    first,     then    the
  767.        multiplication.     You  may  use    as  many  matched  sets     of
  768.        parentheses  as    necessary  to  disambiguate  the  order     of
  769.        evaluation:
  770.  
  771.            (  ( (2+3) / 2 )    * 5  )
  772.  
  773.        In fact,    it is a    good  idea  to    use  parentheses  liberally
  774.        whenever    you are    unsure of operator precedence.
  775.  
  776.        7.3  AAAAssssssssoooocccciiiiaaaattttiiiivvvviiiittttyyyy
  777.  
  778.        You also    learned    (hopefully in the same algebra class)  that
  779.        expressions  are     always    evaluated from left to right.  This
  780.        same rule applys    to expressions    in  C.     This  property     of
  781.        operators  is  known  as     associativity.      In C,    most of    the
  782.        binary operators    are evaluated _f_r_o_m _l_e_f_t    _t_o _r_i_g_h_t, while    the
  783.        unary operators are evaluated from _r_i_g_h_t    _t_o _l_e_f_t.
  784.  
  785.        7.4  AAAArrrriiiitttthhhhmmmmeeeettttiiiicccc ooooppppeeeerrrraaaattttoooorrrrssss
  786.  
  787.        Now we  are  finally  prepared  to  formally  introduce    C's
  788.        arithmetic  operators.    They  are  listed  here    in order of
  789.        decreasing precedence:
  790.  
  791.            * / %   multiplication, division    and modulo
  792.            + -     addition    and subtraction
  793.  
  794.        Most of these should already be familiar    to you.     The modulo
  795.        operator     (%)  gives  the remainder from    the division of    the
  796.        left value by the right value.  For example, the    result    of:
  797.        15 % 8 is 7.
  798.  
  799.        7.5  BBBBiiiittttwwwwiiiisssseeee OOOOppppeeeerrrraaaattttoooorrrrssss
  800.  
  801.        C also offers these bit-manipulation operators (again listed
  802.        in decreasing precedence):
  803.  
  804.            << >>   left and    right SHIFT
  805.            &       bitwise AND
  806.            ^       bitwise exclusive OR
  807.            |       bitwise OR
  808.  
  809.        If you have a need  to  do  bit    manipulation  but  are    not
  810.        familiar     with the above    terms (SHIFT, AND, OR and exclusive
  811.        OR), you    should probably     consult  a  textbook  on  computer
  812.  
  813.  
  814.  
  815.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  816.  
  817.  
  818.  
  819.  
  820.  
  821.  
  822.  
  823.  
  824.        14                            Expressions
  825.  
  826.  
  827.        programming since this is beyond    the scope of this tutorial.
  828.  
  829.        We will be learning more    about other C  operators  in  later
  830.        discussions.
  831.  
  832.  
  833.        8.  VVVVaaaarrrriiiiaaaabbbblllleeeessss
  834.  
  835.        Previously, we had only eluded to the fact that C does allow
  836.        you   to      create   named  data    storage     locations  (a.k.a.
  837.        "variables"), now we will formally introduce you    to  all     of
  838.        C's data    types.
  839.  
  840.        Except  for  the     pre-defined  Library  Functions  and    the
  841.        editor's     system-variables  (which  are found in    SHELL.SCI),
  842.        all variables must first    be made    known to the program before
  843.        they  may be used.  Unlike BASIC    where a    variable comes into
  844.        existance the very first    time it    is used    in a  statement,  C
  845.        requires    that every variable be formally    declared before    you
  846.        may use it within your program.    This section will cover    the
  847.        fundamentals of C variable declarations.
  848.  
  849.        8.1  NNNNaaaammmmiiiinnnngggg CCCCoooonnnnvvvveeeennnnttttiiiioooonnnnssss
  850.  
  851.        The precise rules governing the naming of variables  usually
  852.        varies  from  one  C  compiler to another. The rules for    SCI
  853.        variable    names are as follows:
  854.  
  855.        1.  a variable name may contain    any  number  of     characters
  856.        from    the set    of:
  857.  
  858.          1.       the letters "a" through "z" and "A" through "Z".
  859.  
  860.          2.       the underscore (_).
  861.  
  862.          3.       the digits "0" through "9".
  863.  
  864.        2.  the first character of a variable must not  be  a  digit
  865.        (i.e. it must be either a letter or an underscore).
  866.  
  867.        3.  the case  of     a  letter  is    significant,  for  example:
  868.        "foobar" is not the same as "Foobar"    or "FooBar".
  869.  
  870.        4.  a variable name may be as long as you like, but there is
  871.        a  limit  of     79  characters     per  line  imposed  by    the
  872.        interpreter.
  873.  
  874.  
  875.  
  876.  
  877.  
  878.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  879.  
  880.  
  881.  
  882.  
  883.  
  884.  
  885.  
  886.  
  887.        Variables                             15
  888.  
  889.  
  890.        8.2  DDDDaaaattttaaaa TTTTyyyyppppeeeessss
  891.  
  892.        The C language supports many different types  of     variables.
  893.        The  most  notable  difference between them is the amount of
  894.        memory storage each one    addresses.   The  least     amount     of
  895.        memory  a  variable  can     represent  depends  on    the type of
  896.        computer    the program is written for.  Typically,    this  is  a
  897.        byte of information, although some mainframe machines do    not
  898.        have the    capability to access memory in smaller than 2 or  4
  899.        byte  gobbles.    Most personal computers, however can access
  900.        memory one byte at a time and in    C, this    data type is  known
  901.        as the "char", short for    "character".
  902.  
  903.        8.2.1  _C_h_a_r  A "char" variable in SCI is    one byte  long    and
  904.        can  represent  a number    between    -128 and +127.    In order to
  905.        make a variable known to    the program we must  first  declare
  906.        it,  so to declare a "char" variable named "foobar" we would
  907.        write:
  908.  
  909.            char foobar;
  910.  
  911.        We can also declare more    than one variable of the same  type
  912.        on the same line    by seperating each with    a comma, like so:
  913.  
  914.            char foobar, snafu, gurgle;
  915.  
  916.        8.2.2  _I_n_t  Another variable type is the     "int",     short    for
  917.        "integer".   Again,  the    amount of memory an "int" addresses
  918.        is machine dependent.  In SCI, an "int" addresses two  bytes
  919.        of  memory,  and     can  represent    a number between -32768    and
  920.        +32767.    "Int"s are declared in a manner    similar    to "char"s:
  921.  
  922.            int foobar;
  923.            int snafu, wowbagger;
  924.  
  925.        Standard    C also defines other data types     such  as  floating
  926.        point   variables,   double  precision  integer    and  double
  927.        precision floating point.  You may also define your own data
  928.        types  that  are     a combination of these    primaries (known as
  929.        "structures").  Unfortunately, these are    all  not  supported
  930.        by this version of SCI.
  931.  
  932.        8.3  SSSSccccooooppppeeee
  933.  
  934.        If you are familiar with    BASIC, then you    already    know that a
  935.        BASIC  program  variable    is "known" throughout the program -
  936.        that is,    any  statement    within    the  program  may  alter  a
  937.        variable's  contents.   This "feature" can lead to some very
  938.  
  939.  
  940.  
  941.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  942.  
  943.  
  944.  
  945.  
  946.  
  947.  
  948.  
  949.  
  950.        16                              Variables
  951.  
  952.  
  953.        difficult to find programming bugs.  For    instance,  you    may
  954.        use a variable as a temporary loop counter in one section of
  955.        the program, only to discover later  that  you  had  already
  956.        decided    to  use     that  variable    for another purpose and    its
  957.        contents    were  continually  being  destroyed.   Ideally,     we
  958.        would like to be    able to    use variable names indiscriminantly
  959.        in one section of a program without having  to  worry  about
  960.        whether    the  variable name is being used in another section
  961.        of the program.    Happily, the C language    offers this ability
  962.        as  you    will  soon see.     This concept of limited (or rather
  963.        "controlled") access to variables is known as "scope".
  964.  
  965.        8.3.1  _G_l_o_b_a_l__V_a_r_i_a_b_l_e_s    In C, you may create variables that
  966.        are  known  throughout  the  program,  just  like  in BASIC.
  967.        Variables that have this    property are known as "globals"    and
  968.        just  like  BASIC,  every  statement  within the    program    may
  969.        retrieve    and store  the    value  of  a  global  variable.      A
  970.        variable     will  attain  global  status  if  it  was declared
  971.        outside of any curly braces ({ and }) that delimit the  body
  972.        of a function.  Here is an example to illustrate:
  973.  
  974.            char c;          # "c"    is a global
  975.            int i, j;      # and    so are "i" and "j"
  976.  
  977.            a_function()      # the    first function in the program
  978.            {
  979.                .
  980.                .
  981.                .
  982.            }
  983.  
  984.            char flag, nyuk;      # some more global variables
  985.  
  986.            another_function() # another function
  987.            {
  988.                .
  989.                .
  990.                .
  991.            }
  992.  
  993.        As you can see, C does not care where  within  a     program  a
  994.        global  variable     is  declared  as  long     as the    declaration
  995.        appears outside of any functions.
  996.  
  997.        SCI ensures that    global variables are  always  set  to  zero
  998.        before  the  program starts up. This is pretty much standard
  999.        behavior    for most C compilers as    well.
  1000.  
  1001.  
  1002.  
  1003.  
  1004.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1005.  
  1006.  
  1007.  
  1008.  
  1009.  
  1010.  
  1011.  
  1012.  
  1013.        Variables                             17
  1014.  
  1015.  
  1016.        In C, functions are also    considered to be globals - they    are
  1017.        known  throughout the program, although they obviously can't
  1018.        be used to store    data.
  1019.  
  1020.        8.3.2  _L_o_c_a_l__V_a_r_i_a_b_l_e_s  Variables that are  declared  inside
  1021.        of  the    curly  braces  that mark the beginning and end of a
  1022.        function    are known as "local" variables.     Locals    exist  only
  1023.        during the life of the function - that is the variable comes
  1024.        into existence after it has been    declared within    a  function
  1025.        and ceases to exist when    the function returns to    its caller.
  1026.        See the example below for clarification:
  1027.  
  1028.            char c;           # these are global variables
  1029.            int i;
  1030.            a_function()       # a function    definition
  1031.            {
  1032.                char snafu; # a local variable
  1033.                int x, y;   # some more locals
  1034.                .
  1035.                .
  1036.                .
  1037.                x = c;       # copy the global to    a local
  1038.            }
  1039.                    # snafu, x and y cease to exist here!
  1040.  
  1041.        Variable    declarations _m_u_s_t appear immediately after  a  left
  1042.        curly  brace;  if a declaration appears anywhere    else within
  1043.        the body    of a function SCI will warn  you  about     a  "syntax
  1044.        error".
  1045.  
  1046.        In addition, variables may be declared within  _a_n_y  compound
  1047.        statement  in  a     function, but the declarations    _m_u_s_t appear
  1048.        immediately after the opening brace.  Variables declared     in
  1049.        this  context  exist  only  for    the  life  of  the compound
  1050.        statement, i.e. to the matching    closing     brace.      Thus    the
  1051.        memory  these  variables     occupy     can  be re-used within    the
  1052.        function.  Below    is an example to illustrate:
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.  
  1065.  
  1066.  
  1067.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1068.  
  1069.  
  1070.  
  1071.  
  1072.  
  1073.  
  1074.  
  1075.  
  1076.        18                              Variables
  1077.  
  1078.  
  1079.        func()
  1080.        {
  1081.            char a;
  1082.            int i;
  1083.            .
  1084.            .
  1085.            .
  1086.            if ( i==0 )
  1087.            {
  1088.                int j;       # declare an    "int" in a compound stmt
  1089.                .
  1090.                .       # "a", "i" and "j" are all locals here
  1091.                .
  1092.            }           # "j" no longer exists here
  1093.            else if ( i==1 )
  1094.            {
  1095.                char j;       # a different "j" than above
  1096.                .
  1097.                .
  1098.                .
  1099.            }
  1100.        }
  1101.  
  1102.        SCI ensures that    locals are always zero just after they have
  1103.        been   declared.      On  standard    C  compilers,  the  initial
  1104.        contents    of locals is unknown, so  do  not  depend  on  them
  1105.        being zero.
  1106.  
  1107.        8.3.3  _F_u_n_c_t_i_o_n__A_r_g_u_m_e_n_t_s   Function  arguments     are   also
  1108.        considered  to  be  local  variables.  When a function calls
  1109.        another function    and passes it an argument,  the     argument's
  1110.        contents     is  copied  into  a  local  variable in the called
  1111.        function    -  the    value  of  the    caller's  argument  is    not
  1112.        affected.  This is best illustrated with    an example:
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129.  
  1130.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1131.  
  1132.  
  1133.  
  1134.  
  1135.  
  1136.  
  1137.  
  1138.  
  1139.        Variables                             19
  1140.  
  1141.  
  1142.        char c;         # the global variable,    "c"
  1143.        func1()
  1144.        {
  1145.            char c;     # a local may have the    same name as a global
  1146.            c = 1;     # and this sets the LOCAL variable "c"    to 1!
  1147.            func2(c); # now call func2
  1148.        }
  1149.        func2( x    )
  1150.        char x;
  1151.        {
  1152.            char c;     # this    "c" is different from func1's "c"
  1153.            x = 3;     # this    does not affect    func1's    "c"
  1154.            c = 5;     # this    does not affect    the global "c"
  1155.        }
  1156.  
  1157.        8.3.4  _S_y_s_t_e_m__G_l_o_b_a_l_s  As  mentioned  earlier,  the  Library
  1158.        Functions  and the editor's configuration variables that    are
  1159.        declared    in the shell are also globals.    These however,    are
  1160.        more  permanent    than  program  globals.     A program's global
  1161.        variables can be    zapped into non-existence simply by editing
  1162.        the  program  and removing the statement    that declares them.
  1163.        System globals can not be destroyed since SCI will not allow
  1164.        you  to    modify    the  shell program (or any program for that
  1165.        matter) while it    is still running.
  1166.  
  1167.        8.4  LLLLooooccccaaaattttiiiioooonnnn ooooffff    VVVVaaaarrrriiiiaaaabbbblllleeeessss
  1168.  
  1169.        At this point it    may be useful to discuss  where     in  memory
  1170.        each  of     these    different  types  of  variables    is located.
  1171.        Although    this depends on    the compiler's    implementation    and
  1172.        the  hardware,  most  C    compilers  take     advantage  of some
  1173.        commonly    used data structures.
  1174.  
  1175.        8.4.1  _T_h_e__S_t_a_c_k      The  stack  is  simply  a  chunk  of    the
  1176.        computer's  memory  that    can only be accessed (read from    and
  1177.        written to) indirectly through a    machine    register  known     as
  1178.        the  "stack  pointer".    If  the     CPU does can not provide a
  1179.        stack pointer register, the authors of the C  compiler  will
  1180.        typically  write     some subroutines in the machine's language
  1181.        to emulate a hardware stack.  Reading  and  writing  to    the
  1182.        stack  proceeds    as follows: before an item is read from    the
  1183.        stack, the stack    pointer    is  decremented     to  point  to    the
  1184.        previous     item  in  the stack memory. This then,    is the item
  1185.        read from the stack; After an item  is  written    into  stack
  1186.        memory,    the  stack  pointer  is    incremented to point to    the
  1187.        next item in the    stack.    Thus, the operation  of     the  stack
  1188.        can be thought of as a stack of pancakes    - numbers are piled
  1189.        onto the    stack for temporary storage, then removed from    the
  1190.  
  1191.  
  1192.  
  1193.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1194.  
  1195.  
  1196.  
  1197.  
  1198.  
  1199.  
  1200.  
  1201.  
  1202.        20                              Variables
  1203.  
  1204.  
  1205.        top as needed.
  1206.  
  1207.        In general, the C  language  depends  very  heavily  on    the
  1208.        stack.    Local  variables, including function arguments,    are
  1209.        piled onto the  stack  when  a  function     begins,  and  then
  1210.        removed    and discarded when it terminates.  As a    C statement
  1211.        is executed, the    components  of    the  statement    (constants,
  1212.        variables,  etc.) are "pushed" onto the stack until they    are
  1213.        needed.     Then,    when  the  statement  is   evaluated,    the
  1214.        components are "poped" off the stack.
  1215.  
  1216.        Most compilers take  advantage  of  the    machine's  built-in
  1217.        stack  (if  the    CPU  happens  to  have one, as most do), so
  1218.        access to the stack  is    very  efficient.  Still,  this    has
  1219.        become  a  major     point    of  criticism by opponents of the C
  1220.        language.
  1221.  
  1222.        8.4.2  _P_r_o_g_r_a_m__a_n_d__D_a_t_a__S_e_g_m_e_n_t_s     Global    data variables    are
  1223.        usually    stored    in  the     same  section of memory as program
  1224.        code; most 8 and    16 bit CPU's do    not provide seperate memory
  1225.        segments    for program code and global data.
  1226.  
  1227.        Some minicomputers and most mainframes do  provide  seperate
  1228.        program code and    data memory areas.  The    machine    then limits
  1229.        access to these    segments  by  disabling     the  program  from
  1230.        storing    data  in  the code segment and possibly    causing    the
  1231.        program to go berserk.  Also,  the  program  is    limited     to
  1232.        accessing only its own global data area and attempts to read
  1233.        or write    data outside of     this  global  data  segment  is  a
  1234.        violation.
  1235.  
  1236.        Alas, a microcomputer's operating system    is at the mercy     of
  1237.        the  currently  executing program and a careless    program    has
  1238.        the ability to corrupt the operating system  and     bring    the
  1239.        computer    to its knees.
  1240.  
  1241.  
  1242.        9.  CCCCoooonnnnssssttttaaaannnnttttssss
  1243.  
  1244.        You already know    about decimal integer constants    because     we
  1245.        have  been  using  them    throughout  this  tutorial.   The C
  1246.        language     also  allows    you   to   represent   numbers     in
  1247.        hexadecimal, octal and ASCII.
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1257.  
  1258.  
  1259.  
  1260.  
  1261.  
  1262.  
  1263.  
  1264.  
  1265.        Constants                             21
  1266.  
  1267.  
  1268.        9.1  HHHHeeeexxxxaaaaddddeeeecccciiiimmmmaaaallll    CCCCoooonnnnssssttttaaaannnnttttssss
  1269.  
  1270.        Hexadecimal numbers  are     distinguished    from  other  number
  1271.        representations    and variables by preceding them    with a "0x"
  1272.        (zero-"ex"), for    example:
  1273.  
  1274.            0x0
  1275.            0x1b
  1276.            0xfa70
  1277.  
  1278.        are all valid hexadecimal number    representations.   You    may
  1279.        also  use  an  upper  case  "X"    in  "0X" and upper case    "A"
  1280.        through "F" if you desire.
  1281.  
  1282.        9.2  OOOOccccttttaaaallll CCCCoooonnnnssssttttaaaannnnttttssss
  1283.  
  1284.        Octal numbers are distinguished by  preceding  them  with  a
  1285.        zero.  These are    all valid octal    numbers:
  1286.  
  1287.            00
  1288.            033
  1289.            0175160
  1290.  
  1291.        9.3  AAAASSSSCCCCIIIIIIII CCCChhhhaaaarrrraaaacccctttteeeerrrr CCCCoooonnnnssssttttaaaannnnttttssss
  1292.  
  1293.        The numeric value of ASCII characters can be represented     by
  1294.        surrounding the ASCII character in apostrophes, like this:
  1295.  
  1296.            'A'     is equivalent to    decimal    65
  1297.            ' '     is a space and is equivalent to decimal 32
  1298.  
  1299.        Certain    non-printing   ASCII   characters   can      also     be
  1300.        conveniently   represented   as     character  constants.     By
  1301.        preceeding certain  lower  case    letters     with  a  backslash
  1302.        character  ("\"),  the two-character combination    can be used
  1303.        to represent a single one byte  value.    One  of     these    you
  1304.        already    know  as  the "newline"    character, '\n'.  Here is a
  1305.        complete    list of    these:
  1306.  
  1307.            '\b'   "backspace", equivalent to decimal 8.
  1308.            '\r'   "carriage    return", equivalent to 13.
  1309.            '\n'   "newline", equivalent to 10.
  1310.            '\f'   "formfeed", equivalent to    12.
  1311.            '\t'   "tab", equivalent    to 9.
  1312.  
  1313.        In addition, you    can represent  any  ASCII  character  as  a
  1314.        character  constant using its octal equivalent preceded by a
  1315.        backslash.  The only restriction     here  is  that     the  octal
  1316.  
  1317.  
  1318.  
  1319.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1320.  
  1321.  
  1322.  
  1323.  
  1324.  
  1325.  
  1326.  
  1327.  
  1328.        22                              Constants
  1329.  
  1330.  
  1331.        representation must be exactly 3    octal digits.  For example:
  1332.  
  1333.            '\033' is an ASCII "escape" character
  1334.            '\101' is an ASCII "A", equivalent to 65
  1335.            '\377' is equivalent to -1
  1336.  
  1337.        and so on - you get the idea.
  1338.  
  1339.        9.4  SSSSttttrrrriiiinnnngggg CCCCoooonnnnssssttttaaaannnnttttssss
  1340.  
  1341.        Finally,    another    type of     constant  you    have  already  been
  1342.        using,    is  the     "string"  constant  -    a  bunch  of  ASCII
  1343.        characters surrounded by    quotes,    for example:
  1344.  
  1345.            "this is    a string\n"
  1346.  
  1347.        A string    always ends with a zero    byte, thus  the     amount     of
  1348.        memory  a  string  takes     up  is     equal    to  the     number     of
  1349.        characters you can count    in the string  plus  one.   In    the
  1350.        example    above,    the  string  requires  18  bytes of storage
  1351.        (realize    that the "\n" sequence is a single character -    the
  1352.        "newline"!).
  1353.  
  1354.        String constants    have an    interesting numeric equivalent - it
  1355.        is  an  address    in  the     computer's  memory where the ASCII
  1356.        characters in the string    can be found by    functions that    are
  1357.        equiped    to  deal  with    them.    For  instance,    the Library
  1358.        Function    "puts" expects its parameter to    be  an    address     in
  1359.        memory  where  ASCII character can be found and sequentially
  1360.        printed out to the console screen.
  1361.  
  1362.        If you tried to find out    a string constant's  numeric  value
  1363.        from the    shell by typing:
  1364.  
  1365.            shell> "hello?"
  1366.            4380
  1367.            shell> "another string..."
  1368.            4380
  1369.            shell> "what the?"
  1370.            4380
  1371.            >
  1372.  
  1373.        you would be surprised to find that they    all have  the  same
  1374.        address    -  how    could  this  be?   Actually, all the string
  1375.        constants in the    above examples do have    the  same  address.
  1376.        Recall that the shell reads a line of input from    the console
  1377.        and hands it off    to the interpreter for    evaluation.   Since
  1378.        the  strings  all  get read into    the same line buffer by    the
  1379.  
  1380.  
  1381.  
  1382.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1383.  
  1384.  
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.  
  1391.        Constants                             23
  1392.  
  1393.  
  1394.        shell, they all have the    same address,  namely  the  shell's
  1395.        input line buffer.
  1396.  
  1397.        We will discuss strings in more detail  in  the    section     on
  1398.        arrays and pointers.
  1399.  
  1400.  
  1401.        10.  AAAAssssssssiiiiggggnnnnmmmmeeeennnntttt OOOOppppeeeerrrraaaattttoooorrrr
  1402.  
  1403.        In C, we    assign values to variables using  the  "assignment"
  1404.        operator,  "=".     Do  not confuse the assignment    operator (a
  1405.        single  equal  sign)  with  the    "is  equal  to"     relational
  1406.        operator     (two  consecutive  equal  signs),  which  we  will
  1407.        discuss later.  Although    C will allow you to do    this  under
  1408.        certain    conditions,  you  will get unexpected results.    The
  1409.        expression:
  1410.  
  1411.            a = (b +    1) * 2;
  1412.  
  1413.        is read as: take    the results of the calculation of (b + 1) *
  1414.        2  and assign it    to the variable    "a". Note that there may be
  1415.        only one    variable to the    left of    the equal sign.
  1416.  
  1417.        You can if you like, string  several  of     these    assignments
  1418.        together    like this:
  1419.  
  1420.            a = flg = x = (b    + 1) * 2;
  1421.  
  1422.        Note that even here there is always only    one variable to    the
  1423.        left  of     each equal sign.  This    statement is evaluated like
  1424.        so: take    the results of the calculation of (b + 1) *  2    and
  1425.        assign  it  to the variable "x",    then assign the    same number
  1426.        to the variable "flg", and then to "a".    This  implies  that
  1427.        the  assignment    operator  is  evaluated    from _r_i_g_h_t-_t_o-_l_e_f_t,
  1428.        instead of the usual left-to-right.  In fact it is the  only
  1429.        binary operator supported by SCI    that exhibits this peculiar
  1430.        behavior.  This feature is  most     useful     when  initializing
  1431.        several variables, like so:
  1432.  
  1433.            lettercnt = digitcnt = punctcnt = 0;
  1434.  
  1435.  
  1436.        which would set all of the variables to zero.
  1437.  
  1438.        The assignment operator has the    lowest    precedence  (it     is
  1439.        performed  last    in  an    expression) of all the C operators,
  1440.        except for the "comma" operator (see below).
  1441.  
  1442.  
  1443.  
  1444.  
  1445.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1446.  
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.  
  1454.        24                        Assignment Operator
  1455.  
  1456.  
  1457.        10.1  LLLLvvvvaaaalllluuuueeeessss aaaannnndddd RRRRvvvvaaaalllluuuueeeessss
  1458.  
  1459.        It should be intuitively    obvious    that any attempt to store a
  1460.        value  in what we know as a C constant is illegal.  In other
  1461.        words, you would    never attempt to say, store the    number 3 in
  1462.        place of    the number 5:
  1463.  
  1464.            5 = 3;
  1465.  
  1466.        The same    holds true for string constants; you may not  store
  1467.        another string in an existing string constant:
  1468.  
  1469.            "hello" = "world";
  1470.  
  1471.        These types of data (constants) are  collectively  known     as
  1472.        "rvalues"  (pronounced "are-values").  The term rvalue stems
  1473.        from the    fact that they may only    be used    on the    right-hand-
  1474.        side of an assignment operator.
  1475.  
  1476.        On the other hand, variables do allow numbers to     be  stored
  1477.        and  retrieved from them.  This category    of data    is known as
  1478.        "lvalues" (pronounced "ell-values") because they    may be used
  1479.        on the left-hand-side of    an eual    sign.
  1480.  
  1481.        We will encounter lvalues  and  rvalues    again  in  a  later
  1482.        discussion.
  1483.  
  1484.  
  1485.        11.  CCCCoooommmmmmmmaaaa OOOOppppeeeerrrraaaattttoooorrrr
  1486.  
  1487.        In _s_t_a_n_d_a_r_d C  the  punctuation    character  ","    (comma)     is
  1488.        considered  to be an operator, although it does nothing more
  1489.        except insure that sub-expressions within a  statement  will
  1490.        be evaluated in order from left to right.  This operator    has
  1491.        the lowest priority of all.  It is useful for when you  want
  1492.        to  do  more  than  one    thing  in  a  statement,  like    the
  1493.        following:
  1494.  
  1495.            ++a, b=12, c=b+a;
  1496.  
  1497.        Of course, we could also    have written  the  above  statement
  1498.        as:
  1499.  
  1500.  
  1501.  
  1502.  
  1503.  
  1504.  
  1505.  
  1506.  
  1507.  
  1508.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1509.  
  1510.  
  1511.  
  1512.  
  1513.  
  1514.  
  1515.  
  1516.  
  1517.        Comma Operator                             25
  1518.  
  1519.  
  1520.            {
  1521.                ++a;
  1522.                b=12;
  1523.                c=b+a;
  1524.            }
  1525.  
  1526.  
  1527.        but this    would not have been as concise as the first form.
  1528.  
  1529.        Commas are also used to seperate    variable names    in  a  data
  1530.        declaration  as    you  have  already  seen,  and    to seperate
  1531.        arguments in function calls.
  1532.  
  1533.  
  1534.                   NOTE:
  1535.  
  1536.        SCI does    not support the    use of the comma operator  anywhere
  1537.        outside    the context of variable    seperators or function call
  1538.        argument    seperators, as in the  first  example  above.    Any
  1539.        attempt    to  do    so  will result    in a "syntax error" message
  1540.        from the    interpreter.
  1541.  
  1542.  
  1543.        12.  FFFFlllloooowwww CCCCoooonnnnttttrrrroooollll
  1544.  
  1545.        The previous sections have dealt     only  with  data  elements
  1546.        (variables  and    constants)  and     with evaluating arithmetic
  1547.        combinations of these.  C would be a poor language indeed if
  1548.        it  only     allowed a programmer to evaluate a sequential list
  1549.        of arithmetic expressions without giving    him the    opportunity
  1550.        to  act    on the results of these    calculations.  This section
  1551.        will introduce you to C's program control  structures,  also
  1552.        known  as  "flow     control"  structures.     Most of these have
  1553.        constructs that should be familiar to all you BASIC hackers:
  1554.        the conditional ("if-else"), looping ("while" and "for")    and
  1555.        program control switching ("switch").
  1556.  
  1557.        12.1  iiiiffff    aaaannnndddd iiiiffff----eeeellllsssseeee
  1558.  
  1559.        The most    fundamental of the flow    control    constructs  is    the
  1560.        "if".   This  allows you    to perform a statement (or group of
  1561.        statements if we    talk about a compound statement)  "if"    the
  1562.        given condition is true.     In C, a condition is considered to
  1563.        be true when the    value of an expression is non-zero, that is
  1564.        either a    positive or negative number.  It follows then, that
  1565.        an expression that evaluates to zero is considered to  be  a
  1566.        false  condition.   We  write  an "if" conditional in C like
  1567.        this:
  1568.  
  1569.  
  1570.  
  1571.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1572.  
  1573.  
  1574.  
  1575.  
  1576.  
  1577.  
  1578.  
  1579.  
  1580.        26                           Flow    Control
  1581.  
  1582.  
  1583.            if ( <expression> ) <statement>
  1584.  
  1585.        We will be  using  the  angle  brackets    (<>)  to  represent
  1586.        familiar     C concepts so that you    will be    able to    more easily
  1587.        identify    the relavent components: here "<expression>" is    any
  1588.        valid   C   expression,    like  "var-5"  or  "x  +  10";    and
  1589.        "<statement>" may be either a simple or compound    statement -
  1590.        but, more about statements later.
  1591.  
  1592.        The relavent components in the "if" statement are: obviously
  1593.        the  "if" word which identifies this flow control construct;
  1594.        a left parenthesis followed by an expression followed  by  a
  1595.        right parenthesis; then a C statement. Now a few    words about
  1596.        syntactics:
  1597.  
  1598.        1.  The "if" must be in lower case letters, most    C compilers
  1599.        will     usually  not  accept  "If",  or  "IF" or "iF" (and
  1600.        neither will    SCI!).
  1601.  
  1602.        2.  The matched left and    right parentheses must be included,
  1603.        and    SCI  requires  that the    "if", the left parenthesis,
  1604.        the <expression> and    the right parenthesis appear on    the
  1605.        same    line in    the program.
  1606.  
  1607.        3.  The <statement> may be either a simple  statement  or  a
  1608.        compound statement.
  1609.  
  1610.  
  1611.                   NOTE:
  1612.  
  1613.        SCI requires that the "if" and the parentheses appear on    the
  1614.        same  line  in  your  program  text, but    the <statement>    may
  1615.        appear on the following line.  This is only a restriction of
  1616.        the  SCI     interpreter - the standard C language lets you    put
  1617.        as much horizontal and vertical "distance" between  elements
  1618.        of an "if" statement as you like.
  1619.  
  1620.        The "if"    flow control construct behaves as follows:
  1621.  
  1622.        1.  The <expression> is evaluated.
  1623.  
  1624.        2.  If the result of <expression> is true (a non-zero value)
  1625.        then    the <statement>    is executed.
  1626.  
  1627.        3.  If the result is false (zero) the <statement> is skipped
  1628.        and program control passes to the next statement.
  1629.  
  1630.        For example:
  1631.  
  1632.  
  1633.  
  1634.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.        Flow Control                             27
  1644.  
  1645.  
  1646.            if ( 2 +    2 ) a =    5;
  1647.  
  1648.        would  always  set  the    variable  "a"  to  5  because    the
  1649.        <expression>,  which  evaluates to 4 in this case, is always
  1650.        non-zero. And the <statement> in    this example:
  1651.  
  1652.            if ( 0 )    a = 5;
  1653.  
  1654.        would never be reached because the  <expression>     is  always
  1655.        false.  As a last example, look at this:
  1656.  
  1657.            if ( a =    b + c )    b = b +    1;
  1658.  
  1659.        Here the    value of the <expression> depends on the results of
  1660.        the addition of "b" and "c", which we have no way of knowing
  1661.        just by looking at the example out of context.  As  a  side-
  1662.        effect, the result of the addition is stored in the variable
  1663.        "a".  It    is very    important that you realize that     the  equal
  1664.        sign  in     "a = b    + c" is    not making a comparison    between    the
  1665.        value of    "a" and    "b + c", as you    might assume  if  you  were
  1666.        looking at a similar statement in BASIC.     In other words, we
  1667.        are _n_o_t saying "if a is equal to    the sum    of b and c".
  1668.  
  1669.        12.1.1  _M_o_r_e__A_b_o_u_t__S_t_a_t_e_m_e_n_t_s  Earlier we promised  to  tell
  1670.        you more    about the concept of C statements.  A statement, as
  1671.        you already know, can be    either an expression such as "a    = a
  1672.        +  5"  followed by a semicolon (don't forget the    semicolon!)
  1673.        or it may be a group of these simple  statements     surrounded
  1674.        by left and right curly braces, like this:
  1675.  
  1676.            { a = b + c; b =    b + 1; }
  1677.  
  1678.  
  1679.        or this:
  1680.  
  1681.            {
  1682.                a = b + c;
  1683.                b = b + 1;
  1684.            }
  1685.  
  1686.  
  1687.        or a compound statement within a    compound  statement  as     in
  1688.        this example:
  1689.  
  1690.  
  1691.  
  1692.  
  1693.  
  1694.  
  1695.  
  1696.  
  1697.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1698.  
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.  
  1706.        28                           Flow    Control
  1707.  
  1708.  
  1709.            {
  1710.                { a = b;    b = 1; }
  1711.                a = b + c;
  1712.                b = b + 1;
  1713.            }
  1714.  
  1715.        We now expand our definition of a C statement to    include    the
  1716.        "if"  and  later    all of the other flow control constructs as
  1717.        well.  In other words, the template for an  "if"     we  showed
  1718.        you before:
  1719.  
  1720.            if ( <expression> ) <statment>
  1721.  
  1722.  
  1723.        can be thought of as a  single  unit  and  used    wherever  a
  1724.        <statement>  is    used.    Now  we     can write multiple "nested
  1725.        if's" like this:
  1726.  
  1727.            if ( a +    5 )
  1728.                if ( b -    1 )
  1729.                    c = 0;
  1730.  
  1731.  
  1732.        which would be "read" by    the computer as    follows:
  1733.  
  1734.        1.  if "a +  5"    is  true  (non-zero)  then  go    to  step  2
  1735.        otherwise go    to step    3.
  1736.  
  1737.        2.  if "b - 1" is true, then assign 0 to    "c".
  1738.  
  1739.        3.  go on to the    next statement in the program.
  1740.  
  1741.        The "if"    statement also has an optional "else" clause, which
  1742.        looks like this:
  1743.  
  1744.            if ( <expression> ) <statement> else <statement>
  1745.  
  1746.        Notice that the "else" keyword must be in lower case letters
  1747.        also.  Again,  the  first  <statement>,    the "else", and    the
  1748.        second <statement> may be on seperate lines of program  text
  1749.        or  they     may  all  be  on  the    same  line.   The "if-else"
  1750.        statement, as it    is called, is read as follows:
  1751.  
  1752.        1.  if the <expression> is  true,  then    execute     the  first
  1753.        <statement> and then    go to step 3.
  1754.  
  1755.        2.  else, execute the second <statement>    and then go to step
  1756.        3.
  1757.  
  1758.  
  1759.  
  1760.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1761.  
  1762.  
  1763.  
  1764.  
  1765.  
  1766.  
  1767.  
  1768.  
  1769.        Flow Control                             29
  1770.  
  1771.  
  1772.        3.  go on to the    next statement in the program.
  1773.  
  1774.        The C language allows you to nest  "if-else"  statements     as
  1775.        deeply as you wish, for example:
  1776.  
  1777.            if ( a +    3 )
  1778.                if ( b +    5 )
  1779.                    if ( c +    7 )
  1780.                        d = 0;
  1781.                    else
  1782.                        d = 1;
  1783.                else
  1784.                    d = 2;
  1785.            else
  1786.                d = 3;
  1787.  
  1788.        It should be  obvious  from  the     way  the  statements  were
  1789.        indented     how  each "else" matches its "if".  As    a matter of
  1790.        definition, an "else" clause matches the     nearest  preceding
  1791.        "if"  clause.   If  there are more "else's" than    "if's" in a
  1792.        program,    then this is an    error condition     and  you  will     be
  1793.        warned  by SCI.    If you are ever    unsure how nested "if-else"
  1794.        combinations will match up, you can always use curly  braces
  1795.        to bind them together the way you want:
  1796.  
  1797.            if ( a +    3 )
  1798.            {
  1799.                if ( b +    5 )
  1800.                {
  1801.                    if ( c +    7 )
  1802.                        d = 0;
  1803.                    else
  1804.                        d = 1;
  1805.                }
  1806.                else
  1807.                {
  1808.                    d = 2;
  1809.                }
  1810.            }
  1811.            else
  1812.            {
  1813.                d = 3;
  1814.            }
  1815.  
  1816.        You can also use    another    "if-else" statement in    the  "else"
  1817.        clause of a preceding "if-else",    for example:
  1818.  
  1819.  
  1820.  
  1821.  
  1822.  
  1823.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1824.  
  1825.  
  1826.  
  1827.  
  1828.  
  1829.  
  1830.  
  1831.  
  1832.        30                           Flow    Control
  1833.  
  1834.  
  1835.            if ( a +    3 )
  1836.                d = 1;
  1837.            else
  1838.            {
  1839.                if ( a +    4 )
  1840.                    d = 2;
  1841.                else
  1842.                {
  1843.                    if ( a +    5 )
  1844.                        d = 3;
  1845.                    else
  1846.                        d = 4;
  1847.                }
  1848.            }
  1849.  
  1850.        Because it is a matter of personal style, there are no  hard
  1851.        and  fast  rules    to follow when indenting program statements
  1852.        like this. However,  the     above    example     is  more  commonly
  1853.        written like this:
  1854.  
  1855.            if ( a +    3 )
  1856.                d = 1;
  1857.            else if ( a + 4 )
  1858.                d = 2;
  1859.            else if ( a + 5 )
  1860.                d = 3;
  1861.            else
  1862.                d = 4;
  1863.  
  1864.        This saves you from running off the right edge of the screen
  1865.        when  writing  very  deeply  nested "if-else's" and it looks
  1866.        very much like a    multi-path switch (an "ON  GOTO"  statement
  1867.        in BASIC).
  1868.  
  1869.        12.1.2  _R_e_l_a_t_i_o_n_a_l__O_p_e_r_a_t_o_r_s  Sometimes it is  necessary     to
  1870.        change  the  program flow depending on whether a    variable is
  1871.        equal to    a certain value.  The C    language has  this  ability
  1872.        to test equality    of two expressions using a set of operators
  1873.        (similar    to the addition, multiplication, assignment,  etc.)
  1874.        known  as  the "relational operators".  If we wanted to know
  1875.        if a variable were equal    to a certain value, for    instance we
  1876.        could say:
  1877.  
  1878.            a == 5
  1879.  
  1880.        The "=="    (which is read as: "is equal to") operator compares
  1881.        the two items to    the left and right of it and leaves a value
  1882.        of one if they are equal, zero if they are unequal.  So    the
  1883.  
  1884.  
  1885.  
  1886.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1887.  
  1888.  
  1889.  
  1890.  
  1891.  
  1892.  
  1893.  
  1894.  
  1895.        Flow Control                             31
  1896.  
  1897.  
  1898.        value  of  this expression would    be one if "a" is equal to 5
  1899.        and zero    otherwise. Thus, the statement:
  1900.  
  1901.            if ( a == 5 )
  1902.                b = 0;
  1903.  
  1904.  
  1905.        would set "b" to    zero only if "a" equals    5.
  1906.  
  1907.        We promised you a set of    these operators, so here they are:
  1908.  
  1909.            _o_p_e_r_a_t_o_r:   _r_e_a_d    _a_s:
  1910.  
  1911.            ==       is equal to
  1912.            !=       is not equal    to
  1913.            <       is less than
  1914.            >       is greater than
  1915.            <=       is less than    or equal to
  1916.            >=       is greater than or equal to
  1917.  
  1918.        Notice that there may be    no spaces  between  the     two  equal
  1919.        signs  (=)  in  the  "is     equal to" operator nor    between    the
  1920.        exclamation point (!) and the equal in  the  "is     not  equal
  1921.        to".  If    there is a space between them, they will be assumed
  1922.        to be two seperate operators and     you  will  get     a  "syntax
  1923.        error" message from SCI.     Needless to say, the same goes    for
  1924.        the <= and >=.
  1925.  
  1926.        12.1.3  _L_o_g_i_c_a_l__O_p_e_r_a_t_o_r_s  The C    language also allows you to
  1927.        combine groups of relational expressions    with "and" and "or"
  1928.        clauses.     For example, given two    sets of    conditions you    can
  1929.        determine  if  both  are     true,    or if at least one is true.
  1930.        These "and" and "or"  clauses  are  known  as  the  "logical
  1931.        operators" in C:
  1932.  
  1933.            _o_p_e_r_a_t_o_r:   _r_e_a_d    _a_s:
  1934.  
  1935.            &&       and
  1936.            ||       or
  1937.  
  1938.        Notice  that  there  may     be  no     spaces     between  the    two
  1939.        ampersands (&) and vertical bars    (|).  The expression:
  1940.  
  1941.            a==5 && b==3
  1942.  
  1943.  
  1944.        will be true only if "a"    is equal to 5 _a_n_d "b" is  equal     to
  1945.        3.
  1946.  
  1947.  
  1948.  
  1949.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  1950.  
  1951.  
  1952.  
  1953.  
  1954.  
  1955.  
  1956.  
  1957.  
  1958.        32                           Flow    Control
  1959.  
  1960.  
  1961.            a<0 || 10<a
  1962.  
  1963.        In this example the expression is true if "a" is    less than 0
  1964.        _o_r  greater  than  10  (do  you    see  that 10<a and a>10    are
  1965.        identical?).
  1966.  
  1967.        One final note about the    logical    operators: standard C stops
  1968.        evaluating  an  expression  that     contains logical operators
  1969.        after the truth or falsehood of    the  expression     is  known.
  1970.        For example:
  1971.  
  1972.            a==b && c==d
  1973.  
  1974.        Assume that "a" is not equal to "b". Standard  C     would    not
  1975.        even  bother  checking the relation "c==d" because the "and"
  1976.        clause requires both expressions    to the left  and  right     of
  1977.        the "&&"    to be true - if    one of the components is false,    the
  1978.        entire expression is false.  So,    since the  first  component
  1979.        encountered  ("a==b")  was  found  to be    false, the truth or
  1980.        falsehood of the    entire    expression  is    already     known    and
  1981.        there is    no need    to evaluate "c==d".
  1982.  
  1983.  
  1984.                   NOTE:
  1985.  
  1986.        SCI is not as smart as a    standard  C  compiler  and  blindly
  1987.        evaluates  every     sub-expression     in  a    logical    expression.
  1988.        This can    lead to    some  very  hard  to  find  errors  if    for
  1989.        example you alter a variable in one of the subexpressions of
  1990.        a logical operation - sorry folks!
  1991.  
  1992.        12.1.4  _P_r_e_c_e_d_e_n_c_e__a_n_d__A_s_s_o_c_i_a_t_i_v_i_t_y   You  can    combine     as
  1993.        many "and" and "or" clauses as necessary:
  1994.  
  1995.            a==5 || b==3 && c==4
  1996.  
  1997.        This expression will be true under one of two conditions: 1)
  1998.        b  is equal to 3    AND c is equal to 4, or    2) a is    equal to 5.
  1999.        This example shows a  very  important  property    of  logical
  2000.        operators that we have already encountered in the discussion
  2001.        of  the    arithmetic  operators  (+,  -,    *,  etc.),   namely
  2002.        precedence.   In     C,  the  &&  operator takes precedence    (is
  2003.        performed before) the ||    operator.
  2004.  
  2005.        As with the arithmetic operators    the logical  operators    are
  2006.        performed  from left to right.  So, if we have more than    one
  2007.        operator    of the same precedence in an expression:
  2008.  
  2009.  
  2010.  
  2011.  
  2012.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2013.  
  2014.  
  2015.  
  2016.  
  2017.  
  2018.  
  2019.  
  2020.  
  2021.        Flow Control                             33
  2022.  
  2023.  
  2024.            a==5 && b==5 && c==5
  2025.  
  2026.  
  2027.        we know that C performs the tests for equality from left     to
  2028.        right.
  2029.  
  2030.        Although    we haven't come    right out and said  it    before,     it
  2031.        should  be  obvious  from  the  examples    that the relational
  2032.        operators have higher precedence    than the logical operators.
  2033.        Specifically, >,    >=, < and <= have higher precedence than ==
  2034.        and != which have higher    precedence  than  &&  which  has  a
  2035.        higher  precedence  than     ||.   Please refer to the Language
  2036.        Summary section of the User's Manual for    a complete list     of
  2037.        C operators and their order of precedence.
  2038.  
  2039.        Furthermore, relational operators  associate  from  left     to
  2040.        right, although it is hardly ever necessary to use more than
  2041.        one consecutive relational:
  2042.  
  2043.            a == 5 != 1
  2044.  
  2045.        Notice in this example that "a  ==  5"  is  performed  first
  2046.        which  would  result in either a    zero or    a one.    Examine    the
  2047.        following expression closely:
  2048.  
  2049.            a < 5 ==    b < 5
  2050.  
  2051.        This expresion will be true if "a" and  "b"  are     _b_o_t_h  _l_e_s_s
  2052.        _t_h_a_n _5 or "a" and "b" are _b_o_t_h _e_q_u_a_l _t_o _o_r _g_r_e_a_t_e_r _t_h_a_n _5.
  2053.  
  2054.        As always, whenever you are in doubt about the associativity
  2055.        or  precedence  of operators, either use    parentheses to bind
  2056.        operands    and operators together,    or  consult  the  table     of
  2057.        operators in the    User's Manual.
  2058.  
  2059.        12.1.5  _E_x_a_m_p_l_e_s     Finally armed with these new  facts  about
  2060.        C, we are ready to try some practical examples using the    SCI
  2061.        interpreter.  Enter the    following  program  using  the    SCI
  2062.        editor:
  2063.  
  2064.  
  2065.  
  2066.  
  2067.  
  2068.  
  2069.  
  2070.  
  2071.  
  2072.  
  2073.  
  2074.  
  2075.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2076.  
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084.        34                           Flow    Control
  2085.  
  2086.  
  2087.            convert(n)
  2088.            {
  2089.                char c;
  2090.  
  2091.                puts("to    decimal    (d), hex (x) or    octal (o) ?");
  2092.                c=getchar();
  2093.                if(c=='d')
  2094.                    putd(n);
  2095.                else if(c=='x')
  2096.                    putx(n);
  2097.                else if(c=='o')
  2098.                    puto(n);
  2099.                else
  2100.                    puts("what?0);
  2101.            }
  2102.  
  2103.        As you can  probably  tell,  this  is  a     number     conversion
  2104.        routine.     It asks the operator whether to convert the number
  2105.        passed to it ("n") to decimal, hexadecimal or octal.  Now at
  2106.        the shell prompt, type:
  2107.  
  2108.            shell> convert( 255 )
  2109.            to decimal (d), hex (x) or octal    (o) ?x
  2110.            0xff
  2111.            0
  2112.            shell>
  2113.  
  2114.        If your screen  did  not     look  like  the  above,  there     is
  2115.        something wrong - fix it    up and try again.
  2116.  
  2117.        Now modify the program to accept    either lower or    upper  case
  2118.        d's, x's    and o's    (hint: use the || operator).
  2119.  
  2120.        12.2  wwwwhhhhiiiilllleeee
  2121.  
  2122.        One of the things that makes a computer such a powerful tool
  2123.        is its tireless ability to perform repetitive tasks. This is
  2124.        why every programming language has some    sort  of  "looping"
  2125.        flow  control.    The  C    language offers    three types of loop
  2126.        constucts: the "while", "for" and "do-while".  This  version
  2127.        of SCI only supports the    "while"    and "for".
  2128.  
  2129.        The "while" flow    control    looks something    like this:
  2130.  
  2131.            while ( <expression> ) <statement>
  2132.  
  2133.        Notice that its    structure  is  very  similar  to  the  "if"
  2134.        construct  and  all  of the syntactical rules apply as well.
  2135.  
  2136.  
  2137.  
  2138.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2139.  
  2140.  
  2141.  
  2142.  
  2143.  
  2144.  
  2145.  
  2146.  
  2147.        Flow Control                             35
  2148.  
  2149.  
  2150.        This statement is executed as follows:
  2151.  
  2152.        1.  evaluate <expression> and if    it is false, go    to step    4.
  2153.  
  2154.        2.  execute <statement>.
  2155.  
  2156.        3.  go to step 1
  2157.  
  2158.        4.  go on to the    next statement in the program.
  2159.  
  2160.        As with the "if"    statement, <expression>    is considered to be
  2161.        true  if     it evaluates to non-zero, and false if    it is zero.
  2162.        Let's look at an    example:
  2163.  
  2164.            loop()
  2165.            {
  2166.                int a;
  2167.  
  2168.                a = 10;
  2169.                while ( a > 0 )
  2170.                {
  2171.                    putd( a );
  2172.                    a = a - 1;
  2173.                }
  2174.                puts("all done\n");
  2175.            }
  2176.  
  2177.        This loop will get executed exactly 10 times - each time    the
  2178.        variable     "a"  is  decremented  by one until it equals zero.
  2179.        When "a"    reaches    zero, the expression "a    >  0"  will  become
  2180.        false  and  program  execution  will  continue with the next
  2181.        statement in the    program,  namely  the  statement  puts("all
  2182.        done\\n");.
  2183.  
  2184.        There is    also a more direct method  of  breaking     out  of  a
  2185.        "while"    loop  without  having to wait until control returns
  2186.        back to the <expression>    evaluation and    testing.   Using  a
  2187.        "break"    statement,  you     can directly jump out of a "while"
  2188.        and continue with the next statement in    the  program.    The
  2189.        following demonstrates the use of a "break":
  2190.  
  2191.  
  2192.  
  2193.  
  2194.  
  2195.  
  2196.  
  2197.  
  2198.  
  2199.  
  2200.  
  2201.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2202.  
  2203.  
  2204.  
  2205.  
  2206.  
  2207.  
  2208.  
  2209.  
  2210.        36                           Flow    Control
  2211.  
  2212.  
  2213.            loop()
  2214.            {
  2215.           int i, q;
  2216.  
  2217.           i = 12345;
  2218.           while    (1)
  2219.           {
  2220.              q = i/10;
  2221.              putchar( i-q*10+'0' );
  2222.  
  2223.              if    ( q==0 )
  2224.             break;
  2225.  
  2226.              i = q;
  2227.           }
  2228.            }
  2229.  
  2230.        Since the <expression> is always     true  (1  is  always  non-
  2231.        zero), this loop    would be repeated until    the cows came home.
  2232.        The "if"    statement within the loop will    break  out  of    the
  2233.        loop  when  the    quotient from the division results in zero.
  2234.        We leave    as an exercise for the student to figure  out  what
  2235.        this little program does.
  2236.  
  2237.        12.3  ffffoooorrrr
  2238.  
  2239.        The "for" looping construct is similar to the "while".    Its
  2240.        format is as follows:
  2241.  
  2242.        for ( <expression> ; <expression> ; <expression>    ) <statement>
  2243.  
  2244.        The syntactical requirements  of     the  "for"  construct    are
  2245.        similiar     to  those  of    the  "while"  -     the  "for" and    the
  2246.        parentheses and everything between them must be on the  same
  2247.        program    line.    Also,  the  three <expression>'s inside    the
  2248.        parentheses  must  be  seperated     from  each  other  by    two
  2249.        semicolons as shown.
  2250.  
  2251.        Actually, the "for" is simply a method of clearly presenting
  2252.        to  the reader the most commonly    needed elements    relavent to
  2253.        a program loop: an "initialization" part, a "loop test" part
  2254.        and  an    "iteration" part.  These three elements    are clearly
  2255.        identifyable, and correspond to (reading    from left to right)
  2256.        the three <expressions> within the parentheses.
  2257.  
  2258.        A "for" statement would be executed as follows:
  2259.  
  2260.  
  2261.  
  2262.  
  2263.  
  2264.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2265.  
  2266.  
  2267.  
  2268.  
  2269.  
  2270.  
  2271.  
  2272.  
  2273.        Flow Control                             37
  2274.  
  2275.  
  2276.        1.  evaluate the    first <expression>, disregard the result.
  2277.  
  2278.        2.  evaluate the    second <expression> and    if it is false,     go
  2279.        to step 5.
  2280.  
  2281.        3.  execute <statement>.
  2282.  
  2283.        4.  evaluate the    third <expression> and go to step 2.
  2284.  
  2285.        5.  go on to the    next statement in the program.
  2286.  
  2287.        We could    have  written  the  first  example  given  for    the
  2288.        "while" using a "for" statement:
  2289.  
  2290.            loop()
  2291.            {
  2292.                int a;
  2293.  
  2294.                for ( a = 10; a > 0; a =    a - 1 )
  2295.                    putd( a );
  2296.            }
  2297.  
  2298.        The "break" statement may also be used to  break     out  of  a
  2299.        "for"  loop.   One  last    interesting feature of the "for" is
  2300.        that any    or all of the three <expressions> may  be  missing.
  2301.        If  the second <expression> is missing, the "loop test" will
  2302.        always evaluate to true.     Thus, the second  example  of    the
  2303.        "while" loop above could    have been written:
  2304.  
  2305.            loop()
  2306.            {
  2307.           int i, q;
  2308.  
  2309.           for (    i=12345; ; q!=0    )
  2310.           {
  2311.              q = i/10;
  2312.              putchar( i-q*10+'0' );
  2313.              i = q;
  2314.           }
  2315.            }
  2316.  
  2317.        Here, the three <expressions> are:
  2318.  
  2319.            1. i=12345
  2320.            2. the second <expression> is missing!
  2321.            3. q!=0
  2322.  
  2323.  
  2324.  
  2325.  
  2326.  
  2327.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2328.  
  2329.  
  2330.  
  2331.  
  2332.  
  2333.  
  2334.  
  2335.  
  2336.        38                           Flow    Control
  2337.  
  2338.  
  2339.        And the most efficient way of writing a "forever" loop is:
  2340.  
  2341.        for ( ;;    )
  2342.            puts( "hello, world\n" );
  2343.  
  2344.  
  2345.  
  2346.        12.4  sssswwwwiiiittttcccchhhh
  2347.  
  2348.        The last    and most complex flow control we  will    examine     is
  2349.        the  multi-path "switch"    statement.  The    "switch" is similar
  2350.        to BASIC's "ON GOTO" statement.    Here is    the template  of  a
  2351.        "switch"    statement:
  2352.  
  2353.            switch (    <expression> )
  2354.            {
  2355.            case <constant expression> : <statement>
  2356.            case <constant expression> : <statement>
  2357.                .
  2358.                .
  2359.                .
  2360.            case <constant expression> : <statement>
  2361.            default : <statement>
  2362.            }
  2363.  
  2364.        Again,  the  word  "switch",  the  left     parenthesis,    the
  2365.        <expression>  and  the right parenthesis    must be    on the same
  2366.        program source line.  The  matching  left  and  right  curly
  2367.        brace  at  the  beginning  and  end  of    the  switch are    not
  2368.        actually    required but are necessary as you  will     soon  see.
  2369.        The  words  "case"  and "default" are only meaningful within
  2370.        the context of a     "switch"  statement.    There  may  be    any
  2371.        number  of "case    <constant expression> :" sequences but only
  2372.        one "default :".     The  <constant     expression>'s    are  simply
  2373.        <expression>'s  that contain only constants (no variables!).
  2374.        So,  the     following  would  all    be  examples  of  <constant
  2375.        expression>'s:
  2376.  
  2377.            2 + 2
  2378.            25 * (365 / 7)
  2379.            37/12 > 10
  2380.  
  2381.  
  2382.  
  2383.                   NOTE:
  2384.  
  2385.        Standard    C requires that    only <constant expression>'s follow
  2386.        a   "case",   however  SCI  allows  you    to  use     any  valid
  2387.  
  2388.  
  2389.  
  2390.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2391.  
  2392.  
  2393.  
  2394.  
  2395.  
  2396.  
  2397.  
  2398.  
  2399.        Flow Control                             39
  2400.  
  2401.  
  2402.        <expression> as an added    bonus.    Keep this fact in mind when
  2403.        writing    programs  that    will  eventually  be transported to
  2404.        standard    C!
  2405.  
  2406.        The "switch" statement behaves as follows:
  2407.  
  2408.        1   evaluate the    <expression>.
  2409.  
  2410.        2   compare the results    of  <expression>  to  each  of    the
  2411.        <constant  expression>'s after the "case's" sequentially
  2412.        from    top to bottom.
  2413.  
  2414.        3   if  the  value  of  <expression>  matches  one  of    the
  2415.        <constant expression>'s, continue program execution with
  2416.        the statement immediately following the colon. All other
  2417.        "case" and <constant    expressions> are ignored.
  2418.  
  2419.        4   if    none   of   the      <constant   expression>'s   match
  2420.        <expression>,   jump      to  the  <statement>    immediately
  2421.        following the word "default"
  2422.  
  2423.        5   if a    "break"    statement is encountered, jump to  the    end
  2424.        of  the  "switch" statement (the <statement>    immediately
  2425.        following the }).
  2426.  
  2427.        Although    this seems complicated    at  first,  a  "switch"     is
  2428.        really just a multi-way program jump.  It allows    you to jump
  2429.        to anywhere within a statement, based on     the  value  of     an
  2430.        expression.
  2431.  
  2432.        Here's an example of a switch:
  2433.  
  2434.  
  2435.  
  2436.  
  2437.  
  2438.  
  2439.  
  2440.  
  2441.  
  2442.  
  2443.  
  2444.  
  2445.  
  2446.  
  2447.  
  2448.  
  2449.  
  2450.  
  2451.  
  2452.  
  2453.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2454.  
  2455.  
  2456.  
  2457.  
  2458.  
  2459.  
  2460.  
  2461.  
  2462.        40                           Flow    Control
  2463.  
  2464.  
  2465.        convert(n)
  2466.        {
  2467.            char c;
  2468.  
  2469.            puts("to    decimal    (d), hex (x) or    octal (o) ?");
  2470.            switch (    getchar() )
  2471.            {
  2472.            case 'd':
  2473.                putd(n);
  2474.                break;
  2475.            case 'x':
  2476.                putx(n);
  2477.                break;
  2478.            case 'o':
  2479.                puto(n);
  2480.                break;
  2481.            default:
  2482.                puts("what?\n");
  2483.            }
  2484.        }
  2485.  
  2486.  
  2487.  
  2488.                   NOTE:
  2489.  
  2490.        Standard    C allows you to    place the "default"  word  anywhere
  2491.        within  the  "switch",  and  program control will jump there
  2492.        only after all of the "case <constant expression> :"'s  have
  2493.        been  checked  and no match found.  Here    again, SCI dares to
  2494.        be different!   If  a  "default"     is  encountered  before  a
  2495.        matching     "case", the program continues with the    <statement>
  2496.        following the "default".     Therefore, it is a  good  idea     to
  2497.        always  place  your  "default"  statements at the end of    the
  2498.        "switch".
  2499.  
  2500.  
  2501.        13.  AAAArrrrrrrraaaayyyyssss
  2502.  
  2503.        An array    in C is    a  block  of  contiguous  memory  locations
  2504.        (meaning     they  are located "one    after the other" in memory)
  2505.        that all    have the same type ("char" or  "int")  and  can     be
  2506.        accessed     individually.     These    individual data    items in an
  2507.        array are known as the array's "elements".  You have already
  2508.        used  arrays  earlier,  in your very first C program, namely
  2509.        the sequence of    ASCII  characters  in  the  string  "hello,
  2510.        world\n".   The    array's     elements  are the ASCII characters
  2511.        'h', 'e', 'l', etc.  This array however,    could not  be  used
  2512.        to  store  any  information  other  than     that  sequence     of
  2513.  
  2514.  
  2515.  
  2516.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2517.  
  2518.  
  2519.  
  2520.  
  2521.  
  2522.  
  2523.  
  2524.  
  2525.        Arrays                                 41
  2526.  
  2527.  
  2528.        characters, just    like the integer constant 5 let's say,    can
  2529.        not be used to store a different    number.     In this section we
  2530.        will show you how to create and use arrays for data  storage
  2531.        and retrieval.
  2532.  
  2533.        Arrays  are  declared  in  a  similar  fashion    as   simple
  2534.        variables,  but following the array's name you must indicate
  2535.        how many    elements the array will    have.  The size    of an array
  2536.        is  constant,  once  it    has  been  declared  it     can not be
  2537.        changed.     Below is an example of    an array declaration
  2538.  
  2539.            char vartable[15], macnam[100];
  2540.  
  2541.        This statement declares two arrays  that     have  15  and    100
  2542.        elements     respectively.     The  square  brackets    ([  and     ])
  2543.        identifies the variable as being    an  array,  they  are  also
  2544.        required     when  you  wish  to  access  one  of  the  array's
  2545.        elements:
  2546.  
  2547.            c = vartable[ 5 ];
  2548.  
  2549.        In C, array elements are    counted    from zero instead  of  one,
  2550.        so the above statement takes the    _s_i_x_t_h element of "vartable"
  2551.        and stores it in    the  variable  "c".  To     access     the  _f_i_r_s_t
  2552.        element of the array, we    would write:
  2553.  
  2554.            vartable[0] = 35;
  2555.  
  2556.        Consequently,  the  _l_a_s_t     element  of  the  array  would     be
  2557.        "vartable[14]"  and _n_o_t "vartable[15]".    In fact, if you    did
  2558.        attempt to store     a  number  in    "vartable[15]",     you  would
  2559.        overwrite  some    unknown    location in memory that    was already
  2560.        being used as storage for another variable  or,    worse  yet,
  2561.        that  was  part    of  your  program  code.   The    results     of
  2562.        overrunning a C array like this are  unpredictable  and    are
  2563.        dependent  on  the  environment    the C program is running in
  2564.        (the type of machine, the C compiler used, etc.)
  2565.  
  2566.        When the    name of    an array is  used  by  itself  without    the
  2567.        square brackets as in:
  2568.  
  2569.            i = vartable + 5;
  2570.  
  2571.        it is taken to be a pointer to  the  first  element  of    the
  2572.        array.    In  the     example  above,  "i" would be assigned    the
  2573.        _m_e_m_o_r_y _l_o_c_a_t_i_o_n of the sixth element in the array,  and    _n_o_t
  2574.        _t_h_e _v_a_l_u_e of this memory    location.
  2575.  
  2576.  
  2577.  
  2578.  
  2579.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2580.  
  2581.  
  2582.  
  2583.  
  2584.  
  2585.  
  2586.  
  2587.  
  2588.        42                             Arrays
  2589.  
  2590.  
  2591.        The Library Function "gets()" reads a line of input from    the
  2592.        console    keyboard  and  places the characters at    the address
  2593.        pointed to by its argument.  This  function  waits  for    the
  2594.        user  to     hit  a     carriage  return  before it returns to    the
  2595.        caller.    The input line is always  terminated  with  a  zero
  2596.        byte  by     "gets()"  and the carriage return is stripped out.
  2597.        This  makes  it    suitable  for  printing     by  its   partner,
  2598.        "puts()".  Try the following program:
  2599.  
  2600.            greet()
  2601.            {
  2602.                char name[ 80 ];
  2603.  
  2604.                puts("hello, what's your    name? ");
  2605.                gets( name );
  2606.                puts("nice to meet you, ");
  2607.                puts( name );
  2608.                puts(". Have a nice day!\n");
  2609.            }
  2610.  
  2611.  
  2612.        14.  PPPPooooiiiinnnntttteeeerrrrssss
  2613.  
  2614.        The last    example    above  leads  us  directly  into  our  next
  2615.        discussion.   In     C, you    have the ability to access a memory
  2616.        location    by "pointing" at it with a variable.  This type     of
  2617.        variable    is known as a "pointer"    in C.
  2618.  
  2619.  
  2620.                   NOTE:
  2621.  
  2622.        The number of bytes of  storage    a  pointer  variable  needs
  2623.        depends    on the environment the C program is running in.    All
  2624.        8-bit personal computers    (8080, z80, 6502, etc.)    use 2 bytes
  2625.        for pointer variables.  The IBM-PC which    has an 8088 CPU    may
  2626.        use either 2 or 4 bytes for pointer variables, depending     on
  2627.        the C compiler used.  SCI always    uses 2 bytes.
  2628.  
  2629.        C knows about the type of variable being    pointed    at from    the
  2630.        pointer's declaration:
  2631.  
  2632.            char *char_pointer;
  2633.            int *int_pointer;
  2634.  
  2635.        Above  we  declared  two      variables,   "char_pointer"    and
  2636.        "int_pointer".     The   asterisk      (*)  in  the    declaration
  2637.        statement identifies the    variables as being  pointers.    the
  2638.        "char"  and  "int" keywords define the type of variable that
  2639.  
  2640.  
  2641.  
  2642.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2643.  
  2644.  
  2645.  
  2646.  
  2647.  
  2648.  
  2649.  
  2650.  
  2651.        Pointers                                 43
  2652.  
  2653.  
  2654.        the pointer points to. To illustrate:
  2655.  
  2656.            i = *int_pointer;
  2657.  
  2658.        This would retrieve the _i_n_t_e_g_e_r (two bytes in SCI) found     at
  2659.        the   memory   location     addressed   by      the  _c_o_n_t_e_n_t_s     of
  2660.        "int_pointer", and store    it in "i".   In     this  example,     we
  2661.        can't  tell what    will be    stored in "i" because we don't know
  2662.        what the    contents  of  "int_pointer"  is.   Recall  from     an
  2663.        earlier discussion that SCI always initializes its variables
  2664.        to zero so in this case,    "i" would  contain  the     two  bytes
  2665.        found in    memory locations zero and one.
  2666.  
  2667.        Unless you know what is in memory locations  zero  and  one,
  2668.        this  information is not    very useful.  The power    of pointers
  2669.        lies in the fact    that they can be made to point at an array,
  2670.        like this:
  2671.  
  2672.            char vartable[15], *cp;
  2673.  
  2674.            cp = vartable;
  2675.            c = *cp;
  2676.            cp = cp+1;
  2677.            d = *cp;
  2678.            cp = cp+1;
  2679.            e = *cp;
  2680.  
  2681.        Here we have set    the character pointer "cp" to point at    the
  2682.        first  element  of  the    array  "vartable", and assigned    the
  2683.        _c_o_n_t_e_n_t_s    of this    first element to the variable "c"  just     by
  2684.        letting    "cp"  point at it.  By simply adding one to "cp" we
  2685.        have made it to point at    the next element in "vartable".
  2686.  
  2687.        14.1  LLLLvvvvaaaalllluuuueeeessss aaaannnndddd RRRRvvvvaaaalllluuuueeeessss RRRReeeevvvviiiissssiiiitttteeeedddd
  2688.  
  2689.        Pointers    are useful because they    can be changed    (bent?)     to
  2690.        address    any location in    memory whereas arrays are fixed    and
  2691.        always point to their first element.  For example,  if  your
  2692.        tried to    do this:
  2693.  
  2694.            char a[10];
  2695.  
  2696.            a = a + 1;
  2697.  
  2698.        you would get an    error message.    The  C    language  _d_o_e_s    _n_o_t
  2699.        _a_l_l_o_w  _y_o_u  _t_o _c_h_a_n_g_e _t_h_e _v_a_l_u_e _o_f _a_n _a_r_r_a_y _v_a_r_i_a_b_l_e.  If it
  2700.        did  there  might  be  the  possibility    of   your   program
  2701.        "forgetting"  where  the    data in    the array is located.  Thus
  2702.  
  2703.  
  2704.  
  2705.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2706.  
  2707.  
  2708.  
  2709.  
  2710.  
  2711.  
  2712.  
  2713.  
  2714.        44                               Pointers
  2715.  
  2716.  
  2717.        arrays can be put  in  the  same     category  as  strings    and
  2718.        integer     constants,   namely   "rvalues"  (see    an  earlier
  2719.        discussion on Lvalues and Rvalues).
  2720.  
  2721.        The attempt to change the array variable    "a" in the  example
  2722.        above  would  therefore    reward    you with a "need an lvalue"
  2723.        error message from the SCI interpreter.
  2724.  
  2725.        Pointers    on the other hand are more analagous to    variables -
  2726.        they  can  be  modified    and  are therefore considered to be
  2727.        "lvalues".
  2728.  
  2729.        14.2  PPPPooooiiiinnnntttteeeerrrr OOOOppppeeeerrrraaaattttoooorrrr
  2730.  
  2731.        The asterisk in the examples above is known as the "pointer"
  2732.        operator.   This    is a unary operator and    is used    in the same
  2733.        manner as the negation  (-)  unary  operator.   The  pointer
  2734.        operation  tells     C to treat its    associated pointer variable
  2735.        as a memory address and to store    or retrieve the     data  item
  2736.        at  that     address.   Note  that    the  operand  of  a pointer
  2737.        operator    must have been declared    as a  pointer,    or  C  will
  2738.        complain.   This     is  in     your  own best    interest because we
  2739.        humans  tend  to     forget     little     details  like    this.    For
  2740.        example,    if you wrote:
  2741.  
  2742.            char c, d;
  2743.  
  2744.            d = *c;
  2745.  
  2746.  
  2747.        you would get a "not a pointer" error message from SCI.
  2748.  
  2749.        Now, try    typing in this little program using the    SCI editor:
  2750.  
  2751.            prints(s)
  2752.            char *s;
  2753.            {
  2754.                while(*s)
  2755.                {
  2756.                    putchar(*s);
  2757.                    s=s+1;
  2758.                }
  2759.            }
  2760.  
  2761.        The Library Function "putchar()"    accepts    a  single  argument
  2762.        and  prints the ASCII representation of this argument to    the
  2763.        console screen.    This program takes a pointer to    a character
  2764.        string  as  an  argument.   Then,  while    the character being
  2765.  
  2766.  
  2767.  
  2768.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2769.  
  2770.  
  2771.  
  2772.  
  2773.  
  2774.  
  2775.  
  2776.  
  2777.        Pointers                                 45
  2778.  
  2779.  
  2780.        pointed at is non-zero,    "putchar()"  prints  the  character
  2781.        onto  the  console.  The    pointer    is then    incremented (s=s+1)
  2782.        so that it points at the    next character in the string.    Now
  2783.        execute the following command from the shell:
  2784.  
  2785.            shell> prints("hello, world\n");
  2786.  
  2787.        This should  have  resulted  in    the  words  "hello,  world"
  2788.        printed on the console.
  2789.  
  2790.        Except for the fact that    pointers may be    changed    and  arrays
  2791.        may  not, C treats both of them identically.  For example if
  2792.        we have the following two data declarations:
  2793.  
  2794.            char c, ca[ 10 ];
  2795.            char *cp;
  2796.  
  2797.        we can choose to    view the array variable    "ca" as    a  pointer,
  2798.        and  the     pointer variable "cp" as an array in our programs,
  2799.        like so:
  2800.  
  2801.            c = *ca;
  2802.            cp[ 5 ] = c;
  2803.  
  2804.        So, we could have written the  sample  program  from  before
  2805.        like this:
  2806.  
  2807.            prints(s)
  2808.            char *s;
  2809.            {
  2810.                int i;
  2811.  
  2812.                for ( i=0; s[i];    i=i+1 )
  2813.                    putchar(    s[i] );
  2814.            }
  2815.  
  2816.        This would have left the    pointer    argument "s" unaltered when
  2817.        the  "for"  loop    was finished.  This is sometimes necessary,
  2818.        as in the following example:
  2819.  
  2820.  
  2821.  
  2822.  
  2823.  
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829.  
  2830.  
  2831.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2832.  
  2833.  
  2834.  
  2835.  
  2836.  
  2837.  
  2838.  
  2839.  
  2840.        46                               Pointers
  2841.  
  2842.  
  2843.            prints10(s)
  2844.            char *s;
  2845.            {
  2846.                int i, j;
  2847.  
  2848.                for ( j=0; j<10;    j=j+1 )
  2849.                {
  2850.                    for ( i=0; s[i];    i=i+1 )
  2851.                        putchar(    s[i] );
  2852.                }
  2853.            }
  2854.  
  2855.        Here the    string passed to "prints10()"  is  printed  on    the
  2856.        console    ten  times.   If  we  had incremented the character
  2857.        pointer "s" instead of using the    index "i", then    the  second
  2858.        time  through  the  outer  loop    would have started with    "s"
  2859.        pointing    to the character after the end of the string.
  2860.  
  2861.        14.2.1  _P_o_i_n_t_e_r__E_x_p_r_e_s_s_i_o_n_s  We stated that C knows the type
  2862.        of  data     item  a  pointer is pointing to ("char" or "int").
  2863.        Assume that we have a pointer variable named "ip",  then     in
  2864.        this example:
  2865.  
  2866.            i = *(ip    + 5);
  2867.  
  2868.        we are trying to    retrieve the data item pointed at  by  "ip"
  2869.        and  offset by 5.  If "ip" was a    pointer    to an "int", we    are
  2870.        retrieving the sixth 2-byte integer of the array    pointed     at
  2871.        by "ip".     Physically, this would    be the eleventh    and twelfth
  2872.        bytes  of  the  array.    Notice    that  this  expression     is
  2873.        functionally equivalent to:
  2874.  
  2875.            i = ip[ 5 ];
  2876.  
  2877.        C allows    you to perform certain mathematical and     relational
  2878.        operations on pointers, specifically:
  2879.  
  2880.        1.  you may add a constant or an    expression  that  evaluates
  2881.        to a    constant to a pointer.
  2882.  
  2883.        2.  you may subtract two    pointers, but only if they point to
  2884.        the    same  type  of    data.    For  instance,    you may    not
  2885.        subtract a "char" pointer from an  "int"  pointer.    The
  2886.        result  is  the  number  of    elements  between  the    two
  2887.        pointers.
  2888.  
  2889.        3.  you    may  compare  two  pointers  using  the     relational
  2890.        operators (==, !=, <    <= > and >=).
  2891.  
  2892.  
  2893.  
  2894.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2895.  
  2896.  
  2897.  
  2898.  
  2899.  
  2900.  
  2901.  
  2902.  
  2903.        Pointers                                 47
  2904.  
  2905.  
  2906.        All  other  mathematical     operations  on     pointers  are    not
  2907.        allowed.
  2908.  
  2909.        On occasion  you     may  wish  to    use  integer  constants     as
  2910.        pointers, like this:
  2911.  
  2912.            char c;
  2913.  
  2914.            c = *0x0100;
  2915.  
  2916.        When  a    constant  is  used  as    the  target  of     a  pointer
  2917.        operation,  SCI    will access the    two bytes (an "int") at    the
  2918.        location    specified by the value of  the    constant,  in  this
  2919.        case  at     location  100 hex.  You can get as creative as    you
  2920.        want when using constants as pointers:
  2921.  
  2922.            char c, offs;
  2923.  
  2924.            c = *((0x101 + offs) * 2);
  2925.  
  2926.        Note that SCI will allow    you to use variables that have    not
  2927.        been declared as    pointers in pointer expressions    if they    are
  2928.        enclosed    in parentheses as shown    above.
  2929.  
  2930.  
  2931.                   NOTE:
  2932.  
  2933.        Standard    C does not allow you to    use constant expressions as
  2934.        pointers,  any  attempt    to  do so will usually result in an
  2935.        error message.
  2936.  
  2937.        14.2.2  _p_r_i_n_t_f_(_)     C  functions  do  not    intrinsically  know
  2938.        whether    their  arguments  are  printable strings or just an
  2939.        array or    numbers, like BASIC does.  Therefore there are no C
  2940.        functions  that    are  analogous    to  BASIC's PRINT statement
  2941.        which prints either a number or a string     depending  on    its
  2942.        argument.   The    standard  C  Library  Function    "printf()",
  2943.        however,    performs a print operation similar to BASIC's PRINT
  2944.        statement.   "Printf",  which is    read as    "print-eff", stands
  2945.        for "print formatted".  It is the most  unusual    standard  C
  2946.        function     because it accepts a variable number of arguments,
  2947.        depending on the    contents of its    first argument.     The  first
  2948.        argument     to "printf" is    a string of characters and is known
  2949.        as the "control string".     "Printf" works    like this: it scans
  2950.        through the characters in the control string and    prints them
  2951.        out on the console screen;   if    a  percent  symbol  (%)     is
  2952.        encountered  in    the control string, the    character following
  2953.        the "%"    determines  how     printf's  next     _a_r_g_u_m_e_n_t  will     be
  2954.  
  2955.  
  2956.  
  2957.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  2958.  
  2959.  
  2960.  
  2961.  
  2962.  
  2963.  
  2964.  
  2965.  
  2966.        48                               Pointers
  2967.  
  2968.  
  2969.        processed.   For    example, if the    character following the    "%"
  2970.        is a lower case letter "s", the next argument is    assumed     to
  2971.        be  a  character     string     and  is printed out to    the console
  2972.        instead    of  the     "%s"  character   combination.       A   "%d"
  2973.        combination in the control string takes its next    argument to
  2974.        be an integer and prints    its decimal value.  "Printf"  keeps
  2975.        track  of which arguments have already been printed by a    "%-
  2976.        letter" combination, so that the    next "%-letter"    combination
  2977.        affects the next    argument in the    argument list.
  2978.  
  2979.        For example, try    the following command from the shell:
  2980.  
  2981.        printf("%s, did you know    %d*%d is %d?0,"Bob",376,49,376*49)
  2982.  
  2983.        The "%s"    conversion treats the second argument, "Bob"  as  a
  2984.        string  (which  it  is!)    and prints it; the first "%d" grabs
  2985.        the next    argument in the    list  (376)  and  prints  it  as  a
  2986.        decimal    number;     the  second  "%d"  prints  49 as a decimal
  2987.        number; finally,    the third "%d" takes the product of 376    and
  2988.        49  and    prints    it  as    a decimal number.  What    should have
  2989.        appeared    on your    screen is:
  2990.  
  2991.            Bob, did    you know 376*49    is 18424?
  2992.  
  2993.        "Printf"    also recognizes    these other conversion codes:
  2994.  
  2995.        %x      prints its argument as a     hexadecimal  number.    The
  2996.            characters "0x" do not appear in    the printed number;
  2997.            you must    add them if needed like    so:
  2998.  
  2999.                    printf( "%d = 0x%x0, 376, 376 )
  3000.  
  3001.        %o      prints its argument as an octal number.
  3002.  
  3003.        %c      prints its argument as an ASCII character.
  3004.  
  3005.        14.3  AAAAddddddddrrrreeeessssssss OOOOppppeeeerrrraaaattttoooorrrr
  3006.  
  3007.        In an earlier discussion    about the scope     of  variables,     we
  3008.        said  when  a  variable    is passed to a function, the called
  3009.        function    creates    a clone    of the caller's    variable and copies
  3010.        its  contents  into  this  local     variable.   This  way    the
  3011.        function     can  not  alter  the  contents     of  the   caller's
  3012.        variable.   How    then  can  we  have  a    function  alter    the
  3013.        contents    of our local variables    if  it    becomes     necessary?
  3014.        There  are several options open to us: 1) write the function
  3015.        so that it returns a value which    we can then assign  to    our
  3016.        local  variable,     2)  have the function put the value into a
  3017.  
  3018.  
  3019.  
  3020.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3021.  
  3022.  
  3023.  
  3024.  
  3025.  
  3026.  
  3027.  
  3028.  
  3029.        Pointers                                 49
  3030.  
  3031.  
  3032.        global variable which we    can access, or 3) pass the function
  3033.        the  address  of     our local variable.  The first    option only
  3034.        allows the function to pass back    one piece  of  information,
  3035.        thus  limiting  its  usefulness.      Option 2 is an acceptable
  3036.        method but forces the function to become    more dependent upon
  3037.        the   entire   program    structure.    This   is      fine    for
  3038.        application-specific functions, but  severly  restricts    the
  3039.        modularity  of  general    purpose     functions.   The  accepted
  3040.        method is to pass the function the address of  our  variable
  3041.        using the "address operator", "&", like so:
  3042.  
  3043.            prog()
  3044.            {
  3045.                char c;
  3046.  
  3047.                func( &c    ); # call "func()", pass the address of    "c"
  3048.            }
  3049.            func( ptr )
  3050.            char *ptr;
  3051.            {
  3052.                *ptr = 12;
  3053.            }
  3054.  
  3055.        The ampersand (&) as used above is  a  unary  operator  that
  3056.        tells  C     we  want  to  use  the     _a_d_d_r_e_s_s  of the associated
  3057.        variable    instead    of  its     _c_o_n_t_e_n_t_s.   _I_n     _o_t_h_e_r    _w_o_r_d_s,    _t_h_e
  3058.        _a_d_d_r_e_s_s _o_p_e_r_a_t_o_r    _y_i_e_l_d_s _a _p_o_i_n_t_e_r to its    associated operand.
  3059.        That's why we declared the argument to the function "func()"
  3060.        as  a  pointer  to a "char".  In    the above example then,    the
  3061.        local variable "c" in "prog()" would have  been    set  to     12
  3062.        after the call to "func()".
  3063.  
  3064.        Extreme caution must be exercised when passing  pointers     to
  3065.        variables  like this.  If we had    instead    declared "ptr" as a
  3066.        pointer to an "int" (int    *ptr;) in the  function,  "func()",
  3067.        then  the  assignment  "*ptr = 12;" would have destroyed    the
  3068.        memory  location     following  "c"     and  possibly    caused    the
  3069.        program to crash.
  3070.  
  3071.        Note that you may only use the address operator on  lvalues;
  3072.        this  means  only simple    variables and pointers.     If you    try
  3073.        to use the address operator on a    constant, a  string  or     an
  3074.        array you will evoke a "need an lvalue" error from SCI.
  3075.  
  3076.        Now  enter  and    test  this  little  program  from  the    SCI
  3077.        interpreter:
  3078.  
  3079.  
  3080.  
  3081.  
  3082.  
  3083.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3084.  
  3085.  
  3086.  
  3087.  
  3088.  
  3089.  
  3090.  
  3091.  
  3092.        50                               Pointers
  3093.  
  3094.  
  3095.            words()
  3096.            {
  3097.                char *word, *cp,    linebuf[80];
  3098.  
  3099.                puts("type some words: ");
  3100.                gets(cp = linebuf);
  3101.                while(cp) {
  3102.                    cp = parse(cp, &word);
  3103.                    puts("word = <");
  3104.                    puts(word);
  3105.                    puts(">\n");
  3106.                }
  3107.            }
  3108.  
  3109.            parse(str,word)
  3110.            char *str;
  3111.            int *word;
  3112.            {
  3113.                while(*str==' ')
  3114.                    ++str;
  3115.                *word=str;
  3116.                while(*str!=' ' && *str)
  3117.                    ++str;
  3118.                if(*str==0)
  3119.                    return 0;
  3120.                *str=0;
  3121.                return str+1;
  3122.            }
  3123.  
  3124.  
  3125.        and from    the shell execute  the    function  "words()".   What
  3126.        does this program do?
  3127.  
  3128.        14.3.1  _s_c_a_n_f_(_)     The  companion     to  the  Library  Function
  3129.        "printf()"  is  "scanf()"  (read    "scan-eff").  This function
  3130.        performs    the reverse operation of "printf()",  that  is,     it
  3131.        converts     strings and numbers read from the console keyboard
  3132.        and places them into program variables.    This means that    its
  3133.        arguments must be _p_o_i_n_t_e_r_s to the appropriate data type.
  3134.  
  3135.        Examine the following program:
  3136.  
  3137.  
  3138.  
  3139.  
  3140.  
  3141.  
  3142.  
  3143.  
  3144.  
  3145.  
  3146.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3147.  
  3148.  
  3149.  
  3150.  
  3151.  
  3152.  
  3153.  
  3154.  
  3155.        Pointers                                 51
  3156.  
  3157.  
  3158.            getname()
  3159.            {
  3160.                char firstname[20], lastname[20];
  3161.                int zip;
  3162.  
  3163.                puts("First name    last name and zipcode?");
  3164.                scanf("%s %s %d", firstname, lastname, &zip );
  3165.  
  3166.                printf("firstname = %s\n",firstname);
  3167.                printf("lastname    = %s\n",lastname);
  3168.                printf("zipcode = %d\n",zip);
  3169.            }
  3170.  
  3171.        Scanf assumes that a string is a    stream of consecutive  non-
  3172.        blank  characters.  The function    will not stop reading input
  3173.        until all of  its  conversion  (%-letter)  codes     have  been
  3174.        satisfied, or until an end of input (control-Z in MS-DOS) is
  3175.        encountered.  This means    that carriage returns _d_o _n_o_t  cause
  3176.        scanf  to  quit    reading    and return to the caller.  Carriage
  3177.        returns are simply treated as spaces and    tabs,  collectively
  3178.        known  as  "white  space".   In the program above, you could
  3179.        have entered you    first and last name on    seperate  lines     if
  3180.        you  like,  or  on  the    same  line seperated by    one or more
  3181.        spaces or tabs.
  3182.  
  3183.        Notice that the _a_d_d_r_e_s_s of the integer  variable     "zip"    was
  3184.        passed  to scanf; do you    now understand why?  If    we had used
  3185.        the following statement instead:
  3186.  
  3187.            scanf( "%d", zip    );
  3188.  
  3189.  
  3190.        then the    _c_o_n_t_e_n_t_s of "zip"  would  have    been  used  as    the
  3191.        location     where    scanf would place an integer value.  If    the
  3192.        contents    of "zip" had been zero,    then memory locations  zero
  3193.        and  one     would    have  been altered by scanf, and would have
  3194.        possibly    damaged    the operating system.
  3195.  
  3196.  
  3197.        15.  IIIInnnnccccrrrreeeemmmmeeeennnntttt aaaannnndddd DDDDeeeeccccrrrreeeemmmmeeeennnntttt OOOOppppeeeerrrraaaattttoooorrrrssss
  3198.  
  3199.        As we have already seen,     we  can  use  several    methods     to
  3200.        access  elements    in an array.  Let's say    we had an array    and
  3201.        wanted to access    its elements sequentially,  one     after    the
  3202.        other.    We  could either declare a pointer to the array    and
  3203.        then increment the pointer by one; or we     could    declare     an
  3204.        integer    variable to be used as an array    index and increment
  3205.        it each time by one, like so:
  3206.  
  3207.  
  3208.  
  3209.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3210.  
  3211.  
  3212.  
  3213.  
  3214.  
  3215.  
  3216.  
  3217.  
  3218.        52                  Increment    and Decrement Operators
  3219.  
  3220.  
  3221.            char a[10], *p;
  3222.            int i;
  3223.  
  3224.            # set all 10 elements in    the array "a" to zero,
  3225.            # using a pointer:
  3226.            p=a;
  3227.            i=0;
  3228.            while(i<10)
  3229.            {
  3230.                *p = 0;
  3231.                p=p+1;
  3232.                i=i+1;
  3233.            }
  3234.  
  3235.            # ...and    using an index:
  3236.            i=0;
  3237.            while(i<10)
  3238.            {
  3239.                a[i] = 0;
  3240.                i=i+1;
  3241.            }
  3242.  
  3243.        Since these operations come up often in programming,  the  C
  3244.        language     offers    a very efficient method    of incrementing    and
  3245.        decrementing  varibles.     These    are  appropriately  enough,
  3246.        called  the  "increment"    and "decrement"    operators, "++"    and
  3247.        "--".  The increment/decrement operators    are unary operators
  3248.        and  can    appear either before or    after a    variable name, like
  3249.        this:
  3250.  
  3251.            int i;
  3252.  
  3253.            ++i;    # increment "i" by one
  3254.            i++;    # same thing
  3255.            --i;    # decrement "i" by one
  3256.            i--;    # and again
  3257.  
  3258.        If the operator appears _b_e_f_o_r_e the variable, it is known     as
  3259.        a  "pre-"  increment  or     decrement; if it appears _a_f_t_e_r    the
  3260.        variable, it is a  "post-"  increment/decrement.      The  pre-
  3261.        increment/decrement  operators perform their function _b_e_f_o_r_e
  3262.        the variable is used in the expression,    whereas     the  post-
  3263.        increment/decrement  operators  perform their function _a_f_t_e_r
  3264.        the variable has    been used in the expression.  This is  best
  3265.        explained with an example:
  3266.  
  3267.  
  3268.  
  3269.  
  3270.  
  3271.  
  3272.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3273.  
  3274.  
  3275.  
  3276.  
  3277.  
  3278.  
  3279.  
  3280.  
  3281.        Increment and Decrement Operators                 53
  3282.  
  3283.  
  3284.            incdec()
  3285.            {
  3286.                int i;
  3287.  
  3288.                i = 0;
  3289.                putd( ++i );
  3290.  
  3291.                i = 0;
  3292.                putd( i++ );
  3293.            }
  3294.  
  3295.        The first instance  of  "putd()"     would    print  a  1  -    the
  3296.        variable     "i"  was  increment  by  one  before its value    was
  3297.        passed to "putd()".  Now    we set "i" to zero  again  and    the
  3298.        second call to "putd()" will print a 0.    This is    because    the
  3299.        post-increment operator passes  the  value  of  "i"  to    the
  3300.        function    "putd()" _b_e_f_o_r_e    it gets    incremented by one.
  3301.  
  3302.        These operators are very    handy for quickly scanning  through
  3303.        an array    like this:
  3304.  
  3305.            prints(s)
  3306.            char *s;
  3307.            {
  3308.                while ( *s )
  3309.                    putchar(    *s++ );
  3310.            }
  3311.  
  3312.        When using the increment/decrement  operators  on  pointers,
  3313.        SCI  knows  what     data  type  the pointer is referencing    and
  3314.        adjusts the pointer so that it points to     the  next/previous
  3315.        data  item.   In    other words, when incrementing a pointer to
  3316.        an integer, the pointer is incremented by two instead of    one
  3317.        so  that     it  points  to     the next integer.  If we wanted to
  3318.        print out all the numbers in an integer array, we  might     do
  3319.        something like this:
  3320.  
  3321.            dump()
  3322.            {
  3323.                int array[ 10 ],    *ap;
  3324.  
  3325.                ap = array;
  3326.                for ( i=0; i<10;    ++i )
  3327.                    printf( "%d\n", *ap++ );
  3328.            }
  3329.  
  3330.  
  3331.  
  3332.  
  3333.  
  3334.  
  3335.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3336.  
  3337.  
  3338.  
  3339.  
  3340.  
  3341.  
  3342.  
  3343.  
  3344.        54                  Increment    and Decrement Operators
  3345.  
  3346.  
  3347.        16.  AAAA TTTToooouuuurrrr TTTThhhhrrrroooouuuugggghhhh tttthhhheeee FFFFiiiilllleeee IIII////OOOO    FFFFuuuunnnnccccttttiiiioooonnnnssss
  3348.  
  3349.        The formal definition of    the  C    language  does    not  really
  3350.        include    any  of     the Library Functions we have discussed so
  3351.        far.  However, most of these have become     defacto  standards
  3352.        and are considered a part of the    language's support library.
  3353.        Although    the exact usage    of support functions may vary  from
  3354.        one  compiler  implementation  to the next, most    C compilers
  3355.        adhere  to  a  "standard"  to  some  degree.   This  section
  3356.        discusses  SCI's     implementation     of  the file I/O functions
  3357.        which is    fairly compatible with the "standards" proposed     by
  3358.        the authors of the C language.
  3359.  
  3360.        This section only attempts to clarify some points concerning
  3361.        the  file  I/O  functions  and  is not meant as a reference.
  3362.        Please refer to the section in the User's Manual    titled "The
  3363.        Library Function" for exact details about these functions.
  3364.  
  3365.        16.1  ffffooooppppeeeennnn(((())))
  3366.  
  3367.        Before a    file can be used (read from or written to), it must
  3368.        first  be  "opened"  with  the  Library    Function "fopen()".
  3369.        Opening    a  file     ensures  that    the  file  exists  and     is
  3370.        readable/writable  and prepares internal    data structures    for
  3371.        dealing with the    file.  Before a    C program starts up,  three
  3372.        "files"    are  opened for    it by the "operating system", these
  3373.        are known as the    "standard  input",  "standard  output"    and
  3374.        "standard  error" file.    These usually default to the user's
  3375.        console keyboard    and screen.  The "standard error"  file     is
  3376.        an  output  file     and  always defaults to the user's console
  3377.        screen.    It is usually used by the program to display  error
  3378.        messages.   The    reason    we like    to have    two output files is
  3379.        because    we  don't  want     to  intermix  program    error    and
  3380.        informational  messages    with  program  output  data, and to
  3381.        insure that error  messages  always  appear  on    the  user's
  3382.        console.
  3383.  
  3384.        To open a file, "fopen()" must be called    with two arguments:
  3385.        the  file  name,    and a character    string that defines how    the
  3386.        file is to be accessed. For example,
  3387.  
  3388.            int channel;
  3389.  
  3390.            channel = fopen(    "SHELL.SCI", "r" );
  3391.  
  3392.        would open the file "SHELL.SCI" for reading  ("r").   MS-DOS
  3393.        allows  the  file  name    to be in upper or lower    case, other
  3394.        operating systems may  not  be  so  indifferent    about  file
  3395.  
  3396.  
  3397.  
  3398.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3399.  
  3400.  
  3401.  
  3402.  
  3403.  
  3404.  
  3405.  
  3406.  
  3407.        A Tour Through the File I/O Functions                 55
  3408.  
  3409.  
  3410.        names.    The  second  string, known as the "open    mode", must
  3411.        contain either a     lower    case  "r"  to  open  the  file    for
  3412.        reading,     "w" for writing or "a"    for appending.    When a file
  3413.        is opened for reading, it must already  exist  or  "fopen()"
  3414.        will return an error code.  If a    file is    opened for writing,
  3415.        it may or may not exist;    if  it    does  exist,  it  is  first
  3416.        deleted    before the open.  If a file is opened for appending
  3417.        and the file exists, it is opened for writing, but  data     is
  3418.        written to the end of the file.    If the file does not exist,
  3419.        an open for append acts like an open  for  write.   You    may
  3420.        also  open  a file for both reading and writing,    meaning    you
  3421.        may intermix read and write functions on    the same file,    but
  3422.        see   the   section   on     the  Library  Functions  for  more
  3423.        information.
  3424.  
  3425.        The value returned by "fopen()" is an integer known  as    the
  3426.        "channel     number"  and  points  to  the previously mentioned
  3427.        internal    file control data structure.  This  channel  number
  3428.        is  then     used  by  the    other  file read/write functions to
  3429.        access the file.     If "fopen()" was unable to find  the  file
  3430.        (file  opened  for reading) or the file could not be created
  3431.        (file opened for    writing), it  returns  a  zero,     indicating
  3432.        failure.
  3433.  
  3434.        The special channel numbers 1, 2    and 3 may be used  to  read
  3435.        and write from/to the standard input, output and    error files
  3436.        respectively.  These channel numbers may    be  used  with    the
  3437.        file  read/write     routines at any time, unless of course    you
  3438.        have closed them.
  3439.  
  3440.        16.2  ffffcccclllloooosssseeee(((())))
  3441.  
  3442.        When a file is no longer    needed,    it should  be  "closed"     by
  3443.        the program.  Closing a file ensures that the file is safely
  3444.        stored on disk and it frees up  the  internal  file  control
  3445.        data structure.
  3446.  
  3447.        This function expects a single argument,    the file pointer:
  3448.  
  3449.            fclose( fp );
  3450.  
  3451.        and returns a zero if the file was closed successfully, or a
  3452.        -1  if  an error    occured    (the file was never opened, disk is
  3453.        write protected,    etc.).
  3454.  
  3455.  
  3456.  
  3457.  
  3458.  
  3459.  
  3460.  
  3461.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3462.  
  3463.  
  3464.  
  3465.  
  3466.  
  3467.  
  3468.  
  3469.  
  3470.        56              A Tour Through the File I/O Functions
  3471.  
  3472.  
  3473.        16.3  ffffggggeeeettttcccc(((()))) aaaannnndddd ffffppppuuuuttttcccc(((())))
  3474.  
  3475.        The functions "fgetc()" and "fputc()" are used to  read    and
  3476.        write  respectively a single character from/to a    file.  Both
  3477.        of these    functions advance a "file position  pointer"  which
  3478.        points  to the next character to    be read/written    to/from    the
  3479.        file.  This file    position pointer is one    of the items in    the
  3480.        aforementioned  internal    file control data structure.  These
  3481.        functions are used like so:
  3482.  
  3483.            copy(fromfile,tofile)
  3484.            char *fromfile, *tofile;
  3485.            {
  3486.                int fromchannel,    tochannel, c;
  3487.  
  3488.                fromchannel = fopen( fromfile, "r" );
  3489.                tochannel = fopen( tofile, "w" );
  3490.                while ( (c = fgetc( fromchannel )) != -1    )
  3491.                    fputc( c, tochannel );
  3492.                fclose( fromchannel );
  3493.                fclose( tochannel );
  3494.            }
  3495.  
  3496.        This little program copies the file whose name is the string
  3497.        at "fromfile" to    the file whose name is at "tofile".
  3498.  
  3499.        The function "fgetc()" returns the character that  was  read
  3500.        from the    file (a    single byte value from 0 to 255) or a minus
  3501.        one if the end of the file was  reached    or  if    some  other
  3502.        error occured.  The function "fputc()" returns the character
  3503.        that was    written    or a minus one if an error occured.
  3504.  
  3505.        16.4  ffffggggeeeettttssss(((()))) aaaannnndddd ffffppppuuuuttttssss(((())))
  3506.  
  3507.        You may also read and write disk    files a    "line"    at  a  time
  3508.        with  the  functions "fgets()" and "fputs()".  A    "line" is a
  3509.        sequence    of characters in the file that end with     a  newline
  3510.        ("\n")  character.   These  are    similar     to  the  functions
  3511.        "gets()"    and "puts()", which  read  and    write  from/to    the
  3512.        standard    input and standard output.
  3513.  
  3514.        Note   that   the   two     functions   fputs("hello",2)    and
  3515.        puts("hello") are identical.
  3516.  
  3517.  
  3518.  
  3519.  
  3520.  
  3521.  
  3522.  
  3523.  
  3524.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3525.  
  3526.  
  3527.  
  3528.  
  3529.  
  3530.  
  3531.  
  3532.  
  3533.        A Tour Through the File I/O Functions                 57
  3534.  
  3535.  
  3536.        16.5  ffffrrrreeeeaaaadddd(((()))) aaaannnndddd ffffwwwwrrrriiiitttteeee(((())))
  3537.  
  3538.        Sometimes it is useful to be able to read or write a file in
  3539.        arbitrarily  long  "blocks".  For example, suppose we wanted
  3540.        to store    an  array  of  integer    numbers     in  a    file.    The
  3541.        character  read/write  functions     ("fgetc()"  and "fputc()")
  3542.        would work but would be less efficient than writing  several
  3543.        characters   at     a   time.   The  functions  "fread()"    and
  3544.        "fwrite()" are ideal for    these situations:
  3545.  
  3546.            sortfile()
  3547.            {
  3548.                int array[ 100 ];
  3549.                int channel;
  3550.  
  3551.                channel = fopen(    "NUMBERS.DAT", "r" );
  3552.                fread( array, 200, channel );
  3553.                fclose( channel );
  3554.  
  3555.                sort( array, 100    );
  3556.  
  3557.                channel = fopen(    "NUMBERS.DAT", "w" );
  3558.                fwrite( array, 200, channel );
  3559.                fclose( channel );
  3560.            }
  3561.  
  3562.            sort(a,n)
  3563.            int a[],    n;
  3564.            {
  3565.                int temp, i, j;
  3566.  
  3567.                for ( i=0; i<n-2; ++i ) {
  3568.                    for ( j=i; j<n-1; ++j ) {
  3569.                        if ( a[j] > a[j+1] ) {
  3570.                            temp=a[j];
  3571.                            a[j]=a[j+1];
  3572.                            a[j+1]=temp;
  3573.                        }
  3574.                    }
  3575.                }
  3576.            }
  3577.  
  3578.        This program reads an array of  100  numbers  from  a  file,
  3579.        sorts  them  in    numeric     order    and writes them    back to    the
  3580.        file.  Note that    we asked "fread()" and "fwrite()"  for    200
  3581.        bytes.    Since  the  array consists of 100 integers and each
  3582.        integer is 2 bytes, the array is    200 bytes long.
  3583.  
  3584.  
  3585.  
  3586.  
  3587.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3588.  
  3589.  
  3590.  
  3591.  
  3592.  
  3593.  
  3594.  
  3595.  
  3596.        58              A Tour Through the File I/O Functions
  3597.  
  3598.  
  3599.        Also, be    sure to    close a    file when it is    no  longer  needed.
  3600.        If  we  had  neglected to close the file    after the "fopen()"
  3601.        for reading, the    second call to "fopen()" would have altered
  3602.        our file    pointer.  The value of the first file pointer would
  3603.        have been destroyed  and     the  internal    file  control  data
  3604.        structure  would     have been lost    in limbo forever.  Although
  3605.        this wouldn't have caused any  damage,  it  is  very  sloppy
  3606.        programming.   Keep  in    mind  that  you     have  only 10 file
  3607.        control data structures available.
  3608.  
  3609.        16.6  ffffsssseeeeeeeekkkk(((()))) aaaannnndddd fffftttteeeellllllll(((())))
  3610.  
  3611.        All of the file read/write functions  advance  an  invisible
  3612.        "file  position    pointer" which determines where    in the file
  3613.        the  next  character  will  be  read  from  or  written    to.
  3614.        Sometimes it is necessary to re-read a character    or group of
  3615.        characters in a file, or    to write over the current  contents
  3616.        in a file with new data.     The function "fseek()"    can be used
  3617.        to relocate the file position pointer to    anywhere within    the
  3618.        file,  and allow    you to re-read or re-write data    in the file
  3619.        as necessary.
  3620.  
  3621.        Ftell simply returns the    current    value of the file  position
  3622.        pointer.
  3623.  
  3624.        Examine the following sample program:
  3625.  
  3626.  
  3627.  
  3628.  
  3629.  
  3630.  
  3631.  
  3632.  
  3633.  
  3634.  
  3635.  
  3636.  
  3637.  
  3638.  
  3639.  
  3640.  
  3641.  
  3642.  
  3643.  
  3644.  
  3645.  
  3646.  
  3647.  
  3648.  
  3649.  
  3650.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3651.  
  3652.  
  3653.  
  3654.  
  3655.  
  3656.  
  3657.  
  3658.  
  3659.        A Tour Through the File I/O Functions                 59
  3660.  
  3661.  
  3662.            link()
  3663.            {
  3664.                int start, current, inchannel, outchannel, c;
  3665.  
  3666.                inchannel = fopen( "RAW.DAT", "r" );
  3667.                outchannel = fopen( "LINKED.DAT", "wr" );
  3668.  
  3669.                start = 0;
  3670.                fwrite( &start, 2, outchannel );
  3671.                while ( (c=fgetc( inchannel )) != -1 ) {
  3672.                    if ( fputc( c, outchannel ) == 0x00ff )
  3673.                        current = ftell(    outchannel );
  3674.                        fseek( outchannel, start, 0 );
  3675.                        fwrite( ¤t, 2, outchannel );
  3676.                        fseek( outchannel, current, 0 );
  3677.                        start = current;
  3678.                    }
  3679.                }
  3680.                fclose( inchannel );
  3681.                fclose( outchannel );
  3682.            }
  3683.  
  3684.        This program copies the file RAW.DAT  to     LINKED.DAT.   Each
  3685.        time  a byte of all one's (FF hexadecimal) is encountered in
  3686.        RAW.DAT,    the program backs up to    the previous start location
  3687.        in  LINKED.DAT  (indicated  in  the  variable  "start")    and
  3688.        inserts     the   file's    current      file     position   pointer
  3689.        ("current").   In  other     words,     the program creates a file
  3690.        identical to RAW.DAT  except  that  the    data  in  the  file
  3691.        contains     information that tells    where all of the 0xff's    are
  3692.        located within the file - a linked list.
  3693.  
  3694.        Since SCI only supports integer variables, this    limits    the
  3695.        maximum    range  of  absolute file positioning available with
  3696.        "fseek()" to 32767 from the beginning or    end  of     the  file.
  3697.        You  can     however,  position  the file pointer to within    +/-
  3698.        32767 bytes from    the _c_u_r_r_e_n_t position.  This allows  you     to
  3699.        position     the  file  pointer  anywhere  within  the file, no
  3700.        matter how large    the file is.  Standard C uses  "long"  data
  3701.        variables   instead  of    "int"'s     for  specifying  the  file
  3702.        position    offset.     Long's    are usually twice the  size  of     an
  3703.        "int"  (four  bytes  instead of two), which gives you a much
  3704.        larger range of absolute    file positioning.
  3705.  
  3706.  
  3707.  
  3708.  
  3709.  
  3710.  
  3711.  
  3712.  
  3713.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3714.  
  3715.  
  3716.  
  3717.  
  3718.  
  3719.  
  3720.  
  3721.  
  3722.        60                           The Debugger
  3723.  
  3724.  
  3725.        17.  TTTThhhheeee    DDDDeeeebbbbuuuuggggggggeeeerrrr
  3726.  
  3727.        SCI provides a  powerful     program  debugging  facility  that
  3728.        allows  you  to execute your programs with complete control.
  3729.        When the    debugger  is  active,  it  takes  control  of  your
  3730.        program    and  allows  you  to  step through the program in a
  3731.        controlled fashion.  You    have the option    of either executing
  3732.        a  line at a time, or stop at any line in the program.  From
  3733.        the  debugger  you  can    also  examine  and  change  program
  3734.        variables  in  the  middle  of a    program    run, or    execute    any
  3735.        valid C statement.
  3736.  
  3737.        Besides being a reference for the SCI debug  facility,  this
  3738.        section    will introduce you to general debugging    strategies,
  3739.        and show    you how    you can    use the     SCI  debugger    to  gain  a
  3740.        better knowledge    of C program flow.
  3741.  
  3742.        17.1  IIIInnnnttttrrrroooodddduuuuccccttttiiiioooonnnn
  3743.  
  3744.        The SCI debugger    operates in what  is  known  as     "symbolic"
  3745.        mode.   As  you    probably  already  know, a computer can    not
  3746.        directly    execute    program    instructions written in    the  C    (or
  3747.        any   other   higher-level)   language.      The    C  language
  3748.        instructions must first be converted to machine language    and
  3749.        then  executed  by  the    computer.   This  is  the  mode     of
  3750.        operation when using a C     compiler.   Alternatively,  the  C
  3751.        source  code  can be directly executed by a program known as
  3752.        an "interpreter", which    is  exactly  how  SCI  works.  A  C
  3753.        program    that  has been compiled    is completely unreadable by
  3754.        us humans - all resemblence to the original C code has  been
  3755.        stripped     from the program since    it is intended only for    the
  3756.        computer's   "eyes".    We   say      that      the     "symbolic"
  3757.        representation  of  a  machine  readable     program  has  been
  3758.        removed.     On the    other hand,  since  an    interpreter  always
  3759.        keeps  a    "symbolic" (human readable) form of your program in
  3760.        memory, it is very easy to follow the program as    it is being
  3761.        executed     by  the  interpreter.     A  debugger  that has this
  3762.        ability to let the human    reader follow along as the  program
  3763.        is  executed  by     the  computer,     is  known  as    a "symbolic
  3764.        debugger".
  3765.  
  3766.        There are basically two types of     program  errors  that    can
  3767.        occur:  unrecoverable and recoverable.  Unrecoverable errors
  3768.        are typified by the computer's  refusal    to  answer  to    the
  3769.        programmer's  desperate    pounding  on  the keyboard - we    say
  3770.        that the    computer has "locked up" and  gone  south  for    the
  3771.        winter.     These    errors may be caused by    partial    or complete
  3772.        destruction of the  program  itself,  or     of  the  operating
  3773.  
  3774.  
  3775.  
  3776.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3777.  
  3778.  
  3779.  
  3780.  
  3781.  
  3782.  
  3783.  
  3784.  
  3785.        The Debugger                             61
  3786.  
  3787.  
  3788.        system  and usually require you to turn the computer off    and
  3789.        then on again.  Recoverable errors are the kind which do    not
  3790.        allow the program to run    to normal completion and return    you
  3791.        to either the operating system or to the    calling    program, or
  3792.        simply  "get stuck" in a    never ending loop.  The    category of
  3793.        recoverable errors also include incorrect results:
  3794.  
  3795.            YOU: what is 2 plus 2?
  3796.            COMPUTER: 5
  3797.  
  3798.  
  3799.        and unexpected results:
  3800.  
  3801.            COMPUTER: shall I delete    this file?
  3802.            YOU: No
  3803.            COMPUTER: OK, file deleted!
  3804.  
  3805.        For obvious reasons, SCI's built-in debugger is only capable
  3806.        of dealing with recoverable errors.
  3807.  
  3808.        The apporach to finding both of these  types  of     errors     is
  3809.        basically  the same: allow the program to run normally up to
  3810.        the point just before it    goes berzerk, then stop    and look at
  3811.        how it got there.  Usually, the hardest task is finding that
  3812.        point where your    program    goes over the edge.  You  have    two
  3813.        choices:    either run the program from the    very beginning,    one
  3814.        line at a time until something unexpected happens, or  allow
  3815.        the program to run normally and stop just before    the section
  3816.        of code that is suspect.     The method of executing a  program
  3817.        a  line    at a time is known as "single-stepping".  Running a
  3818.        program normally    and having it stop at a    given line is known
  3819.        as  "running to breakpoint".  The SCI debugger allows you to
  3820.        use both    of these approaches in any combination.
  3821.  
  3822.        17.2  EEEEnnnnaaaabbbblllliiiinnnngggg tttthhhheeee DDDDeeeebbbbuuuuggggggggeeeerrrr
  3823.  
  3824.        The Library  Function  "debug"  is  used     to  turn  the    SCI
  3825.        debugger     on and    off and    may be called either from the shell
  3826.        prompt or from within your program.  A  single  argument     to
  3827.        the "debug()" function determines the debugger mode.  If    the
  3828.        argument    is zero    (debug mode 0),    the debugger is     completely
  3829.        disabled.   If  the  argument  is  a one    (debug mode 1),    the
  3830.        debugger    will only grab control of a running program if    you
  3831.        hit  the     <ESCAPE>  key    from  the  keyboard,  otherwise    the
  3832.        program will run     normally;  if    the  debug  mode  is  2     or
  3833.        greater,    the debugger is    always in control of your program.
  3834.  
  3835.  
  3836.  
  3837.  
  3838.  
  3839.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3840.  
  3841.  
  3842.  
  3843.  
  3844.  
  3845.  
  3846.  
  3847.  
  3848.        62                           The Debugger
  3849.  
  3850.  
  3851.        Thus, your program might    look like this:
  3852.  
  3853.            func()
  3854.            {
  3855.                int i;
  3856.                .
  3857.                .
  3858.                .
  3859.                debug(2);       # turn debugger ON
  3860.                while(i<10)     # scrutinize this loop
  3861.                {
  3862.                    .
  3863.                    .
  3864.                    .
  3865.                }
  3866.                debug(1);       # turn debugger OFF again
  3867.            }
  3868.  
  3869.        You can also turn the debugger on directy from the  keyboard
  3870.        while a program is running.  By pressing    the <ESCAPE> key in
  3871.        debug mode 1, the program is stopped in    mid  execution    and
  3872.        the debugger is turned on.  Thus, if you    have a program that
  3873.        seems to    be stuck in a forever loop, you    can get    control    and
  3874.        take a look at what's causing the problem.
  3875.  
  3876.        When the    debugger gets control  of  your     program,  it  will
  3877.        automatically  display  the  line number    and program text of
  3878.        the next    line to    be executed.  It is  important    to  realize
  3879.        that  the  displayed program line has not yet been executed.
  3880.        Directly    below the  displayed  line  is    a  circumflex  that
  3881.        points  the  first  item     in the    line that will be executed.
  3882.        For example, if you had more than one statement on a  single
  3883.        line, you might see:
  3884.  
  3885.         12:    i = 10;     putd(i);
  3886.                      ^
  3887.  
  3888.        The debugger then displays its "debug>" prompt and waits    for
  3889.        you to enter a command.    Debugger commands always start with
  3890.        a dot (.)  in  the  first  column,  followed  by     a  command
  3891.        mnemonic     letter.   You    can also enter a C statement at    the
  3892.        debugger's "debug>" prompt and have  it    evaluated  and    the
  3893.        results displayed, just like in the shell.
  3894.  
  3895.        We will now walk    through    a sample program using the debugger
  3896.        as a way    of introducing you to the debugger commands.
  3897.  
  3898.  
  3899.  
  3900.  
  3901.  
  3902.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3903.  
  3904.  
  3905.  
  3906.  
  3907.  
  3908.  
  3909.  
  3910.  
  3911.        The Debugger                             63
  3912.  
  3913.  
  3914.        17.3  SSSSaaaammmmpppplllleeee DDDDeeeebbbbuuuugggg SSSSeeeessssssssiiiioooonnnn
  3915.  
  3916.        If you haven't done so already, list the    sample program that
  3917.        came  with  your    distribution disk, CALC.SCI, either on your
  3918.        printer or "TYPE" it out    on your    screen.     This is  a  simple
  3919.        integer    calculator program that    does addition, subtraction,
  3920.        multiplication and division.
  3921.  
  3922.        At the shell prompt, load CALC.SCI  then     type  "calc()"     to
  3923.        start the program.  The program displays    its prompt (->)    and
  3924.        waits for  you  to  enter  a  command.    Try  entering  some
  3925.        mathematical expressions:
  3926.  
  3927.         shell> load calc.sci
  3928.         shell> calc()
  3929.         -> 2+2
  3930.         4
  3931.         -> 2+3*4
  3932.         14
  3933.         -> 3*4+2
  3934.         14
  3935.         -> 2-30/2
  3936.         -13
  3937.  
  3938.        Notice that  the     program  is  smart  enough  to     know  that
  3939.        multiplication  and  division  have  higher  precedence than
  3940.        addition    and subtraction.  To get out  of  the  program    and
  3941.        back to the shell, type a carriage return:
  3942.  
  3943.         ->
  3944.         0
  3945.         shell>
  3946.  
  3947.        Now, let's try the same scenario    but this time turn  on    the
  3948.        SCI debugger before you start the calculator:
  3949.  
  3950.         > debug(2)
  3951.         0
  3952.         > calc()
  3953.             calc()
  3954.             ^
  3955.         debug>
  3956.  
  3957.        The debugger displays the C statement  you  entered  on    the
  3958.        shell's    command     line, prompts you with    its "debug>" prompt
  3959.        and waits for you to enter a command.  Now just type  a    few
  3960.        <RETURN>'s:
  3961.  
  3962.  
  3963.  
  3964.  
  3965.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  3966.  
  3967.  
  3968.  
  3969.  
  3970.  
  3971.  
  3972.  
  3973.  
  3974.        64                           The Debugger
  3975.  
  3976.  
  3977.         debug>
  3978.          7:calc()
  3979.                ^
  3980.         debug>
  3981.          8:{
  3982.             ^
  3983.         debug>
  3984.         12:   Stacktop = 10;
  3985.                   ^
  3986.         debug>
  3987.         13:   for(;;)
  3988.              ^
  3989.         debug>
  3990.  
  3991.        The program is being executed one line at a time    each time a
  3992.        <RETURN>     is  hit.   Notice  that  each    line  is  displayed
  3993.        preceded    by the line number of the program.   The  statement
  3994.        you entered from    the shell that started up the calculator is
  3995.        not a part of the program.  This    is why it was not preceeded
  3996.        with a line number.
  3997.  
  3998.        17.3.1  _E_x_i_t_i_n_g__t_h_e__D_e_b_u_g_g_e_r  To    halt the program and return
  3999.        back to the shell, use the debugger's "quit" command:
  4000.  
  4001.         debug> .q
  4002.         0
  4003.         shell>
  4004.  
  4005.        Now we're back to the  shell's  prompt.     The  ".q"  command
  4006.        stopped    the  program and turned    the debugger off.  Since we
  4007.        want to experiment some more,  turn  the     debugger  back     on
  4008.        again and start up the program:
  4009.  
  4010.         shell> debug(2)
  4011.         0
  4012.         shell> calc()
  4013.             calc()
  4014.             ^
  4015.         debug>
  4016.  
  4017.        17.3.2  _S_i_n_g_l_e__S_t_e_p_p_i_n_g     You  can  execute  more  than    one
  4018.        program    line  at  a  time  with    the "step" command.  At    the
  4019.        "debug>"    prompt,    type ".s" followed by the number of program
  4020.        lines you want to execute:
  4021.  
  4022.  
  4023.  
  4024.  
  4025.  
  4026.  
  4027.  
  4028.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  4029.  
  4030.  
  4031.  
  4032.  
  4033.  
  4034.  
  4035.  
  4036.  
  4037.        The Debugger                             65
  4038.  
  4039.  
  4040.         debug> .s 4
  4041.         13:   for(;;)
  4042.               ^
  4043.         debug>
  4044.  
  4045.        The debugger executed 4 lines, then stopped.  This is useful
  4046.        when  you  want    to  get     through  a section of code quickly
  4047.        without having to hit <RETURN> and waiting for each line     to
  4048.        be  displayed.    The  "continue"     command is equivalent to a
  4049.        ".s" with an infinitely large step count:
  4050.  
  4051.         debug> .c
  4052.         -> 2+2
  4053.         4
  4054.         ->
  4055.  
  4056.        The program appears to be running slower    than  when  it    was
  4057.        run  with  the  debugger     turned     off.    This is    because    the
  4058.        debugger    is still  in  control  of  the    program,  and  must
  4059.        examine    each line before it is executed.  The usefulness of
  4060.        the ".c"    command    will become apparent later when    we  discuss
  4061.        breakpoints.   To return    back to    the debugger prompt, hit an
  4062.        <ESCAPE>    while the program is running.  If  the    program     is
  4063.        waiting for input from the console, hitting the <ESCAPE>    key
  4064.        will have no effect.  So    type some  mathematical     expression
  4065.        as  before, hit a <RETURN> and then quickly hit the <ESCAPE>
  4066.        key:
  4067.  
  4068.         -> 2+3*4
  4069.         interrupt
  4070.         66:   for(;;)
  4071.                ^
  4072.         debug>
  4073.  
  4074.        When  the  <ESCAPE>  is    hit,  the  debugger   displays     an
  4075.        "interrupt"  message,  followed    by  the    program    line it    was
  4076.        currently working on.
  4077.  
  4078.        17.3.3  _D_i_s_p_l_a_y_i_n_g__G_l_o_b_a_l__V_a_r_i_a_b_l_e_s    At   any     time    the
  4079.        debugger     is  waiting  for  input you may display all of    the
  4080.        program's global     variables  and     their    contents  with    the
  4081.        "global"    command:
  4082.  
  4083.  
  4084.  
  4085.  
  4086.  
  4087.  
  4088.  
  4089.  
  4090.  
  4091.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  4092.  
  4093.  
  4094.  
  4095.  
  4096.  
  4097.  
  4098.  
  4099.  
  4100.        66                           The Debugger
  4101.  
  4102.  
  4103.         debug> .g
  4104.            char    *Lineptr @9756:    = "+3*4"
  4105.            int     Stack[10] =  2     0  0  0  0  0    0  0  0     0
  4106.            int     Stackptr = 1
  4107.            int     Stacktop = 10
  4108.         debug>
  4109.  
  4110.        The ".g"    command    displays each variable along with its  data
  4111.        type  ("char"  or  "int").  If the variable is an array or a
  4112.        pointer,    its address is also printed in decimal,    for example
  4113.        like  so:  @9756.   Following  that, the    variable's value is
  4114.        displayed.  If the variable is an array or  a  pointer,    the
  4115.        first  ten  items  in  the  array  are displayed.  Character
  4116.        arrays are printed as  strings,    and  integer  arrays  as  a
  4117.        series of decimal numbers.
  4118.  
  4119.        Another form of the ".g"    command, ".G", will display all     of
  4120.        the  program's  functions  and their program line numbers in
  4121.        addition    to global variables:
  4122.  
  4123.         debug> .G
  4124.            char    *Lineptr @9756:    = "+3*4"
  4125.            int     Stack[10] =  2     0  0  0  0  0    0  0  0     0
  4126.            int     Stackptr = 1
  4127.            int     Stacktop = 10
  4128.          7:calc()
  4129.         26:number()
  4130.         36:addition()
  4131.         61:multiplication()
  4132.         86:push( n )
  4133.         93:pop()
  4134.            100:isdigit( c )
  4135.         debug>
  4136.  
  4137.        17.3.4  _B_r_e_a_k_p_o_i_n_t_s  Next we will discuss one  of  the  most
  4138.        powerful     features  of the debugger: breakpoints.  Let's    say
  4139.        we wanted to stop  the  program    every  time  the  functions
  4140.        "push"  and  "pop" were called, so that we could    inspect    the
  4141.        program's state.     Looking at the    debugger's output from    the
  4142.        ".G"  command above, we see that    these functions    are located
  4143.        at lines    82 and 89  respectively.   To  set  breakpoints     at
  4144.        these  line  numbers,  we  would     enter    the  following    two
  4145.        commands:
  4146.  
  4147.  
  4148.  
  4149.  
  4150.  
  4151.  
  4152.  
  4153.  
  4154.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  4155.  
  4156.  
  4157.  
  4158.  
  4159.  
  4160.  
  4161.  
  4162.  
  4163.        The Debugger                             67
  4164.  
  4165.  
  4166.         debug> .b 86
  4167.         breakpoint set:
  4168.         86:push( n )
  4169.         debug> .b 93
  4170.         breakpoint set:
  4171.         93:pop()
  4172.         debug>
  4173.  
  4174.        The debugger prints the program line at which the breakpoint
  4175.        is set for verification.
  4176.  
  4177.        You may set a maximum of    5 breakpoints at any one time.     To
  4178.        display    all  of    the breakpoints    that are currently set,    use
  4179.        the ".B"    command:
  4180.  
  4181.         debug> .B
  4182.         86:push( n )
  4183.         93:pop()
  4184.         debug>
  4185.  
  4186.        Now we can continue executing the program  normally  and     it
  4187.        should  stop as soon as either the "push" or "pop" functions
  4188.        are called.  This is where the ".c" command is used:
  4189.  
  4190.         debug> .c
  4191.         breakpoint:
  4192.         86:push( n )
  4193.                ^
  4194.         debug>
  4195.  
  4196.        As soon as a breakpoint is reached, the    debugger  announces
  4197.        this  fact  and displays    the program line at the    breakpoint.
  4198.        To delete a breakpoint, use the "delete breakpoint" command:
  4199.  
  4200.         debug> .d 86
  4201.         breakpoint deleted:
  4202.         86:push( n )
  4203.         debug>
  4204.  
  4205.        Again, the program line at which    the breakpoint was  deleted
  4206.        is   displayed  for  verification.   When  a  breakpoint     is
  4207.        deleted,    the debugger will no longer stop  at  this  program
  4208.        line after a ".c" command.
  4209.  
  4210.        To delete all breakpoints set, use the ".D" command:
  4211.  
  4212.  
  4213.  
  4214.  
  4215.  
  4216.  
  4217.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  4218.  
  4219.  
  4220.  
  4221.  
  4222.  
  4223.  
  4224.  
  4225.  
  4226.        68                           The Debugger
  4227.  
  4228.  
  4229.         debug> .D
  4230.         all breakpoints    deleted
  4231.         debug>
  4232.  
  4233.        17.3.5  _F_u_n_c_t_i_o_n__C_a_l_l__T_r_a_c_e__B_a_c_k     Using breakpoints  we    can
  4234.        be  certain  of    only one fact: the program started at point
  4235.        "A", and    stopped    at point "B".  We know    nothing     about    the
  4236.        route it    took in    getting    there.    The debugger's "trace back"
  4237.        command at least    tells us the order of function    calls  that
  4238.        got  us    to point "B": Continuing with our debuging session,
  4239.        type the    following command:
  4240.  
  4241.         debug> .t
  4242.         26:number()
  4243.         61:multiplication()
  4244.         36:addition()
  4245.          7:calc()
  4246.         debug>
  4247.  
  4248.        The function call trace back printed by the ".t"    command     is
  4249.        read  backwards    from  bottom to    top.  In other words in    the
  4250.        above display, the function "calc" (which  is  the  starting
  4251.        point)     called       "addition",     which     in   turn   called
  4252.        "multiplication", and so    on.
  4253.  
  4254.        A variation of the "trace back"    command,  ".T",     will  also
  4255.        display    all  local  variables  and  their contents for each
  4256.        function    in the trace back:
  4257.  
  4258.         debug> .T
  4259.         26:number()
  4260.         61:multiplication()
  4261.            int     num = 0
  4262.         36:addition()
  4263.            int     num = 0
  4264.          7:calc()
  4265.            char     line[80] = "2+3*4"
  4266.         debug>
  4267.  
  4268.        The local variables are displayed in a similar format as    for
  4269.        the ".g"    command.
  4270.  
  4271.        17.3.6  _E_x_a_m_i_n_e__a__P_r_o_g_r_a_m  You may also use the    SCI  editor
  4272.        to examine your program.     The editor will not allow you make
  4273.        any changes when    invoked    from the debugger, since this could
  4274.        completely  alter  the state of the current program run.     To
  4275.        "examine" your program, type:
  4276.  
  4277.  
  4278.  
  4279.  
  4280.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  4281.  
  4282.  
  4283.  
  4284.  
  4285.  
  4286.  
  4287.  
  4288.  
  4289.        The Debugger                             69
  4290.  
  4291.  
  4292.         debug> .e
  4293.  
  4294.        The screen is erased and    the editor is started up  with    the
  4295.        cursor  resting    on  the     line  in the program that is to be
  4296.        executed    next.  You may move about freely in the    editor,    but
  4297.        you may not make    any changes.
  4298.  
  4299.        When you    exit the editor    (with  a  ^Z)  the  debugger  knows
  4300.        which  line  the    cursor was on when you left the    editor,    and
  4301.        you may set a breakpoint    at that    line  by  just    giving    the
  4302.        ".b" command _w_i_t_h_o_u_t a line number.
  4303.  
  4304.  
  4305.  
  4306.  
  4307.  
  4308.  
  4309.  
  4310.  
  4311.  
  4312.  
  4313.  
  4314.  
  4315.  
  4316.  
  4317.  
  4318.  
  4319.  
  4320.  
  4321.  
  4322.  
  4323.  
  4324.  
  4325.  
  4326.  
  4327.  
  4328.  
  4329.  
  4330.  
  4331.  
  4332.  
  4333.  
  4334.  
  4335.  
  4336.  
  4337.  
  4338.  
  4339.  
  4340.  
  4341.  
  4342.  
  4343.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  4344.  
  4345.  
  4346.  
  4347.  
  4348.  
  4349.  
  4350.  
  4351.  
  4352.        70                              The Shell
  4353.  
  4354.  
  4355.        18.  TTTThhhheeee    SSSShhhheeeellllllll
  4356.  
  4357.        This section will discuss in detail  the     operation  of    the
  4358.        program    found in the file SHELL.SCI.  We will also show    you
  4359.        how to customize    the shell program to suit your needs.
  4360.  
  4361.        If you haven't done so already, print out the shell  program
  4362.        file  or     "TYPE"     it out    on your    console    screen.     As you    can
  4363.        see there are basically 2  sections  of    this  program:    the
  4364.        first  section  declares    all of the Library Functions ("sys"
  4365.        call interfaces),  The  second  section    starts    immediately
  4366.        after  the  "entry" keyword with    the function "main()". This
  4367.        is the function that is executed    after  SHELL.SCI  has  been
  4368.        loaded  into  memory.   Let's  examine  this  function  more
  4369.        closely now:
  4370.  
  4371.            .
  4372.            .
  4373.            .
  4374.       46:entry
  4375.       47:main()
  4376.       48:{
  4377.       49:    int f, t;
  4378.       50:    char buf[24];
  4379.       51:    char line[81];
  4380.       52:    char program[ memleft()-1024 ];
  4381.       53:
  4382.       54:    puts(sys(0));
  4383.       55:    puts("\nSCI Shell V1.5 20Oct86 Copyright (C) 1986 Bob Brodt\n");
  4384.       56:    *program='Z';
  4385.       57:    _mhz=12;
  4386.       58:
  4387.       59:    _nr=25;    _nc=80;
  4388.       60:    _ro=_co=1;
  4389.       61:    _cp="\033[%d;%dH";
  4390.       62:    _el="\033[K";
  4391.       63:
  4392.       64:    for(;;)    {
  4393.       65:       puts("shell>    ");
  4394.       66:       line[5]=0;
  4395.       67:       if(gets(line)) {
  4396.       68:          if (!strncmp(line,"edit",4))
  4397.       69:         sys(atoi(line+4),program,19);
  4398.       70:          else if (!strncmp(line,"list",4))    {
  4399.       71:         f=1;
  4400.       72:         t=32765;
  4401.       73:         if(line[4])
  4402.       74:            sscanf(line+4,"%d %d",&f,&t);
  4403.  
  4404.  
  4405.  
  4406.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  4407.  
  4408.  
  4409.  
  4410.  
  4411.  
  4412.  
  4413.  
  4414.  
  4415.        The Shell                             71
  4416.  
  4417.  
  4418.       75:         sys(program,f,t,27);
  4419.       76:          }
  4420.       77:          else if (!strncmp(line,"save",4))
  4421.       78:         sys(line+5,program,26);
  4422.       79:          else if (!strncmp(line,"load",4))
  4423.       80:         sys(line+5,program,25);
  4424.       81:          else if (!strncmp(line,"exit",4))
  4425.       82:         return;
  4426.       83:          else if (!strncmp(line,"dir",3)) {
  4427.       84:         if ( !line[3] )
  4428.       85:            strcpy(line+4,"*.*");
  4429.       86:         if ( dirscan(line+4,buf) ) {
  4430.       87:            printf("%s\n",buf);
  4431.       88:            while(dirscan(0,buf))
  4432.       89:               printf("%s\n",buf);
  4433.       90:         }
  4434.       91:          }
  4435.       92:          else
  4436.       93:         printf("\n%d\n",sys(line,program,16));
  4437.       94:       }
  4438.       95:    }
  4439.       96:}
  4440.  
  4441.        Note that we have included line numbers here for    reference.
  4442.  
  4443.        The data    declarations at    lines 51 and  52  are  the  shell's
  4444.        input   line   buffer   (line[])     and  user  program  buffer
  4445.        (program[]) respectively.  Lines    54 and 55 of  course  print
  4446.        the  program  identification  banners.    Lines 57 through 62
  4447.        assign the editor's customization variables (for    the IBM     PC
  4448.        in  this    version).  Line    64 starts a "forever" loop that    can
  4449.        only terminated by the  "return"     at  line  82.     This  loop
  4450.        starts out by displaying    the shell prompt ("shell> ") on    the
  4451.        console screen, then waiting for    a line of  input  from    the
  4452.        console    keyboard.   The     input    line  buffer  stores  the C
  4453.        statement read in from the console at line 67.  It  is  then
  4454.        compared     to  each  of  the  strings "edit", "list", "save",
  4455.        "load", "exit" and "dir".  If the first four  characters     in
  4456.        the  input buffer don't match any of these strings, the line
  4457.        is assumed to be     a  C  statement  and  handed  off  to    the
  4458.        interpreter  (via  "sys"     function 16) for execution at line
  4459.        93.
  4460.  
  4461.        The program buffer, "program" is    used to     store    the  user's
  4462.        program    functions  and    variables.  The    user can enter data
  4463.        into this buffer    only by     way  of  the  SCI  program  editor
  4464.        ("sys"  function     19).    In  fact,  the    program     buffer     is
  4465.        completely hidden from the user - any attempt  to  reference
  4466.  
  4467.  
  4468.  
  4469.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  4470.  
  4471.  
  4472.  
  4473.  
  4474.  
  4475.  
  4476.  
  4477.  
  4478.        72                              The Shell
  4479.  
  4480.  
  4481.        it  via    a C statement (for example "putchar( program[0]    )")
  4482.        will result in an "undefined  symbol"  error  message.    The
  4483.        user's  program    in  the     "program" buffer is in    "tokenized"
  4484.        form.  That is, each language element (variables,  keywords,
  4485.        punctuation,  etc.)  has    been encoded so    that it    can be more
  4486.        easily and  quickly  recognized    by  the     interpreter.    The
  4487.        tokenized  form    of a program bears almost no resemblance to
  4488.        the human-readable form and should not be tampered with.
  4489.  
  4490.        18.1  CCCCuuuussssttttoooommmmiiiizzzziiiinnnngggg tttthhhheeee SSSShhhheeeellllllll
  4491.  
  4492.        Now we will show    you how    you  can  customize  this  program.
  4493.        Start  up SCI and when the shell's prompt appears, enter    the
  4494.        command:
  4495.  
  4496.            shell> load shell.sci
  4497.  
  4498.  
  4499.        to load the shell file.    Now edit  the  program    from  SCI's
  4500.        editor  and  remove  all     lines    from  the  beginning of    the
  4501.        program up to and including the "entry" keyword.     Next let's
  4502.        change  the  string  on    line  65 (above) to something like:
  4503.        "yes, dear? ".
  4504.  
  4505.        Exit the    editor and from    the shell prompt type:
  4506.  
  4507.            shell> main()
  4508.  
  4509.        You should see the program identification banner     again    and
  4510.        the  new     shell's  prompt,  "yes,  dear?     "!  You can now do
  4511.        everything from    this  new  shell  that    you  did  from    the
  4512.        original     shell - write programs    with the editor, save them,
  4513.        list them and load them.     When you type "exit" to  this    new
  4514.        shell however, you are returned to the original shell.
  4515.  
  4516.        Type an "exit" now to get back to the first shell  and  from
  4517.        there  do a "save newshell". Then type "main()" again to    get
  4518.        the "yes, dear? " shell.     From here, type "load newshell" to
  4519.        load  the  newshell  program.  Edit the newshell    program    and
  4520.        change the "yes,    dear? "     prompt     to  something    like:  "you
  4521.        again?  ".   Now     exit  the  editor and at the "yes, dear? "
  4522.        prompt type "main()".  You  should  again  see  the  program
  4523.        logon  banner  and  the new shell prompt    "you again? ", like
  4524.        this:
  4525.  
  4526.  
  4527.  
  4528.  
  4529.  
  4530.  
  4531.  
  4532.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  4533.  
  4534.  
  4535.  
  4536.  
  4537.  
  4538.  
  4539.  
  4540.  
  4541.        The Shell                             73
  4542.  
  4543.  
  4544.            yes, dear? main()
  4545.            Small C Interpreter V1.5    20Oct86    Copyright (C) 1986 Bob Brodt
  4546.            SCI Shell V1.5 20Oct86 Copyright    (C) 1986 Bob Brodt
  4547.            you again?
  4548.  
  4549.        In all, we now have 3 different shell programs running,    one
  4550.        on  top    of  the    other, and we could actually continue doing
  4551.        this until we run out of    memory!     This is exactly  analagous
  4552.        to the layers of    an onion: each layer gets smaller as you go
  4553.        towards the center of the  onion,  just    as  the     amount     of
  4554.        usable  memory  becomes    less  as  each new shell program is
  4555.        loaded from the previous    shell.
  4556.  
  4557.        Now return to the original shell    like so:
  4558.  
  4559.            you again? exit
  4560.            0
  4561.            yes, dear? exit
  4562.            0
  4563.            shell>
  4564.  
  4565.        It now becomes an easy task to customize    the  shell  program
  4566.        to  your     heart's content using the SCI editor, test it from
  4567.        the SCI interpreter environment and when    it's fully debuged,
  4568.        save  it    to disk.  Of course you    must remember to insert    the
  4569.        Library Function    declarations and the "entry" keyword before
  4570.        the  new     shell    "main()"  function if you intend to replace
  4571.        SHELL.SCI with the new program.
  4572.  
  4573.        18.2  DDDDOOOOSSSS CCCCoooommmmmmmmaaaannnndddd LLLLiiiinnnneeee AAAArrrrgggguuuummmmeeeennnnttttssss    ttttoooo tttthhhheeee SSSShhhheeeellllllll
  4574.  
  4575.        A mechanism has    been  provided    to  pass  operating  system
  4576.        command line arguments to the shell in a    way similar to most
  4577.        commercially available C    compilers.  By specifying a "-A" on
  4578.        the  MS-DOS command lines, all arguments    to the right of    the
  4579.        "-A" will be ignored by SCI and instead passed to the  shell
  4580.        program.
  4581.  
  4582.        SCI always passes two arguments to the  "entry"    program     in
  4583.        the  startup  file,  although  the program is free to use or
  4584.        ignore these arguments.    These are: a count of the number of
  4585.        arguments  following the    "-A" option on the DOS command line
  4586.        and; A pointer to the array of strings  that  contain  these
  4587.        arguments.   These arguments are    commonly declared as "argc"
  4588.        (argument count)    and  "argv"  (argument    vector)     in  the  C
  4589.        community.
  4590.  
  4591.  
  4592.  
  4593.  
  4594.  
  4595.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  4596.  
  4597.  
  4598.  
  4599.  
  4600.  
  4601.  
  4602.  
  4603.  
  4604.        74                              The Shell
  4605.  
  4606.  
  4607.        Make the    following changes and additions    to the    program     in
  4608.        SHELL.SCI:
  4609.  
  4610.            .
  4611.            .
  4612.            .
  4613.        main(argc, arv)
  4614.        int argc;
  4615.        char **argv;
  4616.        {
  4617.            int i;
  4618.  
  4619.            while ( i<argc )
  4620.            {
  4621.                puts(argv[i++]);
  4622.                putchar('0);
  4623.            }
  4624.            .
  4625.            .
  4626.            .
  4627.        }
  4628.  
  4629.        Then, when the following    command    is entered at the operating
  4630.        system level:
  4631.  
  4632.        A>SCI -A    Hello out there!
  4633.  
  4634.  
  4635.        the shell program would start up    like this:
  4636.  
  4637.        Hello
  4638.        out
  4639.        there!
  4640.        Small C Interpreter V1.5    20OCt86    Copyright (C) 1986 Bob Brodt
  4641.        Shell V1.5 20OCt86 Copyright (C)    1986 Bob Brodt
  4642.        >
  4643.  
  4644.  
  4645.  
  4646.  
  4647.  
  4648.  
  4649.  
  4650.  
  4651.  
  4652.  
  4653.  
  4654.  
  4655.  
  4656.  
  4657.  
  4658.        SCI Programmers Manual         Copyright (C) 1986, Bob Brodt
  4659.  
  4660.  
  4661.  
  4662.  
  4663.  
  4664.  
  4665.  
  4666.  
  4667.  
  4668.  
  4669.  
  4670.                  CONTENTS
  4671.  
  4672.  
  4673.     1.  Introduction to SCI    Programming....................      1
  4674.  
  4675.     2.  SCI    Statement Structure............................      2
  4676.  
  4677.     3.  SCI    Program    Structure..............................      2
  4678.  
  4679.     4.  Functions..........................................      6
  4680.         4.1      Library Functions............................      7
  4681.  
  4682.     5.  Your First Program.................................      8
  4683.         5.1      Hello    again, world!..........................      8
  4684.         5.2      Fahrenheit to    Celsius........................      9
  4685.  
  4686.     6.  Statements:    Simple and Compound....................      9
  4687.         6.1      Comment Statements...........................     11
  4688.  
  4689.     7.  Expressions........................................     11
  4690.         7.1      Operators....................................     12
  4691.         7.2      Precedence...................................     12
  4692.         7.3      Associativity................................     13
  4693.         7.4      Arithmetic operators.........................     13
  4694.         7.5      Bitwise Operators............................     13
  4695.  
  4696.     8.  Variables..........................................     14
  4697.         8.1      Naming Conventions...........................     14
  4698.         8.2      Data Types...................................     15
  4699.         8.3      Scope........................................     15
  4700.         8.4      Location of Variables........................     19
  4701.  
  4702.     9.  Constants..........................................     20
  4703.         9.1      Hexadecimal Constants........................     21
  4704.         9.2      Octal    Constants..............................     21
  4705.         9.3      ASCII    Character Constants....................     21
  4706.         9.4      String Constants.............................     22
  4707.  
  4708.        10.  Assignment Operator................................     23
  4709.         10.1  Lvalues and Rvalues..........................     24
  4710.  
  4711.        11.  Comma Operator.....................................     24
  4712.  
  4713.        12.  Flow Control.......................................     25
  4714.         12.1  if and if-else...............................     25
  4715.         12.2  while........................................     34
  4716.         12.3  for..........................................     36
  4717.         12.4  switch.......................................     38
  4718.  
  4719.  
  4720.  
  4721.                   - i -
  4722.  
  4723.  
  4724.  
  4725.  
  4726.  
  4727.  
  4728.  
  4729.  
  4730.  
  4731.  
  4732.  
  4733.        13.  Arrays.............................................     40
  4734.  
  4735.        14.  Pointers...........................................     42
  4736.         14.1  Lvalues and Rvalues Revisited................     43
  4737.         14.2  Pointer Operator.............................     44
  4738.         14.3  Address Operator.............................     48
  4739.  
  4740.        15.  Increment and Decrement Operators..................     51
  4741.  
  4742.        16.  A Tour Through the File I/O    Functions..............     54
  4743.         16.1  fopen()......................................     54
  4744.         16.2  fclose().....................................     55
  4745.         16.3  fgetc() and fputc()..........................     56
  4746.         16.4  fgets() and fputs()..........................     56
  4747.         16.5  fread() and fwrite().........................     57
  4748.         16.6  fseek() and ftell()..........................     58
  4749.  
  4750.        17.  The    Debugger.......................................     60
  4751.         17.1  Introduction.................................     60
  4752.         17.2  Enabling the Debugger........................     61
  4753.         17.3  Sample Debug Session.........................     63
  4754.  
  4755.        18.  The    Shell..........................................     70
  4756.         18.1  Customizing the Shell........................     72
  4757.         18.2  DOS Command Line Arguments to    the Shell......     73
  4758.  
  4759.  
  4760.  
  4761.  
  4762.  
  4763.  
  4764.  
  4765.  
  4766.  
  4767.  
  4768.  
  4769.  
  4770.  
  4771.  
  4772.  
  4773.  
  4774.  
  4775.  
  4776.  
  4777.  
  4778.  
  4779.  
  4780.  
  4781.  
  4782.  
  4783.  
  4784.                   - ii -
  4785.  
  4786.  
  4787.  
  4788.  
  4789.