home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / books / c4yrself.db < prev    next >
Encoding:
Text File  |  1991-03-01  |  900.0 KB  |  19,668 lines

  1. %@1@%%@AB@%Microsoft QuickC Compiler - C FOR YOURSELF%@AE@%%@EH@%%@NL@%
  2.                                       %@NL@%
  3.                                       %@NL@%
  4.                                       %@NL@%
  5.                                       %@NL@%
  6.                                       %@NL@%
  7.                                       %@NL@%
  8.                                       %@NL@%
  9.  
  10. ────────────────────────────────────────────────────────────────────────────%@NL@%
  11.               %@AB@%Microsoft(R) QuickC(R) Compiler - C FOR YOURSELF%@AE@%%@NL@%
  12.                                       %@NL@%
  13.                                 %@AB@%VERSION 2.5%@AE@%%@NL@%
  14. ────────────────────────────────────────────────────────────────────────────%@NL@%
  15.                                       %@NL@%
  16.                                       %@NL@%
  17.                            MICROSOFT CORPORATION %@NL@%
  18.                                       %@NL@%
  19.                                       %@NL@%
  20. %@NL@%
  21. %@NL@%
  22. %@NL@%%@NL@%
  23. %@NL@%
  24.  
  25.  
  26. Information in this document is subject to change without notice and does
  27. not represent a commitment on the part of Microsoft Corporation. The
  28. software described in this document is furnished under a license agreement
  29. or nondisclosure agreement. The software may be used or copied only in
  30. accordance with the terms of the agreement. It is against the law to copy
  31. the software on any medium except as specifically allowed in the license or
  32. nondisclosure agreement. No part of this manual may be reproduced or
  33. transmitted in any form or by any means, electronic or mechanical, including
  34. photocopying and recording, for any purpose without the express written
  35. permission of Microsoft.  
  36. (C) Copyright Microsoft Corporation, 1988, 1990. All rights reserved.%@NL@%
  37. %@NL@%
  38.  
  39. Printed and bound in the United States of America.%@NL@%
  40. %@NL@%
  41.  
  42. Microsoft, MS, MS-DOS, CodeView, QuickC, and XENIX are 
  43. registered trademarks and Windows is a trademark of Microsoft Corporation.%@NL@%
  44. %@NL@%
  45. AT&T is a registered trademark of American Telephone 
  46. and Telegraph Company.%@NL@%
  47. %@NL@%
  48. IBM and PS/2 are registered trademarks of International 
  49. Business Machines Corporation.%@NL@%
  50. %@NL@%
  51. Hercules is a registered trademark and InColor is a trademark 
  52. of Hercules Computer Technology.%@NL@%
  53. %@NL@%
  54. Intel is a registered trademark of Intel Corporation.%@NL@%
  55. %@NL@%
  56. Olivetti is a registered trademark of Ing. C. Olivetti.%@NL@%
  57. %@NL@%
  58. VAX is a registered trademark of Digital Equipment Corporation.%@NL@%
  59. %@NL@%
  60. %@AI@%%@AE@%%@NL@%
  61. %@NL@%
  62. Document No. SY10423-0290
  63.  OEM D703-2Z
  64.  
  65. 10 9 8 7 6 5 4 3 2 1 %@NL@%
  66. %@NL@%
  67. %@NL@%
  68. %@NL@%
  69. %@NL@%
  70. %@NL@%
  71. %@NL@%
  72. %@1@%%@AB@%Table of Contents%@AE@%%@EH@%%@NL@%
  73. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@NL@%
  74. %@NL@%
  75.  
  76. %@NL@%
  77. %@AB@%Introduction%@AE@%%@BO:        5099@%%@NL@%
  78.      About This Book%@BO:        5274@%%@NL@%
  79.      Using the Example Programs%@BO:        5b81@%%@NL@%
  80.      Programming Style Used in This Manual%@BO:        6260@%%@NL@%
  81.      Key to Document Conventions%@BO:        692a@%%@NL@%
  82.      Other Books on C Programming%@BO:        7490@%%@NL@%
  83. %@NL@%
  84. %@NL@%
  85. %@AB@%PART I%@AE@%%@BO:        81fd@%  %@AB@%Learning C%@AE@%%@NL@%
  86. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@NL@%
  87. %@NL@%
  88. %@NL@%
  89. %@AB@%Chapter 1%@AE@%%@BO:        86b5@%  %@AB@%Anatomy of a C Program%@AE@%%@NL@%
  90. %@NL@%
  91.      A Typical C Program%@BO:        89da@%%@NL@%
  92.      Comments%@BO:        8bf6@%%@NL@%
  93.      Statements%@BO:        8eb7@%%@NL@%
  94.      Keywords and Names%@BO:        923e@%%@NL@%
  95.      Preprocessor Directives%@BO:        94b5@%%@NL@%
  96.      Functions%@BO:        9a77@%%@NL@%
  97.      Calling Functions%@BO:        a080@%%@NL@%
  98.      Declaring and Initializing Variables%@BO:        a7c9@%%@NL@%
  99.      External and Local Variables%@BO:        ac47@%%@NL@%
  100.      Function Prototypes%@BO:        b186@%%@NL@%
  101.      A Few Words about printf%@BO:        b5ef@%%@NL@%
  102. %@NL@%
  103. %@AB@%Chapter 2%@AE@%%@BO:        c3e4@%  %@AB@%Functions%@AE@%%@NL@%
  104. %@NL@%
  105.      Functions and Structured Programming%@BO:        c690@%%@NL@%
  106.      The main Function%@BO:        cd12@%%@NL@%
  107.      Placement and Visibility of Functions%@BO:        d49b@%%@NL@%
  108.      Function Definitions and Prototypes%@BO:        db70@%%@NL@%
  109.      Calling a Function%@BO:        e170@%%@NL@%
  110.      Passing Arguments to a Function%@BO:        ea85@%%@NL@%
  111.      Arguments Versus Parameters%@BO:        f4f6@%%@NL@%
  112.      Assigning Parameters%@BO:        f8fd@%%@NL@%
  113.      Passing by Value%@BO:       10322@%%@NL@%
  114.      Returning Values from Functions%@BO:       1128e@%%@NL@%
  115.      Using Return Values%@BO:       1211e@%%@NL@%
  116.      Declaring a Function's Return Type%@BO:       12a14@%%@NL@%
  117.      Function Prototypes%@BO:       1329c@%%@NL@%
  118.             Prototyping Functions without Parameters%@BO:       13e13@%%@NL@%
  119.             Prototyping Functions with Variable Parameters%@BO:       140ab@%%@NL@%
  120.      Old-Style Function Declarations and Definitions%@BO:       145b0@%%@NL@%
  121. %@NL@%
  122. %@AB@%Chapter 3%@AE@%%@BO:       15403@%  %@AB@%Flow Control%@AE@%%@NL@%
  123. %@NL@%
  124.      Loops: while, do, and for%@BO:       157a0@%%@NL@%
  125.             The while Statement%@BO:       1590a@%%@NL@%
  126.             The do Statement%@BO:       164be@%%@NL@%
  127.             The for Statement%@BO:       16e08@%%@NL@%
  128.      Decision-Making Statements: if, else, switch, break, continue,
  129.        and goto%@BO:       181f0@%%@NL@%
  130.             The if Statement%@BO:       183ac@%%@NL@%
  131.             The else Clause%@BO:       18f6a@%%@NL@%
  132.             The switch Statement%@BO:       1989f@%%@NL@%
  133.             The break Statement%@BO:       1b74e@%%@NL@%
  134.             The continue Statement%@BO:       1c4c1@%%@NL@%
  135.             The goto Statement%@BO:       1cb4f@%%@NL@%
  136. %@NL@%
  137. %@AB@%Chapter 4%@AE@%%@BO:       1d5ce@%  %@AB@%Data Types%@AE@%%@NL@%
  138. %@NL@%
  139.      Basic Data Types%@BO:       1d825@%%@NL@%
  140.             Specifying Basic Types%@BO:       1db1a@%%@NL@%
  141.             Specifying Variables%@BO:       1f426@%%@NL@%
  142.             Specifying Constants%@BO:       1fa02@%%@NL@%
  143.      Aggregate Data Types%@BO:       20f98@%%@NL@%
  144.             Arrays%@BO:       2145d@%%@NL@%
  145.             Structures%@BO:       2479f@%%@NL@%
  146.             Unions%@BO:       288e4@%%@NL@%
  147. %@NL@%
  148. %@AB@%Chapter 5%@AE@%%@BO:       29488@%  %@AB@%Advanced Data Types%@AE@%%@NL@%
  149. %@NL@%
  150.      Visibility%@BO:       2980f@%%@NL@%
  151.             Local Variables%@BO:       29ed3@%%@NL@%
  152.             External Variables%@BO:       2ade4@%%@NL@%
  153.             Visibility in Multiple Source Files%@BO:       2b898@%%@NL@%
  154.             Visibility of Functions%@BO:       2c75c@%%@NL@%
  155.      Lifetime%@BO:       2cddf@%%@NL@%
  156.             Extending the Lives of Local Variables%@BO:       2d4b4@%%@NL@%
  157.      Converting Data Types%@BO:       2df7f@%%@NL@%
  158.             Ranking of Data Types%@BO:       2e47d@%%@NL@%
  159.             Promotions and Demotions%@BO:       2e7b8@%%@NL@%
  160.             Automatic Type Conversions%@BO:       2ecf4@%%@NL@%
  161.             Manual Type Conversions through Casting%@BO:       302b3@%%@NL@%
  162.      Register Variables%@BO:       30c2e@%%@NL@%
  163.      Renaming Existing Types with typedef%@BO:       31945@%%@NL@%
  164.      The Enumeration Type%@BO:       31ecb@%%@NL@%
  165. %@NL@%
  166. %@AB@%Chapter 6%@AE@%%@BO:       32e30@%  %@AB@%Operators%@AE@%%@NL@%
  167. %@NL@%
  168.      Introducing C's Operators%@BO:       33370@%%@NL@%
  169.             Arithmetic Operators%@BO:       3358d@%%@NL@%
  170.             Relational Operators%@BO:       33a53@%%@NL@%
  171.             Assignment Operators%@BO:       3429e@%%@NL@%
  172.      C's Unique Operators%@BO:       34b0c@%%@NL@%
  173.             Increment and Decrement Operators%@BO:       34c2c@%%@NL@%
  174.             Bitwise Operators%@BO:       35648@%%@NL@%
  175.             Logical Operators%@BO:       362e1@%%@NL@%
  176.             Address Operators%@BO:       36dbb@%%@NL@%
  177.             Conditional Operator%@BO:       375c8@%%@NL@%
  178.             The sizeof Operator%@BO:       37974@%%@NL@%
  179.             Comma Operator%@BO:       37dcb@%%@NL@%
  180.             Base Operator%@BO:       384e1@%%@NL@%
  181.      Operator Precedence%@BO:       38659@%%@NL@%
  182. %@NL@%
  183. %@AB@%Chapter 7%@AE@%%@BO:       39f56@%  %@AB@%Preprocessor Directives%@AE@%%@NL@%
  184. %@NL@%
  185.      The #include Directive%@BO:       3a6f3@%%@NL@%
  186.             Specifying Include Files%@BO:       3b19f@%%@NL@%
  187.      The #define and #undef Directives%@BO:       3b7a3@%%@NL@%
  188.             Simple Text Replacement%@BO:       3b937@%%@NL@%
  189.             Function-Like Macros%@BO:       3bfdb@%%@NL@%
  190.             The #undef Directive%@BO:       3cc72@%%@NL@%
  191.      Conditional Directives%@BO:       3cf7c@%%@NL@%
  192.             The defined Operator%@BO:       3dd70@%%@NL@%
  193.      Pragmas%@BO:       3ec24@%%@NL@%
  194. %@NL@%
  195. %@AB@%Chapter 8%@AE@%%@BO:       3f2a2@%  %@AB@%Pointers%@AE@%%@NL@%
  196. %@NL@%
  197.      Using Pointers in C%@BO:       3f671@%%@NL@%
  198.      Pointers to Simple Variables%@BO:       3faa0@%%@NL@%
  199.             Declaring a Pointer Variable%@BO:       40199@%%@NL@%
  200.             How Pointers Are Stored%@BO:       413dd@%%@NL@%
  201.             Initializing a Pointer Variable%@BO:       4196c@%%@NL@%
  202.             Using a Pointer Variable%@BO:       42427@%%@NL@%
  203.             Summary of Pointer Basics%@BO:       42d9e@%%@NL@%
  204.      Pointers to Arrays%@BO:       430d5@%%@NL@%
  205.             Arrays and Pointer Arithmetic%@BO:       43c05@%%@NL@%
  206.             Comparing Pointers%@BO:       44c3c@%%@NL@%
  207.             PARRAY.C Revisited%@BO:       45138@%%@NL@%
  208.      Pointers and Strings%@BO:       45ade@%%@NL@%
  209.      Passing Pointers to Functions%@BO:       471d9@%%@NL@%
  210.             Passing Address Constants Versus Passing Pointer Variables%@BO:       48a6d@%%@NL@%
  211.      Arrays of Pointers%@BO:       49648@%%@NL@%
  212.      A Pause for Reflection%@BO:       4b45c@%%@NL@%
  213. %@NL@%
  214. %@AB@%Chapter 9%@AE@%%@BO:       4b6ea@%  %@AB@%Advanced Pointers%@AE@%%@NL@%
  215. %@NL@%
  216.      Pointers to Pointers%@BO:       4b8e2@%%@NL@%
  217.             Equivalence of Array and Pointer Notation%@BO:       4c4df@%%@NL@%
  218.             Getting Command-Line Arguments%@BO:       4d72b@%%@NL@%
  219.             Null Pointers%@BO:       4e1ed@%%@NL@%
  220.      Pointers to Structures%@BO:       4e98e@%%@NL@%
  221.      Pointers to Functions%@BO:       5010b@%%@NL@%
  222.             Passing Function Pointers as Arguments%@BO:       51379@%%@NL@%
  223.      A Parting Word on Pointers%@BO:       51b50@%%@NL@%
  224. %@NL@%
  225. %@AB@%Chapter 10%@AE@%%@BO:       51f42@%  %@AB@%Programming Pitfalls%@AE@%%@NL@%
  226. %@NL@%
  227.      Operator Problems%@BO:       52215@%%@NL@%
  228.             Confusing Assignment and Equality Operators%@BO:       52307@%%@NL@%
  229.             Confusing Operator Precedence%@BO:       52aab@%%@NL@%
  230.             Confusing Structure-Member Operators%@BO:       53400@%%@NL@%
  231.      Array Problems%@BO:       53843@%%@NL@%
  232.             Array Indexing Errors%@BO:       53941@%%@NL@%
  233.             Omitting an Array Subscript in Multidimensional Arrays%@BO:       53d4f@%%@NL@%
  234.             Overrunning Array Boundaries%@BO:       542c0@%%@NL@%
  235.      String Problems%@BO:       54694@%%@NL@%
  236.             Confusing Character Constants and Character Strings%@BO:       54791@%%@NL@%
  237.             Forgetting the Null Character That Terminates Strings%@BO:       54b82@%%@NL@%
  238.             Forgetting to Allocate Memory for a String%@BO:       551dd@%%@NL@%
  239.      Pointer Problems%@BO:       557b2@%%@NL@%
  240.             Using the Wrong Address Operator to Initialize a Pointer%@BO:       5591b@%%@NL@%
  241.             Declaring a Pointer with the Wrong Type%@BO:       5609e@%%@NL@%
  242.             Using Dangling Pointers%@BO:       56776@%%@NL@%
  243.      Library-Function Problems%@BO:       56f72@%%@NL@%
  244.             Failing to Check Return Values from Library Functions%@BO:       57106@%%@NL@%
  245.             Duplicating Library-Function Names%@BO:       57615@%%@NL@%
  246.             Forgetting to Include Header Files for Library Functions%@BO:       57cf3@%%@NL@%
  247.             Omitting the Address-Of Operator When Calling scanf%@BO:       58545@%%@NL@%
  248.      Macro Problems%@BO:       58b2d@%%@NL@%
  249.             Omitting Parentheses from Macro Arguments%@BO:       58ca3@%%@NL@%
  250.             Using Increment and Decrement Operators in Macro Arguments%@BO:       593cc@%%@NL@%
  251.      Miscellaneous Problems%@BO:       5a43c@%%@NL@%
  252.             Mismatching if and else Statements%@BO:       5a4fb@%%@NL@%
  253.             Misplacing Semicolons%@BO:       5ab17@%%@NL@%
  254.             Omitting Double Backslashes in DOS Path Specifications%@BO:       5b5dd@%%@NL@%
  255.             Omitting break Statements from a switch Statement%@BO:       5ba10@%%@NL@%
  256.             Mixing Signed and Unsigned Values%@BO:       5bfed@%%@NL@%
  257. %@NL@%
  258. %@NL@%
  259. %@AB@%PART II%@AE@%%@BO:       5c92a@%  %@AB@%Using C%@AE@%%@NL@%
  260. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@NL@%
  261. %@NL@%
  262. %@NL@%
  263. %@AB@%Chapter 11%@AE@%%@BO:       5cd0a@%  %@AB@%Input and Output%@AE@%%@NL@%
  264. %@NL@%
  265.      Input and Output Streams%@BO:       5d111@%%@NL@%
  266.      Screen and Keyboard I/O%@BO:       5d691@%%@NL@%
  267.             Manipulating and Printing Strings%@BO:       5d89d@%%@NL@%
  268.             Printing Numeric Values%@BO:       5fce6@%%@NL@%
  269.             Using scanf for Keyboard Input%@BO:       61d67@%%@NL@%
  270.      Standard Disk I/O%@BO:       63951@%%@NL@%
  271.             Creating and Writing to a Text File%@BO:       63da7@%%@NL@%
  272.             Reading a Text File in Binary Mode%@BO:       6575f@%%@NL@%
  273.             Binary and Text Files%@BO:       669bd@%%@NL@%
  274.             Text Format for Numeric Variables%@BO:       67d2f@%%@NL@%
  275.             Using Binary Format%@BO:       6a107@%%@NL@%
  276.      Low-Level Input and Output%@BO:       6c9fd@%%@NL@%
  277.             Low-Level Reading and Writing%@BO:       6cf9a@%%@NL@%
  278. %@NL@%
  279. %@AB@%Chapter 12%@AE@%%@BO:       6ea5f@%  %@AB@%Dynamic Memory Allocation%@AE@%%@NL@%
  280. %@NL@%
  281.      Why Allocate?%@BO:       6ed94@%%@NL@%
  282.      Memory Allocation Basics%@BO:       6f425@%%@NL@%
  283.             Preparing to Allocate Memory%@BO:       7028c@%%@NL@%
  284.             Specifying the Size of the Allocated Block%@BO:       70937@%%@NL@%
  285.             A Graphic Illustration%@BO:       70d10@%%@NL@%
  286.             Assigning the Address that malloc Returns%@BO:       71653@%%@NL@%
  287.             Checking the Return from malloc%@BO:       71ae1@%%@NL@%
  288.             Accessing an Allocated Memory Block%@BO:       722b1@%%@NL@%
  289.             Allocating Memory for Different Data Types%@BO:       72758@%%@NL@%
  290.             Deallocating Memory with the free Function%@BO:       73367@%%@NL@%
  291.      Specialized Memory-Allocating Functions%@BO:       738b2@%%@NL@%
  292.             The calloc Function%@BO:       73a39@%%@NL@%
  293.             The realloc Function%@BO:       73f87@%%@NL@%
  294.      Keeping Out of Trouble%@BO:       745d9@%%@NL@%
  295. %@NL@%
  296. %@AB@%Chapter 13%@AE@%%@BO:       74e41@%  %@AB@%Graphics%@AE@%%@NL@%
  297. %@NL@%
  298.      Graphics Mode%@BO:       750c7@%%@NL@%
  299.             Checking the Current Video Mode%@BO:       75988@%%@NL@%
  300.             Setting the Video Mode%@BO:       75f2c@%%@NL@%
  301.             Writing a Graphics Program%@BO:       76931@%%@NL@%
  302.             Using Color Graphics Modes%@BO:       79fdf@%%@NL@%
  303.             Using the Color Video Text Modes%@BO:       7e660@%%@NL@%
  304.      Text Coordinates%@BO:       7f578@%%@NL@%
  305.      Graphics Coordinates%@BO:       7f95a@%%@NL@%
  306.             The Physical Screen%@BO:       7fb3b@%%@NL@%
  307.             Viewport Coordinates%@BO:       80c43@%%@NL@%
  308.             Real Coordinates in a Window%@BO:       80e8f@%%@NL@%
  309. %@NL@%
  310. %@AB@%Chapter 14%@AE@%%@BO:       8470a@%  %@AB@%Presentation Graphics%@AE@%%@NL@%
  311. %@NL@%
  312.      Terminology%@BO:       84d2f@%%@NL@%
  313.      Presentation Graphics Program Structure%@BO:       86fcf@%%@NL@%
  314.      Five Example Chart Programs%@BO:       87d38@%%@NL@%
  315.      Palettes%@BO:       8afe9@%%@NL@%
  316.             Color Pool%@BO:       8b52d@%%@NL@%
  317.             Style Pool%@BO:       8bf55@%%@NL@%
  318.             Pattern Pool%@BO:       8c444@%%@NL@%
  319.             Character Pool%@BO:       8d543@%%@NL@%
  320.      Customizing Presentation Graphics%@BO:       8d6e6@%%@NL@%
  321.             Chart Environment%@BO:       8d8a7@%%@NL@%
  322.             titletype%@BO:       8e478@%%@NL@%
  323.             axistype%@BO:       8edea@%%@NL@%
  324.             windowtype%@BO:       91ee0@%%@NL@%
  325.             legendtype%@BO:       92eed@%%@NL@%
  326.             chartenv%@BO:       93e61@%%@NL@%
  327.      An Overview of the Presentation Graphics Functions%@BO:       951d7@%%@NL@%
  328. %@NL@%
  329. %@AB@%Chapter 15%@AE@%%@BO:       95d73@%  %@AB@%Fonts%@AE@%%@NL@%
  330. %@NL@%
  331.      QuickC Fonts%@BO:       960d5@%%@NL@%
  332.      Using QuickC's Font Library%@BO:       96dbe@%%@NL@%
  333.             Register Fonts%@BO:       97290@%%@NL@%
  334.             Set Current Font%@BO:       97732@%%@NL@%
  335.             Display Text%@BO:       98eaa@%%@NL@%
  336.      An Example Program%@BO:       9906f@%%@NL@%
  337.      A Few Hints%@BO:       99e94@%%@NL@%
  338. %@NL@%
  339. %@AB@%Chapter 16%@AE@%%@BO:       9a669@%  %@AB@%In-Line Assembly%@AE@%%@NL@%
  340. %@NL@%
  341.      Advantages of In-Line Assembly%@BO:       9aa4c@%%@NL@%
  342.      The _asm Keyword%@BO:       9af33@%%@NL@%
  343.      Using Assembly Language in _asm Blocks%@BO:       9b744@%%@NL@%
  344.             Instruction Set%@BO:       9b8c8@%%@NL@%
  345.             Expressions%@BO:       9bba5@%%@NL@%
  346.             Data Directives and Operators%@BO:       9bc91@%%@NL@%
  347.             EVEN and ALIGN Directives%@BO:       9bf0b@%%@NL@%
  348.             Macros%@BO:       9c0fc@%%@NL@%
  349.             Segment References%@BO:       9c2fe@%%@NL@%
  350.             Type and Variable Sizes%@BO:       9c41b@%%@NL@%
  351.      Using C in _asm Blocks%@BO:       9cf42@%%@NL@%
  352.             Using Operators%@BO:       9d42a@%%@NL@%
  353.             Using C Symbols%@BO:       9d950@%%@NL@%
  354.             Accessing C Data%@BO:       9de3d@%%@NL@%
  355.             Writing Functions%@BO:       9e5cd@%%@NL@%
  356.      Using and Preserving Registers%@BO:       9f2f2@%%@NL@%
  357.      Jumping to Labels%@BO:       9fbd3@%%@NL@%
  358.      Calling C Functions%@BO:       a0498@%%@NL@%
  359.      Defining _asm Blocks as C Macros%@BO:       a09db@%%@NL@%
  360.      Optimizing%@BO:       a1697@%%@NL@%
  361.      References and Books on Assembly Language%@BO:       a2124@%%@NL@%
  362. %@NL@%
  363. %@AB@%Appendix A%@AE@%%@BO:       a28b2@%  %@AB@%C Language Guide%@AE@%%@NL@%
  364. %@NL@%
  365.      General Syntax%@BO:       a2c28@%%@NL@%
  366.             User-Defined Names%@BO:       a2fdd@%%@NL@%
  367.             Keywords%@BO:       a343d@%%@NL@%
  368.      Functions%@BO:       a393a@%%@NL@%
  369.      Flow Control%@BO:       a3efa@%%@NL@%
  370.             The break Statement%@BO:       a418e@%%@NL@%
  371.             The continue Statement%@BO:       a44ad@%%@NL@%
  372.             The do Statement%@BO:       a4846@%%@NL@%
  373.             The for Statement%@BO:       a4c3b@%%@NL@%
  374.             The goto Statement%@BO:       a52f6@%%@NL@%
  375.             The if Statement%@BO:       a55e8@%%@NL@%
  376.             The return Statement%@BO:       a5a3c@%%@NL@%
  377.             The switch Statement%@BO:       a5bdd@%%@NL@%
  378.             The while Statement%@BO:       a646c@%%@NL@%
  379.      Data Types%@BO:       a67e8@%%@NL@%
  380.             Basic Data Types%@BO:       a68be@%%@NL@%
  381.             Aggregate Data Types%@BO:       a893e@%%@NL@%
  382.      Advanced Data Types%@BO:       a92e4@%%@NL@%
  383.             Visibility%@BO:       a93be@%%@NL@%
  384.             Lifetime%@BO:       a9557@%%@NL@%
  385.             Type Conversions%@BO:       a9699@%%@NL@%
  386.             User-Defined Types%@BO:       a9922@%%@NL@%
  387.             Enumerated Types%@BO:       a9ce9@%%@NL@%
  388.      Operators%@BO:       aa0ec@%%@NL@%
  389.      Preprocessor Directives%@BO:       ab6ec@%%@NL@%
  390.      Pointers%@BO:       ac78b@%%@NL@%
  391. %@NL@%
  392. %@AB@%Appendix B%@AE@%%@BO:       ace49@%  %@AB@%C Library Guide%@AE@%%@NL@%
  393. %@NL@%
  394.      Overview of the C Run-Time Library%@BO:       ad133@%%@NL@%
  395.      Buffer-Manipulation Routines%@BO:       aefe3@%%@NL@%
  396.      Character Classification and Conversion Routines%@BO:       b02f5@%%@NL@%
  397.      Data Conversion Routines%@BO:       b143e@%%@NL@%
  398.      Error Message Routines%@BO:       b259d@%%@NL@%
  399.      Graphics 1: Low-Level Graphics Routines%@BO:       b352c@%%@NL@%
  400.      Graphics 2: Presentation Graphics Routines%@BO:       bf8f5@%%@NL@%
  401.      Graphics 3: Font Display Routines%@BO:       c254d@%%@NL@%
  402.      Input and Output Routines%@BO:       c3528@%%@NL@%
  403.      Math Routines%@BO:       cca69@%%@NL@%
  404.      Memory-Allocation Routines%@BO:       d00e5@%%@NL@%
  405.      Process-Control Routines%@BO:       d1476@%%@NL@%
  406.      Searching and Sorting Routines%@BO:       d20b7@%%@NL@%
  407.      String-Manipulation Routines%@BO:       d343e@%%@NL@%
  408.      Time Routines%@BO:       d6b62@%%@NL@%
  409. %@NL@%
  410. %@AB@%Glossary%@AE@%%@BO:       d7f4f@%%@NL@%
  411. %@NL@%
  412. %@NL@%
  413. %@NL@%
  414. %@CR:C6A-Intro   @%%@1@%%@AB@%Introduction%@AE@%%@EH@%%@NL@%
  415. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  416. %@NL@%
  417. Ever since Microsoft introduced the QuickC(R) Compiler, version 1.0 in 1987,
  418. QuickC users have asked for more information on the C programming language.
  419. %@AI@%C for Yourself%@AE@% answers that need, particularly for those who have some
  420. programming experience but are new to the C language.  %@NL@%
  421. %@NL@%
  422. %@NL@%
  423. %@2@%%@CR:C6A00000001 @%%@AB@%About This Book%@AE@%%@EH@%%@NL@%
  424. %@NL@%
  425. %@AI@%C for Yourself%@AE@% assumes you have programmed before but are not familiar with
  426. C. Thus, it doesn't explain basic programming ideas such as why program
  427. loops are useful. It assumes that you already know about loops in general
  428. and now want to learn how to write them in the C language. The following
  429. list summarizes the book's contents:  %@NL@%
  430. %@NL@%
  431. %@NL@%
  432.   ■   Part 1, "Learning C," covers basic C language topics such as functions
  433.       and data types. The chapters in this section are designed to be read
  434.       in order, from beginning to end.%@NL@%
  435. %@NL@%
  436.   ■   Part 2, "Using C," covers practical programming topics such as
  437.       input/output and graphics. This section is organized topically, so you
  438.       don't have to read the chapters in any particular order.%@NL@%
  439. %@NL@%
  440.   ■   Appendix A, "C Language Guide," summarizes the QuickC implementation
  441.       of the C language. You can use this appendix as a quick reference once
  442.       you have read Part 1 and have some familiarity with C.%@NL@%
  443. %@NL@%
  444.   ■   Appendix B, "C Library Guide," summarizes the most commonly used
  445.       functions in the QuickC run-time library. This appendix is designed
  446.       mainly for browsing when you're not using QuickC. When you are in the
  447.       QuickC environment, use the Microsoft(R) QuickC Advisor (online help)
  448.       to get information about C language features and run-time library
  449.       functions.
  450. %@NL@%
  451. ────────────────────────────────────────────────────────────────────────────%@NL@%
  452. NOTE
  453.  
  454. %@AI@%The pages that follow use the term "OS/2" to refer to the OS/2 systems─
  455. %@AI@%Microsoft %@AI@%(R)%@AE@%%@AI@%%@AE@%%@AI@% Operating System/2 (MS %@AE@%%@AI@%(R)%@AE@%%@AI@%%@AE@%%@AI@% OS/2) and IBM%@AE@%%@AI@% %@AE@%%@AI@%(R)%@AE@%%@AI@%%@AE@%%@AI@% OS/2. Similarly,
  456. %@AI@%the term "DOS" refers to both the MS-DOS%@AE@%%@AI@% (R)%@AE@%%@AI@%%@AE@%%@AI@% and IBM%@AE@%%@AI@% %@AE@%%@AI@%(R) %@AE@%%@AI@%%@AE@%%@AI@%Personal Computer
  457. %@AI@%DOS operating systems. The name of a specific operating system is used when
  458. %@AI@%it is necessary to note features that are unique to that system.%@AE@%%@AI@%%@AE@%%@AE@%%@NL@%
  459. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  460. %@NL@%
  461. %@NL@%
  462. %@NL@%
  463. %@NL@%
  464. %@NL@%
  465. %@2@%%@CR:C6A00000002 @%%@AB@%Using the Example Programs%@AE@%%@EH@%%@NL@%
  466. %@NL@%
  467. The example programs in this book are available through online help. This
  468. feature allows you to load, run, and experiment with example programs as you
  469. read.  %@NL@%
  470. %@NL@%
  471. %@AU@% You can use online  help to load and run  example programs.%@AE@%  %@NL@%
  472. %@NL@%
  473. You must be using the QuickC environment to load an example. To load the
  474. program, select Contents from the Help menu, then select the title of this
  475. book. Find the desired program in Help, then copy it into the editor using
  476. QuickC's Copy and Paste functions.  %@NL@%
  477. %@NL@%
  478. After you copy a sample program into the QuickC Editor, you can treat it as
  479. you would any C source program. You can compile or edit the program, save it
  480. on disk, and so on.  %@NL@%
  481. %@NL@%
  482. QuickC online help includes all the significant examples in this book (it
  483. doesn't include code fragments and some very short programs). Every program
  484. that is in online help begins with a line in this general form:  %@NL@%
  485. %@NL@%
  486. %@AS@%  /* POINTER.C: Demonstrate pointer basics. */%@AE@%%@NL@%
  487. %@NL@%
  488. The line contains the program's name and a brief description of what it
  489. does. The program containing the above line is listed as POINTER.C in online
  490. help.  %@NL@%
  491. %@NL@%
  492. All the examples available in online help compile without errors at Warning
  493. Level 3, in which QuickC does the most stringent error-checking. At this
  494. Warning Level, some examples will generate the following harmless warnings:
  495. %@NL@%
  496. %@NL@%
  497. %@AS@%  C4103: 'main' : function definition used as prototype
  498. %@AS@%  C4035: 'main' : no return value
  499. %@AS@%  C4051: data conversion%@AE@%%@NL@%
  500. %@NL@%
  501. You can eliminate these warnings by compiling at a lower Warning Level.  %@NL@%
  502. %@NL@%
  503. %@NL@%
  504. %@2@%%@CR:C6A00000003 @%%@AB@%Programming Style Used in This Manual%@AE@%%@EH@%%@NL@%
  505. %@NL@%
  506. The C language allows considerable flexibility in formatting source code.
  507. The style used in this book is recommended for program readability, but you
  508. do not have to use it when writing your programs. Below is a list of style
  509. guidelines used in this book for example programs:  %@NL@%
  510. %@NL@%
  511. %@NL@%
  512.   ■   Each example program begins with a comment that names the program and
  513.       states what it does.%@NL@%
  514. %@NL@%
  515.   ■   Each statement or function is listed on its own line.%@NL@%
  516. %@NL@%
  517.   ■   Variable and function names are in lowercase. The names of symbolic
  518.       constants, such as TRUE or FALSE, are in uppercase.%@NL@%
  519. %@NL@%
  520.   ■   If a function doesn't take any arguments, an opening and a closing
  521.       parenthesis follow the function name with no extra space:
  522. %@NL@%
  523. %@AS@%      getch();%@AE@%%@NL@%
  524. %@NL@%
  525. %@NL@%
  526.   ■   If a function takes arguments, a space appears after the opening
  527.       parenthesis and before the closing parenthesis:
  528. %@NL@%
  529. %@AS@%      printf( "Number = %i", num_penguins );%@AE@%%@NL@%
  530. %@NL@%
  531. %@NL@%
  532.   ■   Binary operators such as addition and subtraction are preceded and
  533.       followed by a space:
  534. %@NL@%
  535. %@AS@%      3 + 5%@AE@%%@NL@%
  536. %@NL@%
  537. %@NL@%
  538.   ■   If parentheses are used to control operator precedence, no extra
  539.       spaces are included:
  540. %@NL@%
  541. %@AS@%      (3 + 5) * 2%@AE@%%@NL@%
  542. %@NL@%
  543. %@NL@%
  544.   ■   Opening and closing braces are aligned under the first character of
  545.       the controlling keyword. The block underneath is indented 3 spaces:
  546. %@NL@%
  547. %@AS@%      if( a == b )
  548. %@AS@%      {
  549. %@AS@%         c = 50;
  550. %@AS@%         printf( "%i\n", a );
  551. %@AS@%      }%@AE@%%@NL@%
  552. %@NL@%
  553. %@NL@%
  554. %@NL@%
  555. %@NL@%
  556. %@2@%%@CR:C6A00000004 @%%@AB@%Key to Document Conventions%@AE@%%@EH@%%@NL@%
  557. %@NL@%
  558. This book uses the following document conventions:  %@NL@%
  559. %@NL@%
  560. %@AB@%Example%@AE@%                           %@AB@%Description%@AE@%
  561. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  562. COPY TEST.OBJ C:                  Uppercase letters represent DOS commands
  563.                                   and file names.
  564.  
  565. %@AB@%printf%@AE@%                            Boldface letters indicate standard 
  566.                                   features of the C language: keywords, 
  567.                                   operators, and standard library 
  568.                                   functions.
  569.  
  570. %@AI@%expression%@AE@%                        Words in italics indicate placeholders 
  571.                                   for information you must supply, such as
  572.                                   a file name. Italics are also 
  573.                                   occasionally used for emphasis in the 
  574.                                   text.
  575.  
  576. %@AS@%main()%@AE@%                            This typeface is used for example 
  577. %@AS@%{%@AE@%                                 programs, program fragments, and the 
  578. %@AS@%}%@AE@%                                 names of user-defined functions and 
  579.                                   variables. It also indicates user input 
  580.                                   and screen output. %@AS@% %@AE@%
  581.  
  582. %@AB@%CL%@AE@% %@AI@%options%@AE@% «%@AI@%files...%@AE@%»             A horizontal ellipsis following an item 
  583.                                   indicates that more items having the 
  584.                                   same form may follow.
  585.  
  586. %@AS@%while( )%@AE@%%@AS@%%@AE@%                          A vertical ellipsis tells you that part 
  587. %@AS@%{%@AE@%                                 of the example program has been 
  588. %@AS@%   .%@AE@%                              intentionally omitted.
  589. %@AS@%   .%@AE@%                              
  590. %@AS@%   .%@AE@%                              
  591. %@AS@%}%@AE@%                                 
  592.  
  593. SHIFT                             Small capital letters denote names of 
  594.                                   keys on the keyboard. A plus sign ( + ) 
  595.                                   indicates a combination of keys. For 
  596.                                   example, SHIFT+F5 tells you to hold down
  597.                                   the SHIFT key while pressing the F5 key.
  598.  
  599. "array pointer"                   The first time a new term is defined, it
  600.                                   is enclosed in quotation marks. Since 
  601.                                   some knowledge of programming is assumed,
  602.                                   common terms such as memory or branch 
  603.                                   are not defined.
  604.  
  605. American National Standards       The first time an acronym appears, it is
  606. Institute (ANSI)                  spelled out.
  607.  
  608. %@NL@%
  609. %@2@%%@CR:C6A00000005 @%%@AB@%Other Books on C Programming%@AE@%%@EH@%%@NL@%
  610. %@NL@%
  611. This book provides an introduction to the C language and some practical
  612. programming topics. It does not attempt to teach you basic computer
  613. programming or advanced C programming techniques. The following books cover
  614. a variety of topics that you may find useful. They are listed only for your
  615. convenience. With the exception of its own publications, Microsoft does not
  616. endorse these books or recommend them over others on the same subject.  %@NL@%
  617. %@NL@%
  618. Feibel, Werner. %@AI@%Advanced QuickC%@AE@%,
  619.     2d ed. Berkeley, California: Osborne McGraw-Hill, 1989.%@NL@%
  620. %@NL@%
  621. %@STUB@%    An intermediate-level C programming guide using QuickC. It includes data
  622.     structures, parsing, simulations, and the DOS interface.%@NL@%
  623. %@NL@%
  624. Hancock, Les, and Morris Krieger. %@AI@%The C Primer%@AE@%,
  625.     2d ed. New York: McGraw-Hill, 1986.%@NL@%
  626. %@NL@%
  627. %@STUB@%    A beginner's guide to C programming.%@NL@%
  628. %@NL@%
  629. Hansen, Augie. %@AI@%Proficient C%@AE@%.
  630.     Redmond, Washington: Microsoft Press, 1987.%@NL@%
  631. %@NL@%
  632. %@STUB@%    An intermediate-level guide to C programming.%@NL@%
  633. %@NL@%
  634. Harbison, Samuel P., and Guy L. Steele. %@AI@%C: A Reference Manual%@AE@%,
  635.     2d ed. Englewood Cliffs, New Jersey: Prentice-Hall, 1987.%@NL@%
  636. %@NL@%
  637. %@STUB@%    A comprehensive guide to the C language and the standard library.%@NL@%
  638. %@NL@%
  639. Hergert, Douglas. %@AI@%The ABC's of QuickC%@AE@%.
  640.     Alameda, California: SYBEX, Inc., 1989.%@NL@%
  641. %@NL@%
  642. %@STUB@%    A beginner's guide to QuickC programming.%@NL@%
  643. %@NL@%
  644. Kernighan, Brian W., and Dennis M. Ritchie. %@AI@%The C Programming Language%@AE@%,
  645.      2d ed. Englewood Cliffs, New Jersey: Prentice Hall, 1988.%@NL@%
  646. %@NL@%
  647. %@STUB@%    The first edition of this book is the classic definition of the C
  648.     language. The second edition includes new information on the proposed
  649.     ANSI C standard.%@NL@%
  650. %@NL@%
  651. Lafore, Robert. %@AI@%Microsoft C Programming for the IBM%@AE@%.
  652.     Indianapolis, Indiana: Howard W. Sams & Company, 1987.%@NL@%
  653. %@NL@%
  654. %@STUB@%    The first half of the book teaches C. The second half concentrates on
  655.     specifics of the PC environment, such as BIOS calls, memory, and video
  656.     displays.%@NL@%
  657. %@NL@%
  658. Plum, Thomas. %@AI@%Learning to Program in C%@AE@%.
  659.     Hasbrouck Heights, New Jersey: Hayden Book Company, 1983.%@NL@%
  660. %@NL@%
  661. %@STUB@%    A widely used introductory college text on computer programming in C.%@NL@%
  662. %@NL@%
  663. Schustack, Steve. %@AI@%Variations in C%@AE@%.
  664.     Redmond, Washington: Microsoft Press, 1985.%@NL@%
  665. %@NL@%
  666. %@STUB@%    An intermediate-level guide to developing business applications in C.%@NL@%
  667. %@NL@%
  668. Waite, Mitchell, Stephen Prate, Bryan Costales, and Harry Henderson (The
  669. Waite Group). %@AI@%Microsoft QuickC Programming%@AE@%.
  670.     Redmond, Washington: Microsoft Press, 1988.%@NL@%
  671. %@NL@%
  672. %@STUB@%    Beginning- to intermediate-level C programming, with special emphasis on
  673.     the QuickC Compiler.%@NL@%
  674. %@NL@%
  675. Ward, Robert. %@AI@%Debugging C%@AE@%.
  676.     Indianapolis, Indiana: Que Corporation, 1986.%@NL@%
  677. %@NL@%
  678. %@STUB@%    An advanced guide to the theory and practice of debugging C programs.%@NL@%
  679. %@NL@%
  680. Wilton, Richard. %@AI@%Programmer's Guide to PC and PS/2 Video Systems%@AE@%.
  681.     Redmond, Washington: Microsoft Press, 1987.%@NL@%
  682. %@NL@%
  683. %@STUB@%    An advanced guide to all the PC and PS/2(R) video modes.%@NL@%
  684. %@NL@%
  685. %@NL@%
  686. %@NL@%
  687. %@NL@%
  688. %@NL@%
  689. %@NL@%
  690. %@CR:C6A-Part 01 @%%@1@%%@AB@%PART I  Learning C%@AE@%%@EH@%%@NL@%
  691. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  692. %@NL@%
  693. The C language has steadily increased in popularity since it was created in
  694. the early 1970s. C is currently the language of choice for many professional
  695. software developers and is becoming quite popular among nonprofessional
  696. programmers, as well.  %@NL@%
  697. %@NL@%
  698. %@AI@%C for Yourself%@AE@%  is divided into two parts. Part 1 is called "Learning C" and
  699. discusses the C language itself. This part assumes you know the fundamentals
  700. of computer programming but do not know C. Experienced C programmers may
  701. only want to skim these chapters. Part 2, "Using C," discusses practical
  702. programming capabilities, such as graphics, which are provided in the QuickC
  703. run-time library. It should be read after you have finished Part 1 and have
  704. some familiarity with the C language.  %@NL@%
  705. %@NL@%
  706. Part 1 begins with basic topics such as data types and functions, and it
  707. progresses to more advanced subjects such as pointers. This part of the book
  708. closes with a discussion of common C programming pitfalls.  %@NL@%
  709. %@NL@%
  710. %@NL@%
  711. %@NL@%
  712. %@NL@%
  713. %@NL@%
  714. %@NL@%
  715. %@CR:C6A00010001 @%%@1@%%@AB@%Chapter 1  Anatomy of a C Program%@AE@%%@EH@%%@NL@%
  716. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  717. %@NL@%
  718. As a knowledgeable programmer, you'll probably be tempted to immerse
  719. yourself in C immediately. But before taking that plunge, you should know
  720. the basic model for all C programs. This chapter sketches the anatomy of a C
  721. program without getting bogged down in formal definitions or exceptions to
  722. the rules. (You'll find plenty of rules in the chapters that follow.)  %@NL@%
  723. %@NL@%
  724. The discussion revolves around a short, reasonably typical C program named
  725. VOLUME.C. To get comfortable with the look of C programs, as well as the
  726. basic ideas that shape them, refer to VOLUME.C frequently as you read.  %@NL@%
  727. %@NL@%
  728. %@NL@%
  729. %@2@%%@CR:C6A00010002 @%%@AB@%A Typical C Program%@AE@%%@EH@%%@NL@%
  730. %@NL@%
  731. VOLUME.C is a simple program that calculates the volume of a sphere and
  732. prints the following result on the screen:  %@NL@%
  733. %@NL@%
  734. %@AS@%  Volume: 113.040001%@AE@%%@NL@%
  735. %@NL@%
  736. Like all of the sample programs in this book, you'll find VOLUME.C in
  737. QuickC's online help. The "Introduction" explains how to load sample
  738. programs. Figure 1.1 illustrates the VOLUME.C program.  %@NL@%
  739. %@NL@%
  740. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  741. %@NL@%
  742. %@NL@%
  743. %@2@%%@CR:C6A00010003 @%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  744. %@NL@%
  745. The first line in VOLUME.C is a comment:  %@NL@%
  746. %@NL@%
  747. %@AS@%  /* VOLUME.C: Calculate sphere's volume. */%@AE@%%@NL@%
  748. %@NL@%
  749. %@AU@% Comments make a program more readable.%@AE@%  %@NL@%
  750. %@NL@%
  751. In C, a comment begins with a slash-asterisk (%@AB@%/*%@AE@%) and ends with an
  752. asterisk-slash (%@AB@%*/ %@AE@%). Because C is a compact language with very few
  753. keywords, comments play an important role in making your programs readable.
  754. %@NL@%
  755. %@NL@%
  756. You can't nest comments (put one comment inside another). The following line
  757. creates a syntax error:  %@NL@%
  758. %@NL@%
  759. %@AS@%  /* Error! /* You can't */ nest comments in C. */%@AE@%%@NL@%
  760. %@NL@%
  761. %@NL@%
  762. %@2@%%@CR:C6A00010004 @%%@AB@%Statements%@AE@%%@EH@%%@NL@%
  763. %@NL@%
  764. C statements always end with semicolons. Here is a statement from the
  765. VOLUME.C program:  %@NL@%
  766. %@NL@%
  767. %@AS@%  result = 4 * PI * result;%@AE@%%@NL@%
  768. %@NL@%
  769. %@AU@% Statement blocks are enclosed in braces.%@AE@%  %@NL@%
  770. %@NL@%
  771. You can also enclose a group of statements in braces, making a "statement
  772. block." Statement blocks contain related statements, such as the statements
  773. in the body of a function.  %@NL@%
  774. %@NL@%
  775. The C language ignores white space (tabs, blanks, and line breaks) in your
  776. source program, so you can arrange your program in almost any style.
  777. However, a few de facto rules help promote readability. A typical C program
  778. is written with one statement per line. Braces align vertically, and
  779. statements inside braces are indented. The "Introduction" describes the
  780. programming style used in this book.  %@NL@%
  781. %@NL@%
  782. %@NL@%
  783. %@2@%%@CR:C6A00010005 @%%@AB@%Keywords and Names%@AE@%%@EH@%%@NL@%
  784. %@NL@%
  785. C is a case-sensitive language (it distinguishes between uppercase and
  786. lowercase letters). All of C's keywords are spelled completely in lowercase;
  787. online help contains a complete list of C keywords.  %@NL@%
  788. %@NL@%
  789. You can declare names in any combination of either case, but many
  790. programmers prefer to use lowercase for variable and function names, saving
  791. uppercase for declaring symbolic constants. (A "symbolic constant" is a
  792. descriptive name that represents a constant value. In VOLUME.C, %@AS@% PI %@AE@% is a
  793. symbolic constant.)  %@NL@%
  794. %@NL@%
  795. %@NL@%
  796. %@2@%%@CR:C6A00010006 @%%@AB@%Preprocessor Directives%@AE@%%@EH@%%@NL@%
  797. %@NL@%
  798. %@AU@% A preprocessor  directive is a command to the QuickC compiler.%@AE@%  %@NL@%
  799. %@NL@%
  800. Not every line in a C program is an executable statement. Programs can also
  801. contain "preprocessor directives"─ commands for the QuickC compiler. A
  802. directive begins with a number sign (%@AB@%#%@AE@%) and does not end with a semicolon.  %@NL@%
  803. %@NL@%
  804. The second and third lines of VOLUME.C contain preprocessor directives. The
  805. %@AB@%#include%@AE@% directive in the second line tells QuickC to insert the file
  806. STDIO.H when it compiles VOLUME.C:  %@NL@%
  807. %@NL@%
  808. %@AS@%  #include <stdio.h>%@AE@%%@NL@%
  809. %@NL@%
  810. STDIO.H is one of the many "header files" supplied with QuickC. Header files
  811. contain declarations and definitions required by C library functions.
  812. ("Library functions" are supplied with QuickC rather than written by you.)
  813. In the VOLUME.C program, the %@AB@%printf%@AE@% library function requires information
  814. from the STDIO.H header file.  %@NL@%
  815. %@NL@%
  816. The %@AB@%#define%@AE@% directive in the third line defines a symbolic constant named %@AS@%
  817. %@AS@%PI%@AE@%:  %@NL@%
  818. %@NL@%
  819. %@AS@%  #define PI 3.14%@AE@%%@NL@%
  820. %@NL@%
  821. Wherever %@AS@% PI %@AE@% appears later in the source program, QuickC substitutes the
  822. text %@AS@% 3.14%@AE@%. The text can be any combination of letters, digits, or other
  823. characters. The effect is much like a search and replace operation in a word
  824. processor.  %@NL@%
  825. %@NL@%
  826. %@NL@%
  827. %@2@%%@CR:C6A00010007 @%%@AB@%Functions%@AE@%%@EH@%%@NL@%
  828. %@NL@%
  829. %@AU@% A function performs a specific task and can also return a value.%@AE@%  %@NL@%
  830. %@NL@%
  831. Functions are the building blocks of C. Every C program has at least one
  832. function, and every executable C statement appears inside some function or
  833. another. In plain English, a "function" is a group of statements that
  834. performs a specific task and often returns a value to the statement that
  835. calls it.  %@NL@%
  836. %@NL@%
  837. C functions serve the same purposes as QuickPascal procedures and functions
  838. or BASIC %@AB@%SUB%@AE@% and %@AB@%FUNCTION%@AE@% procedures. They allow you to write wellorganized
  839. programs that perform different tasks in separate parts.  %@NL@%
  840. %@NL@%
  841. %@AU@% The C language has no input/output statements.%@AE@%  %@NL@%
  842. %@NL@%
  843. C also uses functions to perform all input and output (I/O). Unlike other
  844. high-level languages, C has no I/O statements such as %@AB@%PRINT%@AE@% or %@AB@%READ%@AE@%.
  845. Instead, all I/O is done by calling C library functions such as %@AB@%printf%@AE@%.  %@NL@%
  846. %@NL@%
  847. %@AU@% Every C program has a function named%@AE@%%@AB@% main.%@AE@%  %@NL@%
  848. %@NL@%
  849. The VOLUME.C program contains two functions, named %@AB@%main%@AE@% and %@AS@%sphere%@AE@% (see
  850. Figure 1.1). The main execution section of every C program is itself a
  851. function named %@AB@%main,%@AE@% which marks where execution starts and ends. When you
  852. run VOLUME.C, execution starts at the beginning of the %@AB@%main%@AE@% function and
  853. stops at the end of %@AB@%main%@AE@%.  %@NL@%
  854. %@NL@%
  855. %@NL@%
  856. %@2@%%@CR:C6A00010008 @%%@AB@%Calling Functions%@AE@%%@EH@%%@NL@%
  857. %@NL@%
  858. Functions can be called (executed) from anywhere in a program, and they can
  859. receive values as well as return them. A value that you pass (send) to a
  860. function is called an "argument."  %@NL@%
  861. %@NL@%
  862. Calling a C function is a simple matter. You state the name of the function
  863. and supply in parentheses any arguments you want to pass to it. You must
  864. place a comma between arguments.  %@NL@%
  865. %@NL@%
  866. The VOLUME.C program contains two function calls, one to the %@AB@%printf%@AE@% library
  867. function and the other to the %@AS@% sphere %@AE@% function, which is defined in the
  868. program. The following statement calls the %@AB@%printf%@AE@% function:  %@NL@%
  869. %@NL@%
  870. %@AS@%  printf( "Volume: %f\n", volume );%@AE@%%@NL@%
  871. %@NL@%
  872. The statement passes two arguments to %@AB@%printf%@AE@%. The first, %@AS@%"Volume: %f\n"%@AE@%,
  873. supplies text and some formatting information. The second, %@AS@% volume%@AE@%, supplies
  874. a numeric value. See "A Few Words about %@AB@%printf%@AE@%," below, for more
  875. information.  %@NL@%
  876. %@NL@%
  877. In C, a function does not necessarily have to return a value. It can either
  878. return a value (like a QuickPascal function) or return nothing (like a
  879. QuickPascal  procedure).  %@NL@%
  880. %@NL@%
  881. When a function returns a value, the value is often assigned to a variable.
  882. The following statement from VOLUME.C calls the %@AS@% sphere %@AE@% function and
  883. assigns its return value to the variable %@AS@% volume%@AE@%:  %@NL@%
  884. %@NL@%
  885. %@AS@%  volume = sphere( radius );%@AE@%%@NL@%
  886. %@NL@%
  887. A function uses the %@AB@%return%@AE@% keyword to return a value. In VOLUME.C, the last
  888. statement in the %@AS@% sphere %@AE@% function returns the value of the variable %@AS@% result
  889. %@AS@%%@AE@% to the statement that calls %@AS@% sphere%@AE@%:  %@NL@%
  890. %@NL@%
  891. %@AS@%  return result;%@AE@%%@NL@%
  892. %@NL@%
  893. %@NL@%
  894. %@2@%%@CR:C6A00010009 @%%@AB@%Declaring and Initializing Variables%@AE@%%@EH@%%@NL@%
  895. %@NL@%
  896. You must "declare" every variable in a C program by stating its name and
  897. type. If you refer to an undeclared variable, QuickC displays an error
  898. message when you compile the program.  %@NL@%
  899. %@NL@%
  900. The following statement from VOLUME.C declares a %@AB@%float%@AE@% (floating-point) type
  901. variable named %@AS@% volume%@AE@%:  %@NL@%
  902. %@NL@%
  903. %@AS@%  float volume;%@AE@%%@NL@%
  904. %@NL@%
  905. After declaring a variable, you should "initialize" it─give it an initial
  906. value─before using it. Uninitialized variables might have any value, so they
  907. are dangerous to use. The VOLUME.C program initializes the variable %@AS@% volume %@AE@%
  908. by as- signing it the return value from a function call:  %@NL@%
  909. %@NL@%
  910. %@AS@%  volume = sphere( radius );%@AE@%%@NL@%
  911. %@NL@%
  912. You can also initialize a variable when it is declared, a convenient and
  913. common practice. The following statement from VOLUME.C declares the variable
  914. %@AS@% radius %@AE@% as an %@AB@%int%@AE@% (integer) variable and initializes it with the value 3:  %@NL@%
  915. %@NL@%
  916. %@AS@%  int radius = 3;%@AE@%%@NL@%
  917. %@NL@%
  918. %@NL@%
  919. %@2@%%@CR:C6A00010010 @%%@AB@%External and Local Variables%@AE@%%@EH@%%@NL@%
  920. %@NL@%
  921. The place where you declare a variable controls where it is visible. A
  922. variable declared outside any function is "external": you can refer to it
  923. anywhere within the program. (External variables are called "global" in some
  924. other languages.)  %@NL@%
  925. %@NL@%
  926. A variable declared inside the braces of a function is "local." You can
  927. refer to it inside the function but nowhere else. In VOLUME.C, the %@AS@% result %@AE@%
  928. variable is declared inside the %@AS@% sphere %@AE@% function:  %@NL@%
  929. %@NL@%
  930. %@AS@%  float sphere( int rad )
  931. %@AS@%  {
  932. %@AS@%     float result;
  933. %@AS@%     .
  934. %@AS@%     .
  935. %@AS@%     .
  936. %@AS@%  }%@AE@%%@NL@%
  937. %@NL@%
  938. %@AU@% Use external variables only when necessary.%@AE@%  %@NL@%
  939. %@NL@%
  940. Because it is local to the %@AS@% sphere %@AE@% function, the %@AS@% result %@AE@% variable cannot
  941. be used elsewhere in VOLUME.C. Making variables local whenever possible
  942. minimizes the risk that a variable's value will be changed accidentally in
  943. some other part of the program.  %@NL@%
  944. %@NL@%
  945. When a function receives arguments, the arguments become local variables
  946. within the function. The %@AS@% sphere %@AE@% function requires one argument, which it
  947. names %@AS@% rad%@AE@%. Within the function, %@AS@% rad %@AE@% is a local variable.  %@NL@%
  948. %@NL@%
  949. %@NL@%
  950. %@2@%%@CR:C6A00010011 @%%@AB@%Function Prototypes%@AE@%%@EH@%%@NL@%
  951. %@NL@%
  952. %@AU@% Function prototypes allow QuickC to check every function reference for
  953. %@AU@%accuracy.%@AE@%  %@NL@%
  954. %@NL@%
  955. A function can be declared in much the same way as a variable. Function
  956. declarations, often called "prototypes," allow QuickC to do "type checking."
  957. Given the information in the prototype, QuickC can check every subsequent
  958. use of the function to make sure you pass the right number and type of
  959. arguments and use the correct return type.  %@NL@%
  960. %@NL@%
  961. A function prototype gives the following information:  %@NL@%
  962. %@NL@%
  963. %@NL@%
  964.   ■   The function's name%@NL@%
  965. %@NL@%
  966.   ■   The type of value the function returns%@NL@%
  967. %@NL@%
  968.   ■   A list of arguments the function requires%@NL@%
  969. %@NL@%
  970. %@NL@%
  971. The VOLUME.C program contains one function prototype, for the %@AS@% sphere %@AE@%
  972. function:  %@NL@%
  973. %@NL@%
  974. %@AS@%  float sphere( int rad );%@AE@%%@NL@%
  975. %@NL@%
  976. The prototype states that the %@AS@% sphere %@AE@% function returns a %@AB@%float%@AE@%
  977. (floating-point) value and requires one %@AB@%int%@AE@% (integer) argument.  %@NL@%
  978. %@NL@%
  979. %@NL@%
  980. %@2@%%@CR:C6A00010012 @%%@AB@%A Few Words about printf%@AE@%%@EH@%%@NL@%
  981. %@NL@%
  982. The VOLUME.C program, like most examples in this book, uses the %@AB@%printf%@AE@%
  983. library function to display text. You won't need to know all of the details
  984. of %@AB@%printf%@AE@% to read the rest of this book, but the examples will be easier to
  985. follow if you know a few basic concepts.  %@NL@%
  986. %@NL@%
  987. The %@AB@%printf%@AE@% function works like the QuickBASIC %@AB@%PRINT USING%@AE@% statement or the
  988. QuickPascal %@AB@%Writeln%@AE@% procedure. It can display string and numeric data in
  989. various formats, and it normally prints to the screen.  %@NL@%
  990. %@NL@%
  991. You can print a simple message by passing %@AB@%printf%@AE@% a string (characters in
  992. double quotes) as an argument:  %@NL@%
  993. %@NL@%
  994. %@AS@%  printf( "Hi, Mom!" );%@AE@%%@NL@%
  995. %@NL@%
  996. The statement prints  %@NL@%
  997. %@NL@%
  998. %@AS@%  Hi, Mom!%@AE@%%@NL@%
  999. %@NL@%
  1000. The %@AB@%printf%@AE@% function doesn't automatically add a newline character at the end
  1001. of a line. The statements  %@NL@%
  1002. %@NL@%
  1003. %@AS@%  printf( "Le Nozze di Figaro" );
  1004. %@AS@%  printf( " by W. A. Mozart" );%@AE@%%@NL@%
  1005. %@NL@%
  1006. print the following message on one line:  %@NL@%
  1007. %@NL@%
  1008. %@AS@%  Le Nozze di Figaro by W. A. Mozart%@AE@%%@NL@%
  1009. %@NL@%
  1010. To start a new line, use the escape sequence %@AB@%\n%@AE@% as follows:  %@NL@%
  1011. %@NL@%
  1012. %@AS@%  printf( "Hi,\nMom!" );%@AE@%%@NL@%
  1013. %@NL@%
  1014. The statement prints two words on separate lines:  %@NL@%
  1015. %@NL@%
  1016. %@AS@%  Hi,
  1017. %@AS@%  Mom!%@AE@%%@NL@%
  1018. %@NL@%
  1019. The%@AB@% f%@AE@% in %@AB@%printf%@AE@% stands for formatting. To print the values of variables and
  1020. other items, you supply %@AB@%printf%@AE@% with format codes that tell %@AB@%printf%@AE@% the proper
  1021. format for each item. The codes are placed in the first argument, which is
  1022. enclosed in double quotes.  %@NL@%
  1023. %@NL@%
  1024. The following statement uses the %@AB@%%x%@AE@% code to print the integer 553 in
  1025. hexadecimal format. It passes two arguments to %@AB@%printf%@AE@%:  %@NL@%
  1026. %@NL@%
  1027. %@AS@%  printf( "%x", 553 );%@AE@%%@NL@%
  1028. %@NL@%
  1029. The first argument (%@AS@%"%x"%@AE@%) contains the format code and the second argument
  1030. (%@AS@%553%@AE@%) contains the item to be formatted. The line displays the following:  %@NL@%
  1031. %@NL@%
  1032. %@AS@%  229%@AE@%%@NL@%
  1033. %@NL@%
  1034. The %@AB@%printf%@AE@% function accepts several other format codes. For instance, the
  1035. VOLUME.C program uses %@AB@%%f%@AE@% to print a floating-point number. Some programs in
  1036. later chapters use %@AB@%%d%@AE@% to print integers or %@AB@%%ld%@AE@% to print long integers.  %@NL@%
  1037. %@NL@%
  1038. The first argument passed to %@AB@%printf%@AE@% can contain any combination of
  1039. characters and format codes. The other arguments contain the items that you
  1040. want %@AB@%printf%@AE@% to format. The statement  %@NL@%
  1041. %@NL@%
  1042. %@AS@%  printf( "%d times %d = %d\n", 2, 128, 2 * 128 );%@AE@%%@NL@%
  1043. %@NL@%
  1044. prints the line:  %@NL@%
  1045. %@NL@%
  1046. %@AS@%  2 times 128 = 256%@AE@%%@NL@%
  1047. %@NL@%
  1048. The %@AB@%printf%@AE@% function matches the format codes to the items you want to
  1049. format, in left-to-right order. In the code above, the first %@AB@%%d%@AE@% formats the
  1050. number 2, the second formats the 128, and the third formats the expression 2
  1051. * 128 (which evaluates to the number 256).  %@NL@%
  1052. %@NL@%
  1053. There's much more to say about %@AB@%printf%@AE@% and other I/O functions, but the rest
  1054. can wait until you reach Chapter 11, "Input and Output," which describes I/O
  1055. in detail.  %@NL@%
  1056. %@NL@%
  1057. Now that you've glimpsed the big picture, we can take a closer look at some
  1058. specifics of C programming, beginning with Chapter 2, "Functions."  %@NL@%
  1059. %@NL@%
  1060. %@NL@%
  1061. %@NL@%
  1062. %@NL@%
  1063. %@NL@%
  1064. %@NL@%
  1065. %@CR:C6A00020001 @%%@1@%%@AB@%Chapter 2  Functions%@AE@%%@EH@%%@NL@%
  1066. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1067. %@NL@%
  1068. Chapter 1, "Anatomy of a C Program," introduced functions, the building
  1069. blocks of C programs. In this chapter, you'll learn how to use functions in
  1070. C programs.  %@NL@%
  1071. %@NL@%
  1072. We begin by discussing some function basics, including the role of the %@AB@%main%@AE@%
  1073. function. We then show you how to call functions, pass data to them, return
  1074. data from them, and declare them. The chapter concludes with a brief look at
  1075. old-style function declarations, which you may encounter in some programs.  %@NL@%
  1076. %@NL@%
  1077. %@NL@%
  1078. %@2@%%@CR:C6A00020002 @%%@AB@%Functions and Structured Programming%@AE@%%@EH@%%@NL@%
  1079. %@NL@%
  1080. As we mentioned in Chapter 1, a C function is a collection of statements,
  1081. enclosed in braces (%@AS@%{ }%@AE@%), which performs a particular task. It can receive
  1082. arguments (data) and also return a value.  %@NL@%
  1083. %@NL@%
  1084. Functions allow you to program with a "divide and conquer" strategy. Rather
  1085. than try to solve a large problem all at once, you break the problem into
  1086. several parts and attack each one separately. This approach, known as
  1087. "structured programming," allows you to write clear, reliable programs that
  1088. perform separate tasks in discrete, logically contained modules. In the C
  1089. language, these modules are called functions.  %@NL@%
  1090. %@NL@%
  1091. Functions offer several advantages. They can  %@NL@%
  1092. %@NL@%
  1093. %@NL@%
  1094.   ■   Make programs easier to write and read. All of the statements related
  1095.       to a task are located in one place.%@NL@%
  1096. %@NL@%
  1097.   ■   Prevent unexpected side effects by using private (local) variables
  1098.       that are not visible to other parts of the program.%@NL@%
  1099. %@NL@%
  1100.   ■   Eliminate unnecessary repetition of code for frequently performed
  1101.       tasks.%@NL@%
  1102. %@NL@%
  1103.   ■   Simplify debugging. Once the function works reliably, you can use it
  1104.       with confidence in many different situations.%@NL@%
  1105. %@NL@%
  1106. %@NL@%
  1107. If you know QuickPascal or QuickBASIC, you will see many similarities in the
  1108. C language. A C function serves the same basic purpose as a QuickPascal
  1109. function or procedure or a QuickBASIC %@AB@%FUNCTION%@AE@% or %@AB@%SUB%@AE@% procedure. In later
  1110. sections, we'll note some differences between C and these languages.  %@NL@%
  1111. %@NL@%
  1112. %@NL@%
  1113. %@2@%%@CR:C6A00020003 @%%@AB@%The main Function%@AE@%%@EH@%%@NL@%
  1114. %@NL@%
  1115. %@AU@% Every C program must  have one and only  one main function.%@AE@%  %@NL@%
  1116. %@NL@%
  1117. Every C program must have a function named %@AB@%main%@AE@%, which tells where program
  1118. execution begins and ends. Although %@AB@%main%@AE@% is not a C keyword, it has only one
  1119. use: naming the %@AB@%main%@AE@% function. A program must have only one %@AB@%main%@AE@% function,
  1120. and you shouldn't use the name anywhere else.  %@NL@%
  1121. %@NL@%
  1122. Below is the simplest possible C program:  %@NL@%
  1123. %@NL@%
  1124. %@AS@%  main()
  1125. %@AS@%  {
  1126. %@AS@%  }%@AE@%%@NL@%
  1127. %@NL@%
  1128. The braces (%@AS@%{ }%@AE@%) mark the %@AB@%main%@AE@% function's beginning and end, as they do in
  1129. every function. This program doesn't contain any executable statements; it
  1130. simply begins and ends.  %@NL@%
  1131. %@NL@%
  1132. Most functions have executable statements, of course, and these appear
  1133. within the function's braces. The following program contains a statement
  1134. which prints %@AS@% Hello, world! %@AE@% on the screen:  %@NL@%
  1135. %@NL@%
  1136. %@AS@%  main()
  1137. %@AS@%  {
  1138. %@AS@%     printf( "Hello, world!\n" );
  1139. %@AS@%  }%@AE@%%@NL@%
  1140. %@NL@%
  1141. The %@AB@%main%@AE@% function is called by the operating system when it runs your
  1142. program. While it's possible to call the %@AB@%main%@AE@% function in a program, you
  1143. should never do so, just as you wouldn't write a QuickBASIC program
  1144. containing the line  %@NL@%
  1145. %@NL@%
  1146. %@AS@%  10 GOSUB 10%@AE@%%@NL@%
  1147. %@NL@%
  1148. A program that calls %@AB@%main%@AE@% will start again and again in an endless loop that
  1149. eventually triggers a run-time error.  %@NL@%
  1150. %@NL@%
  1151. Like all functions, %@AB@%main%@AE@% can accept arguments and return a value. Through
  1152. this mechanism, your program can receive command-line arguments from DOS
  1153. when it begins execution and return a value to DOS when it ends. Chapter 9,
  1154. "Advanced Pointers," describes how to receive command-line arguments via
  1155. %@AB@%main%@AE@%.  %@NL@%
  1156. %@NL@%
  1157. %@NL@%
  1158. %@2@%%@CR:C6A00020004 @%%@AB@%Placement and Visibility of Functions%@AE@%%@EH@%%@NL@%
  1159. %@NL@%
  1160. %@AU@% A function is normally visible everywhere in the program.%@AE@%  %@NL@%
  1161. %@NL@%
  1162. Every C function is normally "visible" to all other functions in the same
  1163. program. That is, it can call and be called by any other function. C
  1164. functions can even call themselves, a process known as "recursion."  %@NL@%
  1165. %@NL@%
  1166. In the program below, the functions %@AS@% whiz %@AE@% and %@AS@% bang %@AE@% are visible to %@AB@%main%@AE@%
  1167. and to each other. The %@AB@%main %@AE@% function can call both %@AS@% whiz %@AE@% and %@AS@% bang%@AE@%. In
  1168. addition, %@AS@% whiz %@AE@% can call %@AS@% bang%@AE@%, and vice versa.  %@NL@%
  1169. %@NL@%
  1170. %@AS@%  main()
  1171. %@AS@%  {
  1172. %@AS@%  }
  1173. %@AS@%  
  1174. %@AS@%  whiz()
  1175. %@AS@%  {
  1176. %@AS@%  }
  1177. %@AS@%  
  1178. %@AS@%  bang()
  1179. %@AS@%  {
  1180. %@AS@%  }%@AE@%%@NL@%
  1181. %@NL@%
  1182. Functions can appear in any order and at almost any place in your program.
  1183. Since %@AB@%main%@AE@% starts and ends the program's execution, this function often
  1184. begins the program. But this is a readability convention, not a language
  1185. requirement.  %@NL@%
  1186. %@NL@%
  1187. %@AU@% C functions can't be nested.%@AE@%  %@NL@%
  1188. %@NL@%
  1189. One place where you can't put a function is inside another function. The C
  1190. language doesn't allow you to nest functions. Here C differs from
  1191. QuickPascal, in which one procedure can contain other "hidden" functions or
  1192. procedures. The following program causes a syntax error because the %@AS@% bang %@AE@%
  1193. function appears within the %@AS@% whiz %@AE@% function:  %@NL@%
  1194. %@NL@%
  1195. %@AS@%  main()
  1196. %@AS@%  {
  1197. %@AS@%  }
  1198. %@AS@%  
  1199. %@AS@%  whiz()
  1200. %@AS@%  {
  1201. %@AS@%     /* Error! Incorrect function placement */
  1202. %@AS@%     bang()
  1203. %@AS@%     {
  1204. %@AS@%     }
  1205. %@AS@%  }%@AE@%%@NL@%
  1206. %@NL@%
  1207. %@NL@%
  1208. %@2@%%@CR:C6A00020005 @%%@AB@%Function Definitions and Prototypes%@AE@%%@EH@%%@NL@%
  1209. %@NL@%
  1210. Now that you understand some function basics, we can look at functions in
  1211. more detail. A function, or more precisely, "function definition," contains
  1212. several parts. Figure 2.1 shows the parts of the %@AS@% sphere %@AE@% function
  1213. definition from the VOLUME.C example in Chapter 1, "Anatomy of a C Program."
  1214. %@NL@%
  1215. %@NL@%
  1216. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  1217. %@NL@%
  1218. The function "header" specifies the type of value a function returns and the
  1219. function's name. The header also contains an argument list, which specifies
  1220. the arguments the function requires. The rest of the function
  1221. definition─everything inside the braces─is the function "body."  %@NL@%
  1222. %@NL@%
  1223. The ANSI C standard, which QuickC follows, recommends that you supply a
  1224. function "prototype" (declaration) for every function definition in your
  1225. program. The prototype is identical to the function header except that it
  1226. ends with a semicolon. Figure 2.2 shows the %@AS@% sphere %@AE@% function prototype from
  1227. VOLUME.C.  %@NL@%
  1228. %@NL@%
  1229. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  1230. %@NL@%
  1231. The function prototype normally appears near the beginning of the program
  1232. and serves a purpose similar to a variable declaration. It provides advance
  1233. information about the function, which QuickC can use to check the accuracy
  1234. of subsequent calls to the function. We'll examine prototypes in detail in
  1235. "Function Prototypes," below.  %@NL@%
  1236. %@NL@%
  1237. %@NL@%
  1238. %@2@%%@CR:C6A00020006 @%%@AB@%Calling a Function%@AE@%%@EH@%%@NL@%
  1239. %@NL@%
  1240. You call (execute) a function by stating its name. In the simplest case─when
  1241. a function doesn't receive or return any data─the function call consists of
  1242. the function's name, followed by an empty pair of parentheses and a
  1243. semicolon. The BEEPER.C program, shown below, demonstrates this kind of
  1244. function call.  %@NL@%
  1245. %@NL@%
  1246. %@AS@%  /* BEEPER.C: Demonstrate simple function. */
  1247. %@AS@%  #include <stdio.h>
  1248. %@AS@%  
  1249. %@AS@%  void beep( void );
  1250. %@AS@%  
  1251. %@AS@%  main()
  1252. %@AS@%  {
  1253. %@AS@%     printf( "Time to beep\n" );
  1254. %@AS@%     beep();
  1255. %@AS@%     printf( "All done\n" );
  1256. %@AS@%  }
  1257. %@AS@%  
  1258. %@AS@%  void beep( void )
  1259. %@AS@%  {
  1260. %@AS@%     printf( "Beep!\a\n" );
  1261. %@AS@%  }%@AE@%%@NL@%
  1262. %@NL@%
  1263. When you run BEEPER.C, the program prints:  %@NL@%
  1264. %@NL@%
  1265. %@AS@%  Time to beep
  1266. %@AS@%  Beep!
  1267. %@AS@%  All done%@AE@%%@NL@%
  1268. %@NL@%
  1269. As you may recall from Chapter 1, "Anatomy of a C Program," the %@AB@%\n%@AE@% sequence
  1270. represents the newline character. The %@AB@%\a%@AE@% sequence is the "alert" character
  1271. (ASCII 7) which makes an audible beep.  %@NL@%
  1272. %@NL@%
  1273. In the %@AB@%main%@AE@% function of BEEPER.C, the statement  %@NL@%
  1274. %@NL@%
  1275. %@AS@%  beep();%@AE@%%@NL@%
  1276. %@NL@%
  1277. calls the %@AS@% beep %@AE@% function. Since %@AS@% beep %@AE@% takes no arguments, the parentheses
  1278. of the function call are empty.  %@NL@%
  1279. %@NL@%
  1280. The prototype and definition for the %@AS@% beep %@AE@% function use the%@AB@% void%@AS@% %@AE@%keyword
  1281. twice, first to indicate that the function returns no value, and second to
  1282. indicate that it receives no arguments. We'll return to these points later
  1283. in this chapter.%@AS@%  %@AE@%%@AE@%%@NL@%
  1284. %@NL@%
  1285. A function call transfers control to that function. The statements within
  1286. the function's braces execute in order until the function ends. Then
  1287. execution resumes where it left off.  %@NL@%
  1288. %@NL@%
  1289. A function can end in one of two ways. The %@AS@% beep %@AE@% function above ends by
  1290. "falling off" the closing brace of the function definition. A function can
  1291. also end by executing a %@AB@%return%@AE@% statement, which we discuss later in the
  1292. section "Returning Values from Functions."  %@NL@%
  1293. %@NL@%
  1294. Figure 2.3 illustrates the flow of control in BEEPER.C.  %@NL@%
  1295. %@NL@%
  1296. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  1297. %@NL@%
  1298. %@NL@%
  1299. %@2@%%@CR:C6A00020007 @%%@AB@%Passing Arguments to a Function%@AE@%%@EH@%%@NL@%
  1300. %@NL@%
  1301. If a function requires arguments, you list them in the parentheses of the
  1302. function call. In the BEEPER1.C program below, we revise the %@AS@% beep %@AE@% function
  1303. from BEEPER.C to take one argument.  %@NL@%
  1304. %@NL@%
  1305. %@AS@%  /* BEEPER1.C: Demonstrate passing arguments. */
  1306. %@AS@%  #include <stdio.h>
  1307. %@AS@%  
  1308. %@AS@%  void beep( int num_beep );
  1309. %@AS@%  
  1310. %@AS@%  main()
  1311. %@AS@%  {
  1312. %@AS@%     printf( "Time to beep\n" );
  1313. %@AS@%     beep( 5 );
  1314. %@AS@%     printf( "All done\n" );
  1315. %@AS@%  }
  1316. %@AS@%  
  1317. %@AS@%  void beep( int num_beep )
  1318. %@AS@%  {
  1319. %@AS@%     while( num_beep > 0  )
  1320. %@AS@%     {
  1321. %@AS@%        printf( "Beep!\a\n" );
  1322. %@AS@%        num_beep = num_beep - 1;
  1323. %@AS@%     }
  1324. %@AS@%  }%@AE@%%@NL@%
  1325. %@NL@%
  1326. The function definition states what kind of arguments the function expects.
  1327. In the %@AS@%beep %@AE@% function definition, the header,  %@NL@%
  1328. %@NL@%
  1329. %@AS@%  void beep( int num_beep )%@AE@%%@NL@%
  1330. %@NL@%
  1331. states that %@AS@% beep %@AE@% expects one %@AB@%int%@AE@% (integer) argument named %@AS@% num_beep%@AE@%
  1332. (number of beeps).  %@NL@%
  1333. %@NL@%
  1334. The statement that calls %@AS@% beep%@AE@%,  %@NL@%
  1335. %@NL@%
  1336. %@AS@%  beep( 5 );%@AE@%%@NL@%
  1337. %@NL@%
  1338. gives the value 5 in parentheses, passing that value as an argument. Figure
  1339. 2.4 shows argument passing in BEEPER1.C.  %@NL@%
  1340. %@NL@%
  1341. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  1342. %@NL@%
  1343. %@AU@% Function arguments are assigned to local variables inside the function.%@AE@%  %@NL@%
  1344. %@NL@%
  1345. When %@AS@% beep %@AE@% receives the value 5, the function automatically assigns the
  1346. value to %@AS@% num_beep%@AE@%, which the function can then treat as a local variable.
  1347. In this case, the function uses %@AS@% num_beep %@AE@% as a loop counter to repeat the
  1348. statement  %@NL@%
  1349. %@NL@%
  1350. %@AS@%  printf( "Beep!\a\n" );%@AE@%%@NL@%
  1351. %@NL@%
  1352. %@AS@%%@AE@%num_beep  times. (The C %@AB@%while%@AE@% loop is very similar to %@AB@%WHILE%@AE@% loops in
  1353. QuickBASIC or QuickPascal. You don't need to know the details of loops for
  1354. now; they're explained in Chapter 3, "Flow Control.")  %@NL@%
  1355. %@NL@%
  1356. If a function expects more than one argument, you separate the arguments
  1357. with commas. For instance, the statement  %@NL@%
  1358. %@NL@%
  1359. %@AS@%  printf( "%d times %d equals %d\n", 2, 16, 2 * 16 );%@AE@%%@NL@%
  1360. %@NL@%
  1361. passes four arguments to the %@AB@%printf%@AE@% function. The first argument is the
  1362. string  %@NL@%
  1363. %@NL@%
  1364. %@AS@%  "%d times %d equals %d\n"%@AE@%%@NL@%
  1365. %@NL@%
  1366. The second and third arguments are constants (%@AS@%2 %@AE@% and %@AS@% 16%@AE@%). The fourth
  1367. argument is an expression (%@AS@%2 * 16%@AE@%) that evaluates to a constant.  %@NL@%
  1368. %@NL@%
  1369. %@NL@%
  1370. %@2@%%@CR:C6A00020008 @%%@AB@%Arguments Versus Parameters%@AE@%%@EH@%%@NL@%
  1371. %@NL@%
  1372. In the C language, a value passed to a function is called either an
  1373. "argument" or a "parameter," depending on viewpoint. From the viewpoint of
  1374. the statement that calls the function, the value is an argument. In the view
  1375. of the function receiving it, the value is a parameter.  %@NL@%
  1376. %@NL@%
  1377. Thus, in BEEPER1.C, the following function call passes an argument to the %@AS@%
  1378. %@AS@%beep %@AE@% function:  %@NL@%
  1379. %@NL@%
  1380. %@AS@%  beep( 5 );%@AE@%%@NL@%
  1381. %@NL@%
  1382. Looking at the same value from the receiving end, the header of the %@AS@% beep %@AE@%
  1383. function declares a parameter named %@AS@% num_beep %@AE@% as follows:  %@NL@%
  1384. %@NL@%
  1385. %@AS@%  void beep( int num_beep );%@AE@%%@NL@%
  1386. %@NL@%
  1387. The argument and parameter refer to the same value─in this case, the value
  1388. 5. The naming distinction is just a matter of viewpoint, similar to the way
  1389. you call a letter outgoing mail if you're sending it, or incoming mail if
  1390. you're receiving it.  %@NL@%
  1391. %@NL@%
  1392. %@NL@%
  1393. %@2@%%@CR:C6A00020009 @%%@AB@%Assigning Parameters%@AE@%%@EH@%%@NL@%
  1394. %@NL@%
  1395. When you list a parameter in the function header, it becomes a local
  1396. variable within the function. This process is easy to follow when it
  1397. involves only one argument, as in the BEEPER1.C program above. The function
  1398. call passes one value, which the function assigns to one variable. The
  1399. variable can be treated like any other variable declared within the
  1400. function.  %@NL@%
  1401. %@NL@%
  1402. %@AU@% There is a one-to-one correspondence between arguments and parameters.%@AE@%  %@NL@%
  1403. %@NL@%
  1404. If a function takes more than one argument, the values are passed in order.
  1405. The first argument in the function call is assigned to the first variable,
  1406. the second argument is assigned to the second variable, and so on.  %@NL@%
  1407. %@NL@%
  1408. The SHOWME.C program below demonstrates this process. Its %@AS@% showme %@AE@% function
  1409. takes three arguments. The %@AB@%main%@AE@% function defines three integer variables and
  1410. passes their values to %@AS@% showme%@AE@%, which prints the values that it receives.
  1411. (You normally wouldn't write a function just to print one line, of course.
  1412. We'll add more to SHOWME.C in a later revision.)  %@NL@%
  1413. %@NL@%
  1414. %@AS@%  /* SHOWME.C: Demonstrate passing by value. */
  1415. %@AS@%  #include <stdio.h>
  1416. %@AS@%  
  1417. %@AS@%  void showme( int a, int b, int c );%@AE@%%@NL@%
  1418. %@NL@%
  1419. %@AS@%  main()
  1420. %@AS@%  {
  1421. %@AS@%     int x = 10, y = 20, z = 30;
  1422. %@AS@%     showme( z, y, x );
  1423. %@AS@%  }
  1424. %@AS@%  
  1425. %@AS@%  void showme( int a, int b, int c )
  1426. %@AS@%  {
  1427. %@AS@%     printf( "a=%d b=%d c=%d", a, b, c );
  1428. %@AS@%  }%@AE@%%@NL@%
  1429. %@NL@%
  1430. Here's the output from SHOWME.C:  %@NL@%
  1431. %@NL@%
  1432. %@AS@%  a=30 b=20 c=10%@AE@%%@NL@%
  1433. %@NL@%
  1434. The function call in SHOWME.C passes the values of %@AS@% z%@AE@%, %@AS@% y%@AE@%, and %@AS@% x %@AE@% in the
  1435. order listed:  %@NL@%
  1436. %@NL@%
  1437. %@AS@%  showme( z, y, x );%@AE@%%@NL@%
  1438. %@NL@%
  1439. %@AU@% Functions receive parameters in the order they are passed.%@AE@%  %@NL@%
  1440. %@NL@%
  1441. These values are assigned, in the same order, to the parameters listed in
  1442. the %@AS@% showme %@AE@% function header:  %@NL@%
  1443. %@NL@%
  1444. %@AS@%  void showme( int a, int b, int c )%@AE@%%@NL@%
  1445. %@NL@%
  1446. The position of the parameters, not their names, controls which arguments
  1447. the parameters receive. The first argument (%@AS@% z %@AE@%) listed in the function call
  1448. is assigned to the first parameter (%@AS@% a %@AE@%) in the function header, the second
  1449. argument (%@AS@% y %@AE@%) to the second parameter (%@AS@% b %@AE@%), and so on. Figure 2.5 shows
  1450. this process.  %@NL@%
  1451. %@NL@%
  1452. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  1453. %@NL@%
  1454. %@NL@%
  1455. %@2@%%@CR:C6A00020010 @%%@AB@%Passing by Value%@AE@%%@EH@%%@NL@%
  1456. %@NL@%
  1457. %@AU@% The C language passes copies of function arguments.%@AE@%  %@NL@%
  1458. %@NL@%
  1459. In C, all function arguments (except arrays) are passed "by value" rather
  1460. than "by reference." That is, a function receives a local copy of each
  1461. argument, not the argument itself. These copies are local variables within
  1462. the function. They are created and initialized automatically when the
  1463. function begins, and they disappear when it ends. Like all local variables,
  1464. their values can be changed without  affecting variables elsewhere in the
  1465. program.  %@NL@%
  1466. %@NL@%
  1467. We can clarify this point by adding a few statements to the SHOWME.C
  1468. program. The new program, SHOWMORE.C, will change the values of the local
  1469. variables in the %@AS@% showme %@AE@% function without changing the values of the
  1470. original variables.  %@NL@%
  1471. %@NL@%
  1472. %@AS@%  /* SHOWMORE.C: Demonstrate passing by value. */
  1473. %@AS@%  #include <stdio.h>
  1474. %@AS@%  
  1475. %@AS@%  void showme( int any, int old, int name );
  1476. %@AS@%  
  1477. %@AS@%  main()
  1478. %@AS@%  {
  1479. %@AS@%     int x = 10, y = 20, z = 30;
  1480. %@AS@%     showme( z, y, x );
  1481. %@AS@%     printf( "  z=%d   y=%d    x=%d\n", z, y, x );
  1482. %@AS@%  }
  1483. %@AS@%  
  1484. %@AS@%  void showme( int any, int old, int name )
  1485. %@AS@%  {
  1486. %@AS@%     printf( "any=%d old=%d name=%d\n", any, old, name );
  1487. %@AS@%     any = 55;
  1488. %@AS@%     old = 66;
  1489. %@AS@%     name = 77;
  1490. %@AS@%     printf( "any=%d old=%d name=%d\n", any, old, name );
  1491. %@AS@%  }%@AE@%%@NL@%
  1492. %@NL@%
  1493. Here is the output from SHOWMORE.C:  %@NL@%
  1494. %@NL@%
  1495. %@AS@%  any=30 old=20 name=10
  1496. %@AS@%  any=55 old=66 name=77
  1497. %@AS@%    z=30   y=20    x=10%@AE@%%@NL@%
  1498. %@NL@%
  1499. First, note that the %@AS@% showme %@AE@% function in SHOWMORE.C uses new names (%@AS@% any%@AE@%, %@AS@%
  1500. %@AS@%old%@AE@%, and %@AS@% name%@AE@%) when assigning the parameters it receives:  %@NL@%
  1501. %@NL@%
  1502. %@AS@%  void showme( int any, int old, int name )%@AE@%%@NL@%
  1503. %@NL@%
  1504. %@AU@% Function parameters can have any legal variable names.%@AE@%  %@NL@%
  1505. %@NL@%
  1506. Because these variables are local to the function, they can have any legal
  1507. names. (The rules for variable names are described in Chapter 4, "Data
  1508. Types.") The %@AS@% showme %@AE@% function prints the values of its parameters
  1509. immediately after assigning them:  %@NL@%
  1510. %@NL@%
  1511. %@AS@%  printf( "any=%d old=%d name=%d", any, old, name );%@AE@%%@NL@%
  1512. %@NL@%
  1513. Then the function assigns new values to the variables and prints them again:
  1514. %@NL@%
  1515. %@NL@%
  1516. %@AS@%  any = 55;
  1517. %@AS@%  old = 66;
  1518. %@AS@%  name = 77;
  1519. %@AS@%  printf( "any=%d old=%d name=%d", any, old, name );%@AE@%%@NL@%
  1520. %@NL@%
  1521. %@AU@% Local variables are private to the function containing them.%@AE@%  %@NL@%
  1522. %@NL@%
  1523. Changing the local variables in the %@AS@% showme %@AE@% function doesn't affect the
  1524. original variables in the %@AB@%main%@AE@% function. Remember, a variable defined inside
  1525. a function is only visible inside that function. After control returns to
  1526. %@AB@%main%@AE@%, SHOWMORE.C prints the values of the original variables:  %@NL@%
  1527. %@NL@%
  1528. %@AS@%  printf( "  z=%d   y=%d    x=%d\n", z, y, x );%@AE@%%@NL@%
  1529. %@NL@%
  1530. As the program output shows, the original values are unchanged:  %@NL@%
  1531. %@NL@%
  1532. %@AS@%  z=30   y=20    x=10%@AE@%%@NL@%
  1533. %@NL@%
  1534. We'll say more about the visibility of variables in Chapter 5, "Advanced
  1535. Data Types." For now, just remember that when you pass a value to a
  1536. function, the function makes a local copy of that value. The local copy can
  1537. be manipulated without changing the original.  %@NL@%
  1538. %@NL@%
  1539. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1540. NOTE
  1541.  
  1542. %@AI@%In QuickPascal, you can pass either the value of an argument or the
  1543. %@AI@%argument's address. In C, function arguments are only passed by value.
  1544. %@AI@%However, that value can be an address. Chapter 8, "Pointers," explains how
  1545. %@AI@%to pass addresses to functions.%@AE@%%@NL@%
  1546. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  1547. %@NL@%
  1548. %@NL@%
  1549. %@2@%%@CR:C6A00020011 @%%@AB@%Returning Values from Functions%@AE@%%@EH@%%@NL@%
  1550. %@NL@%
  1551. %@AU@% The return keyword  ends a function and  can return one value.%@AE@%  %@NL@%
  1552. %@NL@%
  1553. Most C functions return a value. This is done with the %@AB@%return%@AE@% statement,
  1554. which also ends the function. The VOLUME.C program from Chapter 1, "Anatomy
  1555. of a C Program," (see Figure 2.1) contains such a statement. In that
  1556. program, the %@AS@% sphere %@AE@% function returns the value of the variable %@AS@% result %@AE@% as
  1557. follows:  %@NL@%
  1558. %@NL@%
  1559. %@AS@%  return result;%@AE@%%@NL@%
  1560. %@NL@%
  1561. The following statement in the %@AB@%main%@AE@% function of VOLUME.C calls the %@AS@% sphere %@AE@%
  1562. function and assigns its return value to the variable %@AS@% volume%@AE@%:  %@NL@%
  1563. %@NL@%
  1564. %@AS@%  volume = sphere( radius );%@AE@%%@NL@%
  1565. %@NL@%
  1566. Figure 2.6 shows the flow of control as the %@AS@% sphere %@AE@% function returns a
  1567. value in VOLUME.C.  %@NL@%
  1568. %@NL@%
  1569. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  1570. %@NL@%
  1571. A %@AB@%return%@AE@% statement can only return a single value. If a function needs to
  1572. return multiple values, the normal method is to use pointers─a major topic
  1573. that we'll discuss in Chapter 8, "Pointers."  %@NL@%
  1574. %@NL@%
  1575. ────────────────────────────────────────────────────────────────────────────%@NL@%
  1576. NOTE
  1577.  
  1578. %@AI@%In QuickPascal, a function returns a value and a procedure does not. The
  1579. %@AI@%same distinction applies to QuickBASIC %@AI@%FUNCTION %@AE@%%@AI@%and %@AE@%%@AI@%%@AB@%SUB %@AE@%%@AE@%%@AI@%procedures,
  1580. %@AI@%respectively. In the C language, a function can do both. It can return a
  1581. %@AI@%value or return nothing.%@AE@%%@AE@%%@NL@%
  1582. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  1583. %@NL@%
  1584. A function can contain more than one %@AB@%return%@AE@% statement, as shown below:  %@NL@%
  1585. %@NL@%
  1586. %@AS@%  if( error == 0 )
  1587. %@AS@%    return 0;
  1588. %@AS@%  else
  1589. %@AS@%    return 1;%@AE@%%@NL@%
  1590. %@NL@%
  1591. The code returns a different value in different cases. It returns the value
  1592. 0 when the variable %@AS@% error %@AE@% is 0 and the value 1 when %@AS@% error %@AE@% is nonzero.
  1593. (In C, the %@AB@%if%@AE@% and %@AB@%else%@AE@% statements work much like those in other languages.
  1594. Chapter 3, "Flow Control," explains these statements.)  %@NL@%
  1595. %@NL@%
  1596. %@AU@% A return statement can  appear anywhere and  need not return a value.%@AE@%  %@NL@%
  1597. %@NL@%
  1598. You can place the %@AB@%return%@AE@% keyword anywhere within a function, and the
  1599. statement need not necessarily return a value. In the following fragment,
  1600. the naked %@AB@%return%@AE@% statement simply ends the function if the value of %@AS@% count %@AE@%
  1601. exceeds 500:  %@NL@%
  1602. %@NL@%
  1603. %@AS@%  if( count > 500 )
  1604. %@AS@%     return;
  1605. %@AS@%  else
  1606. %@AS@%     /* execute more statements... */%@AE@%%@NL@%
  1607. %@NL@%
  1608. A %@AB@%return%@AE@% statement ends the function immediately, no matter where it
  1609. appears. In the function shown below, the statements following the %@AB@%return%@AE@%
  1610. never execute:  %@NL@%
  1611. %@NL@%
  1612. %@AS@%  void do_nothing( void )
  1613. %@AS@%  {
  1614. %@AS@%     return;
  1615. %@AS@%     /* The following statements do not execute */
  1616. %@AS@%     printf( "This function " );
  1617. %@AS@%     printf( "prints nothing.\n" );
  1618. %@AS@%  }%@AE@%%@NL@%
  1619. %@NL@%
  1620. If a function doesn't return a value, and you want the function to end by
  1621. falling off its closing brace, no %@AB@%return%@AE@% statement is needed. This method is
  1622. used to end the %@AS@% beep %@AE@% function in BEEPER.C, discussed earlier in this
  1623. chapter:  %@NL@%
  1624. %@NL@%
  1625. %@AS@%  void beep( void )
  1626. %@AS@%  {
  1627. %@AS@%     printf( "Beep!\a\n" );
  1628. %@AS@%  }%@AE@%%@NL@%
  1629. %@NL@%
  1630. You could add a %@AB@%return%@AE@% to the end of this function, but it's not necessary.
  1631. The function ends automatically.  %@NL@%
  1632. %@NL@%
  1633. %@NL@%
  1634. %@2@%%@CR:C6A00020012 @%%@AB@%Using Return Values%@AE@%%@EH@%%@NL@%
  1635. %@NL@%
  1636. %@AU@% Function return values are  often assigned to variables.%@AE@%  %@NL@%
  1637. %@NL@%
  1638. A function's return value can be used in the same way you would use any
  1639. value of its type. In the VOLUME.C program from Chapter 1, "Anatomy of a C
  1640. Program," the statement that calls %@AS@% sphere %@AE@% assigns the function's return
  1641. value to the variable %@AS@% volume%@AE@%:  %@NL@%
  1642. %@NL@%
  1643. %@AS@%  volume = sphere( radius );%@AE@%%@NL@%
  1644. %@NL@%
  1645. If there's no need to save the return value, you can use it directly. You
  1646. may have noticed that the variable %@AS@% volume %@AE@% isn't really needed in the
  1647. VOLUME.C program, which simply prints the variable's value and ends. Most
  1648. programmers would make the program more compact by replacing the two
  1649. statements  %@NL@%
  1650. %@NL@%
  1651. %@AS@%  volume = sphere( radius );
  1652. %@AS@%  printf( "Volume: %f\n", volume );%@AE@%%@NL@%
  1653. %@NL@%
  1654. with this one:  %@NL@%
  1655. %@NL@%
  1656. %@AS@%  printf( "Volume: %f\n", sphere( radius ) );%@AE@%%@NL@%
  1657. %@NL@%
  1658. The second version puts the %@AS@% sphere %@AE@% function call right in the %@AB@%printf%@AE@%
  1659. statement, eliminating the superfluous variable. Instead of assigning the
  1660. return value to a variable and passing that variable's value to %@AB@%printf%@AE@%, the
  1661. statement uses the value directly. (The %@AS@% sphere %@AE@% function is called first.
  1662. Then the return value from %@AS@% sphere %@AE@% is passed as an argument to the %@AB@%printf%@AE@%
  1663. function.)  %@NL@%
  1664. %@NL@%
  1665. While this change streamlines the program, it also makes the code a little
  1666. harder to follow. If you don't read carefully, you might overlook the fact
  1667. that the %@AB@%printf%@AE@% function call contains another function call.  %@NL@%
  1668. %@NL@%
  1669. %@AU@% Unused return values  are discarded.%@AE@%  %@NL@%
  1670. %@NL@%
  1671. Occasionally, you may have no use for a function's return value. The %@AB@%printf%@AE@%
  1672. function, for example, returns the number of characters it displayed, but
  1673. few programs need this information. If you don't use a return value, it's
  1674. discarded.  %@NL@%
  1675. %@NL@%
  1676. You should never ignore the error codes that library functions return to
  1677. show whether the function succeeded. See Chapter 10, "Programming Pitfalls,"
  1678. for more information about library function return values.  %@NL@%
  1679. %@NL@%
  1680. %@NL@%
  1681. %@2@%%@CR:C6A00020013 @%%@AB@%Declaring a Function's Return Type%@AE@%%@EH@%%@NL@%
  1682. %@NL@%
  1683. Thus far, we have explained how a function can return a value─and how the
  1684. calling statement can use that value─without paying much attention to what
  1685. type of value the function returns. (The C language supports various data
  1686. types, such as %@AB@%int%@AE@% for integer values, and %@AB@%float%@AE@% for floating-point values.
  1687. Chapter 4 describes data types in detail.)  %@NL@%
  1688. %@NL@%
  1689. The return type is important because it controls what the function returns.
  1690. If a function returns an integer when you expect a floating-point value,
  1691. your program may not work correctly.  %@NL@%
  1692. %@NL@%
  1693. %@AU@% A function's prototype and definition control what  type of value it
  1694. %@AU@%returns.%@AE@%  %@NL@%
  1695. %@NL@%
  1696. The function's return type is specified in its prototype and definition.
  1697. Below are the prototype and definition of the %@AS@% sphere %@AE@% function from the
  1698. VOLUME.C program in Chapter 1, "Anatomy of a C Program." They specify that
  1699. the function returns a %@AB@%float%@AE@% value.  %@NL@%
  1700. %@NL@%
  1701. %@AS@%  float sphere( int rad );  /* function prototype */
  1702. %@AS@%  
  1703. %@AS@%  float sphere( int rad )   /* function header */%@AE@%%@NL@%
  1704. %@NL@%
  1705. The type name (here, %@AB@%float%@AE@%) in front of the function name shows what type of
  1706. value the function returns. If the %@AS@% sphere %@AE@% function returned an %@AB@%int%@AE@% value,
  1707. its prototype and header would look like this:  %@NL@%
  1708. %@NL@%
  1709. %@AS@%  int sphere( int rad ); /* function prototype */
  1710. %@AS@%  
  1711. %@AS@%  int sphere( int rad )  /* function header */%@AE@%%@NL@%
  1712. %@NL@%
  1713. %@AU@% Use the void type name  to show a function  returns no value.%@AE@%  %@NL@%
  1714. %@NL@%
  1715. You should declare the return type for every function─even for functions
  1716. that don't return a value. These functions are declared with the %@AB@%void%@AE@% type
  1717. name. In the SHOWME.C program, shown above, the prototype of the %@AS@% showme %@AE@%
  1718. function follows this pattern:  %@NL@%
  1719. %@NL@%
  1720. %@AS@%  void showme( int a, int b, int c );%@AE@%%@NL@%
  1721. %@NL@%
  1722. The %@AB@%void%@AE@% that precedes the function name indicates that %@AS@% showme %@AE@% returns
  1723. nothing.  %@NL@%
  1724. %@NL@%
  1725. %@NL@%
  1726. %@2@%%@CR:C6A00020014 @%%@AB@%Function Prototypes%@AE@%%@EH@%%@NL@%
  1727. %@NL@%
  1728. Function prototyping is the major innovation of the ANSI standard for C. As
  1729. we mentioned earlier, a function prototype gives the same information as the
  1730. function's header: the name of the function, the type of value the function
  1731. returns, and the number and type of parameters the function requires.  %@NL@%
  1732. %@NL@%
  1733. %@AU@%   Function prototypes allow QuickC to check function references for
  1734. %@AU@%accuracy.%@AE@%  %@NL@%
  1735. %@NL@%
  1736. Function prototypes normally appear near the start of the program, before
  1737. the first function definition. Given the information in the prototype,
  1738. QuickC can perform "type checking." It checks each reference to the
  1739. function─its definition, as well as every function call─to make sure that
  1740. the reference uses the right number and type of arguments and the correct
  1741. return value. Without type checking, it's easy to create bugs by passing the
  1742. wrong type of value to a function or assuming the wrong return type.  %@NL@%
  1743. %@NL@%
  1744. C programs normally include one prototype for each function they define,
  1745. except the %@AB@%main%@AE@% function. Most programmers don't bother to prototype %@AB@%main%@AE@%
  1746. unless the program receives command-line arguments or returns a value to DOS
  1747. when it ends. (Command-line arguments are discussed in Chapter 9, "Advanced
  1748. Pointers.")  %@NL@%
  1749. %@NL@%
  1750. Here is the function prototype for the %@AS@% sphere %@AE@% function in VOLUME.C:  %@NL@%
  1751. %@NL@%
  1752. %@AS@%  float sphere( int rad );%@AE@%%@NL@%
  1753. %@NL@%
  1754. You can see that %@AS@% sphere %@AE@% expects a single %@AB@%int%@AE@%-type parameter and returns a
  1755. value of type %@AB@%float%@AE@%. On the other hand, the prototype for %@AS@% showme %@AE@% in
  1756. SHOWME.C indicates that %@AS@% showme %@AE@% expects three %@AB@%int%@AE@%-type parameters and
  1757. returns nothing:  %@NL@%
  1758. %@NL@%
  1759. %@AS@%  void showme( int a, int b, int c );%@AE@%%@NL@%
  1760. %@NL@%
  1761. It's common to use the same parameter names in both the function prototype
  1762. and the function header. In SHOWME.C, for instance, the %@AS@% showme %@AE@% function
  1763. prototype,  %@NL@%
  1764. %@NL@%
  1765. %@AS@%  void showme( int a, int b, int c );%@AE@%%@NL@%
  1766. %@NL@%
  1767. uses the names %@AS@% a%@AE@%, %@AS@% b%@AE@%, and %@AS@% c%@AE@%, as does the header for that function,  %@NL@%
  1768. %@NL@%
  1769. %@AS@%  void showme( int a, int b, int c )%@AE@%%@NL@%
  1770. %@NL@%
  1771. Using the same names in both parameter lists makes the program more
  1772. readable, but it's not a language requirement. The names in the prototype's
  1773. parameter list are merely cosmetic. You can use any names you choose, or
  1774. even omit the names completely. The prototype in SHOWME.C works just as well
  1775. when written  %@NL@%
  1776. %@NL@%
  1777. %@AS@%  void showme( int, int, int );%@AE@%%@NL@%
  1778. %@NL@%
  1779. as when you supply the names %@AS@% a%@AE@%, %@AS@% b%@AE@%, and %@AS@% c%@AE@%. Both versions fully specify the
  1780. number (three) and type (%@AB@%int%@AE@%) of the parameters the function expects.  %@NL@%
  1781. %@NL@%
  1782. %@NL@%
  1783. %@3@%%@CR:C6A00020015 @%%@AB@%Prototyping Functions without Parameters%@AE@%%@EH@%%@NL@%
  1784. %@NL@%
  1785. If a function doesn't expect any parameters, you might be tempted to leave
  1786. its parameter list blank. But it's better to put %@AB@%void%@AE@% in its parameter list,
  1787. as shown here:  %@NL@%
  1788. %@NL@%
  1789. %@AS@%  void beep( void );%@AE@%%@NL@%
  1790. %@NL@%
  1791. The %@AB@%void%@AE@% in parentheses specifies that the %@AS@% beep %@AE@% function requires no
  1792. parameters. If you leave the parentheses empty, the compiler draws no
  1793. conclusion about what parameters the function takes and won't be able to
  1794. detect an error if you mistakenly pass an argument to the function.  %@NL@%
  1795. %@NL@%
  1796. %@NL@%
  1797. %@3@%%@CR:C6A00020016 @%%@AB@%Prototyping Functions with Variable Parameters%@AE@%%@EH@%%@NL@%
  1798. %@NL@%
  1799. Some functions, such as the %@AB@%printf%@AE@% library function, can handle a variable
  1800. number of parameters. This capability can make functions more flexible. As
  1801. earlier examples have shown, the %@AB@%printf%@AE@% function can take one parameter or
  1802. several, depending on how many values you need to print.  %@NL@%
  1803. %@NL@%
  1804. To declare a function with a variable number of parameters, end the
  1805. parameter list with a comma and an ellipsis (%@AS@%, . . .%@AE@%). The following
  1806. prototype, for example, declares that the %@AS@% sample %@AE@% function expects at least
  1807. one %@AB@%int%@AE@%-type parameter and zero or more additional parameters:  %@NL@%
  1808. %@NL@%
  1809. %@AS@%  void sample( int a,... );%@AE@%%@NL@%
  1810. %@NL@%
  1811. The ellipsis stands for an unspecified number of parameters with types that
  1812. are also unspecified. The parameter list in the function header should
  1813. follow the same pattern.  %@NL@%
  1814. %@NL@%
  1815. Don't declare a variable number of parameters unless it's necessary. Giving
  1816. this sort of prototype for a function that takes a fixed number of
  1817. parameters defeats the prototype's main purpose. QuickC can't perform type
  1818. checking for parameters you leave out of a prototype.  %@NL@%
  1819. %@NL@%
  1820. %@NL@%
  1821. %@2@%%@CR:C6A00020017 @%%@AB@%Old-Style Function Declarations and Definitions%@AE@%%@EH@%%@NL@%
  1822. %@NL@%
  1823. This book explains how to declare and define functions under the ANSI
  1824. standard for C, which is now the norm. The original C language used slightly
  1825. different rules for function declarations and definitions. QuickC can
  1826. compile these "oldstyle" programs, but the ANSI standard recommends you use
  1827. the full function prototypes we just described.  %@NL@%
  1828. %@NL@%
  1829. Still, you may encounter old-style function declarations and definitions in
  1830. many existing C programs. So, you should be familiar with the style.  %@NL@%
  1831. %@NL@%
  1832. We'll use the VOLUME.C program from Chapter 1, "Anatomy of a C Program," to
  1833. demonstrate the old style. First, here's the ANSI-style program presented in
  1834. Chapter 1:  %@NL@%
  1835. %@NL@%
  1836. %@AS@%  /* VOLUME.C: Calculate sphere's volume. */
  1837. %@AS@%  #include <stdio.h>
  1838. %@AS@%  #define PI 3.14
  1839. %@AS@%  
  1840. %@AS@%  float sphere( int rad );
  1841. %@AS@%  
  1842. %@AS@%  main()
  1843. %@AS@%  {
  1844. %@AS@%     float volume;
  1845. %@AS@%     int radius = 3;
  1846. %@AS@%     volume = sphere( radius );
  1847. %@AS@%     printf( "Volume: %f\n", volume );
  1848. %@AS@%  }
  1849. %@AS@%  
  1850. %@AS@%  float sphere( int rad )
  1851. %@AS@%  {
  1852. %@AS@%     float result;
  1853. %@AS@%     result = rad * rad * rad;
  1854. %@AS@%     result = 4 * PI * result;
  1855. %@AS@%     result = result / 3;
  1856. %@AS@%     return result;
  1857. %@AS@%  }%@AE@%%@NL@%
  1858. %@NL@%
  1859. The same program written in the old style would look something like this:  %@NL@%
  1860. %@NL@%
  1861. %@AS@%  /* OLDSTYLE.C: Old-style function. */
  1862. %@AS@%  
  1863. %@AS@%  #include <stdio.h>
  1864. %@AS@%  #define PI 3.14
  1865. %@AS@%  
  1866. %@AS@%  float sphere();
  1867. %@AS@%  
  1868. %@AS@%  main()
  1869. %@AS@%  {
  1870. %@AS@%     float volume;
  1871. %@AS@%     int radius = 3;
  1872. %@AS@%     volume = sphere( radius );
  1873. %@AS@%     printf( "Volume: %f\n", volume );
  1874. %@AS@%  }
  1875. %@AS@%  
  1876. %@AS@%  float sphere( rad )
  1877. %@AS@%  int rad;
  1878. %@AS@%  {
  1879. %@AS@%     float result;
  1880. %@AS@%     result = rad * rad * rad;
  1881. %@AS@%     result = 4 * PI * result;
  1882. %@AS@%     result = result / 3;
  1883. %@AS@%     return result;
  1884. %@AS@%  }%@AE@%%@NL@%
  1885. %@NL@%
  1886. You'll notice two distinct differences. First, the old style doesn't allow a
  1887. parameter list in the function declaration. In the ANSI version, VOLUME.C,
  1888. the declaration of the %@AS@% sphere %@AE@% function specifies that the function takes a
  1889. single %@AB@%int%@AE@% parameter:  %@NL@%
  1890. %@NL@%
  1891. %@AS@%  float sphere( int rad );%@AE@%%@NL@%
  1892. %@NL@%
  1893. The corresponding declaration in OLDSTYLE.C omits the parameter list:  %@NL@%
  1894. %@NL@%
  1895. %@AS@%  float sphere();%@AE@%%@NL@%
  1896. %@NL@%
  1897. An old-style function declaration cannot provide any information about the
  1898. function's parameters.  %@NL@%
  1899. %@NL@%
  1900. The other change is in the way the function definition lists parameters. In
  1901. VOLUME.C, the function header lists the same information as the function
  1902. prototype, giving the type (%@AB@%int%@AE@%) and name (%@AS@% rad %@AE@%) of the function's
  1903. parameter:  %@NL@%
  1904. %@NL@%
  1905. %@AS@%  float sphere( int rad )
  1906. %@AS@%  {
  1907. %@AS@%     .
  1908. %@AS@%     .
  1909. %@AS@%     .
  1910. %@AS@%  }%@AE@%%@NL@%
  1911. %@NL@%
  1912. In OLDSTYLE.C, the function header gives the parameter's name (%@AS@% rad %@AE@%), but
  1913. not its type. The parameter's type is declared in a statement directly below
  1914. the function header (and before the left brace that begins the function
  1915. body):  %@NL@%
  1916. %@NL@%
  1917. %@AS@%  float sphere( rad )
  1918. %@AS@%  int rad;
  1919. %@AS@%  {
  1920. %@AS@%     .
  1921. %@AS@%     .
  1922. %@AS@%     .
  1923. %@AS@%  }%@AE@%%@NL@%
  1924. %@NL@%
  1925. The rest of OLDSTYLE.C is identical to VOLUME.C.  %@NL@%
  1926. %@NL@%
  1927. Now that you understand the basics of functions, we can turn our attention
  1928. to the C statements that a function can contain, beginning with flow-control
  1929. statements, the subject of the next chapter.  %@NL@%
  1930. %@NL@%
  1931. %@NL@%
  1932. %@NL@%
  1933. %@NL@%
  1934. %@NL@%
  1935. %@NL@%
  1936. %@CR:C6A00030001 @%%@1@%%@AB@%Chapter 3  Flow Control%@AE@%%@EH@%%@NL@%
  1937. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  1938. %@NL@%
  1939. Flow control─diverting execution by looping and branching─is one area where
  1940. C closely resembles other languages. If you know how to loop and branch in
  1941. QuickBASIC or QuickPascal, learning the C equivalents is mainly a matter of
  1942. adjusting to somewhat different syntax. Here, as elsewhere, C never uses two
  1943. keywords when one will do. For instance, C has no "then" keyword. Instead,
  1944. it uses simple punctuation.  %@NL@%
  1945. %@NL@%
  1946. This chapter has two parts. The first part examines the looping statements:
  1947. %@AB@%while%@AE@%, %@AB@%do%@AE@%, and %@AB@%for%@AE@%. The second part describes the decision-making
  1948. statements: %@AB@%if%@AE@%, %@AB@%else%@AE@%, %@AB@%switch%@AE@%, %@AB@%break%@AE@%, %@AB@%continue%@AE@%, and %@AB@%goto%@AE@%.  %@NL@%
  1949. %@NL@%
  1950. %@NL@%
  1951. %@2@%%@CR:C6A00030002 @%%@AB@%Loops: while, do, and for%@AE@%%@EH@%%@NL@%
  1952. %@NL@%
  1953. This section discusses the C statements that create loops: %@AB@%while%@AE@%, %@AB@%do%@AE@%, and
  1954. %@AB@%for%@AE@%. These loops repeat while a condition is true or for a set number of
  1955. times. We'll begin with the simplest loop, the %@AB@%while%@AE@% statement.  %@NL@%
  1956. %@NL@%
  1957. %@NL@%
  1958. %@3@%%@CR:C6A00030003 @%%@AB@%The while Statement%@AE@%%@EH@%%@NL@%
  1959. %@NL@%
  1960. %@AU@%    A while loop evaluates its test expression before executing the body of
  1961. %@AU@%the loop.%@AE@%  %@NL@%
  1962. %@NL@%
  1963. A %@AB@%while%@AE@% loop repeats as long as a given condition remains true. It consists
  1964. of the %@AB@%while%@AE@% keyword followed by a test expression in parentheses and a loop
  1965. body, as shown in Figure 3.1. The "test expression" can be any C expression
  1966. and is evaluated before the loop body is executed. The loop body is a single
  1967. statement or a statement block that executes once every time the loop is
  1968. iterated. The distinguishing feature of a %@AB@%while%@AE@% loop is that it evaluates
  1969. the test expression before it executes the loop body, unlike the %@AB@%do%@AE@% loop,
  1970. which we'll examine next.  %@NL@%
  1971. %@NL@%
  1972. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  1973. %@NL@%
  1974. We've incorporated the simple %@AB@%while%@AE@% loop from Figure 3.1 in the WHILE.C
  1975. program, shown below.  %@NL@%
  1976. %@NL@%
  1977. %@AS@%  /* WHILE.C: Demonstrate while loop. */
  1978. %@AS@%  
  1979. %@AS@%  #include <stdio.h>
  1980. %@AS@%  
  1981. %@AS@%  main()
  1982. %@AS@%  {
  1983. %@AS@%     int test = 10;
  1984. %@AS@%  
  1985. %@AS@%     while( test > 0 )
  1986. %@AS@%     {
  1987. %@AS@%        printf( "test = %d\n", test );
  1988. %@AS@%        test = test - 2;
  1989. %@AS@%     }
  1990. %@AS@%  }%@AE@%%@NL@%
  1991. %@NL@%
  1992. Here is the output from WHILE.C:  %@NL@%
  1993. %@NL@%
  1994. %@AS@%  test = 10
  1995. %@AS@%  test = 8
  1996. %@AS@%  test = 6
  1997. %@AS@%  test = 4
  1998. %@AS@%  test = 2%@AE@%%@NL@%
  1999. %@NL@%
  2000. In WHILE.C, if the variable %@AS@% test %@AE@% is positive when the loop begins, the
  2001. test expression evaluates as true and the loop executes. If %@AS@% test %@AE@% has a 0
  2002. or negative value when the loop starts, the test expression is false; the
  2003. loop body does not execute and the action falls through to the statement
  2004. that follows the loop.  %@NL@%
  2005. %@NL@%
  2006. (Chapter 6, "Operators," explains true and false values. For now, it's
  2007. enough to know that an expression is evaluated as false if it equals 0. Any
  2008. nonzero value is true.)  %@NL@%
  2009. %@NL@%
  2010. The loop body in WHILE.C happens to be a statement block enclosed in braces.
  2011. If the loop body is a single statement, as in the following code, no braces
  2012. are needed.  %@NL@%
  2013. %@NL@%
  2014. %@AS@%  main()
  2015. %@AS@%  {
  2016. %@AS@%     int test = 10;
  2017. %@AS@%     while( test > 0 )
  2018. %@AS@%        test = test - 2;
  2019. %@AS@%  }%@AE@%%@NL@%
  2020. %@NL@%
  2021. Occasionally, you'll see a %@AB@%while%@AE@% loop with a test expression such as  %@NL@%
  2022. %@NL@%
  2023. %@AS@%  while( 1 )%@AE@%%@NL@%
  2024. %@NL@%
  2025. or  %@NL@%
  2026. %@NL@%
  2027. %@AS@%  #define TRUE 1
  2028. %@AS@%     .
  2029. %@AS@%     .
  2030. %@AS@%     .
  2031. %@AS@%  while( TRUE )%@AE@%%@NL@%
  2032. %@NL@%
  2033. The test expressions above are always true, creating an indefinite loop that
  2034. never ends naturally. You can only terminate this kind of loop with some
  2035. overt action, usually by executing a %@AB@%break%@AE@% statement. (See "The break
  2036. Statement" later in this chapter.) You can use such a loop to repeat an
  2037. action for an indefinite time period─until a certain key is pressed, for
  2038. instance.  %@NL@%
  2039. %@NL@%
  2040. %@NL@%
  2041. %@3@%%@CR:C6A00030004 @%%@AB@%The do Statement%@AE@%%@EH@%%@NL@%
  2042. %@NL@%
  2043. A %@AB@%do%@AE@% loop is simply a %@AB@%while%@AE@% loop turned on its head. First comes the loop
  2044. body, then the test expression. Unlike a %@AB@%while%@AE@% loop, a %@AB@%do%@AE@% loop always
  2045. executes its loop body at least once.  %@NL@%
  2046. %@NL@%
  2047. %@AU@%   A do loop always executes at least once.%@AE@%  %@NL@%
  2048. %@NL@%
  2049. The difference is important. A %@AB@%while%@AE@% statement evaluates the test expression
  2050. before it executes the loop body. If the test expression in a %@AB@%while%@AE@%
  2051. statement is false, the loop body doesn't execute at all. A %@AB@%do%@AE@% statement, on
  2052. the other hand, evaluates the test expression after executing the loop body.
  2053. Thus, the body of a %@AB@%do%@AE@% statement always executes at least once, even if the
  2054. test expression is false when the loop begins.  %@NL@%
  2055. %@NL@%
  2056. Figure 3.2 contrasts the %@AB@%while%@AE@% loop from WHILE.C with a comparable %@AB@%do%@AE@% loop
  2057. to emphasize this difference. You'll notice that the %@AB@%do%@AE@% keyword comes right
  2058. before the loop body, which is followed by the %@AB@%while%@AE@% keyword and a test
  2059. expression─the same test expression that WHILE.C uses. Notice the semicolon
  2060. that ends the %@AB@%do%@AE@% loop. A %@AB@%do%@AE@% loop always ends with a semicolon; a %@AB@%while%@AE@% loop
  2061. never does.  %@NL@%
  2062. %@NL@%
  2063. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  2064. %@NL@%
  2065. The DO.C program below uses the %@AB@%do%@AE@% loop from Figure 3.2 to perform the same
  2066. action that WHILE.C does.  %@NL@%
  2067. %@NL@%
  2068. %@AS@%  /* DO.C: Demonstrate do loop. */
  2069. %@AS@%  
  2070. %@AS@%  #include <stdio.h>
  2071. %@AS@%  
  2072. %@AS@%  main()
  2073. %@AS@%  {
  2074. %@AS@%     int test = 10;
  2075. %@AS@%     do
  2076. %@AS@%     {
  2077. %@AS@%        printf( "test = %d\n", test );
  2078. %@AS@%        test = test - 2;
  2079. %@AS@%     }  while( test > 0 );
  2080. %@AS@%  }%@AE@%%@NL@%
  2081. %@NL@%
  2082. DO.C gives the same output as WHILE.C:  %@NL@%
  2083. %@NL@%
  2084. %@AS@%  test = 10
  2085. %@AS@%  test = 8
  2086. %@AS@%  test = 6
  2087. %@AS@%  test = 4
  2088. %@AS@%  test = 2%@AE@%%@NL@%
  2089. %@NL@%
  2090. The programs do not give the same output if you modify them so that the
  2091. value of %@AS@% test %@AE@% is 0 when the loop starts. In that case, the loop body in
  2092. DO.C executes once, but the loop body in WHILE.C doesn't execute at all. You
  2093. should only use a %@AB@%do%@AE@% loop when you always want the loop body to execute at
  2094. least once.  %@NL@%
  2095. %@NL@%
  2096. %@NL@%
  2097. %@3@%%@CR:C6A00030005 @%%@AB@%The for Statement%@AE@%%@EH@%%@NL@%
  2098. %@NL@%
  2099. As in QuickBASIC or QuickPascal, the %@AB@%for%@AE@% statement in C is often used to
  2100. repeat a statement a set number of times. Let's begin with a simple example.
  2101. The FORLOOP.C program, shown below, uses %@AB@%for%@AE@% to repeat a %@AB@%printf%@AE@% statement
  2102. five times.  %@NL@%
  2103. %@NL@%
  2104. %@AS@%  /* FORLOOP.C: Demonstrate for loop. */
  2105. %@AS@%  
  2106. %@AS@%  #include <stdio.h>
  2107. %@AS@%  
  2108. %@AS@%  main()
  2109. %@AS@%  {
  2110. %@AS@%     int test;
  2111. %@AS@%     for( test = 10; test > 0; test = test - 2 )
  2112. %@AS@%        printf( "test = %d\n", test );
  2113. %@AS@%  }%@AE@%%@NL@%
  2114. %@NL@%
  2115. FORLOOP.C gives the same output as WHILE.C and DO.C:  %@NL@%
  2116. %@NL@%
  2117. %@AS@%  test = 10
  2118. %@AS@%  test = 8
  2119. %@AS@%  test = 6
  2120. %@AS@%  test = 4
  2121. %@AS@%  test = 2%@AE@%%@NL@%
  2122. %@NL@%
  2123. Figure 3.3 shows the parts of the %@AB@%for%@AE@% loop in FORLOOP.C.  %@NL@%
  2124. %@NL@%
  2125. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  2126. %@NL@%
  2127. A %@AB@%for%@AE@% statement is more complex than a %@AB@%while%@AE@% or %@AB@%do%@AE@% statement. The part in
  2128. parentheses can contain three expressions separated by semicolons:  %@NL@%
  2129. %@NL@%
  2130. %@NL@%
  2131.   ■   An "initializing expression" that often initializes a loop counter%@NL@%
  2132. %@NL@%
  2133.   ■   A "test expression" that states how long the loop continues%@NL@%
  2134. %@NL@%
  2135.   ■   A "modifying expression" that often modifies a loop counter%@NL@%
  2136. %@NL@%
  2137. %@NL@%
  2138. Like the test expression in a %@AB@%while%@AE@% statement, the test expression in a %@AB@%for%@AE@%
  2139. statement causes the loop to continue as long as the test expression
  2140. evaluates as true.  %@NL@%
  2141. %@NL@%
  2142. All of the expressions in the parentheses of a %@AB@%for%@AE@% statement are optional.
  2143. If you omit the test expression (the second one), the statement repeats
  2144. indefinitely. In the following program, for instance, all of the expressions
  2145. in the parentheses of the %@AB@%for%@AE@% loop are empty:  %@NL@%
  2146. %@NL@%
  2147. %@AS@%  main()
  2148. %@AS@%  {
  2149. %@AS@%     for( ; ; )
  2150. %@AS@%        printf( "Hi, Mom!\n" );
  2151. %@AS@%  }%@AE@%%@NL@%
  2152. %@NL@%
  2153. The loop above repeats indefinitely because it has no test expression that
  2154. specifies when to end the loop. It has the same effect as the following
  2155. %@AB@%while%@AE@% loop, whose test expression is always true:  %@NL@%
  2156. %@NL@%
  2157. %@AS@%  main()
  2158. %@AS@%  {
  2159. %@AS@%     while( 1 )
  2160. %@AS@%        printf( "Hi, Mom!\n" );
  2161. %@AS@%  }%@AE@%%@NL@%
  2162. %@NL@%
  2163. You can use multiple expressions for either the initializing expression or
  2164. the modifying expression, as in FORLOOP1.C:  %@NL@%
  2165. %@NL@%
  2166. %@AS@%  /* FORLOOP1.C: Demonstrate multiple expressions. */
  2167. %@AS@%  
  2168. %@AS@%  #include <stdio.h>
  2169. %@AS@%  
  2170. %@AS@%  main()
  2171. %@AS@%  {
  2172. %@AS@%     int a, b;
  2173. %@AS@%     for( a = 256, b = 1; b < 512; a = a / 2, b = b * 2 )
  2174. %@AS@%        printf( "a = %d  b = %d\n", a, b );
  2175. %@AS@%  }%@AE@%%@NL@%
  2176. %@NL@%
  2177. The output from FORLOOP1.C appears below:  %@NL@%
  2178. %@NL@%
  2179. %@AS@%  a = 256  b = 1
  2180. %@AS@%  a = 128  b = 2
  2181. %@AS@%  a = 64  b = 4
  2182. %@AS@%  a = 32  b = 8
  2183. %@AS@%  a = 16  b = 16
  2184. %@AS@%  a = 8    b = 32
  2185. %@AS@%  a = 4    b = 64
  2186. %@AS@%  a = 2    b = 128
  2187. %@AS@%  a = 1    b = 256%@AE@%%@NL@%
  2188. %@NL@%
  2189. In the FORLOOP1.C program, the initializing expression of the %@AB@%for%@AE@% loop
  2190. initializes two variables (%@AS@% a %@AE@% and %@AS@% b %@AE@%) instead of one. The modifying
  2191. expression changes the values of the same two variables. Use commas to
  2192. separate multiple expressions in cases such as this.  %@NL@%
  2193. %@NL@%
  2194. Although %@AB@%for%@AE@% and %@AB@%while%@AE@% might seem quite different, they're interchangeable
  2195. in most cases. The FORLOOP2.C program demonstrates this principle. Both
  2196. loops, while constructed differently, produce the same effect─printing the
  2197. numbers from 0 through 9.  %@NL@%
  2198. %@NL@%
  2199. %@AS@%  /* FORLOOP2.C: Demonstrate similarity of for and while. */
  2200. %@AS@%  
  2201. %@AS@%  #include <stdio.h>
  2202. %@AS@%  
  2203. %@AS@%  main()
  2204. %@AS@%  {
  2205. %@AS@%     int count;
  2206. %@AS@%  
  2207. %@AS@%     for( count = 0; count < 10; count = count + 1 )
  2208. %@AS@%        printf( "count = %d\n", count );
  2209. %@AS@%  
  2210. %@AS@%     count = 0;
  2211. %@AS@%     while( count < 10 )
  2212. %@AS@%     {
  2213. %@AS@%        printf( "count = %d\n", count );
  2214. %@AS@%        count = count +1;
  2215. %@AS@%     }
  2216. %@AS@%  
  2217. %@AS@%  }%@AE@%%@NL@%
  2218. %@NL@%
  2219. The two loops in FORLOOP2.C function identically. The %@AB@%for%@AE@% loop prints the
  2220. numbers from 0 through 9:  %@NL@%
  2221. %@NL@%
  2222. %@AS@%  for( count = 0; count < 10; count = count + 1; )
  2223. %@AS@%     printf( "count = %d\n", count );%@AE@%%@NL@%
  2224. %@NL@%
  2225. as does the %@AB@%while%@AE@% loop:  %@NL@%
  2226. %@NL@%
  2227. %@AS@%  count = 0;
  2228. %@AS@%  while( count < 10 )
  2229. %@AS@%  {
  2230. %@AS@%     printf( "count = %d\n", count );
  2231. %@AS@%     count = count + 1;
  2232. %@AS@%  }%@AE@%%@NL@%
  2233. %@NL@%
  2234. Most programmers prefer %@AB@%for%@AE@% over %@AB@%while%@AE@% in a case like this, because %@AB@%for%@AE@%
  2235. groups all the loop-control statements in one place. The %@AB@%for%@AE@% statement is
  2236. also appropriate when you need to initialize one or more values at the
  2237. beginning of the loop. The %@AB@%while%@AE@% and %@AB@%do%@AE@% statements are more appropriate for
  2238. cases in which the value used in the test expression has already been
  2239. initialized.  %@NL@%
  2240. %@NL@%
  2241. %@NL@%
  2242. %@2@%%@CR:C6A00030006 @%%@AB@%Decision-Making Statements: if, else, switch, break, continue, and goto%@AE@%%@EH@%%@NL@%
  2243. %@NL@%
  2244. The C language provides six statements for decision making: %@AB@%if%@AE@%, %@AB@%else%@AE@%,
  2245. %@AB@%switch%@AE@%, %@AB@%break%@AE@%, %@AB@%continue%@AE@%, and %@AB@%goto%@AE@%. Like their counterparts in other
  2246. languages, these statements transfer control based on the outcome of a
  2247. logical test.  %@NL@%
  2248. %@NL@%
  2249. %@NL@%
  2250. %@3@%%@CR:C6A00030007 @%%@AB@%The if Statement%@AE@%%@EH@%%@NL@%
  2251. %@NL@%
  2252. %@AU@% The body of an if statement executes when its test expression is true.%@AE@%  %@NL@%
  2253. %@NL@%
  2254. An %@AB@%if%@AE@% statement consists of the %@AB@%if%@AE@% keyword followed by a test expression in
  2255. parentheses and a second statement. The second statement is executed if the
  2256. test expression is true, or skipped if the expression is false.  %@NL@%
  2257. %@NL@%
  2258. The IFF.C program contains a simple %@AB@%if%@AE@% test. It prints a prompt and waits
  2259. for you to press a key.  %@NL@%
  2260. %@NL@%
  2261. %@AS@%  /* IFF.C: Demonstrate if statement. */
  2262. %@AS@%  
  2263. %@AS@%  #include <stdio.h>
  2264. %@AS@%  #include <conio.h>
  2265. %@AS@%  
  2266. %@AS@%  main()
  2267. %@AS@%  {
  2268. %@AS@%     char ch;
  2269. %@AS@%     printf( "Press the b key to hear a bell.\n" );
  2270. %@AS@%     ch = getch();
  2271. %@AS@%     if( ch == 'b' )
  2272. %@AS@%        printf( "Beep!\a\n" );
  2273. %@AS@%  }%@AE@%%@NL@%
  2274. %@NL@%
  2275. In the IFF.C program, the statement  %@NL@%
  2276. %@NL@%
  2277. %@AS@%  ch = getch();%@AE@%%@NL@%
  2278. %@NL@%
  2279. calls the %@AB@%getch%@AE@% library function to get a keypress from the keyboard and
  2280. then assigns the result to the variable %@AS@% ch%@AE@%. If you press the b key, the
  2281. program prints  %@NL@%
  2282. %@NL@%
  2283. %@AS@%  Beep!%@AE@%%@NL@%
  2284. %@NL@%
  2285. and sounds a beep. (To simplify the code, IFF.C tests only for a lowercase b
  2286. character. A program would normally use a library function such as %@AB@%tolower%@AE@%
  2287. to test for both upper and lowercase.)  %@NL@%
  2288. %@NL@%
  2289. Figure 3.4 illustrates the parts of the %@AB@%if%@AE@% statement in the IFF.C program.  %@NL@%
  2290. %@NL@%
  2291. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  2292. %@NL@%
  2293. The test expression of the %@AB@%if%@AE@% statement  %@NL@%
  2294. %@NL@%
  2295. %@AS@%  ch == 'b'%@AE@%%@NL@%
  2296. %@NL@%
  2297. %@AU@% The equality operator (==) tests if values are equal.%@AE@%  %@NL@%
  2298. %@NL@%
  2299. is true when the variable %@AS@% ch %@AE@% equals the letter b. In C the equality
  2300. operator (%@AB@%==%@AE@%) tests if two values are equal. (Chapter 6 discusses
  2301. operators.)  %@NL@%
  2302. %@NL@%
  2303. The body of the %@AB@%if%@AE@% statement in IFF.C happens to be a single statement, but
  2304. the body can also be a statement block, as in the following fragment:  %@NL@%
  2305. %@NL@%
  2306. %@AS@%  if( ch == 'b' )
  2307. %@AS@%  {
  2308. %@AS@%     printf( "Beep!\a\n" );
  2309. %@AS@%     printf( "You pressed the 'b' key\n" );
  2310. %@AS@%  }%@AE@%%@NL@%
  2311. %@NL@%
  2312. You can also nest %@AB@%if%@AE@% statements, as shown below:  %@NL@%
  2313. %@NL@%
  2314. %@AS@%  if( ch == 'b' )
  2315. %@AS@%  {
  2316. %@AS@%     printf( "Beep!\a\n" );
  2317. %@AS@%     beep_count = beepcount + 1;
  2318. %@AS@%     if( beep_count > 10 )
  2319. %@AS@%     {
  2320. %@AS@%        printf( "More than 10 beeps...\n" );
  2321. %@AS@%        if( beep_count > 100 )
  2322. %@AS@%    printf( "Don't wear out the 'b' key!\n" );
  2323. %@AS@%     }
  2324. %@AS@%  }%@AE@%%@NL@%
  2325. %@NL@%
  2326. The code nests three %@AB@%if%@AE@% statements. The first %@AB@%if%@AE@% tests whether %@AS@% ch %@AE@% equals
  2327. the letter b; the second tests whether the variable %@AS@% beep_count %@AE@% is greater
  2328. than 10. The third tests whether %@AS@% beep_count %@AE@% exceeds 100.  %@NL@%
  2329. %@NL@%
  2330. %@NL@%
  2331. %@3@%%@CR:C6A00030008 @%%@AB@%The else Clause%@AE@%%@EH@%%@NL@%
  2332. %@NL@%
  2333. %@AU@% An else clause can follow an if statement.%@AE@%  %@NL@%
  2334. %@NL@%
  2335. The %@AB@%else%@AE@% keyword is used with %@AB@%if%@AE@% to form an either-or construct that
  2336. executes one statement when an expression is true and another when it's
  2337. false. The ELSE.C program demonstrates %@AB@%else%@AE@% by adding an %@AB@%else%@AE@% clause to the
  2338. code from IFF.C. It sounds a beep and prints %@AS@% Beep! %@AE@% if you type the letter
  2339. b, or it prints %@AS@% Bye bye %@AE@% if you type any other letter.  %@NL@%
  2340. %@NL@%
  2341. %@AS@%  /* ELSE.C: Demonstrate else clause. */
  2342. %@AS@%  
  2343. %@AS@%  #include <stdio.h>
  2344. %@AS@%  #include <conio.h>
  2345. %@AS@%  
  2346. %@AS@%  main()
  2347. %@AS@%  {
  2348. %@AS@%     char ch;
  2349. %@AS@%     printf( "Press the b key to hear a bell.\n" );
  2350. %@AS@%     ch = getch();
  2351. %@AS@%     if( ch == 'b' )
  2352. %@AS@%        printf( "Beep!\a\n" );
  2353. %@AS@%     else
  2354. %@AS@%        printf( "Bye bye\n" );
  2355. %@AS@%  }%@AE@%%@NL@%
  2356. %@NL@%
  2357. %@AU@% To create an else-if construct, place an if statement after an else.%@AE@%  %@NL@%
  2358. %@NL@%
  2359. The C language has no "elseif" keyword, but it's easy to create the same
  2360. effect, because the statement that follows %@AB@%else%@AE@% can be any C
  2361. statement─including another %@AB@%if%@AE@% statement. The ELSE1.C program uses %@AB@%if%@AE@% and
  2362. %@AB@%else%@AE@% to test three conditions. It sounds a beep when you type the letter b,
  2363. it prints %@AS@% Enter %@AE@% when you press the ENTER key, or it prints %@AS@% Bye bye %@AE@% when
  2364. you press any other key.  %@NL@%
  2365. %@NL@%
  2366. %@AS@%  /* ELSE1.C: Demonstrate else-if construct. */
  2367. %@AS@%  
  2368. %@AS@%  #include <stdio.h>
  2369. %@AS@%  #include <conio.h>
  2370. %@AS@%  
  2371. %@AS@%  main()
  2372. %@AS@%  {
  2373. %@AS@%     char ch;
  2374. %@AS@%     printf( "Press the b key to hear a bell.\n" );
  2375. %@AS@%     ch = getch();
  2376. %@AS@%     if( ch == 'b' )
  2377. %@AS@%        printf( "Beep!\a\n" );
  2378. %@AS@%     else
  2379. %@AS@%        if( ch == '\r' )
  2380. %@AS@%           printf( "Enter\n" );
  2381. %@AS@%     else
  2382. %@AS@%        printf( "Bye bye\n" );
  2383. %@AS@%  }%@AE@%%@NL@%
  2384. %@NL@%
  2385. The %@AB@%else%@AE@% keyword is tied to the closest preceding %@AB@%if%@AE@% that's not already
  2386. matched by an %@AB@%else%@AE@%. Keep this rule in mind when creating nested %@AB@%if%@AE@%-%@AB@%else%@AE@%
  2387. constructs. (See the section "Mismatching if and else Statements" in Chapter
  2388. 10, "Programming Pitfalls.")  %@NL@%
  2389. %@NL@%
  2390. %@NL@%
  2391. %@3@%%@CR:C6A00030009 @%%@AB@%The switch Statement%@AE@%%@EH@%%@NL@%
  2392. %@NL@%
  2393. %@AU@% The switch statement can perform multiple branches.%@AE@%  %@NL@%
  2394. %@NL@%
  2395. The %@AB@%switch%@AE@% statement offers an elegant option in situations that require
  2396. multiple branches. It tests a single expression that can have several
  2397. values, providing a different action for each value.  %@NL@%
  2398. %@NL@%
  2399. One disadvantage of %@AB@%if%@AE@% and %@AB@%else%@AE@% is that they only allow one branch per
  2400. keyword. The program either executes the statement that follows the %@AB@%if%@AE@% or
  2401. %@AB@%else%@AE@%, or it doesn't. To perform more complex tests, you have to pile on more
  2402. %@AB@%if%@AE@% and %@AB@%else%@AE@% statements, as in the ELSE1.C program above.  %@NL@%
  2403. %@NL@%
  2404. A program that handles keyboard input, for instance, may require several
  2405. different responses to various keypresses. The ELSE1.C program above used
  2406. combinations of %@AB@%if%@AE@% and %@AB@%else%@AE@% to process keyboard input. We've used a single
  2407. %@AB@%switch%@AE@% statement in the SWITCH.C program below to do the same job:  %@NL@%
  2408. %@NL@%
  2409. %@AS@%  /* SWITCH.C: Demonstrate switch statement. */
  2410. %@AS@%  
  2411. %@AS@%  #include <stdio.h>
  2412. %@AS@%  #include <conio.h>
  2413. %@AS@%  
  2414. %@AS@%  main()
  2415. %@AS@%  {
  2416. %@AS@%     char ch;
  2417. %@AS@%     printf( "Press the b key to hear a bell.\n" );
  2418. %@AS@%     ch = getch();
  2419. %@AS@%     switch( ch )
  2420. %@AS@%     {
  2421. %@AS@%        case 'b':
  2422. %@AS@%           printf( "Beep!\a\n" );
  2423. %@AS@%           break;
  2424. %@AS@%        case '\r':
  2425. %@AS@%           printf( "Enter\n" );
  2426. %@AS@%           break;
  2427. %@AS@%        default:
  2428. %@AS@%           printf( "Bye bye" );
  2429. %@AS@%           break;
  2430. %@AS@%     }
  2431. %@AS@%  }%@AE@%%@NL@%
  2432. %@NL@%
  2433. The SWITCH.C program produces the same output as ELSE1.C. Figure 3.5
  2434. illustrates the %@AB@%switch%@AE@% statement in SWITCH.C, comparing it with the %@AB@%if%@AE@%-%@AB@%else%@AE@%
  2435. construct in ELSE1.C.  %@NL@%
  2436. %@NL@%
  2437. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  2438. %@NL@%
  2439. As in other decision-making statements, the parentheses after the keyword
  2440. contain the expression to test. This can be any expression that yields a
  2441. constant value. The test expression in SWITCH.C evaluates the value of the
  2442. variable %@AS@% ch%@AE@%:  %@NL@%
  2443. %@NL@%
  2444. %@AS@%  switch( ch )%@AE@%%@NL@%
  2445. %@NL@%
  2446. %@AU@% The switch statement branches to one of several labeled alternatives.%@AE@%  %@NL@%
  2447. %@NL@%
  2448. The test expression is followed by a statement block enclosed in curly
  2449. braces. The block contains alternate sections of code that you want to
  2450. execute under various circumstances. The program's action branches to one of
  2451. the alternatives, depending on the value of the test expression.  %@NL@%
  2452. %@NL@%
  2453. Each alternative in the statement block starts with a "case label," which
  2454. consists of the %@AB@%case%@AE@% keyword, a constant or constant expression, and a
  2455. colon. (The only other C statement that uses labels is %@AB@%goto%@AE@%, which we'll
  2456. discuss later in this chapter.)  %@NL@%
  2457. %@NL@%
  2458. Below is the first case label in SWITCH.C:  %@NL@%
  2459. %@NL@%
  2460. %@AS@%  case 'b':%@AE@%%@NL@%
  2461. %@NL@%
  2462. This case label lists the character constant %@AS@% 'b'%@AE@%. If the variable %@AS@% ch %@AE@%
  2463. equals %@AS@% 'b'%@AE@%, the program's action branches to this label. If %@AS@% ch %@AE@% equals %@AS@%
  2464. %@AS@%'\r'%@AE@%, the program branches to the following label:  %@NL@%
  2465. %@NL@%
  2466. %@AS@%  case '\r':%@AE@%%@NL@%
  2467. %@NL@%
  2468. The basic effect of %@AB@%switch%@AE@% is similar to the %@AB@%SELECT CASE%@AE@% statement in
  2469. QuickBASIC. The program can branch to many different alternatives, but only
  2470. one at a time.  %@NL@%
  2471. %@NL@%
  2472. A %@AB@%switch%@AE@% statement can have as many %@AB@%case%@AE@% alternatives as you need. Each
  2473. alternative must be labeled with a constant value. (You can't use a variable
  2474. in the label.)  %@NL@%
  2475. %@NL@%
  2476. ────────────────────────────────────────────────────────────────────────────%@NL@%
  2477. NOTE
  2478.  
  2479. %@AI@%In previous versions of QuickC, the constant in a case label could only be a%@AI@%
  2480. %@AI@%%@AE@%%@AI@%%@AB@%char%@AE@%%@AE@%%@AI@% or %@AE@%%@AI@%%@AB@%int%@AE@%%@AE@%%@AI@% value. In QuickC 2.5, the constant can be any integral type,
  2481. %@AI@%including a %@AE@%%@AI@%%@AB@%long%@AE@%%@AE@%%@AI@% or %@AE@%%@AI@%%@AB@%unsigned%@AE@%%@AE@%%@AI@%%@AB@% %@AE@%%@AE@%%@AI@%%@AB@%long%@AE@%%@AE@%%@AI@% as well as a %@AE@%%@AI@%%@AB@%char%@AE@%%@AE@%%@AI@% or %@AE@%%@AI@%%@AB@%int%@AE@%%@AE@%%@AI@%.
  2482. %@AI@%hapter 4, "Data Types," describes the %@AE@%%@AI@%%@AB@%char%@AE@%%@AE@%%@AI@%, %@AE@%%@AI@%%@AB@%int%@AE@%%@AE@%%@AI@%, and %@AE@%%@AI@%%@AB@%long%@AE@%%@AE@%%@AI@% types.%@AE@%%@AE@%%@NL@%
  2483. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  2484. %@NL@%
  2485. %@AU@% The default keyword is used only in switch statements.%@AE@%  %@NL@%
  2486. %@NL@%
  2487. SWITCH.C also shows how to use the %@AB@%default%@AE@% keyword in a %@AB@%switch%@AE@% statement.
  2488. The statements after the %@AB@%default%@AE@% label execute if the value of the test
  2489. expression doesn't equal any of the values listed in other labels. In
  2490. SWITCH.C, the code following %@AB@%default%@AE@% executes when the variable %@AS@% ch %@AE@% equals
  2491. anything other than %@AS@% 'b' %@AE@% or %@AS@% '\r'%@AE@%.  %@NL@%
  2492. %@NL@%
  2493. Not every %@AB@%switch%@AE@% statement requires a %@AB@%default%@AE@% label. If no %@AB@%default%@AE@% is
  2494. present, and the test expression doesn't match any of the values listed in
  2495. the other %@AB@%case%@AE@% labels, no statements are executed.  %@NL@%
  2496. %@NL@%
  2497. %@AU@% Use the break keyword to exit a switch statement.%@AE@%  %@NL@%
  2498. %@NL@%
  2499. You normally place a %@AB@%break%@AE@% statement at the end of each alternative, as
  2500. shown in SWITCH.C. The %@AB@%break%@AE@% statement exits the %@AB@%switch%@AE@% statement block
  2501. immediately. If you don't put a %@AB@%break%@AE@% at the end of the alternative, the
  2502. action falls through to the next statement.  %@NL@%
  2503. %@NL@%
  2504. For instance, say that you remove all the %@AB@%break%@AE@% statements from SWITCH.C, as
  2505. shown below:  %@NL@%
  2506. %@NL@%
  2507. %@AS@%  switch( ch )
  2508. %@AS@%  {
  2509. %@AS@%     case 'b':
  2510. %@AS@%        printf( "Beep!\a\n" );
  2511. %@AS@%     case '\r':
  2512. %@AS@%        printf( "Enter\n" );
  2513. %@AS@%     default:
  2514. %@AS@%        printf( "Bye bye" );
  2515. %@AS@%  }%@AE@%%@NL@%
  2516. %@NL@%
  2517. If you run the revised program and type the letter b, the program executes
  2518. the first alternative, producing this output:  %@NL@%
  2519. %@NL@%
  2520. %@AS@%  Beep!%@AE@%%@NL@%
  2521. %@NL@%
  2522. then goes on to execute the statements that follow:  %@NL@%
  2523. %@NL@%
  2524. %@AS@%  Enter
  2525. %@AS@%  Bye bye%@AE@%%@NL@%
  2526. %@NL@%
  2527. Occasionally, you may want to fall through from one %@AB@%case%@AE@% alternative to
  2528. another. But you should be careful not to omit %@AB@%break%@AE@% statements
  2529. accidentally. (See the section "Omitting break Statements from a switch
  2530. Statement" in Chapter 10, "Programming Pitfalls.")  %@NL@%
  2531. %@NL@%
  2532. If you end each alternative with a %@AB@%break%@AE@%, as in SWITCH.C, the order of the
  2533. alternatives isn't critical. The program branches to the label containing
  2534. the correct value, no matter where that label appears in the %@AB@%switch%@AE@%
  2535. statement block. For instance, you can reverse the order of the alternatives
  2536. in SWITCH.C without changing the program's output. For readability's sake,
  2537. many programmers put %@AB@%default%@AE@% at the end of a %@AB@%switch %@AE@%statement and arrange
  2538. the other alternatives alphabetically or numerically.  %@NL@%
  2539. %@NL@%
  2540. Sometimes you'll want to execute the same code for more than one case. This
  2541. is done by grouping all the desired labels in front of one alternative. For
  2542. instance, if you revise the second alternative in SWITCH.C to read  %@NL@%
  2543. %@NL@%
  2544. %@AS@%  case '\r':
  2545. %@AS@%  case '\t':
  2546. %@AS@%  case ' ':
  2547. %@AS@%    printf( "What a boring choice!\n" );
  2548. %@AS@%    break;%@AE@%%@NL@%
  2549. %@NL@%
  2550. the program will print  %@NL@%
  2551. %@NL@%
  2552. %@AS@%  What a boring choice!%@AE@%%@NL@%
  2553. %@NL@%
  2554. when you press the ENTER key, the TAB key, or the SPACEBAR.  %@NL@%
  2555. %@NL@%
  2556. %@NL@%
  2557. %@3@%%@CR:C6A00030010 @%%@AB@%The break Statement%@AE@%%@EH@%%@NL@%
  2558. %@NL@%
  2559. The previous section explained how to use %@AB@%break%@AE@% to exit from a %@AB@%switch%@AE@%
  2560. statement. You can also use %@AB@%break%@AE@% to end a loop immediately. The BREAKER.C
  2561. program shows how to do this. The program prints a prompt, then displays
  2562. characters as they are typed until the TAB key is pressed.  %@NL@%
  2563. %@NL@%
  2564. %@AS@%  /* BREAKER.C: Demonstrate break statement. */
  2565. %@AS@%  
  2566. %@AS@%  #include <stdio.h>
  2567. %@AS@%  #include <conio.h>
  2568. %@AS@%  
  2569. %@AS@%  main()
  2570. %@AS@%  {
  2571. %@AS@%     char ch;
  2572. %@AS@%     printf( "Press any key. Press Tab to quit.\n" );
  2573. %@AS@%     while( 1 )
  2574. %@AS@%     {
  2575. %@AS@%        ch = getche();
  2576. %@AS@%        if( ch == '\t' )%@AE@%%@NL@%
  2577. %@NL@%
  2578. %@AS@%  {
  2579. %@AS@%    printf( "\a\nYou pressed Tab\n" );
  2580. %@AS@%    break;
  2581. %@AS@%        }
  2582. %@AS@%     }
  2583. %@AS@%  }%@AE@%%@NL@%
  2584. %@NL@%
  2585. The %@AB@%while%@AE@% statement in BREAKER.C creates an indefinite loop that calls the
  2586. %@AB@%getche%@AE@% function again and again, assigning the function's return value to
  2587. the variable %@AS@% ch%@AE@%. The %@AB@%if%@AE@% statement in the loop body compares %@AS@% ch %@AE@% to the tab
  2588. character. When TAB is pressed, BREAKER.C prints %@AS@% You pressed Tab %@AE@% and
  2589. executes the %@AB@%break%@AE@% statement, which terminates the %@AB@%while%@AE@% loop and ends the
  2590. program.  %@NL@%
  2591. %@NL@%
  2592. %@AU@% A break statement exits only one loop.%@AE@%  %@NL@%
  2593. %@NL@%
  2594. It's important to remember that the %@AB@%break%@AE@% statement only ends the loop in
  2595. which it appears. If two loops are nested, executing a %@AB@%break%@AE@% in the inner
  2596. loop exits that loop but not the outer loop. BREAKER1.C shows how %@AB@%break%@AE@%
  2597. works within nested loops. The program's inner loop checks for the TAB key
  2598. and the outer loop checks for the ENTER key.  %@NL@%
  2599. %@NL@%
  2600. %@AS@%  /* BREAKER1.C: Break only exits one loop. */
  2601. %@AS@%  
  2602. %@AS@%  #include <stdio.h>
  2603. %@AS@%  #include <conio.h>
  2604. %@AS@%  
  2605. %@AS@%  main()
  2606. %@AS@%  {
  2607. %@AS@%     char ch;
  2608. %@AS@%     printf( "Press any key. Press Enter to quit.\n" );
  2609. %@AS@%     do
  2610. %@AS@%     {
  2611. %@AS@%        while( ( ch = getche() ) != '\r' )
  2612. %@AS@%        {
  2613. %@AS@%           if( ch == '\t' )
  2614. %@AS@%           {
  2615. %@AS@%              printf( "\a\nYou pressed Tab\n" );
  2616. %@AS@%              break;
  2617. %@AS@%           }
  2618. %@AS@%        }
  2619. %@AS@%     } while( ch != '\r' );
  2620. %@AS@%     printf( "\nBye bye." );
  2621. %@AS@%  }%@AE@%%@NL@%
  2622. %@NL@%
  2623. The BREAKER1.C program includes a %@AB@%while%@AE@% loop nested within a %@AB@%do%@AE@% loop. Both
  2624. loops test the same condition─whether the variable %@AS@% ch %@AE@% equals the ENTER key
  2625. (%@AB@%\r%@AE@%). The %@AB@%while%@AE@% loop also calls the %@AB@%getche%@AE@% function, assigning the
  2626. function's return value to %@AS@% ch%@AE@%.  %@NL@%
  2627. %@NL@%
  2628. When TAB is pressed, the program prints %@AS@% You pressed Tab %@AE@% and executes a
  2629. %@AB@%break%@AE@% statement, which terminates the inner loop. The %@AB@%break%@AE@% does not end the
  2630. outer loop, however. The program continues until ENTER is pressed, providing
  2631. the condition that ends both loops.  %@NL@%
  2632. %@NL@%
  2633. Note that %@AB@%break%@AE@% can only be used to exit a loop or %@AB@%switch%@AE@% statement. While
  2634. you might be tempted to use %@AB@%break%@AE@% to jump out of complex %@AB@%if%@AE@% or %@AB@%else%@AE@%
  2635. statements, the %@AB@%break%@AE@% statement cannot be used for this purpose. It has no
  2636. effect on %@AB@%if%@AE@% and %@AB@%else%@AE@%.  %@NL@%
  2637. %@NL@%
  2638. %@NL@%
  2639. %@3@%%@CR:C6A00030011 @%%@AB@%The continue Statement%@AE@%%@EH@%%@NL@%
  2640. %@NL@%
  2641. %@AU@% The continue statement skips remaining statements in the loop body where it
  2642. %@AU@%appears.%@AE@%  %@NL@%
  2643. %@NL@%
  2644. The %@AB@%continue%@AE@% statement, like %@AB@%break%@AE@%, interrupts the normal flow of execution
  2645. in a loop body. But instead of ending the loop, %@AB@%continue%@AE@% skips all following
  2646. statements in the loop body and triggers the next iteration of the loop.
  2647. This effect can be useful within complex loops, in which you might wish to
  2648. skip to the next loop iteration from various locations.  %@NL@%
  2649. %@NL@%
  2650. The CONT.C program shows how %@AB@%continue%@AE@% works. It increments the %@AS@% count %@AE@%
  2651. variable, counting from 0 through 9, but stops printing the value of %@AS@% count %@AE@%
  2652. when that value exceeds 3.  %@NL@%
  2653. %@NL@%
  2654. %@AS@%  /* CONT.C: Demonstrate continue statement. */
  2655. %@AS@%  
  2656. %@AS@%  #include <stdio.h>
  2657. %@AS@%  
  2658. %@AS@%  main()
  2659. %@AS@%  {
  2660. %@AS@%     int count;
  2661. %@AS@%     for( count = 0; count < 10; count = count + 1 )
  2662. %@AS@%     {
  2663. %@AS@%        if( count > 3 )
  2664. %@AS@%           continue;
  2665. %@AS@%        printf( "count = %d\n", count );
  2666. %@AS@%     }
  2667. %@AS@%     printf( "Done!\n" );
  2668. %@AS@%  }%@AE@%%@NL@%
  2669. %@NL@%
  2670. Here's the output from CONT.C:  %@NL@%
  2671. %@NL@%
  2672. %@AS@%  count = 0
  2673. %@AS@%  count = 1
  2674. %@AS@%  count = 2
  2675. %@AS@%  count = 3
  2676. %@AS@%  Done!%@AE@%%@NL@%
  2677. %@NL@%
  2678. The %@AB@%continue%@AE@% statement occurs within the body of the %@AB@%for%@AE@% loop. When the
  2679. value of %@AS@% count %@AE@% exceeds 3, the %@AB@%continue%@AE@% skips the rest of the loop body─a
  2680. statement that calls %@AB@%printf%@AE@%─and causes the next iteration of the loop.  %@NL@%
  2681. %@NL@%
  2682. %@NL@%
  2683. %@3@%%@CR:C6A00030012 @%%@AB@%The goto Statement%@AE@%%@EH@%%@NL@%
  2684. %@NL@%
  2685. %@AU@% The goto statement jumps from one part of the function to another.%@AE@%  %@NL@%
  2686. %@NL@%
  2687. Similar to the %@AB@%GOTO%@AE@% statement in BASIC, %@AB@%goto%@AE@% in C performs an unconditional
  2688. jump from one part of a function to any other part. The target of the %@AB@%goto%@AE@%
  2689. statement is a label which you supply. The label must end with a colon, as
  2690. do %@AB@%case%@AE@% labels, which we discussed earlier.  %@NL@%
  2691. %@NL@%
  2692. Most C programmers avoid using the %@AB@%goto%@AE@% statement. It's a bit inconsistent
  2693. with the overall philosophy of C, which encourages structured, modular
  2694. programming. And, regardless of philosophy, it can be very difficult to read
  2695. and debug a program that is littered with haphazard unconditional jumps.  %@NL@%
  2696. %@NL@%
  2697. Nevertheless, %@AB@%goto%@AE@% has at least one sensible use. If a serious error occurs
  2698. deep within a nested series of loops or conditional statements, %@AB@%goto%@AE@% offers
  2699. the simplest escape. The following code has several levels of nesting, with
  2700. a %@AB@%goto%@AE@% statement at the innermost level. If the value of %@AS@% error_count %@AE@%
  2701. exceeds 15, the %@AB@%goto%@AE@% statement executes, transferring control to the label %@AS@%
  2702. %@AS@%bail_out%@AE@%.  %@NL@%
  2703. %@NL@%
  2704. %@AS@%  if( a == 1 )
  2705. %@AS@%  {
  2706. %@AS@%     while( b == 2 )
  2707. %@AS@%     {
  2708. %@AS@%        for( c = 0; c < 3; c = c + 1 )
  2709. %@AS@%        {
  2710. %@AS@%           if( d == 4 )
  2711. %@AS@%           {
  2712. %@AS@%              while( e == 6 )
  2713. %@AS@%              {
  2714. %@AS@%                 if( error_count > 15 )
  2715. %@AS@%                    goto bail_out;
  2716. %@AS@%              }
  2717. %@AS@%           }
  2718. %@AS@%        }
  2719. %@AS@%     }
  2720. %@AS@%  }
  2721. %@AS@%  bail_out:  /* The goto statement transfers control here. */%@AE@%%@NL@%
  2722. %@NL@%
  2723. To achieve the same effect without %@AB@%goto%@AE@%, you'd have to add extra conditional
  2724. tests to this code, making the code more complex and perhaps less efficient.
  2725. %@NL@%
  2726. %@NL@%
  2727. Names in %@AB@%goto%@AE@% labels are governed by the rules for variable names, which
  2728. we'll discuss in the next two chapters. For now, just remember that a %@AB@%goto%@AE@%
  2729. label is visible only in the function in which it appears. You can't execute
  2730. a %@AB@%goto%@AE@% statement to jump from one function to another function.  %@NL@%
  2731. %@NL@%
  2732. The next two chapters explain how to create and manipulate data─variables
  2733. and constants─in C programs. Chapter 4, "Data Types," describes the basics,
  2734. such as how to declare and initialize variables of different types. Chapter
  2735. 5, "Advanced Data Types," describes more advanced topics, such as the
  2736. visibility of variables.  %@NL@%
  2737. %@NL@%
  2738. %@NL@%
  2739. %@NL@%
  2740. %@NL@%
  2741. %@NL@%
  2742. %@NL@%
  2743. %@CR:C6A00040001 @%%@1@%%@AB@%Chapter 4  Data Types%@AE@%%@EH@%%@NL@%
  2744. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2745. %@NL@%
  2746. This chapter explains the C data types and shows how to declare and use C
  2747. variables. The chapter begins by describing the basic data types from which
  2748. all other data types are derived. We then discuss more complex data types,
  2749. including arrays and structures. In Chapter 5, "Advanced Data Types," we'll
  2750. explore more advanced data-handling topics, such as variable visibility and
  2751. automatic type conversions.  %@NL@%
  2752. %@NL@%
  2753. %@NL@%
  2754. %@2@%%@CR:C6A00040002 @%%@AB@%Basic Data Types%@AE@%%@EH@%%@NL@%
  2755. %@NL@%
  2756. All data in C programs is either a constant or variable, and each has an
  2757. associated data type. The concept of types is common to all high-level
  2758. languages. For instance, an integer (whole) number has the %@AB@%INTEGER%@AE@% type in
  2759. QuickBASIC, the %@AB@%Integer%@AE@% type in QuickPascal, and the %@AB@%int%@AE@% type in C. This
  2760. section describes the basic data types in C and explains how to specify
  2761. variables and constants using these types.  %@NL@%
  2762. %@NL@%
  2763. All of the basic data types contain a single value. Types that contain more
  2764. than one value─arrays, structures, and unions─are called "aggregate types."
  2765. We'll discuss aggregate types later in this chapter.  %@NL@%
  2766. %@NL@%
  2767. %@NL@%
  2768. %@3@%%@CR:C6A00040003 @%%@AB@%Specifying Basic Types%@AE@%%@EH@%%@NL@%
  2769. %@NL@%
  2770. The C language has four basic data types, which are specified with the
  2771. keywords %@AB@%char%@AE@%, %@AB@%int%@AE@%, %@AB@%float%@AE@%, and %@AB@%double%@AE@%. The %@AB@%char%@AE@% (character) type is used for
  2772. text and the %@AB@%int%@AE@% type for integers. The %@AB@%float%@AE@% and %@AB@%double%@AE@% types express real
  2773. (floating-point) values.  %@NL@%
  2774. %@NL@%
  2775. The TYPES.C program creates variables of the four basic types and prints
  2776. their values:  %@NL@%
  2777. %@NL@%
  2778. %@AS@%  /* TYPES.C: Illustrate basic data types. */
  2779. %@AS@%  
  2780. %@AS@%  #include <stdio.h>
  2781. %@AS@%  
  2782. %@AS@%  main()
  2783. %@AS@%  {
  2784. %@AS@%     char char_val       = 'a';
  2785. %@AS@%     int int_val         = 543;
  2786. %@AS@%     float float_val     = 11.1;
  2787. %@AS@%     double double_val   = 66.123456789;
  2788. %@AS@%     printf( "char_val   = %c\n", char_val );
  2789. %@AS@%     printf( "int_val    = %d\n", int_val );
  2790. %@AS@%     printf( "float_val  = %f\n", float_val );
  2791. %@AS@%     printf( "double_val = %2.9f\n", double_val );
  2792. %@AS@%  }%@AE@%%@NL@%
  2793. %@NL@%
  2794. Here is the output from TYPES.C:  %@NL@%
  2795. %@NL@%
  2796. %@AS@%  char_val   = a
  2797. %@AS@%  int_val    = 543
  2798. %@AS@%  float_val  = 11.100000
  2799. %@AS@%  double_val = 66.123456789%@AE@%%@NL@%
  2800. %@NL@%
  2801. Each basic data type requires a different amount of memory, as illustrated
  2802. in Figure 4.1. In QuickC, a %@AB@%char%@AE@% contains one byte, an %@AB@%int%@AE@% has two bytes, a
  2803. %@AB@%float%@AE@% has four bytes, and a %@AB@%double%@AE@% type has eight bytes.  %@NL@%
  2804. %@NL@%
  2805. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  2806. %@NL@%
  2807. ────────────────────────────────────────────────────────────────────────────%@NL@%
  2808. NOTE
  2809.  
  2810. %@AI@%The C language is designed to run on many different computers, with machine
  2811. %@AI@%architectures that may be quite different. To accommodate these differences,
  2812. %@AI@%some C data types are "implementation dependent," meaning their sizes depend
  2813. %@AI@%on which computer you're using. For instance, the%@AI@% %@AE@%%@AI@%%@AB@%int%@AE@%%@AE@%%@AI@% (i%@AE@%%@AI@%nteger) type
  2814. %@AI@%contains two bytes on IBM PC computers and four bytes on VAX%@AE@%%@AI@%(R)
  2815. %@AI@%%@AE@%%@AI@%minicomputers. These differences are %@AE@%%@AI@%%@AE@%%@AI@%i%@AE@%%@AI@%mportant only if you're transporting a
  2816. %@AI@%program%@AE@%%@AI@%%@AE@%%@AI@% f%@AE@%%@AI@%rom one%@AE@%%@AI@%%@AE@%%@AI@% %@AE@%%@AI@%operating system to another. Since QuickC runs only under
  2817. %@AI@%one operating system (DOS), this book describes C data types in DOS.%@AE@%%@AI@%%@AE@%%@AI@%%@AE@%%@AE@%%@NL@%
  2818. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  2819. %@NL@%
  2820. %@NL@%
  2821. %@4@%%@AB@%Special Type Specifiers%@AE@%%@EH@%%@NL@%
  2822. %@NL@%
  2823. The C language has four special type specifiers─%@AB@%signed%@AE@%, %@AB@%unsigned%@AE@%, %@AB@%long%@AE@%, and
  2824. %@AB@%short%@AE@%. These act as "adjectives" to modify the range of values expressed by
  2825. a basic data type.  %@NL@%
  2826. %@NL@%
  2827. %@AU@% The char and int data types  are signed by default.%@AE@%  %@NL@%
  2828. %@NL@%
  2829. The %@AB@%signed%@AE@% keyword signifies that a value can be either negative or
  2830. nonnegative. If you don't specify, a %@AB@%char%@AE@% or %@AB@%int%@AE@% value is signed.  %@NL@%
  2831. %@NL@%
  2832. You can preface a %@AB@%char%@AE@% or %@AB@%int%@AE@% with %@AB@%unsigned%@AE@% to extend the range of
  2833. nonnegative values. An %@AB@%unsigned int%@AE@% can have a value in the range 0 through
  2834. 65,535, and an %@AB@%unsigned char%@AE@% can have a value of 0 through 255.  %@NL@%
  2835. %@NL@%
  2836. The %@AB@%long%@AE@% keyword is used to increase the size of an %@AB@%int%@AE@% or %@AB@%double%@AE@% type. A
  2837. %@AB@%long int%@AE@% value contains four bytes (twice as many as an %@AB@%int%@AE@%) and expresses
  2838. an integer in the range -2,147,483,648 through 2,147,483,647. A %@AB@%long double%@AE@%
  2839. value contains 10 bytes and can express a floating-point number with 19
  2840. digits of precision.  %@NL@%
  2841. %@NL@%
  2842. In QuickC, the %@AB@%short int%@AE@% type is identical to the %@AB@%int%@AE@% type. (This is not the
  2843. case in some operating systems other than DOS.)  %@NL@%
  2844. %@NL@%
  2845. Table 4.1 lists the basic data types and the range of values each can
  2846. express.  %@NL@%
  2847. %@NL@%
  2848. %@AB@%Table 4.1  %@AB@%Basic Data Types%@AE@%%@AE@%
  2849.  
  2850. %@TH:  38  1798 02 17 25 34 @%
  2851. Type Name        Other Names              Range of Values
  2852. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2853. %@AB@%char%@AE@%             %@AB@%signed char%@AE@%              -128 to 127
  2854.  
  2855. %@AB@%unsigned char%@AE@%    none                     0 to 255
  2856.  
  2857. %@AB@%int%@AE@%              %@AB@%signed%@AE@%, %@AB@%signed int%@AE@%       -32,768 to 32,767
  2858.  
  2859. %@AB@%unsigned%@AE@%         %@AB@%unsigned int%@AE@%             0 to 65,535
  2860.  
  2861. %@AB@%unsigned short%@AE@%   %@AB@%unsigned short int %@AE@%      0 to 65,535
  2862.  
  2863. %@AB@%short%@AE@%            %@AB@%short int%@AE@%, %@AB@%signed short%@AE@%  -32,768 to 32,767
  2864.  
  2865.                  %@AB@%signed short int%@AE@% 
  2866.  
  2867. %@AB@%long%@AE@%             %@AB@%long int%@AE@%, %@AB@%signed long%@AE@%    -2,147,483,648 to%@AB@%%@AE@%
  2868.  
  2869.                  %@AB@%signed long int%@AE@%          2,147,483,647
  2870.  
  2871. %@AB@%unsigned long%@AE@%    %@AB@%unsigned long int%@AE@%        0 to 4,294,967,295
  2872.                  %@AB@%%@AE@%                         
  2873.                  %@AB@%%@AE@%                         
  2874.                  %@AB@% %@AE@%                        
  2875.  
  2876. %@AB@%float%@AE@%            none                     Approximately 1.2E-38 to 3.4E+38
  2877.                                           (7-digit 
  2878.                                           precision)
  2879.  
  2880. %@AB@%double%@AE@%           none                     Approximately 2.2E-308 to 
  2881.                                           1.8E+308 (15-digit 
  2882.                                           precision)
  2883.  
  2884. %@AB@%long double%@AE@%      none                     Approximately 3.4E-4932 to 
  2885.                                           1.2E+4932 (19-digit precision)
  2886.  
  2887. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2888.  
  2889. %@TE:  38  1798 02 17 25 34 @%
  2890.  
  2891. Most programmers take advantage of type defaults. If a type qualifier
  2892. appears alone, the type %@AB@%int%@AE@% is implied. By itself, %@AB@%short%@AE@% is a synonym for
  2893. %@AB@%short int%@AE@%. Where %@AB@%long%@AE@% appears alone it is a synonym for %@AB@%long int%@AE@%, and where
  2894. %@AB@%unsigned%@AE@% appears alone it is a synonym for %@AB@%unsigned int%@AE@%.  %@NL@%
  2895. %@NL@%
  2896. %@NL@%
  2897. %@3@%%@CR:C6A00040004 @%%@AB@%Specifying Variables%@AE@%%@EH@%%@NL@%
  2898. %@NL@%
  2899. As we mentioned in Chapter 1, "Anatomy of a C Program," you must declare
  2900. every variable in a C program by stating the variable's name and type.
  2901. Variable names are governed by the following rules, which also apply to
  2902. other userdefined names such as function names:  %@NL@%
  2903. %@NL@%
  2904. %@NL@%
  2905.   ■   C is case-sensitive. For example, %@AS@% myvar%@AE@%, %@AS@% MyVar%@AE@%, and %@AS@% MYVAR %@AE@% are
  2906.       different names.%@NL@%
  2907. %@NL@%
  2908.   ■   The name can't be a keyword (see online help for a list of keywords).%@NL@%
  2909. %@NL@%
  2910.   ■   The first character must be a letter or underscore (%@AS@% %@AE@%%@AB@%_ %@AE@%). Many of
  2911.       QuickC's system-defined names, including some library-routine names,
  2912.       begin with underscores. To avoid conflicts with such names, don't
  2913.       create names that begin with underscores.%@NL@%
  2914. %@NL@%
  2915.   ■   Other characters can be letters, digits, or underscores.%@NL@%
  2916. %@NL@%
  2917.   ■   The first 31 characters of local variable names are significant. The
  2918.       name can contain more than 31 characters, but QuickC ignores
  2919.       everything beyond the thirty-first character. Global variable names
  2920.       are normally significant to 30 characters.%@NL@%
  2921. %@NL@%
  2922. %@NL@%
  2923. All C keywords are lowercase, and it's common to use lowercase for variable
  2924. names. Mixed case is becoming popular in some contexts, however. OS/2 and
  2925. Microsoft Windows(tm) use mixed case for most system-defined names.  %@NL@%
  2926. %@NL@%
  2927. %@NL@%
  2928. %@3@%%@CR:C6A00040005 @%%@AB@%Specifying Constants%@AE@%%@EH@%%@NL@%
  2929. %@NL@%
  2930. Constants─values that don't change during the life of the program─can be
  2931. numbers, characters, or strings. Your program can also define "symbolic
  2932. constants," which are names that represent constant values. This section
  2933. describes how to specify C constants.  %@NL@%
  2934. %@NL@%
  2935. %@NL@%
  2936. %@4@%%@AB@%Numeric Constants%@AE@%%@EH@%%@NL@%
  2937. %@NL@%
  2938. A numeric constant can have any basic data type, and can be specified in
  2939. decimal, hexadecimal, or octal notation. Table 4.2 shows how to specify
  2940. numeric constants.  %@NL@%
  2941. %@NL@%
  2942. %@AB@%Table 4.2  %@AB@%Constant Specifications%@AE@%%@AE@%
  2943.  
  2944. %@TH:  13   691 02 19 57 @%
  2945. Constant           Type
  2946. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2947. 255                decimal %@AB@%int%@AE@%
  2948. 0xFF               hexadecimal %@AB@%int%@AE@% (255)
  2949. 0377               octal %@AB@%int %@AE@%(255)
  2950. 255L               %@AB@%long int%@AE@%
  2951. 255U               %@AB@%unsigned int%@AE@%
  2952. 0xFFul             %@AB@%long unsigned %@AE@%hexadecimal %@AB@%int%@AE@% (255)
  2953. 15.75E2            floating point (1575)
  2954. -.123              floating point
  2955. .123               floating point
  2956. 3e0f               floating point
  2957. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  2958. %@TE:  13   691 02 19 57 @%
  2959.  
  2960. A number without a suffix, such as 255, is treated as decimal. The %@AS@% 0x %@AE@%
  2961. prefix specifies a hexadecimal number, and the %@AS@% 0 %@AE@% (zero) prefix specifies
  2962. octal (base 8).  %@NL@%
  2963. %@NL@%
  2964. If a number doesn't have a decimal point, it is an integer. Integers are
  2965. signed by default; you can use the suffix %@AS@% U %@AE@% or %@AS@% u %@AE@% to specify an unsigned
  2966. constant. To specify a %@AB@%long%@AE@% integer, place the suffix %@AS@% L %@AE@% or %@AS@% l %@AE@% after the
  2967. number.  %@NL@%
  2968. %@NL@%
  2969. A floating-point constant contains either a decimal point or an exponent
  2970. preceded by %@AS@% e %@AE@% or %@AS@% E %@AE@%. It can optionally include the suffix %@AS@% F %@AE@% or %@AS@% f %@AE@% to
  2971. denote the %@AB@%float%@AE@% type or the suffix %@AS@% L %@AE@% or %@AS@% l%@AE@% to denote the %@AB@%long double%@AE@%
  2972. type.  %@NL@%
  2973. %@NL@%
  2974. %@NL@%
  2975. %@4@%%@AB@%Character and String Constants%@AE@%%@EH@%%@NL@%
  2976. %@NL@%
  2977. The C language uses different notation for character and string constants. A
  2978. single character enclosed in single quotes is a character constant:  %@NL@%
  2979. %@NL@%
  2980. %@AS@%  'a'%@AE@%%@NL@%
  2981. %@NL@%
  2982. A string constant is 0 or more characters enclosed in double quotes:  %@NL@%
  2983. %@NL@%
  2984. %@AS@%  "Hello"%@AE@%%@NL@%
  2985. %@NL@%
  2986. A string also ends with a null character (%@AB@%\0%@AE@%), as we'll see in the section
  2987. "Strings."  %@NL@%
  2988. %@NL@%
  2989. The difference between character and string constants is important when you
  2990. perform comparisons. The character constant %@AS@% 'a' %@AE@% contains 1 character, but
  2991. the string constant %@AS@% "a" %@AE@% contains 2 characters: the letter %@AS@% a %@AE@% plus a null
  2992. character. Because the two values have a different number of characters, any
  2993. comparison of them is invalid. (See "String Problems" in Chapter 10,
  2994. "Programming Pitfalls.")  %@NL@%
  2995. %@NL@%
  2996. You can specify special characters, such as the tab and backspace, with a
  2997. multi-character sequence that begins with a backslash ( \ ). These sequences
  2998. are sometimes called "escape sequences." Table 4.3 shows the special
  2999. character sequences.  %@NL@%
  3000. %@NL@%
  3001. %@AB@%Table 4.3  %@AB@%Special Characters%@AE@%%@AE@%
  3002.  
  3003. %@TH:  16   906 02 24 52 @%
  3004. Sequence                Character
  3005. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3006. %@AB@%\a%@AE@%                      Alert (bell)
  3007. %@AB@%\b %@AE@%                     Backspace
  3008. %@AB@%\f%@AE@%                      Form feed
  3009. %@AB@%\n%@AE@%                      Newline
  3010. %@AB@%\r%@AE@%                      Carriage return
  3011. %@AB@%\t%@AE@%                      Horizontal tab
  3012. %@AB@%\v%@AE@%                      Vertical tab
  3013. %@AB@%\'%@AE@%                      Single quote
  3014. %@AB@%\"%@AE@%                      Double quote
  3015. %@AB@%\\%@AE@%                      Backslash
  3016. %@AB@%\%@AE@%%@AI@%ooo%@AE@%                    Octal notation
  3017. %@AB@%\%@AE@%%@AI@%xhh%@AE@%                    Hexadecimal notation
  3018. %@AB@%\0%@AE@%                      Null
  3019. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3020. %@TE:  16   906 02 24 52 @%
  3021.  
  3022. Some unusual characters don't have a predefined sequence. You can specify
  3023. these with a backslash ( %@AB@%\ %@AE@%) followed by the hexadecimal or octal number
  3024. representing the character's ASCII value. For instance, a telecommunications
  3025. program might need to specify ASCII 21, the NAK ("not acknowledged")
  3026. character. You can specify this character in either hexadecimal notation, %@AS@%
  3027. %@AS@%'\x15'%@AE@%, or octal notation, %@AS@%'\25'%@AE@%. Note that the hexadecimal number begins
  3028. with %@AS@% \x%@AE@%, while the octal number starts with a backslash alone.  %@NL@%
  3029. %@NL@%
  3030. %@NL@%
  3031. %@4@%%@AB@%Symbolic Constants%@AE@%%@EH@%%@NL@%
  3032. %@NL@%
  3033. A "symbolic constant" is a user-defined name that represents a constant.
  3034. Symbolic constants are usually typed in uppercase. For instance, the
  3035. directive  %@NL@%
  3036. %@NL@%
  3037. %@AS@%  #define PI 3.14%@AE@%%@NL@%
  3038. %@NL@%
  3039. declares a symbolic constant named %@AS@% PI%@AE@%. Wherever %@AS@% PI %@AE@% occurs in the program,
  3040. the compiler substitutes %@AS@% 3.14%@AE@%. Chapter 7, "Preprocessor Directives,"
  3041. discusses symbolic constants and the %@AB@%#define%@AE@% directive.  %@NL@%
  3042. %@NL@%
  3043. %@NL@%
  3044. %@2@%%@CR:C6A00040006 @%%@AB@%Aggregate Data Types%@AE@%%@EH@%%@NL@%
  3045. %@NL@%
  3046. This section describes aggregate data types, which contain organized
  3047. collections of data in a definite order. In C, the aggregate types are
  3048. arrays, structures, and unions.  %@NL@%
  3049. %@NL@%
  3050. An "array" is a collection of data items of the same type. Programs use
  3051. arrays in cases where a standard data format is repeated many times. For
  3052. example, you might use an array to store numbers representing the population
  3053. of Minnesota for all the years from 1950 to 2000. C-language arrays are very
  3054. similar to arrays in QuickPascal and QuickBASIC.  %@NL@%
  3055. %@NL@%
  3056. A "structure" is a collection of data items of different types. Programs use
  3057. structures in cases where a variety of data have a close association. For
  3058. example, you might use a structure to store information about a given
  3059. employee─name, months of employment, and hourly wage. Structures are similar
  3060. to QuickPascal records or QuickBASIC user-defined types.  %@NL@%
  3061. %@NL@%
  3062. A "union" allows you to use different data formats to access the same area
  3063. of memory. It can hold different kinds of information at different times.
  3064. Unions are similar to variant records in QuickPascal.  %@NL@%
  3065. %@NL@%
  3066. %@NL@%
  3067. %@3@%%@CR:C6A00040007 @%%@AB@%Arrays%@AE@%%@EH@%%@NL@%
  3068. %@NL@%
  3069. %@AU@% An array is a group of  data items of the same  type under one name.%@AE@%  %@NL@%
  3070. %@NL@%
  3071. The simplest aggregate data type is an array: a group of data items that
  3072. share the same type and a common name. You can make an array from any data
  3073. type, including basic types such as %@AB@%char%@AE@% and %@AB@%int%@AE@% and more complex types such
  3074. as structures. This section shows how to declare, initialize, and access
  3075. arrays, including arrays with more than one dimension. We'll begin with a
  3076. simple example that creates a one-dimensional array.  %@NL@%
  3077. %@NL@%
  3078. %@NL@%
  3079. %@4@%%@AB@%Creating a Simple Array%@AE@%%@EH@%%@NL@%
  3080. %@NL@%
  3081. The ARRAY.C program creates the array %@AS@% i_array%@AE@%, which contains three
  3082. integers.  %@NL@%
  3083. %@NL@%
  3084. %@AS@%  /* ARRAY.C: Demonstrate one-dimensional array. */
  3085. %@AS@%  
  3086. %@AS@%  #include <stdio.h>
  3087. %@AS@%  
  3088. %@AS@%  main()
  3089. %@AS@%  {
  3090. %@AS@%     int j;
  3091. %@AS@%     int i_array[3];
  3092. %@AS@%  
  3093. %@AS@%     i_array[0] = 176;
  3094. %@AS@%     i_array[1] = 4069;
  3095. %@AS@%     i_array[2] = 303;
  3096. %@AS@%  
  3097. %@AS@%     printf( "--- Values --------     --- Addresses -------\n\n" );
  3098. %@AS@%  
  3099. %@AS@%     for( j = 0; j < 3; j = j + 1 )
  3100. %@AS@%     {
  3101. %@AS@%        printf( "i_array[%d] = %d", j, i_array[j] );
  3102. %@AS@%        printf( "\t&i_array[%d] = %u\n", j, &i_array[j] );
  3103. %@AS@%     }
  3104. %@AS@%  
  3105. %@AS@%  }%@AE@%%@NL@%
  3106. %@NL@%
  3107. Here is the output from ARRAY.C:  %@NL@%
  3108. %@NL@%
  3109. %@AS@%  --- Values --------     --- Addresses -------
  3110. %@AS@%  
  3111. %@AS@%  i_array[0] = 176        &i_array[0] = 3506
  3112. %@AS@%  i_array[1] = 4069       &i_array[1] = 3508
  3113. %@AS@%  i_array[2] = 303        &i_array[2] = 3510%@AE@%%@NL@%
  3114. %@NL@%
  3115. As you can see, ARRAY.C prints the values in %@AS@% i_array %@AE@% and the memory
  3116. address where each array element is stored. You usually don't have to worry
  3117. about actual memory addresses in C, but it's useful to have some idea how
  3118. array elements are stored in memory. Depending on factors such as the amount
  3119. of memory in your system, you may see different addresses when you run
  3120. ARRAY.C.  %@NL@%
  3121. %@NL@%
  3122. (The second %@AB@%printf%@AE@% statement uses the "address-of" operator (%@AB@%&%@AE@%) to determine
  3123. the address of each array element. Chapter 6, "Operators," explains this
  3124. operator. For now, it's sufficient to recognize that the operator allows
  3125. ARRAY.C to print addresses.)  %@NL@%
  3126. %@NL@%
  3127. Figure 4.2 shows how %@AS@% i_array %@AE@% is stored in the addresses from the ARRAY.C
  3128. output.  %@NL@%
  3129. %@NL@%
  3130. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  3131. %@NL@%
  3132. %@NL@%
  3133. %@4@%%@AB@%Declaring the Array%@AE@%%@EH@%%@NL@%
  3134. %@NL@%
  3135. You declare an array variable by stating its type and its name, as you would
  3136. a simple variable. You must also declare the size of the array, stating the
  3137. number of elements with an integer constant in square brackets. For example,
  3138. the line  %@NL@%
  3139. %@NL@%
  3140. %@AS@%  int i_array[3];%@AE@%%@NL@%
  3141. %@NL@%
  3142. from ARRAY.C declares a three-element integer (%@AB@%int%@AE@%) array named %@AS@% i_array%@AE@%.  %@NL@%
  3143. %@NL@%
  3144. Multidimensional arrays are declared the same way, except you must give the
  3145. size of each dimension. The following statement, for instance, declares a
  3146. twodimensional %@AB@%int%@AE@% array named %@AS@% two_dim%@AE@%:  %@NL@%
  3147. %@NL@%
  3148. %@AS@%  int two_dim[2][3];%@AE@%%@NL@%
  3149. %@NL@%
  3150. We'll return to multidimensional arrays a little later in this chapter.  %@NL@%
  3151. %@NL@%
  3152. %@NL@%
  3153. %@4@%%@AB@%Initializing the Array%@AE@%%@EH@%%@NL@%
  3154. %@NL@%
  3155. Arrays, like simple variables, should be initialized before use. ARRAY.C
  3156. initializes %@AS@% i_array %@AE@% with these statements:  %@NL@%
  3157. %@NL@%
  3158. %@AS@%  i_array[0] = 176;
  3159. %@AS@%  i_array[1] = 4069;
  3160. %@AS@%  i_array[2] = 303;%@AE@%%@NL@%
  3161. %@NL@%
  3162. %@AU@% An array can be initialized  when it is declared.%@AE@%  %@NL@%
  3163. %@NL@%
  3164. ARRAY.C declares an array in one statement and then initializes its elements
  3165. one by one. You can also initialize an array when you declare it. The
  3166. following statement does both jobs at once:  %@NL@%
  3167. %@NL@%
  3168. %@AS@%  int i_array[3] = { 176, 4069, 303 };%@AE@%%@NL@%
  3169. %@NL@%
  3170. Note the curly braces around the initializing values. The braces are
  3171. mandatory in this kind of initialization.  %@NL@%
  3172. %@NL@%
  3173. Under the ANSI C standard, which QuickC version 2.5 follows, you can
  3174. simultaneously declare and initialize an array within a function. Pre-ANSI
  3175. compilers, including QuickC version 1.0, don't allow this unless the %@AB@%static%@AE@%
  3176. keyword precedes the array declaration. Chapter 5, "Advanced Data Types,"
  3177. discusses %@AB@%static%@AE@%.  %@NL@%
  3178. %@NL@%
  3179. When you declare and initialize an array at the same time, the initializing
  3180. values are normally constants, as shown above. Occasionally, you may want to
  3181. initialize an array as you declare it using variables instead of constants.
  3182. QuickC version 2.5 allows this, but only within a function. The %@AS@% sample %@AE@%
  3183. array in the following example is initialized legally under QuickC version
  3184. 2.5 but illegally under QuickC version 1.0:  %@NL@%
  3185. %@NL@%
  3186. %@AS@%  func()
  3187. %@AS@%  {
  3188. %@AS@%     int val = 5;
  3189. %@AS@%     int sample[3] = { val, val, val };
  3190. %@AS@%  }%@AE@%%@NL@%
  3191. %@NL@%
  3192. If you initialize a local array in this way, you must include the size of
  3193. the array within the square brackets following the array name. If the
  3194. example initialized the %@AS@% sample %@AE@% array with the following line:  %@NL@%
  3195. %@NL@%
  3196. %@AS@%  int sample[ ] = {val, val, val};%@AE@%%@NL@%
  3197. %@NL@%
  3198. QuickC would issue an error because the size of the array (3) is not
  3199. specified.  %@NL@%
  3200. %@NL@%
  3201. %@NL@%
  3202. %@4@%%@AB@%Specifying Array Elements%@AE@%%@EH@%%@NL@%
  3203. %@NL@%
  3204. %@AU@% Array subscripts are enclosed in square brackets ( [ ] ).%@AE@%  %@NL@%
  3205. %@NL@%
  3206. You specify an array element by giving its position, using an integer value
  3207. called a "subscript." Square brackets ([ ]) enclose each subscript. In the
  3208. ARRAY.C program above we specify the first element of %@AS@% i_array %@AE@% as  %@NL@%
  3209. %@NL@%
  3210. %@AS@%  i_array[0]%@AE@%%@NL@%
  3211. %@NL@%
  3212. Notice that the first element of a C array has the subscript 0, not 1.
  3213. Unlike QuickPascal and QuickBASIC, the C language does not give you the
  3214. option to start at an index number other than 0.  %@NL@%
  3215. %@NL@%
  3216. Since array subscripts begin at 0, the subscript of the last array element
  3217. is 1 less than the number used to declare that dimension of the array. In
  3218. ARRAY.C, the last element of %@AS@% i_array %@AE@% is %@AS@% i_array[2] %@AE@%, not %@AS@% i_array[3]%@AE@%.  %@NL@%
  3219. %@NL@%
  3220. %@AU@% C doesn't check array subscripts.%@AE@%  %@NL@%
  3221. %@NL@%
  3222. Unlike QuickBASIC and QuickPascal, C doesn't check the validity of array
  3223. subscripts. If the ARRAY.C program included the expression  %@NL@%
  3224. %@NL@%
  3225. %@AS@%  i_array[55];%@AE@%%@NL@%
  3226. %@NL@%
  3227. it would refer to a nonexistent array element. (The expression refers to the
  3228. element 55, but %@AS@% i_array %@AE@% contains only three elements.) This would not
  3229. trigger a compiler error or run-time error, however. It's your job to
  3230. remember the size of the array and avoid references that go outside the
  3231. array's boundaries. This rule is also important when you're accessing arrays
  3232. with pointers (see Chapter 8, "Pointers").  %@NL@%
  3233. %@NL@%
  3234. %@NL@%
  3235. %@4@%%@AB@%Strings%@AE@%%@EH@%%@NL@%
  3236. %@NL@%
  3237. %@AU@% A string is an array  of characters.%@AE@%  %@NL@%
  3238. %@NL@%
  3239. You may have wondered why we didn't mention strings in our earlier
  3240. description of basic data types. The reason is that strings aren't a formal
  3241. data type. In the C language, a string is simply an array of characters
  3242. (%@AB@%char%@AE@% values).  %@NL@%
  3243. %@NL@%
  3244. The STRING.C program below creates the string %@AS@% c_array %@AE@% and displays its
  3245. contents in the same format as the previous example. The program prints the
  3246. value of each array element and its address.  %@NL@%
  3247. %@NL@%
  3248. %@AS@%  /* STRING.C: Demonstrate string arrays. */
  3249. %@AS@%  
  3250. %@AS@%  #include <stdio.h>
  3251. %@AS@%  
  3252. %@AS@%  main()
  3253. %@AS@%  {
  3254. %@AS@%     int j;
  3255. %@AS@%     char c_array[] = "Hello";
  3256. %@AS@%  
  3257. %@AS@%     printf( "--- Values --------     --- Addresses -------\n\n" );
  3258. %@AS@%  
  3259. %@AS@%     for( j = 0; j < 6; j = j + 1 )
  3260. %@AS@%     {
  3261. %@AS@%        printf( "c_array[%d]   = %x %c", j, c_array[j], c_array[j] );
  3262. %@AS@%        printf( "\t&c_array[%d]    = %u\n", j, &c_array[j] );
  3263. %@AS@%     }
  3264. %@AS@%  }%@AE@%%@NL@%
  3265. %@NL@%
  3266. Here is the output from STRING.C:  %@NL@%
  3267. %@NL@%
  3268. %@AS@%  --- Values --------     --- Addresses -------
  3269. %@AS@%  
  3270. %@AS@%  c_array[0]   = 48 H     &c_array[0]    = 3522
  3271. %@AS@%  c_array[1]   = 65 e     &c_array[1]    = 3523
  3272. %@AS@%  c_array[2]   = 6c l     &c_array[2]    = 3524
  3273. %@AS@%  c_array[3]   = 6c l     &c_array[3]    = 3525
  3274. %@AS@%  c_array[4]   = 6f o     &c_array[4]    = 3526
  3275. %@AS@%  c_array[5]   = 0        &c_array[5]    = 3527%@AE@%%@NL@%
  3276. %@NL@%
  3277. Figure 4.3 shows how %@AS@% c_array %@AE@% is stored in memory. Again, the addresses in
  3278. the output may differ depending on factors such as the amount of available
  3279. memory.  %@NL@%
  3280. %@NL@%
  3281. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  3282. %@NL@%
  3283. %@AU@% A string ends with  a null character.%@AE@%  %@NL@%
  3284. %@NL@%
  3285. The figure illustrates another important feature of strings. Although %@AS@%
  3286. %@AS@%c_array %@AE@% has five printing characters (%@AS@% Hello %@AE@%), it actually contains six
  3287. characters─five letters plus a null character (%@AB@%\0%@AE@%) that marks the end of the
  3288. string. As noted earlier, the C language automatically adds a null character
  3289. to every string enclosed in double quotes.  %@NL@%
  3290. %@NL@%
  3291. STRING.C uses a shortcut when it initializes %@AS@% c_array%@AE@%. You may have noticed
  3292. that the array declaration  %@NL@%
  3293. %@NL@%
  3294. %@AS@%  char c_array[] = "Hello";%@AE@%%@NL@%
  3295. %@NL@%
  3296. doesn't declare the array's size (the square brackets are empty). When an
  3297. array is initialized at the same time it's declared, QuickC can figure out
  3298. how many elements the array has by counting the number of initializing
  3299. values to the right of the equal sign.  %@NL@%
  3300. %@NL@%
  3301. You can use this shortcut for any type of array, not just a %@AB@%char%@AE@% array. If
  3302. the array has more than one dimension, however, you can only omit the size
  3303. of the first dimension.  %@NL@%
  3304. %@NL@%
  3305. %@NL@%
  3306. %@4@%%@AB@%Multidimensional Arrays%@AE@%%@EH@%%@NL@%
  3307. %@NL@%
  3308. A "multidimensional" array contains two or more array dimensions. The
  3309. TWODIM.C program below creates a two-dimensional array named %@AS@% i_array.  %@AE@%%@NL@%
  3310. %@NL@%
  3311. %@AS@%  /* TWODIM.C: Demonstrate multidimensional arrays. */
  3312. %@AS@%  
  3313. %@AS@%  #include <stdio.h>
  3314. %@AS@%  
  3315. %@AS@%  main()
  3316. %@AS@%  {
  3317. %@AS@%     int j, k;
  3318. %@AS@%     int i_array[2][3] = { { 176, 4069, 303 }, { 6, 55, 777 } };
  3319. %@AS@%  
  3320. %@AS@%     printf( "--- Values --------     --- Addresses -------\n\n" );
  3321. %@AS@%  
  3322. %@AS@%     for( j = 0; j < 2; j = j + 1 )
  3323. %@AS@%     {
  3324. %@AS@%        for( k = 0; k < 3; k = k + 1 )
  3325. %@AS@%        {
  3326. %@AS@%           printf( "i_array[%d][%d] = %d", j, k, i_array[j][k] );
  3327. %@AS@%           printf( "\t&i_array[%d][%d] = %u\n", j, k, &i_array[j][k] );
  3328. %@AS@%        }
  3329. %@AS@%        printf( "\n" );
  3330. %@AS@%     }
  3331. %@AS@%  
  3332. %@AS@%  }%@AE@%%@NL@%
  3333. %@NL@%
  3334. Here's the output from TWODIM.C:  %@NL@%
  3335. %@NL@%
  3336. %@AS@%  --- Values --------     --- Addresses -------
  3337. %@AS@%  
  3338. %@AS@%  i_array[0][0] = 176     &i_array[0][0] = 3498
  3339. %@AS@%  i_array[0][1] = 4069    &i_array[0][1] = 3500
  3340. %@AS@%  i_array[0][2] = 303     &i_array[0][2] = 3502
  3341. %@AS@%  
  3342. %@AS@%  i_array[1][0] = 6       &i_array[1][0] = 3504
  3343. %@AS@%  i_array[1][1] = 55      &i_array[1][1] = 3506
  3344. %@AS@%  i_array[1][2] = 777     &i_array[1][2] = 3508%@AE@%%@NL@%
  3345. %@NL@%
  3346. Each subscript of a multidimensional array appears in its own set of square
  3347. brackets, as the TWODIM.C output shows. When you declare the array, the
  3348. first subscript states the size of the first dimension, the second states
  3349. the size of the second dimension, and so on. In TWODIM.C, the declaration of
  3350. %@AS@% i_array%@AE@%,  %@NL@%
  3351. %@NL@%
  3352. %@AS@%  int i_array[2][3]%@AE@%%@NL@%
  3353. %@NL@%
  3354. states that %@AS@% i_array %@AE@% contains two rows of values, each row containing three
  3355. integers. The statement that declares %@AS@% i_array %@AE@% also initializes the array,
  3356. listing the initializing values in curly braces to the right of the equal
  3357. sign:  %@NL@%
  3358. %@NL@%
  3359. %@AS@%  int i_array[2][3] = { { 176, 4069, 303 }, { 6, 5, 77 } };%@AE@%%@NL@%
  3360. %@NL@%
  3361. The braces clearly show that the array contains two groups of three values.
  3362. %@NL@%
  3363. %@NL@%
  3364. Two-dimensional arrays are often pictured in rows and columns, as in Figure
  3365. 4.4. Of course, since computer memory is linear, %@AS@% i_array %@AE@% is actually
  3366. stored with its rows end-for-end, as in Figure 4.5.  %@NL@%
  3367. %@NL@%
  3368. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  3369. %@NL@%
  3370. You refer to a multidimensional array element the same way you would a
  3371. onedimensional array element, except that you use one subscript for each
  3372. dimension of the array. For instance, the statement  %@NL@%
  3373. %@NL@%
  3374. %@AS@%  printf( "%d\n", i_array[0][1] );%@AE@%%@NL@%
  3375. %@NL@%
  3376. specifies two subscripts. It prints the value stored in element 0, 1 of %@AS@%
  3377. %@AS@%i_array%@AE@%, which is %@AS@% 4069%@AE@%.  %@NL@%
  3378. %@NL@%
  3379. Figure 4.5 shows how to specify every element of %@AS@% i_array %@AE@% in TWODIM.C.  %@NL@%
  3380. %@NL@%
  3381. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  3382. %@NL@%
  3383. %@NL@%
  3384. %@3@%%@CR:C6A00040008 @%%@AB@%Structures%@AE@%%@EH@%%@NL@%
  3385. %@NL@%
  3386. %@AU@% A structure is a group of related data items of different  types under one
  3387. %@AU@%name.%@AE@%  %@NL@%
  3388. %@NL@%
  3389. The second aggregate data type is the structure: a group of related data
  3390. items under one name. While array elements are all the same type, the
  3391. elements of a structure, known as its "members," can be of different types.
  3392. %@NL@%
  3393. %@NL@%
  3394. Structures are equivalent to records in QuickPascal or user-defined types in
  3395. QuickBASIC. As in those languages, the ability to group different types in
  3396. the same construct provides powerful, very flexible data-handling
  3397. capabilities.  %@NL@%
  3398. %@NL@%
  3399. %@NL@%
  3400. %@4@%%@AB@%Creating a Simple Structure%@AE@%%@EH@%%@NL@%
  3401. %@NL@%
  3402. We'll write a simple program to demonstrate the basics of structures.
  3403. Suppose you want to write a payroll program that records these facts about
  3404. an employee:  %@NL@%
  3405. %@NL@%
  3406. %@NL@%
  3407.   ■   Name%@NL@%
  3408. %@NL@%
  3409.   ■   Number of months of service%@NL@%
  3410. %@NL@%
  3411.   ■   Hourly wage%@NL@%
  3412. %@NL@%
  3413. %@NL@%
  3414. Each of these data items requires a different data type. The name can be
  3415. stored in a string (character array), while an integer will do for the
  3416. months of service. The hourly wage may contain a fraction; we'll store it in
  3417. a floating-point variable.  %@NL@%
  3418. %@NL@%
  3419. Although each of these variables has a different type, we can group all of
  3420. them in a single structure. The EMPLOYEE.C program below contains the
  3421. structure.  %@NL@%
  3422. %@NL@%
  3423. %@AS@%  /* EMPLOYEE.C: Demonstrate structures. */
  3424. %@AS@%  
  3425. %@AS@%  #include <stdio.h>
  3426. %@AS@%  #include <string.h>
  3427. %@AS@%  
  3428. %@AS@%  struct employee
  3429. %@AS@%  {
  3430. %@AS@%     char name[10];
  3431. %@AS@%     int months;
  3432. %@AS@%     float wage;
  3433. %@AS@%  };
  3434. %@AS@%  
  3435. %@AS@%  void display( struct employee show );
  3436. %@AS@%  
  3437. %@AS@%  main()
  3438. %@AS@%  {
  3439. %@AS@%     struct employee jones;
  3440. %@AS@%  
  3441. %@AS@%     strcpy( jones.name, "Jones, J" );
  3442. %@AS@%     jones.months = 77;
  3443. %@AS@%     jones.wage = 13.68;
  3444. %@AS@%  
  3445. %@AS@%     display( jones );
  3446. %@AS@%  }
  3447. %@AS@%  
  3448. %@AS@%  void display( struct employee show )
  3449. %@AS@%  {
  3450. %@AS@%     printf( "Name: %s\n", show.name );
  3451. %@AS@%     printf( "Months of service: %d\n", show.months );
  3452. %@AS@%     printf( "Hourly wage: %6.2f\n", show.wage );
  3453. %@AS@%  }%@AE@%%@NL@%
  3454. %@NL@%
  3455. Here is the output of the EMPLOYEE.C program:  %@NL@%
  3456. %@NL@%
  3457. %@AS@%  Name: Jones, J
  3458. %@AS@%  Months of service: 77
  3459. %@AS@%  Hourly wage:  13.68%@AE@%%@NL@%
  3460. %@NL@%
  3461. %@NL@%
  3462. %@4@%%@AB@%Declaring a Structure Type%@AE@%%@EH@%%@NL@%
  3463. %@NL@%
  3464. Since a structure can (and normally does) contain different data types,
  3465. creating it is a little more complicated than making an array or simple
  3466. variable. Before you can create a structure variable, you must declare a
  3467. structure type that tells the compiler how many members the structure
  3468. contains and what types they are.  %@NL@%
  3469. %@NL@%
  3470. A structure-type declaration starts with the keyword %@AB@%struct%@AE@%, which is
  3471. followed by a list of the structure's members enclosed in braces. Between
  3472. the %@AB@%struct%@AE@% and the list of members, you can also specify a "structure tag"─a
  3473. name that other parts of the program can use to refer to the type.  %@NL@%
  3474. %@NL@%
  3475. The structure declaration from EMPLOYEE.C,  %@NL@%
  3476. %@NL@%
  3477. %@AS@%  struct employee
  3478. %@AS@%  {
  3479. %@AS@%     char name[10];
  3480. %@AS@%     int months;
  3481. %@AS@%     float wage;
  3482. %@AS@%  };%@AE@%%@NL@%
  3483. %@NL@%
  3484. %@AU@% A structure declaration makes a template for variables  of the type it
  3485. %@AU@%defines.%@AE@%  %@NL@%
  3486. %@NL@%
  3487. creates a "template" for an %@AS@% employee %@AE@% structure that structure variables of
  3488. this type can use. It's as if you created a brand new data type, tagging it
  3489. %@AS@%employee%@AE@%. Figure 4.6 illustrates the %@AS@% employee %@AE@% structure type.  %@NL@%
  3490. %@NL@%
  3491. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  3492. %@NL@%
  3493. %@NL@%
  3494. %@4@%%@AB@%Creating a Structure Variable%@AE@%%@EH@%%@NL@%
  3495. %@NL@%
  3496. Once you have declared a structure, you can create variables of that type
  3497. using the structure tag. Each variable can contain values of the types
  3498. defined in the structure type. In EMPLOYEE.C, the statement  %@NL@%
  3499. %@NL@%
  3500. %@AS@%  struct employee jones;%@AE@%%@NL@%
  3501. %@NL@%
  3502. declares a structure variable of the type %@AS@% employee %@AE@% named %@AS@% jones%@AE@%. The
  3503. %@AB@%struct%@AE@% states that the variable is a structure. The %@AS@% employee %@AE@% tag specifies
  3504. the variable's structure type, and %@AS@% jones %@AE@% is the variable's name.  %@NL@%
  3505. %@NL@%
  3506. You can also declare the variable in the same statement that declares the
  3507. structure type. The following code declares the %@AS@% employee %@AE@% structure type
  3508. and a variable of that type named %@AS@% jones%@AE@%:  %@NL@%
  3509. %@NL@%
  3510. %@AS@%  struct employee
  3511. %@AS@%  {
  3512. %@AS@%     char name[10];
  3513. %@AS@%     int months;
  3514. %@AS@%     float wage;
  3515. %@AS@%  } jones;%@AE@%%@NL@%
  3516. %@NL@%
  3517. The variable name (%@AS@% jones %@AE@%) appears at the end of the declaration.  %@NL@%
  3518. %@NL@%
  3519. %@AU@% Use the member-of operator (.) to specify structure members.%@AE@%  %@NL@%
  3520. %@NL@%
  3521. You specify structure members by name, using the "member-of" operator (%@AB@%.%@AE@%) to
  3522. separate the variable name and the member name. These are the names of the
  3523. members of the %@AS@% jones %@AE@% structure variable in EMPLOYEE.C:  %@NL@%
  3524. %@NL@%
  3525. %@AS@%  jones.name
  3526. %@AS@%  jones.months
  3527. %@AS@%  jones.wage%@AE@%%@NL@%
  3528. %@NL@%
  3529. Like other variables, structure variables should be initialized before use.
  3530. After %@AS@% jones %@AE@% is declared in EMPLOYEE.C, the statements  %@NL@%
  3531. %@NL@%
  3532. %@AS@%  strcpy( jones.name, "Jones, J" );
  3533. %@AS@%  jones.months = 77;
  3534. %@AS@%  jones.wage = 13.68;%@AE@%%@NL@%
  3535. %@NL@%
  3536. initialize the members of the %@AS@% jones %@AE@% variable. The first statement
  3537. initializes the %@AS@% jones.name %@AE@% member by calling the %@AB@%strcpy%@AE@% ("string copy")
  3538. library function; this function is described in Chapter 11, "Input and
  3539. Output."  %@NL@%
  3540. %@NL@%
  3541. Figure 4.7 shows how the %@AS@% jones %@AE@% structure is stored in memory. Again, since
  3542. computer memory is linear, the members of the structure are laid out
  3543. end-to-end.  %@NL@%
  3544. %@NL@%
  3545. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  3546. %@NL@%
  3547. You can initialize a structure when you declare it. The following code would
  3548. perform both operations in EMPLOYEE.C:  %@NL@%
  3549. %@NL@%
  3550. %@AS@%  struct employee jones =
  3551. %@AS@%  {
  3552. %@AS@%     "Jones, J",
  3553. %@AS@%     77,
  3554. %@AS@%     13.68
  3555. %@AS@%  };%@AE@%%@NL@%
  3556. %@NL@%
  3557. This code declares the %@AS@% jones %@AE@% structure variable and lists the initializing
  3558. value for each of its members.  %@NL@%
  3559. %@NL@%
  3560. %@NL@%
  3561. %@4@%%@AB@%Using Structure Variables%@AE@%%@EH@%%@NL@%
  3562. %@NL@%
  3563. A structure member can be treated like any other variable of its type. You
  3564. can assign a value to it, change its value, and so on. For instance, the
  3565. statement  %@NL@%
  3566. %@NL@%
  3567. %@AS@%  jones.months = 83;%@AE@%%@NL@%
  3568. %@NL@%
  3569. would change the value of the %@AS@% jones.months %@AE@% member in EMPLOYEE.C.  %@NL@%
  3570. %@NL@%
  3571. %@AU@% Assigning one structure  to another copies  the entire structure.%@AE@%  %@NL@%
  3572. %@NL@%
  3573. You can also assign an entire structure to another structure of the same
  3574. type. This copies the entire contents of the first structure to the second.
  3575. You might do this to save time when creating a new structure whose contents
  3576. differ only slightly from those of an existing structure.  %@NL@%
  3577. %@NL@%
  3578. To illustrate, let's modify the EMPLOYEE.C program. Say you have a second
  3579. employee named Lavik whose wage rate and months of service are the same as
  3580. those of Jones and you want to create a second structure. You could begin by
  3581. declaring a second %@AS@% employee %@AE@% structure variable named %@AS@% lavik %@AE@% in this
  3582. fashion:  %@NL@%
  3583. %@NL@%
  3584. %@AS@%  struct employee lavik = jones;%@AE@%%@NL@%
  3585. %@NL@%
  3586. Now the members of the %@AS@% lavik %@AE@% structure contain the same data as the
  3587. members of the %@AS@% jones %@AE@% structure. The %@AS@% lavik.name %@AE@% member contains the
  3588. string %@AS@% Jones, J%@AE@%, the %@AS@% lavik.months %@AE@% member contains the value 77, and the %@AS@%
  3589. %@AS@%lavik.wage %@AE@% member contains the value 13.68. You could add the statement  %@NL@%
  3590. %@NL@%
  3591. %@AS@%  strcpy( lavik.name, "Lavik, B" );%@AE@%%@NL@%
  3592. %@NL@%
  3593. to place a new string in the %@AS@% lavik.name %@AE@% member.  %@NL@%
  3594. %@NL@%
  3595. %@AU@% Structure variables can be passed as function arguments.%@AE@%  %@NL@%
  3596. %@NL@%
  3597. When you pass a structure name to a function, the function creates a local
  3598. structure variable of that type. Like all local variables, the new variable
  3599. is private to the function that includes it.  %@NL@%
  3600. %@NL@%
  3601. For example, if you add the statements  %@NL@%
  3602. %@NL@%
  3603. %@AS@%  strcpy( show.name, "King, M" );
  3604. %@AS@%  printf( "%s\n", show.name );%@AE@%%@NL@%
  3605. %@NL@%
  3606. to the end of the %@AS@% display %@AE@% function in EMPLOYEE.C, then a new string is
  3607. copied into the %@AS@% show.name %@AE@% member of the function's structure variable. The
  3608. %@AB@%printf%@AE@% statement in the second line prints  %@NL@%
  3609. %@NL@%
  3610. %@AS@%  King, M%@AE@%%@NL@%
  3611. %@NL@%
  3612. Since this structure is local to the %@AS@% display %@AE@% function, the change doesn't
  3613. affect the structure defined in the %@AB@%main%@AE@% function. If you add the statement
  3614. %@NL@%
  3615. %@NL@%
  3616. %@AS@%  printf( "%s\n", jones.name );%@AE@%%@NL@%
  3617. %@NL@%
  3618. to the end of the %@AB@%main%@AE@% function, the program prints  %@NL@%
  3619. %@NL@%
  3620. %@AS@%  Jones, J%@AE@%%@NL@%
  3621. %@NL@%
  3622. The original structure is unchanged.  %@NL@%
  3623. %@NL@%
  3624. While you can pass a structure name to a function as we did above, it's more
  3625. common to pass the function a %@AI@%pointer%@AE@% to the structure. This not only
  3626. permits the function to access a structure defined elsewhere in the program,
  3627. but it conserves memory (since the function doesn't create a local copy of
  3628. the structure). Chapter 9, "Advanced Pointers," explains how to access
  3629. structures using pointers.  %@NL@%
  3630. %@NL@%
  3631. %@NL@%
  3632. %@4@%%@AB@%Arrays of Structures%@AE@%%@EH@%%@NL@%
  3633. %@NL@%
  3634. %@AU@% An array of structures  is a group of structures  of the same type.%@AE@%  %@NL@%
  3635. %@NL@%
  3636. Since it's rare for a company to have a single employee, a more practical
  3637. version of the EMPLOYEE.C program would have an array of structures─one
  3638. structure per employee. The concept may sound intimidating, but this is a
  3639. common use of structures.  %@NL@%
  3640. %@NL@%
  3641. The following statement declares a 50-element array named %@AS@% payroll%@AE@%, with
  3642. each element a structure of the type %@AS@% employee %@AE@%:  %@NL@%
  3643. %@NL@%
  3644. %@AS@%  struct employee payroll[50];%@AE@%%@NL@%
  3645. %@NL@%
  3646. To specify members in such an array, you combine array notation and
  3647. structure notation, giving the array name, a subscript, and a member name.
  3648. For instance, the name  %@NL@%
  3649. %@NL@%
  3650. %@AS@%  payroll[0].months%@AE@%%@NL@%
  3651. %@NL@%
  3652. specifies the %@AS@% months %@AE@% member of the first structure in the %@AS@% payroll %@AE@% array.
  3653. The first part of the name (%@AS@% payroll[0] %@AE@%) contains the array name and
  3654. subscript that identify the structure. The second part (%@AS@% months %@AE@%) identifies
  3655. the member within that structure.  %@NL@%
  3656. %@NL@%
  3657. Figure 4.8 depicts the first three elements of the %@AS@% payroll %@AE@% array.  %@NL@%
  3658. %@NL@%
  3659. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  3660. %@NL@%
  3661. Once you grasp the basic idea, it's easy to imagine practical uses for an
  3662. array of structures. Many programs, from an address book to a library card
  3663. catalog, might use a structure to store different types of information about
  3664. an individual item, then store many such structures in an array.  %@NL@%
  3665. %@NL@%
  3666. %@NL@%
  3667. %@4@%%@AB@%Structures of Structures%@AE@%%@EH@%%@NL@%
  3668. %@NL@%
  3669. As noted earlier, a structure can contain members of any data type─including
  3670. other structures. So you can create a structure of structures: a structure
  3671. whose members are structures.  %@NL@%
  3672. %@NL@%
  3673. To illustrate, suppose you write a group of functions that draw various
  3674. kinds of graphic windows and message boxes. You could define a small
  3675. structure something like the following:  %@NL@%
  3676. %@NL@%
  3677. %@AS@%  struct title
  3678. %@AS@%  {
  3679. %@AS@%     char text[70];  /* Title text */
  3680. %@AS@%     int color;      /* Color of title text */
  3681. %@AS@%     short justify;  /* Left, center, or right */
  3682. %@AS@%  };%@AE@%%@NL@%
  3683. %@NL@%
  3684. to aid in drawing titles. The %@AS@% title %@AE@% structure's three members specify the
  3685. title's text, its color, and how its text is justified.  %@NL@%
  3686. %@NL@%
  3687. Once the %@AS@% title %@AE@% structure is defined, you can make it part of other, larger
  3688. structures that use titles. If you define a %@AS@% window %@AE@% structure type to draw
  3689. windows, for example, that structure could include a %@AS@% title %@AE@% along with
  3690. other structure members:  %@NL@%
  3691. %@NL@%
  3692. %@AS@%  struct window
  3693. %@AS@%  {
  3694. %@AS@%     struct title wintitle; /* Window title */
  3695. %@AS@%     /* Other structure members go here... */
  3696. %@AS@%  };%@AE@%%@NL@%
  3697. %@NL@%
  3698. In this structure type, the %@AS@% title %@AE@% member is named %@AS@% wintitle%@AE@%.  %@NL@%
  3699. %@NL@%
  3700. You specify members of such structures using member-of operators and  the
  3701. appropriate names. If you create a variable of the %@AS@% window %@AE@% type named %@AS@%
  3702. %@AS@%mywindow%@AE@%, the name  %@NL@%
  3703. %@NL@%
  3704. %@AS@%  mywindow.wintitle.color%@AE@%%@NL@%
  3705. %@NL@%
  3706. specifies the %@AS@% color %@AE@% member of the %@AS@% wintitle %@AE@% member of the %@AS@% mywindow %@AE@%
  3707. structure.  %@NL@%
  3708. %@NL@%
  3709. If you program using QuickC's Presentation Graphics library, you'll find it
  3710. useful to understand the notation we just explained. Our fictitious %@AS@% title %@AE@%
  3711. structure is a simplified version of the Presentation Graphics %@AB@%titletype%@AE@%
  3712. structure type (see Chapter 14, "Presentation Graphics").  %@NL@%
  3713. %@NL@%
  3714. %@NL@%
  3715. %@4@%%@AB@%Bit Fields%@AE@%%@EH@%%@NL@%
  3716. %@NL@%
  3717. A "bit field" is a specialized structure that provides a way to manipulate
  3718. individual bits or groups of bits. One use for this advanced feature is to
  3719. access hardware addresses such as the computer's video memory.  %@NL@%
  3720. %@NL@%
  3721. %@AU@% The members of a bit-field structure are groups of bits.%@AE@%  %@NL@%
  3722. %@NL@%
  3723. You declare and use a bit-field structure much as you would any other
  3724. structure. The difference is that every one of its members must be a bit or
  3725. group of bits. You can't include other data types in a bit field.  %@NL@%
  3726. %@NL@%
  3727. The following statement declares a bit-field structure type with the tag %@AS@%
  3728. %@AS@%SCREEN%@AE@%:  %@NL@%
  3729. %@NL@%
  3730. %@AS@%  struct SCREEN
  3731. %@AS@%  {
  3732. %@AS@%    unsigned character : 8;
  3733. %@AS@%    unsigned fgcolor   : 3;
  3734. %@AS@%    unsigned intensity : 1;
  3735. %@AS@%    unsigned bgcolor   : 3;
  3736. %@AS@%    unsigned blink     : 1;
  3737. %@AS@%  } screenbuf[25][80];%@AE@%%@NL@%
  3738. %@NL@%
  3739. The colons in the declaration tell QuickC these are bit fields rather than
  3740. normal structure members. The number following each colon tells how many
  3741. bits the field contains. In the %@AS@% SCREEN %@AE@% type the %@AS@% character %@AE@% member has 8
  3742. bits, %@AS@%intensity %@AE@% has 1 bit, and so on. Figure 4.9 illustrates the %@AS@% SCREEN %@AE@%
  3743. type.  %@NL@%
  3744. %@NL@%
  3745. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  3746. %@NL@%
  3747. Figure 4.10 illustrates memory allocation for the %@AS@% SCREEN %@AE@% type. The members
  3748. of the %@AS@% SCREEN %@AE@% type mirror the arrangement of bits in screen memory.  %@NL@%
  3749. %@NL@%
  3750. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  3751. %@NL@%
  3752. Take another look at the structure declaration. In addition to declaring a
  3753. structure type, the statement declares a two-dimensional array variable
  3754. %@AS@%screenbuf%@AE@%, of the same structure type. You could use this array as an
  3755. alternate video buffer. Many graphics programs use a similar arrangement to
  3756. switch between an alternate video buffer and the computer's video memory.  %@NL@%
  3757. %@NL@%
  3758. The five members of the %@AS@% SCREEN %@AE@% type happen to take up a full %@AB@%int%@AE@% (two
  3759. bytes, on DOS machines). A bit field need not fill up a byte or %@AB@%int%@AE@%; the bit
  3760. field can contain as many bits as you need up to the maximum number of bits
  3761. for the field's  %@NL@%
  3762. %@NL@%
  3763. base type. The base type for each field in the example is %@AB@%unsigned%@AE@% (%@AB@%unsigned
  3764. %@AB@%int%@AE@%), so each field can contain a maximum of 16 bits.  %@NL@%
  3765. %@NL@%
  3766. The members of a bit-field structure are accessed with the structure-member
  3767. operator─like other structure members. For instance, the name  %@NL@%
  3768. %@NL@%
  3769. %@AS@%  screenbuf[13][53].blink = 1;%@AE@%%@NL@%
  3770. %@NL@%
  3771. specifies the %@AS@% blink %@AE@% member of element 13, 53 of the %@AS@% screenbuf %@AE@% array.  %@NL@%
  3772. %@NL@%
  3773. The range of values you can assign to a bit-field member depends on the
  3774. member's size. Since the %@AS@% blink %@AE@% member of the %@AS@% SCREEN %@AE@% type contains one
  3775. bit, %@AS@% blink %@AE@% is limited to the value 0 or 1. The %@AS@% fgcolor %@AE@% member contains
  3776. three bits and can have any value from 0-7.  %@NL@%
  3777. %@NL@%
  3778. %@NL@%
  3779. %@3@%%@CR:C6A00040009 @%%@AB@%Unions%@AE@%%@EH@%%@NL@%
  3780. %@NL@%
  3781. %@AU@% A union is a group of  variables of different types  that share storage
  3782. %@AU@%space.%@AE@%  %@NL@%
  3783. %@NL@%
  3784. A union is a variable that can hold any one of several data types at
  3785. different times, using the same storage space. Unions are a rather advanced
  3786. feature. One use of them is to access DOS registers, which you may sometimes
  3787. need to access as bytes and at other times as words.  %@NL@%
  3788. %@NL@%
  3789. As with a structure, you must start by declaring a union type to tell the
  3790. compiler the number and types of the union's members. You include one of
  3791. each type that you expect to use.  %@NL@%
  3792. %@NL@%
  3793. The following code creates a union that can hold a %@AB@%char%@AE@%, %@AB@%int%@AE@%, or %@AB@%long%@AE@% value.
  3794. It declares a union type with the tag %@AS@% u_sample %@AE@% and declares a variable of
  3795. that type named %@AS@% example%@AE@%.  %@NL@%
  3796. %@NL@%
  3797. %@AS@%  union u_sample
  3798. %@AS@%  {
  3799. %@AS@%    char c_val;
  3800. %@AS@%    int i_val;
  3801. %@AS@%    long l_val;
  3802. %@AS@%  }  example;%@AE@%%@NL@%
  3803. %@NL@%
  3804. When you declare a union, QuickC allocates as much storage as the largest
  3805. data type in the union requires. Since the largest type in %@AS@% u_sample%@AE@%  is
  3806. %@AB@%long%@AE@%, this union contains four bytes.  %@NL@%
  3807. %@NL@%
  3808. The elements of a union are called members and use the same notation as
  3809. structure members. Thus, the members of the %@AS@% example %@AE@% union are named  %@NL@%
  3810. %@NL@%
  3811. %@AS@%  example.c_val
  3812. %@AS@%  example.i_val
  3813. %@AS@%  example.l_val%@AE@%%@NL@%
  3814. %@NL@%
  3815. The contents of a union depend on how you access it. For instance, the
  3816. statement  %@NL@%
  3817. %@NL@%
  3818. %@AS@%  example.c_val = '\0';%@AE@%%@NL@%
  3819. %@NL@%
  3820. stores a %@AB@%char%@AE@% value in the %@AS@% example %@AE@% union. Since a %@AB@%char%@AE@% value takes one
  3821. byte, the statement uses only one byte of the space in %@AS@% example%@AE@%. The
  3822. statement  %@NL@%
  3823. %@NL@%
  3824. %@AS@%  example.i_val = 77;%@AE@%%@NL@%
  3825. %@NL@%
  3826. uses two bytes of the union, because an %@AB@%int%@AE@% value requires two bytes of
  3827. storage. Likewise, the statement  %@NL@%
  3828. %@NL@%
  3829. %@AS@%  example.l_val = 75621;%@AE@%%@NL@%
  3830. %@NL@%
  3831. stores %@AB@%long%@AE@% value in %@AS@% example%@AE@%, taking up all four bytes of its storage
  3832. space. Figure 4.11 shows memory allocation for the three members in the %@AS@%
  3833. %@AS@%example %@AE@% union.  %@NL@%
  3834. %@NL@%
  3835. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  3836. %@NL@%
  3837. It's your job to keep track of what is stored in a union. If you store a
  3838. %@AB@%long%@AE@% value in %@AS@% example %@AE@% and mistakenly treat that value as a %@AB@%char%@AE@% value
  3839. later, the result may be nonsense. It's especially important not to confuse
  3840. integer and floating-point types, which are stored in different internal
  3841. formats.  %@NL@%
  3842. %@NL@%
  3843. Now that you're familiar with the data types that C offers, you are ready to
  3844. tackle more advanced data-handling concepts. The next chapter discusses
  3845. several of these.  %@NL@%
  3846. %@NL@%
  3847. %@NL@%
  3848. %@NL@%
  3849. %@NL@%
  3850. %@NL@%
  3851. %@NL@%
  3852. %@CR:C6A00050001 @%%@1@%%@AB@%Chapter 5  Advanced Data Types%@AE@%%@EH@%%@NL@%
  3853. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  3854. %@NL@%
  3855. In Chapter 4, "Data Types," we described the basic C data types and showed
  3856. how to declare and use different kinds of variables. This chapter examines
  3857. more advanced data topics, including the visibility and lifetime of
  3858. variables and the conversion of values from one data type to another.  %@NL@%
  3859. %@NL@%
  3860. If you know QuickPascal or QuickBASIC, some of these topics, such as
  3861. visibility, should be familiar. For example, a variable declared within a
  3862. function is visible (accessible) only in that function. One area in which C
  3863. differs notably from QuickPascal is type conversion. The C language gives
  3864. programmers the freedom to convert a value from one type to another type,
  3865. whereas QuickPascal does not.  %@NL@%
  3866. %@NL@%
  3867. %@NL@%
  3868. %@2@%%@CR:C6A00050002 @%%@AB@%Visibility%@AE@%%@EH@%%@NL@%
  3869. %@NL@%
  3870. Every variable in a C program has a definite "visibility" that determines
  3871. which parts of the program can "see," or access, the variable. Another term
  3872. for visibility is "scope."  %@NL@%
  3873. %@NL@%
  3874. As we mentioned in Chapter 1, "Anatomy of a C Program," there are two basic
  3875. kinds of visibility: local and external. A "local" variable─one declared
  3876. within a function─is visible only within that function. An "external"
  3877. variable─one declared outside all functions─is visible to all functions that
  3878. follow it in the program.  %@NL@%
  3879. %@NL@%
  3880. This section begins by describing local and external visibility, then goes
  3881. on to discuss visibility in multiple-file programs and the visibility of
  3882. functions.  %@NL@%
  3883. %@NL@%
  3884. ────────────────────────────────────────────────────────────────────────────%@NL@%
  3885. NOTE
  3886.  
  3887. %@AI@%While the examples in this section use simple %@AB@%int%@AE@%%@AI@% variables, visibility
  3888. %@AI@%rules apply equally to aggregate types such as arrays and structures.%@AE@%%@AE@%%@NL@%
  3889. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  3890. %@NL@%
  3891. %@AU@% Use external variables  only when necessary.%@AE@%  %@NL@%
  3892. %@NL@%
  3893. C programmers normally limit the visibility of each variable to those parts
  3894. of the program that need to access the variable. For instance, if a variable
  3895. is needed only within one function, it should always be local to that
  3896. function. By restricting a variable's visibility, you can prevent other
  3897. parts of the program from accidentally changing the variable's value. Such
  3898. haphazard side effects were common in older interpreted BASIC programs, in
  3899. which every variable had unlimited  visibility.  %@NL@%
  3900. %@NL@%
  3901. %@NL@%
  3902. %@3@%%@CR:C6A00050003 @%%@AB@%Local Variables%@AE@%%@EH@%%@NL@%
  3903. %@NL@%
  3904. %@AU@% Variables declared  within a function are  local to that function.%@AE@%  %@NL@%
  3905. %@NL@%
  3906. As we noted in Chapter 1, "Anatomy of a C Program," and Chapter 2,
  3907. "Functions," the place where you declare a variable controls where the
  3908. variable is visible. Declaring a variable within a function makes the
  3909. variable local to that function; the variable can be seen only within the
  3910. function.  %@NL@%
  3911. %@NL@%
  3912. The VISIBLE.C program below demonstrates local visibility. It contains a
  3913. function named %@AS@% be_bop %@AE@% that tries to print the value of the local variable %@AS@%
  3914. %@AS@%val%@AE@%.  %@NL@%
  3915. %@NL@%
  3916. %@AS@%  /* VISIBLE.C: Demonstrate local visibility. */
  3917. %@AS@%  
  3918. %@AS@%  #include <stdio.h>
  3919. %@AS@%  void be_bop( void );
  3920. %@AS@%  
  3921. %@AS@%  main()
  3922. %@AS@%  {
  3923. %@AS@%     int val = 10;
  3924. %@AS@%     be_bop();
  3925. %@AS@%  }
  3926. %@AS@%  
  3927. %@AS@%  void be_bop( void )
  3928. %@AS@%  {
  3929. %@AS@%     printf( "val = %d", val ); /* Error! */
  3930. %@AS@%  }%@AE@%%@NL@%
  3931. %@NL@%
  3932. Notice where the %@AS@% val %@AE@% variable is declared. The declaration  %@NL@%
  3933. %@NL@%
  3934. %@AS@%  int val = 10;%@AE@%%@NL@%
  3935. %@NL@%
  3936. occurs within the %@AB@%main%@AE@% function, so %@AS@% val %@AE@% is local to %@AB@%main%@AE@%. When you compile
  3937. VISIBLE.C, QuickC stops, providing this error message:  %@NL@%
  3938. %@NL@%
  3939. %@AS@%  C2065: 'val' : undefined%@AE@%%@NL@%
  3940. %@NL@%
  3941. What happened? The %@AB@%printf%@AE@% statement in the %@AS@% be_bop %@AE@% function  %@NL@%
  3942. %@NL@%
  3943. %@AS@%  printf( "val = %d", val ); /* Error! */%@AE@%%@NL@%
  3944. %@NL@%
  3945. can't "see" the variable %@AS@% val%@AE@%, which is declared locally within %@AB@%main%@AE@%.
  3946. Outside the %@AB@%main%@AE@% function, in which %@AS@% val %@AE@% is declared, the variable doesn't
  3947. exist.  %@NL@%
  3948. %@NL@%
  3949. You could eliminate the error message by declaring %@AS@% val %@AE@% externally, but
  3950. most programmers would avoid that solution. If a variable has external
  3951. visibility, any part of the program might change its value accidentally. A
  3952. better solution is to pass the value of %@AS@% val %@AE@% to %@AS@% be_bop %@AE@% as a function
  3953. argument, as shown in the program VISIBLE1.C below.  %@NL@%
  3954. %@NL@%
  3955. %@AS@%  /* VISIBLE1.C: Demonstrate local visibility. */
  3956. %@AS@%  
  3957. %@AS@%  #include <stdio.h>
  3958. %@AS@%  
  3959. %@AS@%  void be_bop( int param );
  3960. %@AS@%  
  3961. %@AS@%  main()
  3962. %@AS@%  {
  3963. %@AS@%     int val = 10;
  3964. %@AS@%     be_bop( val );
  3965. %@AS@%  }
  3966. %@AS@%  
  3967. %@AS@%  void be_bop( int param )
  3968. %@AS@%  {
  3969. %@AS@%     printf( "%d\n", param );
  3970. %@AS@%  }%@AE@%%@NL@%
  3971. %@NL@%
  3972. The VISIBLE1.C program is identical to VISIBLE.C except for two changes. The
  3973. %@AS@% be_bop %@AE@% function now can accept an argument, and the statement that calls
  3974. %@AS@%be_bop %@AE@% passes the value of %@AS@% val %@AE@% as an argument. These changes allow the %@AS@%
  3975. %@AS@%be_bop %@AE@% function to print the value of %@AS@% val %@AE@% without the drawback of making %@AS@%
  3976. %@AS@%val %@AE@% external.  %@NL@%
  3977. %@NL@%
  3978. Most local variables are declared at the beginning of the function and are
  3979. visible throughout the function. If you declare the variable later in the
  3980. function, it is visible only to statements that follow the declaration.  %@NL@%
  3981. %@NL@%
  3982. The reason for this rule is simple: QuickC, like all language compilers,
  3983. reads your program line by line, from beginning to end. Until the compiler
  3984. sees the variable's declaration, it must treat the variable as undefined.
  3985. This rule applies to all variables, including external variables, as we'll
  3986. see in the next section.  %@NL@%
  3987. %@NL@%
  3988. Although the practice isn't common, you can restrict a local variable's
  3989. visibility even further by declaring it in a statement block inside a
  3990. function. For instance, you might declare a variable within the body of the
  3991. loop or conditional statement. In fact, any pair of curly braces limits the
  3992. visibility of a variable declared within that pair.  %@NL@%
  3993. %@NL@%
  3994. %@NL@%
  3995. %@3@%%@CR:C6A00050004 @%%@AB@%External Variables%@AE@%%@EH@%%@NL@%
  3996. %@NL@%
  3997. If you declare a variable outside all functions, the variable has external
  3998. visibility; every function that follows the declaration can see the
  3999. variable. External variables are called "global" in some other languages.  %@NL@%
  4000. %@NL@%
  4001. Experienced C programmers use external variables only when necessary─for
  4002. instance, when two or more functions need the ability to change the same
  4003. variable or communicate with each other by changing a variable. Even in
  4004. those cases, however, you may be able to avoid the dangers of external
  4005. visibility by passing a pointer to the variable as a function argument. See
  4006. the section "Passing Pointers to Functions" in Chapter 8 ("Pointers") for
  4007. more information.  %@NL@%
  4008. %@NL@%
  4009. Most external variables are declared near the beginning of the program,
  4010. before any function definitions. In this way, you can make the variable
  4011. visible to every function in the program. You could do this in VISIBLE1.C by
  4012. placing the declaration of %@AS@% val%@AE@%,  %@NL@%
  4013. %@NL@%
  4014. %@AS@%  int val = 10;%@AE@%%@NL@%
  4015. %@NL@%
  4016. immediately before the %@AB@%main%@AE@% function.  %@NL@%
  4017. %@NL@%
  4018. If you declare the variable %@AS@% val %@AE@% later in the program, it is not visible to
  4019. functions that precede the declaration. The VISIBLE2.C program below
  4020. demonstrates this principle.  %@NL@%
  4021. %@NL@%
  4022. %@AS@%  /* VISIBLE2.C: Demonstrate external visibility. */
  4023. %@AS@%  
  4024. %@AS@%  #include <stdio.h>
  4025. %@AS@%  
  4026. %@AS@%  void be_bop( int param );
  4027. %@AS@%  
  4028. %@AS@%  main()
  4029. %@AS@%  {
  4030. %@AS@%     be_bop( val ); /* Error! */
  4031. %@AS@%  }
  4032. %@AS@%  
  4033. %@AS@%  int val = 10;
  4034. %@AS@%  
  4035. %@AS@%  void be_bop( int param )
  4036. %@AS@%  {
  4037. %@AS@%     printf( "val = %d\n", param );
  4038. %@AS@%  }%@AE@%%@NL@%
  4039. %@NL@%
  4040. The VISIBLE2.C program is identical to VISIBLE1.C except that %@AS@% val %@AE@% is
  4041. declared externally  %@NL@%
  4042. %@NL@%
  4043. %@AS@%  int val = 10;%@AE@%%@NL@%
  4044. %@NL@%
  4045. following the %@AB@%main%@AE@% function, rather than locally within %@AB@%main%@AE@%.  %@NL@%
  4046. %@NL@%
  4047. Because the declaration occurs outside all functions, the variable is
  4048. external. However, because the declaration follows the %@AB@%main%@AE@% function, the
  4049. variable is not visible within %@AB@%main%@AE@%. When the %@AB@%printf%@AE@% statement in the %@AB@%main%@AE@%
  4050. function refers to %@AS@% val%@AE@%, QuickC issues the error message:  %@NL@%
  4051. %@NL@%
  4052. %@AS@%  C2065: 'val' : undefined%@AE@%%@NL@%
  4053. %@NL@%
  4054. Remember, QuickC reads the program line by line, from start to finish. Since
  4055. the compiler knows nothing about %@AS@% val %@AE@% when it reaches the reference in
  4056. %@AB@%main%@AE@%, it must treat %@AS@% val %@AE@% as undefined. In this program, only the %@AS@% be_bop %@AE@%
  4057. function can refer to %@AS@% val%@AE@%.  %@NL@%
  4058. %@NL@%
  4059. %@NL@%
  4060. %@3@%%@CR:C6A00050005 @%%@AB@%Visibility in Multiple Source Files%@AE@%%@EH@%%@NL@%
  4061. %@NL@%
  4062. A "source file" is the file containing your program's text. Source files
  4063. normally have the .C file extension, to distinguish them from other files
  4064. such as executable (.EXE) files.  %@NL@%
  4065. %@NL@%
  4066. Simple programs have only one source file, but large programs are often
  4067. split into several source files. If you write a word-processing program, for
  4068. instance, you might place all the program's screen-output functions in one
  4069. file, all the file-handling functions in a second file, and so forth.  %@NL@%
  4070. %@NL@%
  4071. %@AU@% Use the extern keyword to make an external variable visible in more than
  4072. %@AU@%one source file.%@AE@%  %@NL@%
  4073. %@NL@%
  4074. Normally, an external variable is visible only in the source file in which
  4075. it is declared. In a multi-file program, however, a function in one file
  4076. might need to access a variable in a second file. To make the variable
  4077. visible in more than one source file, you must declare it with the %@AB@%extern%@AE@%
  4078. keyword.  %@NL@%
  4079. %@NL@%
  4080. Let's look at a short two-file program that shows how to use %@AB@%extern%@AE@%. The
  4081. first source file, FILE1.C, declares two external variables, %@AS@% chico %@AE@% and %@AS@%
  4082. %@AS@%harpo%@AE@%. The file contains one function (%@AB@%main%@AE@%) that calls a second function
  4083. named %@AS@% yonder%@AE@%.  %@NL@%
  4084. %@NL@%
  4085. %@AS@%  /* FILE1.C: Visibility in multiple source files. */
  4086. %@AS@%  
  4087. %@AS@%  int chico = 20, harpo = 30;
  4088. %@AS@%  extern void yonder( void );
  4089. %@AS@%  
  4090. %@AS@%  main()
  4091. %@AS@%  {
  4092. %@AS@%     yonder();
  4093. %@AS@%  }%@AE@%%@NL@%
  4094. %@NL@%
  4095. The second source file, FILE2.C, contains the %@AS@% yonder %@AE@% function that is
  4096. called in FILE1.C. This file also declares the variables %@AS@% chico %@AE@% and %@AS@% harpo,
  4097. %@AS@%%@AE@% but it prefaces their declarations with %@AB@%extern%@AE@% to show that the variables
  4098. are defined externally in some other file. Once this is done, any function
  4099. in FILE2.C can refer to %@AS@% chico %@AE@% and %@AS@% harpo %@AE@% as if they are defined in the
  4100. same file.  %@NL@%
  4101. %@NL@%
  4102. %@AS@%  /* FILE2.C: Visibility in multiple source files. */
  4103. %@AS@%  
  4104. %@AS@%  #include <stdio.h>
  4105. %@AS@%  
  4106. %@AS@%  void yonder( void )
  4107. %@AS@%  {
  4108. %@AS@%     extern int chico, harpo;
  4109. %@AS@%     printf( "chico = %d, harpo = %d\n", chico, harpo );
  4110. %@AS@%  }%@AE@%%@NL@%
  4111. %@NL@%
  4112. You can compile this program in one of two ways. In the QuickC environment,
  4113. choose Set Program List from the Make menu and add FILE1.C and FILE2.C to
  4114. the list. Then choose Build Program from the Make menu.  %@NL@%
  4115. %@NL@%
  4116. You can also enter this command from the DOS command line:  %@NL@%
  4117. %@NL@%
  4118. %@AS@%  qcl FILE1.C FILE2.C%@AE@%%@NL@%
  4119. %@NL@%
  4120. In either case, the executable file is named FILE1.EXE. The program's
  4121. output,  %@NL@%
  4122. %@NL@%
  4123. %@AS@%  chico = 20, harpo = 30%@AE@%%@NL@%
  4124. %@NL@%
  4125. shows that the %@AS@% yonder %@AE@% function in FILE2.C can access the variables defined
  4126. in FILE1.C.  %@NL@%
  4127. %@NL@%
  4128. Sometimes you may want an external variable to be visible only in the source
  4129. file where it's declared. The variable can be shared by functions in one
  4130. file, but it is hidden to all other files, thus minimizing the risk of
  4131. naming conflicts.  %@NL@%
  4132. %@NL@%
  4133. %@AU@% The static keyword  can limit a variable's visibility to one source file.%@AE@%  %@NL@%
  4134. %@NL@%
  4135. To limit a variable's visibility to one file, precede the variable's
  4136. declaration with the keyword %@AB@%static%@AE@%. For example, if FILE1.C declared the %@AS@%
  4137. %@AS@%harpo %@AE@% variable as %@AB@%static%@AE@% in this manner,  %@NL@%
  4138. %@NL@%
  4139. %@AS@%  static int harpo;%@AE@%%@NL@%
  4140. %@NL@%
  4141. it would prevent FILE2.C from accessing %@AS@% harpo %@AE@% at all, even though FILE2.C
  4142. declares (with %@AB@%extern%@AE@%) that %@AS@% harpo %@AE@% is defined somewhere else.  %@NL@%
  4143. %@NL@%
  4144. %@NL@%
  4145. %@3@%%@CR:C6A00050006 @%%@AB@%Visibility of Functions%@AE@%%@EH@%%@NL@%
  4146. %@NL@%
  4147. %@AU@% Functions are normally visible in multiple source files.%@AE@%  %@NL@%
  4148. %@NL@%
  4149. Unlike variables, functions are external by default. That is, they are
  4150. normally visible to every file in a multi-file program. You'll notice that
  4151. in FILE1.C we declared the %@AS@% yonder %@AE@% function with the %@AB@%extern%@AE@% keyword. We did
  4152. this merely to improve readability; the keyword shows clearly that the
  4153. function is defined in some other file. If we removed the %@AB@%extern%@AE@% from the
  4154. declaration of %@AS@% yonder %@AE@% in FILE1.C, the program would work just as well as
  4155. before.  %@NL@%
  4156. %@NL@%
  4157. At times you may want to restrict the visibility of a function in a
  4158. multi-file program, making it visible in some files but not in others. By
  4159. "hiding" a function from other parts of a program, you can reduce the danger
  4160. of naming conflicts. For instance, if you write a library of functions to
  4161. sell commercially, you probably would hide all of the library's local
  4162. function names, to prevent conflicts with function names your customers
  4163. might create.  %@NL@%
  4164. %@NL@%
  4165. %@AU@% The static keyword can  limit a function's visibility.%@AE@%  %@NL@%
  4166. %@NL@%
  4167. As with external variables, you limit a function's visibility using the
  4168. %@AB@%static%@AE@% keyword. A function declared as %@AB@%static%@AE@% is visible only in the source
  4169. file that declares it. If we add %@AB@%static%@AE@% to the header of the %@AS@% yonder %@AE@%
  4170. function, for example,  %@NL@%
  4171. %@NL@%
  4172. %@AS@%  static void yonder( void )%@AE@%%@NL@%
  4173. %@NL@%
  4174. the function could no longer be called from the FILE1.C file.  %@NL@%
  4175. %@NL@%
  4176. %@NL@%
  4177. %@2@%%@CR:C6A00050007 @%%@AB@%Lifetime%@AE@%%@EH@%%@NL@%
  4178. %@NL@%
  4179. In addition to visibility, every variable also has a certain "lifetime"─that
  4180. is, the period during the program's execution when the variable exists.  %@NL@%
  4181. %@NL@%
  4182. External variables exist for the life of the program. Memory is allocated
  4183. for them when the program begins and remains until the program ends.  %@NL@%
  4184. %@NL@%
  4185. %@AU@% An automatic variable  disappears when the function ends.%@AE@%  %@NL@%
  4186. %@NL@%
  4187. Local variables have shorter lifetimes. They come into being when the
  4188. function begins and disappear when the function ends. For this reason, a
  4189. local variable is said to be "automatic." The variable comes and goes
  4190. automatically, each time the function is called.  %@NL@%
  4191. %@NL@%
  4192. Automatic variables conserve memory in a couple of ways. First, since they
  4193. evaporate when the function ends, automatic variables don't consume memory
  4194. when not in use. Second, they are stored in the "stack" memory area, which
  4195. the program allocates at run time. So, automatic variables don't enlarge the
  4196. executable program.  %@NL@%
  4197. %@NL@%
  4198. The C language provides the %@AB@%auto%@AE@% keyword for declaring automatic variables.
  4199. However, this keyword is seldom used, since all local variables are
  4200. automatic unless you specify otherwise. In the following function, both %@AS@% val
  4201. %@AS@%%@AE@% and %@AS@% example %@AE@% are automatic variables:  %@NL@%
  4202. %@NL@%
  4203. %@AS@%  void sample( void )
  4204. %@AS@%  {
  4205. %@AS@%     int val;
  4206. %@AS@%     auto int example;
  4207. %@AS@%  }%@AE@%%@NL@%
  4208. %@NL@%
  4209. The %@AB@%auto%@AE@% preceding the declaration of %@AS@% example %@AE@% has no practical effect. The
  4210. variable %@AS@% example %@AE@% is automatic even if you remove the %@AB@%auto%@AE@% from its
  4211. declaration.  %@NL@%
  4212. %@NL@%
  4213. %@NL@%
  4214. %@3@%%@CR:C6A00050008 @%%@AB@%Extending the Lives of Local Variables%@AE@%%@EH@%%@NL@%
  4215. %@NL@%
  4216. Occasionally, you may want a local variable to retain its value between
  4217. function calls. The %@AB@%static%@AE@% keyword, introduced earlier as a means of
  4218. limiting the visibility of external variables, also performs this task.  %@NL@%
  4219. %@NL@%
  4220. %@AU@% A static local variable  retains its value through  subsequent function
  4221. %@AU@%calls.%@AE@%  %@NL@%
  4222. %@NL@%
  4223. If you precede a local variable declaration with %@AB@%static%@AE@%, the variable exists
  4224. for the life of the program─the same lifetime as an external variable. The
  4225. variable still has local visibility, however.  %@NL@%
  4226. %@NL@%
  4227. The STATIC.C program below shows how to create and use a %@AB@%static%@AE@% local
  4228. variable. In STATIC.C, the value of the %@AS@% methuselah %@AE@% variable persists
  4229. through all calls to the %@AS@% add_val %@AE@% function, which adds values to %@AS@%
  4230. %@AS@%methuselah %@AE@% and prints the variable's value.  %@NL@%
  4231. %@NL@%
  4232. %@AS@%  /* STATIC.C: Demonstrate static variables. */
  4233. %@AS@%  
  4234. %@AS@%  #include <stdio.h>
  4235. %@AS@%  
  4236. %@AS@%  void add_val( int value );
  4237. %@AS@%  
  4238. %@AS@%  main()
  4239. %@AS@%  {
  4240. %@AS@%     add_val( 1 );
  4241. %@AS@%     add_val( 5 );
  4242. %@AS@%     add_val( 20 );
  4243. %@AS@%  }%@AE@%%@NL@%
  4244. %@NL@%
  4245. %@AS@%  void add_val( int value )
  4246. %@AS@%  {
  4247. %@AS@%     static int methuselah;
  4248. %@AS@%     if( value == 1 )
  4249. %@AS@%        methuselah = 0;
  4250. %@AS@%     methuselah = methuselah + value;
  4251. %@AS@%     printf( "methuselah = %d\n", methuselah );
  4252. %@AS@%  }%@AE@%%@NL@%
  4253. %@NL@%
  4254. The %@AS@% add_val %@AE@% function in STATIC.C accepts one parameter and also declares a
  4255. %@AB@%static%@AE@% local variable named %@AS@% methuselah%@AE@%. Each time %@AS@% add_val %@AE@% is called, it
  4256. adds the passed value to %@AS@% methuselah%@AE@%.  %@NL@%
  4257. %@NL@%
  4258. The %@AB@%main%@AE@% function calls the %@AS@% add_val %@AE@% function three times, passing the
  4259. values 1, 5, and 20 to %@AS@% add_val %@AE@% as arguments. The program's output  %@NL@%
  4260. %@NL@%
  4261. %@AS@%  methuselah = 1
  4262. %@AS@%  methuselah = 6
  4263. %@AS@%  methuselah = 26%@AE@%%@NL@%
  4264. %@NL@%
  4265. shows that the value of %@AS@% methuselah %@AE@% persists through all three function
  4266. calls.  %@NL@%
  4267. %@NL@%
  4268. If we remove the %@AB@%static%@AE@% keyword from the declaration of %@AS@% methuselah%@AE@%, the
  4269. variable's value is not preserved between function calls. The value of %@AS@%
  4270. %@AS@%methuselah %@AE@% is unpredictable the second and third times that %@AS@% add_val %@AE@% is
  4271. called.  %@NL@%
  4272. %@NL@%
  4273. Notice that extending a local variable's lifetime with %@AB@%static%@AE@% doesn't affect
  4274. its visibility. The %@AS@% methuselah %@AE@% variable keeps its value between function
  4275. calls, but you can't refer to the variable outside the %@AS@% add_val %@AE@% function.  %@NL@%
  4276. %@NL@%
  4277. %@NL@%
  4278. %@2@%%@CR:C6A00050009 @%%@AB@%Converting Data Types%@AE@%%@EH@%%@NL@%
  4279. %@NL@%
  4280. It's usually best to avoid mixing data items of different types in the same
  4281. expression. You wouldn't normally add a character variable to a
  4282. floating-point variable, for instance. Some languages, such as QuickPascal,
  4283. generally treat type mixing as an error. However, the C language gives you
  4284. the freedom to mix data types when necessary.  %@NL@%
  4285. %@NL@%
  4286. For example, since the %@AB@%char%@AE@% and %@AB@%int%@AE@% types both can store whole numbers,
  4287. there may be times when you have a good reason to add a %@AB@%char%@AE@% value to an %@AB@%int%@AE@%
  4288. value. When you mix types, QuickC does not issue an error message. Instead,
  4289. the compiler converts both data items to the same type and then performs the
  4290. requested operation.  %@NL@%
  4291. %@NL@%
  4292. Type conversion can occur in one of two ways. The first way occurs
  4293. automatically when you combine different types in an expression. You can
  4294. also use special syntax to intentionally "cast" (convert) one type to
  4295. another. We'll discuss both methods in the following sections.  %@NL@%
  4296. %@NL@%
  4297. Knowing how C converts types will help you to find bugs that result from
  4298. unintended type clashes and to minimize errors when you deliberately mix
  4299. types.  %@NL@%
  4300. %@NL@%
  4301. %@NL@%
  4302. %@3@%%@CR:C6A00050010 @%%@AB@%Ranking of Data Types%@AE@%%@EH@%%@NL@%
  4303. %@NL@%
  4304. For purposes of conversion, the C language ranks data types in the order
  4305. shown in Figure 5.1.  %@NL@%
  4306. %@NL@%
  4307. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  4308. %@NL@%
  4309. The ranking illustrated in Figure 5.1 generally reflects the amount of
  4310. storage that each type requires. As you may remember from Chapter 4, "Data
  4311. Types," larger data types require more storage than smaller types. Thus, an
  4312. %@AB@%int%@AE@%, which requires two bytes of storage, outranks a %@AB@%char%@AE@%, which requires
  4313. one byte.  %@NL@%
  4314. %@NL@%
  4315. Within this ranking, an %@AB@%unsigned%@AE@% type outranks the corresponding %@AB@%signed%@AE@%
  4316. type. An %@AB@%unsigned char%@AE@% value is of higher rank than a %@AB@%signed char%@AE@%, and so
  4317. forth.  %@NL@%
  4318. %@NL@%
  4319. %@NL@%
  4320. %@3@%%@CR:C6A00050011 @%%@AB@%Promotions and Demotions%@AE@%%@EH@%%@NL@%
  4321. %@NL@%
  4322. %@AU@% A promotion is usually harmless.%@AE@%  %@NL@%
  4323. %@NL@%
  4324. A type conversion always involves two data items of different types.
  4325. Whenever possible, QuickC converts the lower-ranking (smaller) data item to
  4326. the higher-ranking (larger) type. This kind of conversion, called a
  4327. "promotion," is normally harmless. For example, since a two-byte %@AB@%int%@AE@% has
  4328. more than enough room to store a one-byte %@AB@%char%@AE@%, it's generally safe to
  4329. promote a %@AB@%char%@AE@% value to an %@AB@%int%@AE@%.  %@NL@%
  4330. %@NL@%
  4331. %@AU@% A demotion usually causes a loss of data.%@AE@%  %@NL@%
  4332. %@NL@%
  4333. Sometimes, the compiler is forced to convert a higher-ranking value to a
  4334. lower-ranking type. This kind of conversion, called a "demotion," usually
  4335. causes loss of data. For example, the %@AB@%int%@AE@% value 32,000 is much too large to
  4336. be stored in a %@AB@%char%@AE@% type, which can't hold a number larger than 255. If you
  4337. assign the value 32,000 to a %@AB@%char%@AE@% variable, some data must be lost.  %@NL@%
  4338. %@NL@%
  4339. A demotion of an integer type truncates the higher-ranking type, throwing
  4340. away the data from high-order bytes that can't fit in the smaller-ranking
  4341. value. Some demotions of floating-point types round off a value rather than
  4342. truncate it.  %@NL@%
  4343. %@NL@%
  4344. %@NL@%
  4345. %@3@%%@CR:C6A00050012 @%%@AB@%Automatic Type Conversions%@AE@%%@EH@%%@NL@%
  4346. %@NL@%
  4347. %@AU@% C does an automatic  type conversion when you  mix different data types.%@AE@%  %@NL@%
  4348. %@NL@%
  4349. When a program statement mixes two different data types, QuickC performs an
  4350. automatic type conversion. The following code, for instance, adds the %@AB@%char%@AE@%
  4351. variable %@AS@% a %@AE@% to the %@AB@%int%@AE@% variable %@AS@% b%@AE@%.  %@NL@%
  4352. %@NL@%
  4353. %@AS@%  char a = 5;
  4354. %@AS@%  int b = 32000;
  4355. %@AS@%  b = a + b;%@AE@%%@NL@%
  4356. %@NL@%
  4357. In the statement  %@NL@%
  4358. %@NL@%
  4359. %@AS@%  b = a + b;%@AE@%%@NL@%
  4360. %@NL@%
  4361. the addition operation to the right of the equal sign triggers an automatic
  4362. type conversion. QuickC promotes the %@AB@%char%@AE@% value to an %@AB@%int%@AE@% and then adds the
  4363. two %@AB@%int%@AE@% values.  %@NL@%
  4364. %@NL@%
  4365. If you're not sure whether QuickC is doing an automatic type conversion, set
  4366. Warning Level 2 or higher in the Compiler Flags dialog box. The compiler
  4367. generates the warning message  %@NL@%
  4368. %@NL@%
  4369. %@AS@%  C4051: data conversion%@AE@%%@NL@%
  4370. %@NL@%
  4371. whenever an automatic conversion occurs. This monitoring helps you readily
  4372. identify unwanted conversions.  %@NL@%
  4373. %@NL@%
  4374. If you carelessly mix different types, you may create subtle errors. The
  4375. CONVERT.C program below has a deliberate error that shows what can happen
  4376. when types are mixed. It adds four variables and assigns their sum to a
  4377. fifth variable, causing three promotions and one demotion.  %@NL@%
  4378. %@NL@%
  4379. %@AS@%  /* CONVERT.C: Demonstrate type conversions. */
  4380. %@AS@%  
  4381. %@AS@%  #include <stdio.h>
  4382. %@AS@%  
  4383. %@AS@%  main()
  4384. %@AS@%  {
  4385. %@AS@%     char c_val = 10;
  4386. %@AS@%     int i_val = 20;
  4387. %@AS@%     long l_val = 64000;
  4388. %@AS@%     float f_val = 3.1;
  4389. %@AS@%     int result;
  4390. %@AS@%  
  4391. %@AS@%     result = c_val + i_val + l_val + f_val;  /* Error! */
  4392. %@AS@%  
  4393. %@AS@%     printf( "%d\n", result );
  4394. %@AS@%  }%@AE@%%@NL@%
  4395. %@NL@%
  4396. The CONVERT.C program adds the numbers 10, 20, 64000, and 3.1. Instead of
  4397. the correct result, 64033.10, the program prints  %@NL@%
  4398. %@NL@%
  4399. %@AS@%  -1503%@AE@%%@NL@%
  4400. %@NL@%
  4401. Something definitely went wrong. The problem lies somewhere in the line  %@NL@%
  4402. %@NL@%
  4403. %@AS@%  result = c_val + i_val + l_val + f_val;%@AE@%%@NL@%
  4404. %@NL@%
  4405. which triggers four automatic type conversions. We'll examine the
  4406. conversions in order.  %@NL@%
  4407. %@NL@%
  4408. The first conversion occurs when the %@AB@%char%@AE@% variable %@AS@% c_val %@AE@% is added to the
  4409. %@AB@%int%@AE@% variable %@AS@% i_val%@AE@%:  %@NL@%
  4410. %@NL@%
  4411. %@AS@%  c_val + i_val%@AE@%%@NL@%
  4412. %@NL@%
  4413. Since the variables are different types, QuickC automatically converts the
  4414. lower-ranking %@AB@%char%@AE@% value to the higher-ranking %@AB@%int%@AE@% type before adding them.
  4415. This promotion doesn't create any problems, since there's more than enough
  4416. room to store the one-byte %@AB@%char%@AE@% value in the two-byte %@AB@%int%@AE@%. The sum of this
  4417. addition is 30, another %@AB@%int%@AE@% value.  %@NL@%
  4418. %@NL@%
  4419. The next operation adds that partial sum to the %@AB@%long%@AE@% value of %@AS@% l_val %@AE@% (to
  4420. make the expression easier to read, we'll show the sum from the previous
  4421. addition):  %@NL@%
  4422. %@NL@%
  4423. %@AS@%  30 + l_val%@AE@%%@NL@%
  4424. %@NL@%
  4425. This addition triggers another promotion. The compiler promotes the %@AB@%int%@AE@%
  4426. result of the first addition to a %@AB@%long%@AE@% value before adding it to %@AS@% l_val%@AE@%,
  4427. which is %@AB@%long%@AE@%. Since the four-byte %@AB@%long%@AE@% type has more than enough room to
  4428. store a two-byte %@AB@%int%@AE@%, this promotion is also harmless.  %@NL@%
  4429. %@NL@%
  4430. Now the partial sum equals 64030. The last addition from CONVERT.C  %@NL@%
  4431. %@NL@%
  4432. %@AS@%  64030 + f_val%@AE@%%@NL@%
  4433. %@NL@%
  4434. triggers another harmless conversion: the compiler converts the %@AB@%long%@AE@% result
  4435. of the previous addition to a %@AB@%float%@AE@% value before adding it to %@AS@% f_val%@AE@%. Even
  4436. though floating-point and integer values are stored in different internal
  4437. formats, no data is lost when the %@AB@%long%@AE@% is converted to a %@AB@%float%@AE@%.  %@NL@%
  4438. %@NL@%
  4439. The result of these additions and conversions is the %@AB@%float%@AE@% value 64033.10,
  4440. which is correct. So where does the mistake occur?  %@NL@%
  4441. %@NL@%
  4442. The problem arises when CONVERT.C assigns the final sum to the wrong type of
  4443. variable. You'll recall that the line containing these operations begins
  4444. with the assignment%@AS@% result =%@AE@%.  %@NL@%
  4445. %@NL@%
  4446. Earlier in the program, we declared the variable %@AS@% result %@AE@% as an %@AB@%int%@AE@%. The
  4447. twobyte %@AB@%int%@AE@% variable created to store the result of these additions is too
  4448. small to contain the four-byte %@AB@%float%@AE@% sum that was finally produced.  %@NL@%
  4449. %@NL@%
  4450. The assignment forces QuickC to demote the larger %@AB@%float%@AE@% value to the smaller
  4451. %@AB@%int%@AE@% type. It's impossible to store such a large floating-point value in the
  4452. two bytes of an %@AB@%int%@AE@%, so the final result is incorrect.  %@NL@%
  4453. %@NL@%
  4454. Figure 5.2 shows the progression of automatic type conversions that the
  4455. CONVERT.C program produces.  %@NL@%
  4456. %@NL@%
  4457. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  4458. %@NL@%
  4459. We can fix the conversion error by declaring the variable %@AS@% result %@AE@% as a
  4460. %@AB@%float%@AE@%, substituting  %@NL@%
  4461. %@NL@%
  4462. %@AS@%  float result;%@AE@%%@NL@%
  4463. %@NL@%
  4464. for the earlier declaration. We'll also need to change the format string in
  4465. the %@AB@%printf%@AE@% function call to print a %@AB@%float%@AE@% value, as shown below:  %@NL@%
  4466. %@NL@%
  4467. %@AS@%  printf( "%6.2f\n", result );%@AE@%%@NL@%
  4468. %@NL@%
  4469. Now CONVERT.C prints the expected value of 64033.10.  %@NL@%
  4470. %@NL@%
  4471. %@NL@%
  4472. %@3@%%@CR:C6A00050013 @%%@AB@%Manual Type Conversions through Casting%@AE@%%@EH@%%@NL@%
  4473. %@NL@%
  4474. %@AU@% A cast forces a value  to a particular type.%@AE@%  %@NL@%
  4475. %@NL@%
  4476. The C language also allows you to force a type conversion that would not
  4477. otherwise happen, a process known as "casting." Using casts, it is possible
  4478. to convert a data item to any C data type.  %@NL@%
  4479. %@NL@%
  4480. Sometimes you must use a cast to make the program work properly. When
  4481. calling the %@AB@%malloc%@AE@% library function, for instance, you should perform a cast
  4482. on the value that the function returns. (Chapter 12, "Dynamic Memory
  4483. Allocation," explains %@AB@%malloc%@AE@% and other memory-allocating functions.)  %@NL@%
  4484. %@NL@%
  4485. Casts can also make a program more readable. QuickC does most automatic type
  4486. conversions silently. So if you write a tricky bit of code that relies on
  4487. automatic conversions, you, or some other programmer, may not notice the
  4488. conversions later. To make such code more readable─and easier to debug─you
  4489. can add explicit type casts in places where silent conversions might go
  4490. unnoticed.  %@NL@%
  4491. %@NL@%
  4492. To cast a value to a different type, place the desired type name in
  4493. parentheses in front of the value. For instance, the statement  %@NL@%
  4494. %@NL@%
  4495. %@AS@%  f_val = (float)any_val;%@AE@%%@NL@%
  4496. %@NL@%
  4497. casts the value of the variable %@AS@% any_val %@AE@% to type %@AB@%float%@AE@% before assigning it
  4498. to %@AS@% f_val%@AE@%. Here the type name in parentheses,  %@NL@%
  4499. %@NL@%
  4500. %@AS@%  (float)%@AE@%%@NL@%
  4501. %@NL@%
  4502. performs the cast. No matter what type %@AS@% any_val %@AE@% has, the cast converts that
  4503. type to %@AB@%float%@AE@% before assigning it to %@AS@% f_val%@AE@%.  %@NL@%
  4504. %@NL@%
  4505. When you cast a variable, the cast affects the value the variable yields,
  4506. but not the variable itself. Suppose that %@AS@% any_val %@AE@% is an %@AB@%int%@AE@% variable with
  4507. the value 333. The above cast converts the value 333 to %@AB@%float%@AE@% format before
  4508. assigning it to %@AS@% f_val%@AE@%. But %@AS@% any_val %@AE@% remains an %@AB@%int%@AE@% variable after the
  4509. cast.  %@NL@%
  4510. %@NL@%
  4511. Remember, you can detect automatic type conversions by setting Warning Level
  4512. 2 or higher in QuickC and watching for the following warning:  %@NL@%
  4513. %@NL@%
  4514. %@AS@%  C4051: data conversion%@AE@%%@NL@%
  4515. %@NL@%
  4516. You can then add explicit casts to eliminate the warning where the
  4517. conversions are desirable. (See "Automatic Type Conversions" above.)  %@NL@%
  4518. %@NL@%
  4519. %@NL@%
  4520. %@2@%%@CR:C6A00050014 @%%@AB@%Register Variables%@AE@%%@EH@%%@NL@%
  4521. %@NL@%
  4522. %@AU@% Register variables are stored in processor registers instead of addressable
  4523. %@AU@%memory.%@AE@%  %@NL@%
  4524. %@NL@%
  4525. You can use the %@AB@%register%@AE@% keyword in variable declarations to request that a
  4526. variable be stored in a processor register. Because processor registers can
  4527. be accessed more quickly than addressable memory locations, this storage can
  4528. make a program run faster. Programmers use %@AB@%register%@AE@% to speed access to
  4529. heavily used variables, such as counter variables in loops.  %@NL@%
  4530. %@NL@%
  4531. The %@AB@%register%@AE@% specifier is much less important than it used to be, now that
  4532. most C compilers, including QuickC, can perform optimizations (improvements)
  4533. during compilation. If you compile with the Optimizations option turned on,
  4534. QuickC automatically stores variables in registers when needed. So you
  4535. probably won't need to use %@AB@%register%@AE@% except in special cases.  %@NL@%
  4536. %@NL@%
  4537. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4538. IMPORTANT
  4539.  
  4540. %@AI@%If you compile with Optimizations on, an explicit %@AB@%register%@AE@%%@AI@% declaration can
  4541. %@AI@%override register storage that QuickC would do automatically. Declaring one
  4542. %@AI@%variable with %@AE@%%@AI@%%@AB@%register%@AE@%%@AE@%%@AI@% might prevent QuickC from storing some other variable
  4543. %@AI@%in a register. In the worst case, this can make a program run slower.%@AE@%%@AE@%%@NL@%
  4544. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  4545. %@NL@%
  4546. You can use %@AB@%register%@AE@% only with short integer types (%@AB@%char%@AE@%, %@AB@%int%@AE@%, and %@AB@%short
  4547. %@AB@%int%@AE@%). Other types─including aggregate types such as arrays─are too large to
  4548. fit in a register.  %@NL@%
  4549. %@NL@%
  4550. Only two registers are available for variable storage at any given time.
  4551. (They are DI and SI, for those who have programmed in assembly language.) If
  4552. you request more registers than are available, QuickC stores the extra
  4553. variables in addressable memory, as it does non-%@AB@%register%@AE@% variables.  %@NL@%
  4554. %@NL@%
  4555. The following declaration uses %@AB@%register%@AE@% to ask the compiler to store the %@AB@%int%@AE@%
  4556. variable %@AS@% val %@AE@% in a processor register:  %@NL@%
  4557. %@NL@%
  4558. %@AS@%  register int val;%@AE@%%@NL@%
  4559. %@NL@%
  4560. You can ask the compiler to store more than one variable in a register. For
  4561. instance, the statement  %@NL@%
  4562. %@NL@%
  4563. %@AS@%  register int val, count;%@AE@%%@NL@%
  4564. %@NL@%
  4565. declares %@AS@% val %@AE@% and %@AS@% count %@AE@% as %@AB@%register%@AE@% variables.  %@NL@%
  4566. %@NL@%
  4567. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4568. NOTE
  4569.  
  4570. %@AI@%Since registers are not addressable, you can't use the address-of (%@AB@%&%@AE@%%@AI@%)
  4571. %@AI@%operator to get the address of a variable declared with %@AE@%%@AI@%%@AB@%register%@AE@%%@AE@%%@AI@%. This rule
  4572. %@AI@%applies whether or not QuickC is actually able to store the variable in a
  4573. %@AI@%register. Thus, if you need to access a variable through a pointer, don't
  4574. %@AI@%declare that variable with %@AE@%%@AI@%%@AB@%register%@AE@%%@AE@%%@AI@%. See the section "Initializing a Pointer
  4575. %@AI@%Variable" in Chapter 8, "Pointers."%@AE@%%@AE@%%@NL@%
  4576. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  4577. %@NL@%
  4578. %@NL@%
  4579. %@2@%%@CR:C6A00050015 @%%@AB@%Renaming Existing Types with typedef%@AE@%%@EH@%%@NL@%
  4580. %@NL@%
  4581. The %@AB@%typedef%@AE@% keyword creates a new name for an existing data type. This is a
  4582. convenience feature that you can use to make programs more readable. For
  4583. instance, the declaration  %@NL@%
  4584. %@NL@%
  4585. %@AS@%  typedef int integer;%@AE@%%@NL@%
  4586. %@NL@%
  4587. allows you to use %@AS@% integer %@AE@% as a synonym for %@AB@%int%@AE@%.  %@NL@%
  4588. %@NL@%
  4589. One more practical use of %@AB@%typedef%@AE@% is to substitute a short, descriptive name
  4590. for an aggregate type. For instance, the QuickC Presentation Graphics
  4591. library uses %@AB@%typedef%@AE@% to create descriptive names such as %@AB@%windowtype%@AE@% and
  4592. %@AB@%titletype%@AE@% for structures used in that library.  %@NL@%
  4593. %@NL@%
  4594. ────────────────────────────────────────────────────────────────────────────%@NL@%
  4595. NOTE
  4596.  
  4597. %@AI@%The %@AB@%typedef%@AE@%%@AI@% keyword doesn't create a new data type. It merely allows you to
  4598. %@AI@%use a different name for a type that already exists.%@AE@%%@AE@%%@NL@%
  4599. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  4600. %@NL@%
  4601. You can also use %@AB@%typedef%@AE@% to minimize portability problems. By using %@AB@%typedef%@AE@%
  4602. declarations for data types that are machine dependent, you need only change
  4603. the %@AB@%typedef%@AE@% declaration if you move the program to a different operating
  4604. system.  %@NL@%
  4605. %@NL@%
  4606. %@NL@%
  4607. %@2@%%@CR:C6A00050016 @%%@AB@%The Enumeration Type%@AE@%%@EH@%%@NL@%
  4608. %@NL@%
  4609. The "enumeration type" specifies a set of named integer constants, similar
  4610. to the enumerated type in QuickPascal. In the C language, enumeration types
  4611. are declared with the %@AB@%enum%@AE@% keyword.  %@NL@%
  4612. %@NL@%
  4613. %@AU@% Use enum to name a  set of integer constants.%@AE@%  %@NL@%
  4614. %@NL@%
  4615. The %@AB@%enum%@AE@% type is useful mainly for improving a program's readability. With
  4616. %@AB@%enum%@AE@%, you can use meaningful names for a set of constants whose purpose
  4617. might not otherwise be apparent.  %@NL@%
  4618. %@NL@%
  4619. Suppose you're writing a calendar program in which the constant 0 represents
  4620. Saturday, 1 represents Sunday, and so on. You might begin by declaring the
  4621. enumeration type %@AS@% day %@AE@% in the following manner:  %@NL@%
  4622. %@NL@%
  4623. %@AS@%  enum day
  4624. %@AS@%  {
  4625. %@AS@%     saturday, sunday, monday, tuesday,
  4626. %@AS@%     wednesday, thursday, friday
  4627. %@AS@%  };%@AE@%%@NL@%
  4628. %@NL@%
  4629. Notice this declaration's similarity to a structure declaration. As with
  4630. structures, the type declaration creates a template that you can use to
  4631. declare variables of this type. (See the section "Declaring a Structure
  4632. Type" in Chapter 4, "Data Types.")  %@NL@%
  4633. %@NL@%
  4634. Unless you specify otherwise, the first value in an enumeration type equals
  4635. 0 and others are numbered sequentially. In the %@AB@%enum%@AE@% type shown above, %@AS@%
  4636. %@AS@%saturday %@AE@% equals 0, %@AS@% sunday %@AE@% equals 1, and so forth.  %@NL@%
  4637. %@NL@%
  4638. The values in an enumeration type need not be sequential, however. If you
  4639. want some other order, you can declare explicit values for each member of
  4640. the type. The following declaration, for example, assigns the names %@AS@% zero%@AE@%, %@AS@%
  4641. %@AS@%freeze%@AE@%, and %@AS@%boil %@AE@% to the constants 0, 32, and 220, respectively.  %@NL@%
  4642. %@NL@%
  4643. %@AS@%  enum temps
  4644. %@AS@%  {
  4645. %@AS@%     zero = 0,
  4646. %@AS@%     freeze = 32,
  4647. %@AS@%     boil = 220
  4648. %@AS@%  };%@AE@%%@NL@%
  4649. %@NL@%
  4650. After declaring an enumeration type, you can create a variable of that type
  4651. and assign it a value from the type. The statement  %@NL@%
  4652. %@NL@%
  4653. %@AS@%  enum day today = wednesday;%@AE@%%@NL@%
  4654. %@NL@%
  4655. declares the variable %@AS@% today%@AE@%, assigning it the value %@AS@% wednesday %@AE@% from the %@AS@%
  4656. %@AS@%day %@AE@% enumeration type.  %@NL@%
  4657. %@NL@%
  4658. After you assign its value, you can use the variable %@AS@% today %@AE@% as you would an
  4659. %@AB@%int%@AE@% variable. Although the variable is considered to have the %@AB@%enum%@AE@% type, it
  4660. is an ordinary %@AB@%int%@AE@% for all practical purposes.  %@NL@%
  4661. %@NL@%
  4662. Enumeration types aren't used very often, partly because you can achieve a
  4663. similar effect using the %@AB@%#define%@AE@% directive. (Chapter 7, "Preprocessor
  4664. Directives," explains %@AB@%#define%@AE@% in detail.) For example, the code  %@NL@%
  4665. %@NL@%
  4666. %@AS@%  #define SATURDAY 0
  4667. %@AS@%  #define SUNDAY 1
  4668. %@AS@%  #define MONDAY 2
  4669. %@AS@%  #define TUESDAY 3
  4670. %@AS@%  #define WEDNESDAY 4
  4671. %@AS@%     .
  4672. %@AS@%     .
  4673. %@AS@%     .
  4674. %@AS@%  int today = WEDNESDAY;%@AE@%%@NL@%
  4675. %@NL@%
  4676. uses %@AB@%#define%@AE@% to create symbolic constants named %@AS@% SATURDAY%@AE@%, %@AS@% SUNDAY%@AE@%, %@AS@% MONDAY%@AE@%,
  4677. %@AS@% TUESDAY%@AE@%, and %@AS@% WEDNESDAY%@AE@%, assigning them the values 0 through 4. The last
  4678. line in the example creates the %@AB@%int%@AE@% variable %@AS@% today %@AE@% and assigns it the
  4679. value of %@AS@% WEDNESDAY%@AE@%. The result is identical to the statement shown earlier:
  4680. %@NL@%
  4681. %@NL@%
  4682. %@AS@%  enum day today = wednesday;%@AE@%%@NL@%
  4683. %@NL@%
  4684. One advantage of using %@AB@%enum%@AE@% over %@AB@%#define%@AE@% directives is that it groups
  4685. related names in one place and can be more compact than a long series of
  4686. directives.  %@NL@%
  4687. %@NL@%
  4688. This concludes our main discussion of data types. The next chapter,
  4689. "Operators," examines the C language's rich set of operators, which allow
  4690. you to manipulate data in many different ways.  %@NL@%
  4691. %@NL@%
  4692. %@NL@%
  4693. %@NL@%
  4694. %@NL@%
  4695. %@NL@%
  4696. %@NL@%
  4697. %@CR:C6A00060001 @%%@1@%%@AB@%Chapter 6  Operators%@AE@%%@EH@%%@NL@%
  4698. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4699. %@NL@%
  4700. Compared with other languages, C is very compact, using fewer than 50
  4701. keywords. One reason C can get by with so few reserved words is its
  4702. abundance of powerful operators─well over 30.  %@NL@%
  4703. %@NL@%
  4704. Most C operators are easy to understand and remember. Even if you have never
  4705. seen a C program, you probably understand that the statement  %@NL@%
  4706. %@NL@%
  4707. %@AS@%  val = val * 5;%@AE@%%@NL@%
  4708. %@NL@%
  4709. multiplies the variable %@AS@% val %@AE@% by 5 and assigns the result to %@AS@% val%@AE@%.  %@NL@%
  4710. %@NL@%
  4711. Because the printable ASCII character set has only so many unique symbols, C
  4712. uses some ASCII symbols in more than one operator. For instance, the
  4713. asterisk (%@AB@%*%@AE@%) performs either a multiplication or pointer operation,
  4714. depending on context. Similarly, the ampersand (%@AB@%&%@AE@%) is part of three C
  4715. operators. Depending on context, the ampersand can obtain an address or
  4716. perform a logical or bitwise AND operation. Be careful not to confuse
  4717. operators that look similar but do different jobs.  %@NL@%
  4718. %@NL@%
  4719. This chapter describes the C operators, beginning with those that are common
  4720. to most languages, and then discussing those unique to C.  %@NL@%
  4721. %@NL@%
  4722. %@NL@%
  4723. %@2@%%@CR:C6A00060002 @%%@AB@%Introducing C's Operators%@AE@%%@EH@%%@NL@%
  4724. %@NL@%
  4725. We'll start by discussing C operators that look and behave similarly to
  4726. operators in other languages. These include the following groups:  %@NL@%
  4727. %@NL@%
  4728. %@NL@%
  4729.   ■   Arithmetic operators, which do operations such as addition and
  4730.       multiplication%@NL@%
  4731. %@NL@%
  4732.   ■   Relational operators, which compare two values and give a true or
  4733.       false result%@NL@%
  4734. %@NL@%
  4735.   ■   Assignment operators, which make one value equal to another%@NL@%
  4736. %@NL@%
  4737. %@NL@%
  4738. %@NL@%
  4739. %@3@%%@CR:C6A00060003 @%%@AB@%Arithmetic Operators%@AE@%%@EH@%%@NL@%
  4740. %@NL@%
  4741. The C language's arithmetic operators closely resemble those in other
  4742. languages. Table 6.1 lists C's arithmetic operators.  %@NL@%
  4743. %@NL@%
  4744. %@AB@%Table 6.1  %@AB@%Arithmetic Operators%@AE@%%@AE@%
  4745.  
  4746. %@TH:   8   511 02 26 50 @%
  4747. Operator                  Description
  4748. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4749. %@AB@%*%@AE@%                         Multiplication
  4750. %@AB@%/%@AE@%                         Division
  4751. %@AB@%%%@AE@%                         Modulus
  4752. %@AB@%+%@AE@%                         Addition
  4753. %@AB@%- %@AE@%                        Subtraction%@AB@%%@AE@%
  4754. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4755. %@TE:   8   511 02 26 50 @%
  4756.  
  4757. The "modulus operator" (%@AB@%%%@AE@%) may be unfamiliar. It divides a value and gives
  4758. the remainder. For instance, the statement  %@NL@%
  4759. %@NL@%
  4760. %@AS@%  remainder = 20 % 3;%@AE@%%@NL@%
  4761. %@NL@%
  4762. assigns the value 2 to the variable %@AS@% remainder %@AE@% (20 divided by 3 equals 6,
  4763. with a remainder of 2). If the division doesn't produce a remainder, the
  4764. modulus operator yields the value 0.  %@NL@%
  4765. %@NL@%
  4766. %@NL@%
  4767. %@3@%%@CR:C6A00060004 @%%@AB@%Relational Operators%@AE@%%@EH@%%@NL@%
  4768. %@NL@%
  4769. "Relational operators" evaluate the relationship between two expressions,
  4770. giving a true result (the value 1) or a false result (the value 0). C has
  4771. six relational operators, which are listed in Table 6.2.  %@NL@%
  4772. %@NL@%
  4773. %@AB@%Table 6.2  %@AB@%Relational Operators%@AE@%%@AE@%
  4774.  
  4775. %@TH:   9   543 02 23 53 @%
  4776. Operator               Description
  4777. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4778. %@AB@%<%@AE@%                      Less than
  4779. %@AB@%<=%@AE@%                     Less than or equal
  4780. %@AB@%>%@AE@%                      Greater than
  4781. %@AB@%>=%@AE@%                     Greater than or equal
  4782. %@AB@%==%@AE@%                     Equal
  4783. %@AB@%!=%@AE@%                     Not equal
  4784. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4785. %@TE:   9   543 02 23 53 @%
  4786.  
  4787. The "equality operator" (%@AB@%==%@AE@%), shown above, tests whether two expressions are
  4788. equal.  %@NL@%
  4789. %@NL@%
  4790. Don't confuse the equality operator with the assignment operator (%@AB@%=%@AE@%)
  4791. discussed in the next section. The assignment operator sets one value equal
  4792. to another, as we'll see shortly. (Chapter 10, "Programming Pitfalls,"
  4793. discusses this common programming error.)  %@NL@%
  4794. %@NL@%
  4795. The C language gives the value 1 for true and 0 for false but recognizes any
  4796. nonzero value as true. The following code fragment demonstrates this
  4797. difference:  %@NL@%
  4798. %@NL@%
  4799. %@AS@%  printf( "C generates %d for true\n", 2 == 2 );
  4800. %@AS@%  printf( "C generates %d for false\n", 2 == 4 );
  4801. %@AS@%  if( -33 )
  4802. %@AS@%     printf( "C recognizes any nonzero value as true\n" );%@AE@%%@NL@%
  4803. %@NL@%
  4804. The output from this code,  %@NL@%
  4805. %@NL@%
  4806. %@AS@%  C generates 1 for true
  4807. %@AS@%  C generates 0 for false
  4808. %@AS@%  C recognizes any nonzero value as true%@AE@%%@NL@%
  4809. %@NL@%
  4810. shows that the true expression (%@AS@% 2 == 2 %@AE@%) gives the value 1 and the false
  4811. expression (%@AS@% 2 == 4 %@AE@%) gives the value 0. The last output line shows that C
  4812. recognizes the nonzero value -33 as a true value.  %@NL@%
  4813. %@NL@%
  4814. %@NL@%
  4815. %@3@%%@CR:C6A00060005 @%%@AB@%Assignment Operators%@AE@%%@EH@%%@NL@%
  4816. %@NL@%
  4817. The "assignment operator" (%@AB@%=%@AE@%) sets one value equal to another. The following
  4818. statement assigns the value of %@AS@% sample %@AE@% to %@AS@% val%@AE@%:  %@NL@%
  4819. %@NL@%
  4820. %@AS@%  val = sample;%@AE@%%@NL@%
  4821. %@NL@%
  4822. %@AU@% You can combine an assignment with a bitwise  or arithmetic operation.%@AE@%  %@NL@%
  4823. %@NL@%
  4824. In a convenient shorthand, C allows you to combine the assignment operator
  4825. with any arithmetic or bitwise operator (see the "Arithmetic Operators" and
  4826. "Bitwise Operators" sections). For example, the statement  %@NL@%
  4827. %@NL@%
  4828. %@AS@%  val = val + sample;%@AE@%%@NL@%
  4829. %@NL@%
  4830. can more conveniently be written  %@NL@%
  4831. %@NL@%
  4832. %@AS@%  val += sample;%@AE@%%@NL@%
  4833. %@NL@%
  4834. Both statements add %@AS@% val %@AE@% to %@AS@% sample %@AE@% and then assign the result to %@AS@% val%@AE@%.  %@NL@%
  4835. %@NL@%
  4836. Table 6.3 lists C's special assignment operators.  %@NL@%
  4837. %@NL@%
  4838. %@AB@%Table 6.3  %@AB@%Special Assignment Operators%@AE@%%@AE@%
  4839.  
  4840. %@TH:  13   863 02 12 14 50 @%
  4841. Expression  Equivalent    Operation
  4842. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4843. %@AS@%x *= y%@AE@%      %@AS@% x = x * y%@AE@%    Multiplication
  4844. %@AS@%x /= y%@AE@%      %@AS@% x = x / y%@AE@%    Division
  4845. %@AS@%x %= y%@AE@%      %@AS@% x = x % y%@AE@%    Modulus
  4846. %@AS@%x += y%@AE@%      %@AS@% x = x + y%@AE@%    Addition
  4847. %@AS@%x -= y%@AE@%      %@AS@% x = x - y%@AE@%    Subtraction
  4848. %@AS@%x <<= y%@AE@%     %@AS@% x = x << y%@AE@%   Left shift
  4849. %@AS@%x >>= y%@AE@%     %@AS@% x = x >> y%@AE@%   Right shift
  4850. %@AS@%x &= y%@AE@%      %@AS@% x = x & y%@AE@%    AND
  4851. %@AS@%x ^= y%@AE@%      %@AS@% x = x ^ y%@AE@%    Exclusive OR
  4852. %@AS@%x |= y%@AE@%      %@AS@% x = x | y%@AE@%    Inclusive OR
  4853. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4854. %@TE:  13   863 02 12 14 50 @%
  4855.  
  4856. Note that the equal sign always follows the other operator. In the following
  4857. code,  %@NL@%
  4858. %@NL@%
  4859. %@AS@%  val ^= sample;
  4860. %@AS@%  val =^ sample;%@AE@%%@NL@%
  4861. %@NL@%
  4862. the first statement is meaningful, but the second is a syntax error.  %@NL@%
  4863. %@NL@%
  4864. %@NL@%
  4865. %@2@%%@CR:C6A00060006 @%%@AB@%C's Unique Operators%@AE@%%@EH@%%@NL@%
  4866. %@NL@%
  4867. The remaining sections in this chapter describe C operators that fall into
  4868. two categories: those that are unique to C and those that look or behave
  4869. differently in C than in other languages.  %@NL@%
  4870. %@NL@%
  4871. %@NL@%
  4872. %@3@%%@CR:C6A00060007 @%%@AB@%Increment and Decrement Operators%@AE@%%@EH@%%@NL@%
  4873. %@NL@%
  4874. The C language's unique "increment" (%@AB@%++%@AE@%) and "decrement" (%@AB@%- -%@AE@%) operators are
  4875. very useful. They increase or decrease an expression by a value of 1.  %@NL@%
  4876. %@NL@%
  4877. %@AB@%Table 6.4  %@AB@%Increment and Decrement Operators%@AE@%%@AE@%
  4878.  
  4879. %@TH:   5   370 02 22 54 @%
  4880. Operator              Operation
  4881. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4882. %@AB@%++%@AE@%                    Increment expression by 1
  4883. %@AB@%- -%@AE@%                   Decrement expression by 1
  4884. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4885. %@TE:   5   370 02 22 54 @%
  4886.  
  4887. Thus, the two statements  %@NL@%
  4888. %@NL@%
  4889. %@AS@%  val = val + 1;
  4890. %@AS@%  val++;%@AE@%%@NL@%
  4891. %@NL@%
  4892. are equivalent and so are these statements:  %@NL@%
  4893. %@NL@%
  4894. %@AS@%  val = val - 1;
  4895. %@AS@%  val--;%@AE@%%@NL@%
  4896. %@NL@%
  4897. %@AU@% You can use the ++ and - - operators before  or after an expression.%@AE@%  %@NL@%
  4898. %@NL@%
  4899. The %@AB@%++%@AE@% and %@AB@%- -%@AE@% operators can precede or follow an expression. Placed before
  4900. an expression, the operator changes the expression before the expression's
  4901. value is used. In this case, the operator is said to be a "prefix" operator.
  4902. Placed after an expression, the operator (known as a "postfix" operator)
  4903. changes the value of the expression after the expression's value is used.  %@NL@%
  4904. %@NL@%
  4905. In the DECRMENT.C program, shown below, the decrement operator is used both
  4906. as a prefix operator and a postfix operator.  %@NL@%
  4907. %@NL@%
  4908. %@AS@%  /* DECRMENT.C: Demonstrate prefix and postfix operators. */
  4909. %@AS@%  
  4910. %@AS@%  #include <stdio.h>
  4911. %@AS@%  main()
  4912. %@AS@%  {
  4913. %@AS@%     int val, sample = 3, proton = 3;
  4914. %@AS@%     val = sample--;
  4915. %@AS@%     printf( "val = %d  sample = %d\n", val, sample );
  4916. %@AS@%     val = --proton;
  4917. %@AS@%     printf( "val = %d  proton = %d\n", val, proton );
  4918. %@AS@%  }%@AE@%%@NL@%
  4919. %@NL@%
  4920. Here is the output from DECRMENT.C:  %@NL@%
  4921. %@NL@%
  4922. %@AS@%  val = 3  sample = 2
  4923. %@AS@%  val = 2  proton = 2%@AE@%%@NL@%
  4924. %@NL@%
  4925. In the first use of the decrement operator, the statement  %@NL@%
  4926. %@NL@%
  4927. %@AS@%  val = sample--;%@AE@%%@NL@%
  4928. %@NL@%
  4929. assigns the value of %@AS@% sample %@AE@% (3) to the variable %@AS@% val %@AE@% and then decrements %@AS@%
  4930. %@AS@%sample %@AE@% to the value 2. Contrast this with the statement  %@NL@%
  4931. %@NL@%
  4932. %@AS@%  val = --proton;%@AE@%%@NL@%
  4933. %@NL@%
  4934. which first decrements %@AS@% proton %@AE@% to the value 2 and then assigns that value
  4935. to %@AS@% val%@AE@%.  %@NL@%
  4936. %@NL@%
  4937. %@NL@%
  4938. %@3@%%@CR:C6A00060008 @%%@AB@%Bitwise Operators%@AE@%%@EH@%%@NL@%
  4939. %@NL@%
  4940. The "bitwise operators," listed in Table 6.5, manipulate bits in data of the
  4941. integer type. These operators are often used in programs that must interact
  4942. with hardware.  %@NL@%
  4943. %@NL@%
  4944. %@AB@%Table 6.5  %@AB@%Bitwise Operators%@AE@%%@AE@%
  4945.  
  4946. %@TH:   9   548 02 26 50 @%
  4947. Operator                  Description
  4948. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4949. %@AB@%~%@AE@%                         Complement
  4950. %@AB@%<<%@AE@%                        Left shift
  4951. %@AB@%>>%@AE@%                        Right shift
  4952. %@AB@%&%@AE@%                         AND
  4953. %@AB@%^%@AE@%                         Exclusive OR
  4954. %@AB@%|%@AE@%                         Inclusive OR
  4955. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  4956. %@TE:   9   548 02 26 50 @%
  4957.  
  4958. The %@AB@%~%@AE@% operator, known as the "one's complement," acts on only one value
  4959. (rather than on two, as do most operators). This operator changes every 1
  4960. bit in its operand to a 0 bit and vice versa.  %@NL@%
  4961. %@NL@%
  4962. The %@AB@%%@AE@% and%@AB@% >>%@AE@% operators, known as the "shift operators," shift the left
  4963. operand by the value given in the right operand. These operators offer a
  4964. fast, convenient way to multiply or divide integers by a power of 2.  %@NL@%
  4965. %@NL@%
  4966. The %@AB@%&%@AE@% operator, known as the "bitwise AND," sets a bit to 1 if either of the
  4967. corresponding bits in its operands is 1, or to 0 if both corresponding bits
  4968. are 0. It is often used to "mask," or turn off, one or more bits in a value.
  4969. %@NL@%
  4970. %@NL@%
  4971. The %@AB@%^%@AE@% operator, known as the "bitwise exclusive OR," sets a bit to 1 if the
  4972. corresponding bits in its operands are different, or to 0 if they are the
  4973. same.  %@NL@%
  4974. %@NL@%
  4975. The  %@AB@%|%@AE@%  operator, known as the "bitwise inclusive OR," sets a bit to 1 if
  4976. either of the corresponding bits in its operands is 1, or to 0 if both
  4977. corresponding bits are 0. It is often used to turn on bits in a value.  %@NL@%
  4978. %@NL@%
  4979. Each of the bitwise operators is used in the BITWISE.C program, shown below.
  4980. %@NL@%
  4981. %@NL@%
  4982. %@AS@%  /* BITWISE.C: Demonstrate bitwise operators. */
  4983. %@AS@%  
  4984. %@AS@%  #include <stdio.h>
  4985. %@AS@%  
  4986. %@AS@%  main()
  4987. %@AS@%  {
  4988. %@AS@%     printf( "255 & 15 = %d\n", 255 & 15 );
  4989. %@AS@%     printf( "255 | 15 = %d\n", 255 | 15 );
  4990. %@AS@%     printf( "255 ^ 15 = %d\n", 255 ^ 15 );
  4991. %@AS@%     printf( "2 << 2   = %d\n", 2 << 2 );
  4992. %@AS@%     printf( "16 >> 2  = %d\n", 16 >> 2 );
  4993. %@AS@%     printf( "~2       = %d\n", ~2 );
  4994. %@AS@%  }%@AE@%%@NL@%
  4995. %@NL@%
  4996. The output from BITWISE.C,  %@NL@%
  4997. %@NL@%
  4998. %@AS@%  255 & 15 = 15
  4999. %@AS@%  255 | 15 = 255
  5000. %@AS@%  255 ^ 15 = 240
  5001. %@AS@%  2 << 2   = 8
  5002. %@AS@%  16 >> 2  = 4
  5003. %@AS@%  ~2  = -3%@AE@%%@NL@%
  5004. %@NL@%
  5005. shows the results of the program's various bitwise operations.  %@NL@%
  5006. %@NL@%
  5007. The fourth and fifth output lines show you how to use shift operators to
  5008. multiply and divide by powers of 2. The program multiplies 2 by 4 by
  5009. shifting the value 2 twice to the left:  %@NL@%
  5010. %@NL@%
  5011. %@AS@%  2 << 2   = 8%@AE@%%@NL@%
  5012. %@NL@%
  5013. Similarly, the program divides 16 by 4 by shifting the value 16 twice to the
  5014. right:  %@NL@%
  5015. %@NL@%
  5016. %@AS@%  16 >> 2  = 4%@AE@%%@NL@%
  5017. %@NL@%
  5018. %@NL@%
  5019. %@3@%%@CR:C6A00060009 @%%@AB@%Logical Operators%@AE@%%@EH@%%@NL@%
  5020. %@NL@%
  5021. C has three logical operators─AND, OR, and NOT─that allow you to test more
  5022. than one condition in a single expression. Table 6.6 lists C's logical
  5023. operators.  %@NL@%
  5024. %@NL@%
  5025. %@AB@%Table 6.6  %@AB@%Logical Operators%@AE@%%@AE@%
  5026.  
  5027. %@TH:   6   409 02 27 49 @%
  5028. Operator                   Description
  5029. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5030. %@AB@%!%@AE@%                          Logical NOT
  5031. %@AB@%&&%@AE@%                         Logical AND
  5032. %@AB@%| |%@AE@%                        Logical OR
  5033. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5034. %@TE:   6   409 02 27 49 @%
  5035.  
  5036. The logical OR ( %@AB@%| |%@AE@% ) and AND (%@AB@%&&%@AE@%) operators are often used to combine
  5037. logical tests within a conditional statement. For example, the %@AB@%if%@AE@% statement
  5038. %@NL@%
  5039. %@NL@%
  5040. %@AS@%  if( val > 10 && sample < 10 )
  5041. %@AS@%     printf( "Oh joy!\n" );%@AE@%%@NL@%
  5042. %@NL@%
  5043. prints %@AS@% Oh joy! %@AE@% if both conditions in the test expression are true (if %@AS@% val
  5044. %@AS@%%@AE@% is greater than 10 and %@AS@% sample %@AE@% is less than 10). Here, the relational
  5045. operators (%@AB@%>%@AE@% and %@AB@%%@AE@%) have higher "precedence" than the logical AND operator
  5046. (%@AB@%&&%@AE@%), so the compiler evaluates them first. We discuss operator precedence
  5047. later in this chapter.  %@NL@%
  5048. %@NL@%
  5049. The logical NOT operator (%@AB@%!%@AE@%) reverses an expression's logical value. For
  5050. instance, if the variable %@AS@% val %@AE@% has the value 8, the expression %@AS@% (val == 8) %@AE@%
  5051. is true but the expression %@AS@% !(val == 8) %@AE@% is false.  %@NL@%
  5052. %@NL@%
  5053. The NOT.C program below shows a common use of this operator.  %@NL@%
  5054. %@NL@%
  5055. %@AS@%  /* NOT.C: Demonstrate logical NOT operator. */
  5056. %@AS@%  
  5057. %@AS@%  #include <stdio.h>
  5058. %@AS@%  
  5059. %@AS@%  main()
  5060. %@AS@%  {
  5061. %@AS@%    int val = 0;
  5062. %@AS@%    if( !val )
  5063. %@AS@%       printf( "val is zero" );
  5064. %@AS@%  }%@AE@%%@NL@%
  5065. %@NL@%
  5066. The expression %@AS@% if( !val ) %@AE@% is equivalent to the expression %@AS@% if( val == 0 )%@AE@%.
  5067. When used in this way, the logical NOT operator converts a 0 value to 1 and
  5068. any nonzero value to 0.  %@NL@%
  5069. %@NL@%
  5070. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5071. NOTE
  5072.  
  5073. %@AI@%Don't confuse the logical OR and AND operators with the bitwise OR and AND
  5074. %@AI@%operators discussed in the previous section. The bitwise operators use the
  5075. %@AI@%same ASCII symbols, but have only one character. For instance, logical AND
  5076. %@AI@%is %@AB@%&&%@AE@%%@AI@%, whereas bitwise AND is %@AE@%%@AI@%%@AB@%&%@AE@%%@AE@%%@AI@%.%@AE@%%@AE@%%@NL@%
  5077. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  5078. %@NL@%
  5079. %@NL@%
  5080. %@3@%%@CR:C6A00060010 @%%@AB@%Address Operators%@AE@%%@EH@%%@NL@%
  5081. %@NL@%
  5082. The C language has two operators that work with memory addresses. Table 6.7
  5083. lists C's address operators.  %@NL@%
  5084. %@NL@%
  5085. %@AB@%Table 6.7  %@AB@%Address Operators%@AE@%%@AE@%
  5086.  
  5087. %@TH:   5   373 02 15 61 @%
  5088. Operator       Operation
  5089. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5090. %@AB@%&%@AE@%              Yield address of the operand
  5091. %@AB@%*%@AE@%              Yield value contained at the operand's address
  5092. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5093. %@TE:   5   373 02 15 61 @%
  5094.  
  5095. Both address operators are often used with pointers─variables that contain
  5096. the addresses of other variables. Chapter 8, "Pointers," and Chapter 9,
  5097. "Advanced Pointers," are devoted to explaining pointers, including the use
  5098. of these two operators with them. Since you must understand pointers in
  5099. order to understand these operators fully, we'll describe them briefly here
  5100. and elaborate on their use in Chapter 8.  %@NL@%
  5101. %@NL@%
  5102. The "address-of operator" (%@AB@%&%@AE@%) yields a constant equal to the machine address
  5103. of its operand. For instance, if the variable %@AS@% val %@AE@% contains the value 10,
  5104. and its storage is located at address 1508, the expression %@AS@% val %@AE@% yields the
  5105. value 10, while the expression %@AS@% &val %@AE@% yields the constant 1508.  %@NL@%
  5106. %@NL@%
  5107. Since the address-of operator yields a constant, you can't assign a value to
  5108. an expression that uses it. The statement  %@NL@%
  5109. %@NL@%
  5110. %@AS@%  &val = 20;%@AE@%%@NL@%
  5111. %@NL@%
  5112. is illegal for the same reason that the statement  %@NL@%
  5113. %@NL@%
  5114. %@AS@%  1508 = 20;%@AE@%%@NL@%
  5115. %@NL@%
  5116. won't pass muster.  %@NL@%
  5117. %@NL@%
  5118. The "indirection operator" (%@AB@%*%@AE@%) yields the value contained in the address
  5119. referenced by its operand. If you declare %@AS@% ptr %@AE@% as a pointer variable, the
  5120. expression  %@NL@%
  5121. %@NL@%
  5122. %@AS@%  *ptr%@AE@%%@NL@%
  5123. %@NL@%
  5124. yields the contents of the address to which %@AS@% ptr %@AE@% points.  %@NL@%
  5125. %@NL@%
  5126. %@NL@%
  5127. %@3@%%@CR:C6A00060011 @%%@AB@%Conditional Operator%@AE@%%@EH@%%@NL@%
  5128. %@NL@%
  5129. The "conditional operator" (%@AB@%? :%@AE@%) is made up of two symbols and requires
  5130. three expressions. It is similar to an %@AB@%if%@AE@%-%@AB@%else%@AE@% construct. If the first
  5131. expression evaluates as true, the first operand is assigned the value of the
  5132. second operand. If the first expression is false, the first operand is
  5133. assigned the value of the third operand.  %@NL@%
  5134. %@NL@%
  5135. The following statement gives the absolute value of the variable %@AS@% val%@AE@%. The
  5136. variable is assigned its original value if it is nonnegative or is negated
  5137. if its original value is negative:  %@NL@%
  5138. %@NL@%
  5139. %@AS@%  val = (val >= 0 ) ? val : -val;%@AE@%%@NL@%
  5140. %@NL@%
  5141. The statement is equivalent to the following %@AB@%if%@AE@%-%@AB@%else%@AE@% construct:  %@NL@%
  5142. %@NL@%
  5143. %@AS@%  if( val >= 0 )
  5144. %@AS@%     val = val;
  5145. %@AS@%  else
  5146. %@AS@%     val = -val;%@AE@%%@NL@%
  5147. %@NL@%
  5148. %@NL@%
  5149. %@3@%%@CR:C6A00060012 @%%@AB@%The sizeof Operator%@AE@%%@EH@%%@NL@%
  5150. %@NL@%
  5151. The "%@AB@%sizeof%@AE@% operator" yields the number of bytes contained in its operand,
  5152. which can be either a general data type or a specific variable. If you apply
  5153. %@AB@%sizeof%@AE@% to a type name in parentheses, as in the expression  %@NL@%
  5154. %@NL@%
  5155. %@AS@%  sizeof( int )%@AE@%%@NL@%
  5156. %@NL@%
  5157. the operator yields the size of that data type in bytes. This example yields
  5158. the value 2, indicating that an %@AB@%int%@AE@% contains two bytes on DOS machines. You
  5159. can use this feature to determine the sizes of types that are implementation
  5160. dependent when transporting a program from one machine to another.  %@NL@%
  5161. %@NL@%
  5162. If you place %@AB@%sizeof%@AE@% in front of a variable name, the operator returns the
  5163. number of bytes in the variable. For instance, if you create the string  %@NL@%
  5164. %@NL@%
  5165. %@AS@%  char my_string[] = "Hello";%@AE@%%@NL@%
  5166. %@NL@%
  5167. the expression  %@NL@%
  5168. %@NL@%
  5169. %@AS@%  sizeof my_string%@AE@%%@NL@%
  5170. %@NL@%
  5171. yields the value 6, showing that the string contains 5 printing characters
  5172. and a null character.  %@NL@%
  5173. %@NL@%
  5174. %@NL@%
  5175. %@3@%%@CR:C6A00060013 @%%@AB@%Comma Operator%@AE@%%@EH@%%@NL@%
  5176. %@NL@%
  5177. Preceding chapters have shown various ways to use the comma (%@AB@%,%@AE@%) in C
  5178. programming. For instance, commas can separate multiple function arguments
  5179. or variable declarations. In such cases the comma is not an operator in the
  5180. formal sense but merely punctuation, like the semicolon that ends a
  5181. statement. %@AS@%  %@AE@%%@NL@%
  5182. %@NL@%
  5183. %@AU@% The comma is used as punctuation and as an operator in C.%@AE@%  %@NL@%
  5184. %@NL@%
  5185. In C, the comma can also perform as an operator. The commas that separate
  5186. multiple expressions determine the order in which the expressions are
  5187. evaluated, and the type and value of the result that is returned. The comma
  5188. operator causes expressions to be evaluated from left to right. The value
  5189. and type of the result are the value and type of the rightmost operand.  %@NL@%
  5190. %@NL@%
  5191. For example, the statement  %@NL@%
  5192. %@NL@%
  5193. %@AS@%  val = sample, sample = temp;%@AE@%%@NL@%
  5194. %@NL@%
  5195. first assigns the value of %@AS@% sample %@AE@% to %@AS@% val%@AE@%, then assigns the value of %@AS@% temp
  5196. %@AS@%%@AE@% to %@AS@% sample%@AE@%.  %@NL@%
  5197. %@NL@%
  5198. The comma operator often appears in %@AB@%for%@AE@% statements, where it can separate
  5199. multiple initializing expressions or multiple modifying expressions. The
  5200. FORLOOP1.C program from Chapter 3, "Flow Control," demonstrates both uses.
  5201. Here is the %@AB@%for%@AE@% statement from that program:  %@NL@%
  5202. %@NL@%
  5203. %@AS@%  for( a = 256, b = 1; b < 512; a = a / 2, b = b * 2 )
  5204. %@AS@%     printf( "a = %d \tb = %d\n", a, b );%@AE@%%@NL@%
  5205. %@NL@%
  5206. The statement initializes two variables (%@AS@% a %@AE@% and %@AS@% b %@AE@%) and contains two
  5207. modifying expressions (%@AS@% a = a / 2 %@AE@% and %@AS@% b = b * 2 %@AE@%). Chapter 3 explains the
  5208. FORLOOP1.C program in detail.  %@NL@%
  5209. %@NL@%
  5210. %@NL@%
  5211. %@3@%%@CR:C6A00060014 @%%@AB@%Base Operator%@AE@%%@EH@%%@NL@%
  5212. %@NL@%
  5213. The base operator (%@AB@%:>%@AE@%) associates a base expression with a based pointer.
  5214. Based-object support is a highly advanced feature included in QuickC 2.5 for
  5215. compatibility with Microsoft C version 6.0; please refer to your C 6.0
  5216. documentation for information about based objects.  %@NL@%
  5217. %@NL@%
  5218. %@NL@%
  5219. %@2@%%@CR:C6A00060015 @%%@AB@%Operator Precedence%@AE@%%@EH@%%@NL@%
  5220. %@NL@%
  5221. Like all languages, C has precedence rules that control the order for
  5222. evaluating the elements in expressions containing more than one operator. If
  5223. you're familiar with precedence rules in other languages, you won't find any
  5224. surprises in C. Table 6.8 shows the "pecking order" established for C's
  5225. operators.  %@NL@%
  5226. %@NL@%
  5227. Three general rules control the order of evaluation:  %@NL@%
  5228. %@NL@%
  5229. %@NL@%
  5230.   1.  When two operators have unequal precedence, the operator with higher
  5231.       precedence is evaluated first.%@NL@%
  5232. %@NL@%
  5233.   2.  Operators with equal precedence are evaluated from left to right.%@NL@%
  5234. %@NL@%
  5235.   3.  You can change the normal order of precedence by enclosing an
  5236.       expression in parentheses. The enclosed expression is then evaluated
  5237.       first. (If parentheses are nested, inner parentheses have higher
  5238.       precedence than outer ones.)%@NL@%
  5239. %@NL@%
  5240. %@NL@%
  5241. We'll demonstrate operator precedence with a simple example. Since the
  5242. multiplication operator (*) has higher precedence than the addition operator
  5243. (+), the statement  %@NL@%
  5244. %@NL@%
  5245. %@AS@%%@AE@%val = 2 + 3 * 4  %@NL@%
  5246. %@NL@%
  5247. assigns to%@AS@% val %@AE@%the value of 14 (or 2 + 12) rather than 20 (or 5 * 4). Since
  5248. parentheses have higher precedence than any operator, they can change the
  5249. normal precedence order. If you enclose the addition operation in
  5250. parentheses, as follows  %@NL@%
  5251. %@NL@%
  5252. %@AS@%%@AE@%val = (2 + 3) * 4  %@NL@%
  5253. %@NL@%
  5254. the addition is done first. Now the statement assigns to%@AS@% val %@AE@% the value 20
  5255. (or 5 * 4).  %@NL@%
  5256. %@NL@%
  5257. Table 6.8 lists the C operators and their precedence values. The lines in
  5258. the table separate precedence levels. The highest precedence level is at the
  5259. top of the table.  %@NL@%
  5260. %@NL@%
  5261. %@AB@%Table 6.8  %@AB@%C Operators%@AE@%%@AE@%
  5262.  
  5263. %@TH: 114  4496 02 24 37 15 @%
  5264. Symbol                  Name or Meaning                      Associativity
  5265. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5266. ( )                     Function call                        Left to right
  5267.  
  5268. [ ]                     Array element 
  5269.  
  5270. %@AB@%.%@AE@%                       Structure or union 
  5271.                         member 
  5272.  
  5273. %@AB@%->%@AE@%                      Pointer to structure 
  5274.                         member 
  5275.  
  5276. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5277.  
  5278. %@AB@%- -%@AE@%                     Decrement                            Right to left
  5279.  
  5280. %@AB@%++%@AE@%                      Increment 
  5281.  
  5282. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5283.  
  5284. :>                      Base operator                        Left to right
  5285.  
  5286. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5287.  
  5288. %@AB@%!%@AE@%                       Logical NOT                          Right to left
  5289.  
  5290. %@AB@%~ %@AE@%                      One's complement%@AB@% %@AE@%
  5291.  
  5292. %@AB@%-%@AE@%                       Unary minus 
  5293.  
  5294. %@AB@%+%@AE@%                       Unary plus 
  5295.  
  5296. %@AB@%&%@AE@%                       Address 
  5297.  
  5298. %@AB@%*%@AE@%                       Indirection 
  5299.  
  5300. %@AB@%sizeof%@AE@%                  Size in bytes 
  5301.  
  5302. %@AB@%(%@AE@%type%@AB@%)%@AE@%                  Type cast [for example, (%@AB@%float%@AE@%) i] 
  5303.  
  5304. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5305.  
  5306. %@AB@%*%@AE@%                       Multiply                             Left to right
  5307.  
  5308. %@AB@%/%@AE@%                       Divide 
  5309.  
  5310. %@AB@%%%@AE@%                       Modulus (remainder) 
  5311.  
  5312. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5313.  
  5314. %@AB@%+%@AE@%                       Add                                  Left to right
  5315.  
  5316. %@AB@%-%@AE@%                       Subtract 
  5317.  
  5318. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5319.  
  5320. %@AB@%<<%@AE@%                      Left shift                           Left to right
  5321.  
  5322. %@AB@%>>%@AE@%                      Right shift 
  5323.  
  5324. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5325.  
  5326. %@AB@%<%@AE@%                       Less than                            Left to right
  5327.  
  5328. %@AB@%<=%@AE@%                      Less than or equal 
  5329.  
  5330. %@AB@%>%@AE@%                       Greater than 
  5331.  
  5332. %@AB@%>=%@AE@%                      Greater than or equal 
  5333.  
  5334. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5335.  
  5336. %@AB@%==%@AE@%                      Equal                                Left to right
  5337.  
  5338. %@AB@%!=%@AE@%                      Not equal 
  5339.  
  5340. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5341.  
  5342. %@AB@%&%@AE@%                       Bitwise AND                          Left to right
  5343.  
  5344. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5345.  
  5346. %@AB@%^%@AE@%                       Bitwise exclusive OR                 Left to right
  5347.  
  5348. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5349.  
  5350. %@AB@%|%@AE@%                       Bitwise OR                           Left to right
  5351.  
  5352. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5353.  
  5354. %@AB@%&&%@AE@%                      Logical AND                          Left to right
  5355.  
  5356. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5357.  
  5358. %@AB@%||%@AE@%                      Logical OR                           Left to right
  5359.  
  5360. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5361.  
  5362. %@AB@%? : %@AE@%                    Conditional                          Right to left
  5363.  
  5364. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5365.  
  5366. %@AB@%=%@AE@%                       Assignment                           Right to left
  5367.  
  5368. %@AB@%*=, /=, %=, +=, -=, %@AE@%    Compound assignment 
  5369.  
  5370. %@AB@%<<=, >>=,  &=, ^=, |=%@AE@%   
  5371.  
  5372. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5373.  
  5374. %@AB@%,%@AE@%                       Comma                                Left to right
  5375.  
  5376. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5377.  
  5378. %@TE: 114  4496 02 24 37 15 @%
  5379.  
  5380. %@NL@%
  5381. %@NL@%
  5382. %@NL@%
  5383. %@NL@%
  5384. %@NL@%
  5385. %@CR:C6A00070001 @%%@1@%%@AB@%Chapter 7  Preprocessor Directives%@AE@%%@EH@%%@NL@%
  5386. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5387. %@NL@%
  5388. This chapter describes preprocessor directives─commands that control the
  5389. QuickC compiler. It explains how to insert the contents of one source file
  5390. into another file, how to do text substitutions throughout a file, and how
  5391. to compile different parts of a file in different situations.  %@NL@%
  5392. %@NL@%
  5393. A "preprocessor directive" is a command to the QuickC compiler. Although
  5394. they appear in the same source file as executable statements, preprocessor
  5395. directives aren't statements in the formal sense. Unlike executable
  5396. statements, they are not translated into machine code. Instead, they tell
  5397. the compiler itself to take some action while it translates your source
  5398. program. For instance, an %@AB@%#include%@AE@% directive tells QuickC to insert another
  5399. file into the source file.  %@NL@%
  5400. %@NL@%
  5401. The term "preprocessor" refers to the time when these commands are carried
  5402. out. Like most language compilers, QuickC translates your source program in
  5403. several phases, the first of which is called the "preprocessor phase."
  5404. QuickC first "preprocesses" all the directives in your source program, then
  5405. processes the program's executable statements.  %@NL@%
  5406. %@NL@%
  5407. All preprocessor directives begin with a number sign (%@AB@%#%@AE@%), which must be the
  5408. first nonblank character in the line on which it appears. Since directives
  5409. aren't statements, they don't end with semicolons. You can't put other
  5410. statements or directives on the same line with a preprocessor directive,
  5411. except for a comment, which must appear to the right of the directive.  %@NL@%
  5412. %@NL@%
  5413. Because the compiler reads your source file sequentially, line by line, the
  5414. position of directives is important. A preprocessor directive only affects
  5415. statements that follow it in the source file.  %@NL@%
  5416. %@NL@%
  5417. %@NL@%
  5418. %@2@%%@CR:C6A00070002 @%%@AB@%The #include Directive%@AE@%%@EH@%%@NL@%
  5419. %@NL@%
  5420. %@AU@% The #include directive inserts another file in the source file.%@AE@%  %@NL@%
  5421. %@NL@%
  5422. The %@AB@%#include%@AE@% directive inserts the contents of another file into your source
  5423. file. The inserted file is called an include file or header file.  %@NL@%
  5424. %@NL@%
  5425. When the compiler encounters an %@AB@%#include%@AE@%, it searches for the file named in
  5426. the directive. This directive makes QuickC look for the standard include
  5427. file STDIO.H:  %@NL@%
  5428. %@NL@%
  5429. %@AS@%  #include <stdio.h>%@AE@%%@NL@%
  5430. %@NL@%
  5431. If the designated file is found, the compiler inserts its contents at the
  5432. spot where the %@AB@%#include%@AE@% directive appears. Figure 7.1 illustrates a program
  5433. SAMPLE.C that includes the file STDIO.H.  %@NL@%
  5434. %@NL@%
  5435. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  5436. %@NL@%
  5437. When QuickC compiles the SAMPLE.C program shown in Figure 7.1, it inserts
  5438. the contents of file STDIO.H into SAMPLE.C at the spot marked by the
  5439. %@AB@%#include%@AE@% directive.  %@NL@%
  5440. %@NL@%
  5441. Most include files contain commonly used declarations and definitions.
  5442. Standard include files, supplied with QuickC, contain declarations and
  5443. definitions for QuickC library routines. You can also write include files of
  5444. your own.  %@NL@%
  5445. %@NL@%
  5446. Standard include files end with the .H file extension (STDIO.H is an
  5447. example). You can use any extension for include files you create, but most
  5448. programmers stick with the .H extension.  %@NL@%
  5449. %@NL@%
  5450. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5451. NOTE
  5452.  
  5453. %@AI@%In some languages, it's common to put executable statements, as well as
  5454. %@AI@%declarations and definitions, in include files. This practice is legal but
  5455. %@AI@%not recommended in QuickC. Microsoft debugging tools such as the Microsoft
  5456. %@AI@%CodeView(R) debugger may not recognize executable statements in include
  5457. %@AI@%files.%@AE@%%@NL@%
  5458. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  5459. %@NL@%
  5460. The %@AB@%#include%@AE@% directive doesn't support wild cards, so you can't insert a
  5461. group of related files with a single directive. Each %@AB@%#include%@AE@% directive
  5462. inserts only one file.  %@NL@%
  5463. %@NL@%
  5464. Include files can be nested. For instance, the source program SAMPLE.C might
  5465. include a file named INOUT.H. The INOUT.H file, in turn, might contain a
  5466. second %@AB@%#include%@AE@% directive that includes a file named KEYBOARD.H. Figure 7.2
  5467. illustrates this process.  %@NL@%
  5468. %@NL@%
  5469. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  5470. %@NL@%
  5471. Although it's rarely necessary to nest include files more than two or three
  5472. levels, nesting may continue up to 10 levels.  %@NL@%
  5473. %@NL@%
  5474. %@NL@%
  5475. %@3@%%@CR:C6A00070003 @%%@AB@%Specifying Include Files%@AE@%%@EH@%%@NL@%
  5476. %@NL@%
  5477. There are two ways to tell QuickC where to search for an include file. You
  5478. may have noticed that the %@AB@%#include%@AE@% directive shown earlier encloses the file
  5479. name STDIO.H in angle brackets (%@AB@%<>%@AE@%). If you enclose the file name in angle
  5480. brackets, as in the directive  %@NL@%
  5481. %@NL@%
  5482. %@AS@%  #include <stdio.h>%@AE@%%@NL@%
  5483. %@NL@%
  5484. the compiler searches the "standard directories" for the file.  %@NL@%
  5485. %@NL@%
  5486. In QuickC, the standard directories are one or more directories that you
  5487. define by a DOS environment variable named INCLUDE. An advantage of
  5488. specifying the standard directories is that QuickC can automatically search
  5489. more than one directory.  %@NL@%
  5490. %@NL@%
  5491. Alternatively, you can enclose the file name in double quotes, in the
  5492. following manner,  %@NL@%
  5493. %@NL@%
  5494. %@AS@%  #include "myfile.h"%@AE@%%@NL@%
  5495. %@NL@%
  5496. to cause QuickC to start searching in the directory that contains the
  5497. current source file. If the target file isn't in that directory, the
  5498. compiler searches the standard directories.  %@NL@%
  5499. %@NL@%
  5500. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5501. NOTE
  5502.  
  5503. %@AI@%You can specify additional directories on the DOS command line when you
  5504. %@AI@%invoke QuickC with the QCL command. See Chapter 1, "Creating Executable
  5505. %@AI@%Programs," in the %@AI@%Microsoft QuickC Tool Kit%@AE@%%@AI@%.%@AE@%%@AE@%%@NL@%
  5506. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  5507. %@NL@%
  5508. %@NL@%
  5509. %@2@%%@CR:C6A00070004 @%%@AB@%The #define and #undef Directives%@AE@%%@EH@%%@NL@%
  5510. %@NL@%
  5511. The %@AB@%#define%@AE@% directive performs a text substitution in the source file. This
  5512. directive has two main uses: simple text replacement and creation of
  5513. function-like macros. It is also used with the %@AB@%#undef%@AE@% directive to control
  5514. conditional compilation, as we'll discuss later.  %@NL@%
  5515. %@NL@%
  5516. %@NL@%
  5517. %@3@%%@CR:C6A00070005 @%%@AB@%Simple Text Replacement%@AE@%%@EH@%%@NL@%
  5518. %@NL@%
  5519. %@AU@% The #define directive works  like the search and replace  function of a
  5520. %@AU@%word processor.%@AE@%  %@NL@%
  5521. %@NL@%
  5522. At the simplest level, the %@AB@%#define%@AE@% directive works much like the "search and
  5523. replace" function of a word processor, replacing one piece of text in the
  5524. source file with another piece of text. The %@AB@%#define%@AE@% directive is commonly
  5525. used to create a symbolic constant─a meaningful name for a "magic number"
  5526. whose meaning might not otherwise be apparent. This improves the program's
  5527. readability.  %@NL@%
  5528. %@NL@%
  5529. For instance, in the VOLUME.C program in Chapter 1, "Anatomy of a C
  5530. Program," the directive  %@NL@%
  5531. %@NL@%
  5532. %@AS@%  #define PI 3.14%@AE@%%@NL@%
  5533. %@NL@%
  5534. defines a symbolic constant named %@AS@% PI%@AE@%. The directive causes QuickC to
  5535. replace every occurrence of the text %@AS@% PI %@AE@% in the VOLUME.C source program
  5536. with the text %@AS@% 3.14%@AE@%. For example, when the compiler encounters the program
  5537. line  %@NL@%
  5538. %@NL@%
  5539. %@AS@%  result = 4 * PI * result;%@AE@%%@NL@%
  5540. %@NL@%
  5541. it expands the line to read  %@NL@%
  5542. %@NL@%
  5543. %@AS@%  result = 4 * 3.14 * result;%@AE@%%@NL@%
  5544. %@NL@%
  5545. Besides making your program more readable, symbolic constants can streamline
  5546. its maintenance. For instance, say you later decide to use 3.14159265 rather
  5547. than 3.14 in VOLUME.C. All you need to change is one %@AB@%#define%@AE@% directive at
  5548. the beginning of the program.  %@NL@%
  5549. %@NL@%
  5550. The replacement text can be longer than the 3.14159265 we used above. A
  5551. replacement text can't be longer than 512 bytes in QuickC, but you'll
  5552. rarely, if ever, have to worry about this limit.  %@NL@%
  5553. %@NL@%
  5554. %@NL@%
  5555. %@3@%%@CR:C6A00070006 @%%@AB@%Function-Like Macros%@AE@%%@EH@%%@NL@%
  5556. %@NL@%
  5557. %@AU@% A function-like macro accepts arguments, like a function.%@AE@%  %@NL@%
  5558. %@NL@%
  5559. Some languages use the term "macro" when referring to replacement text. In
  5560. C, a macro can do more than simply replace text. It can also accept
  5561. arguments in much the same way that a function does. In this case the
  5562. replacement text is called a "function-like macro."  %@NL@%
  5563. %@NL@%
  5564. A well-designed macro can be every bit as useful as a function. In fact,
  5565. some C library routines are implemented as macros rather than C functions.  %@NL@%
  5566. %@NL@%
  5567. The MACRO.C program below has a macro that works like the %@AB@%abs%@AE@% library
  5568. function, returning the absolute value of any integer. The macro uses the
  5569. conditional operator (%@AB@%? :%@AE@%), which we explained in Chapter 6.  %@NL@%
  5570. %@NL@%
  5571. %@AS@%  /* MACRO.C: Demonstrate macros. */
  5572. %@AS@%  
  5573. %@AS@%  #include <stdio.h>
  5574. %@AS@%  #define ABS(value)  ( (value) >= 0 ? (value) : -(value) )
  5575. %@AS@%  
  5576. %@AS@%  main()
  5577. %@AS@%  {
  5578. %@AS@%     int val = -20;
  5579. %@AS@%     printf( "result = %d\n", ABS(val) );
  5580. %@AS@%  }%@AE@%%@NL@%
  5581. %@NL@%
  5582. The %@AS@% ABS %@AE@% macro behaves much like a function. You can "call" it by name,
  5583. passing it an argument you want to process. The macro is defined in the
  5584. following program line:  %@NL@%
  5585. %@NL@%
  5586. %@AS@%  #define ABS(value)  ( (value) >= 0 ? (value) : -(value) )%@AE@%%@NL@%
  5587. %@NL@%
  5588. The parameter %@AS@% value %@AE@% appears four times in the macro─once in the macro name
  5589. %@AS@% ABS %@AE@% and three times in the replacement text that follows the name.  %@NL@%
  5590. %@NL@%
  5591. %@AU@% Always enclose macro parameters in parentheses.%@AE@%  %@NL@%
  5592. %@NL@%
  5593. To avoid unwanted side effects, you should always enclose macro parameters
  5594. in parentheses. If the parameter passed to the %@AS@% ABS %@AE@% macro is an expression
  5595. containing operators, the lack of parentheses could cause
  5596. operator-precedence errors. See the section "Omitting Parentheses from Macro
  5597. Arguments" in Chapter 10, "Programming Pitfalls."  %@NL@%
  5598. %@NL@%
  5599. Function-like macros, like other %@AB@%#define%@AE@% directives, are expanded during the
  5600. preprocessor phase of compilation, before QuickC translates any executable
  5601. statements. When QuickC encounters the line  %@NL@%
  5602. %@NL@%
  5603. %@AS@%  printf( "result= %d\n", ABS(val) );%@AE@%%@NL@%
  5604. %@NL@%
  5605. it expands it to read:  %@NL@%
  5606. %@NL@%
  5607. %@AS@%  printf( "result= %d\n", ( (val) >= 0 ? (val) : -(val) ) );%@AE@%%@NL@%
  5608. %@NL@%
  5609. %@AU@% Macros can improve readability.%@AE@%  %@NL@%
  5610. %@NL@%
  5611. A macro can improve a program's readability by describing the nature of an
  5612. operation while hiding its complex details. Most people find the first of
  5613. the two statements above easier to understand than the expanded version.  %@NL@%
  5614. %@NL@%
  5615. %@AU@% Macros are faster than functions but can make  a program bigger.%@AE@%  %@NL@%
  5616. %@NL@%
  5617. Function-like macros are fast, too. Since a macro creates in-line code, it
  5618. doesn't have the overhead associated with a normal function call. On the
  5619. other hand, each use of a macro inserts the same code in your program,
  5620. whereas a function definition occurs only once. So while macros can be
  5621. faster than functions, they can also bloat the size of the executable file.
  5622. %@NL@%
  5623. %@NL@%
  5624. %@NL@%
  5625. %@3@%%@CR:C6A00070007 @%%@AB@%The #undef Directive%@AE@%%@EH@%%@NL@%
  5626. %@NL@%
  5627. The "%@AB@%#undef%@AE@% directive" is related to %@AB@%#define%@AE@%. As the name suggests, %@AB@%#undef%@AE@%
  5628. removes ("undefines") a name that was created with %@AB@%#define%@AE@%. For instance, if
  5629. you create the symbolic constant %@AS@% PI %@AE@% with the %@AB@%#define%@AE@% directive,  %@NL@%
  5630. %@NL@%
  5631. %@AS@%  #define PI  3.14%@AE@%%@NL@%
  5632. %@NL@%
  5633. you can then remove the name %@AS@% PI %@AE@% with the following %@AB@%#undef%@AE@% directive:  %@NL@%
  5634. %@NL@%
  5635. %@AS@%  #undef PI%@AE@%%@NL@%
  5636. %@NL@%
  5637. You can use %@AB@%#define%@AE@% and %@AB@%#undef%@AE@% to create a name that has meaning in only
  5638. part of a source program. The next two sections explain why you might want
  5639. to do this.  %@NL@%
  5640. %@NL@%
  5641. %@NL@%
  5642. %@2@%%@CR:C6A00070008 @%%@AB@%Conditional Directives%@AE@%%@EH@%%@NL@%
  5643. %@NL@%
  5644. %@AU@% Conditional directives are useful for making different versions of a
  5645. %@AU@%program.%@AE@%  %@NL@%
  5646. %@NL@%
  5647. Conditional directives can make QuickC skip part of a source file. They are
  5648. used primarily to create different versions of a program. While developing a
  5649. program, for instance, you might want to include debugging code at some
  5650. times but not others. Or, if you plan to move a program to some other
  5651. machine, you can compile machine-specific sections of code only for a
  5652. certain machine.  %@NL@%
  5653. %@NL@%
  5654. The C-language conditional directives are listed below.  %@NL@%
  5655. %@NL@%
  5656. %@AB@%#if%@AE@%%@AB@%%@AE@%                               %@AB@%#endif%@AE@%%@AB@%%@AE@%
  5657. %@AB@%#else%@AE@%%@AB@%%@AE@%                             %@AB@%#ifdef%@AE@%%@AB@%%@AE@%
  5658. %@AB@%#elif%@AE@%                             %@AB@%#ifndef%@AE@%
  5659.  
  5660. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5661. NOTE 
  5662.  
  5663. %@AI@%The%@AB@% #ifdef%@AE@%%@AI@% and %@AE@%%@AI@%%@AB@%#ifndef %@AE@%%@AE@%%@AI@%directives are obsolete under the ANSI C standard;
  5664. %@AI@%see "The defined Operator" below.%@AE@%%@AE@%%@NL@%
  5665. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  5666. %@NL@%
  5667. %@AU@% The #if directive works  like the if statement.%@AE@%  %@NL@%
  5668. %@NL@%
  5669. The %@AB@%#if%@AE@% and %@AB@%#endif%@AE@% directives work like an %@AB@%if%@AE@% statement, allowing you to
  5670. compile a block of source code if a given condition is true. The %@AB@%#if%@AE@%
  5671. directive is followed by a constant expression, which the compiler tests at
  5672. compile time. If the expression is false, the compiler skips every line
  5673. between the %@AB@%#if%@AE@% and the next %@AB@%#endif%@AE@%.  %@NL@%
  5674. %@NL@%
  5675. The example below calls the %@AS@% display %@AE@% function only if the name %@AS@% DEBUG %@AE@% was
  5676. previously defined as 1 (with %@AB@%#define%@AE@%).  %@NL@%
  5677. %@NL@%
  5678. %@AS@%  #if DEBUG == 1
  5679. %@AS@%     display( debuginfo );
  5680. %@AS@%  #endif%@AE@%%@NL@%
  5681. %@NL@%
  5682. Here, the "conditional block" is a single line (the %@AS@% display %@AE@% function
  5683. call). A conditional block can contain any number of valid C program lines,
  5684. including preprocessor directives as well as executable statements.  %@NL@%
  5685. %@NL@%
  5686. The test expression for a conditional directive can be almost any expression
  5687. that evaluates to a constant, with a few minor exceptions (the expression
  5688. can't use the %@AB@%sizeof%@AE@% operator, type casts, or the %@AB@%float%@AE@% and %@AB@%enum%@AE@% types).  %@NL@%
  5689. %@NL@%
  5690. %@AU@% The #else directive works  like the else keyword.%@AE@%  %@NL@%
  5691. %@NL@%
  5692. The %@AB@%#else%@AE@% and %@AB@%#elif%@AE@% directives work like the %@AB@%else%@AE@% keyword and can perform
  5693. more complex conditional tests. For example, you could use code like that in
  5694. the following example to build different versions of a program for various
  5695. IBM PC computers, including different files for each computer.  %@NL@%
  5696. %@NL@%
  5697. %@AS@%  #if XT == 1
  5698. %@AS@%     #include "XT.H"
  5699. %@AS@%  #elif AT == 1
  5700. %@AS@%     #include "AT.H"
  5701. %@AS@%  #else
  5702. %@AS@%     #include "PS2.H"
  5703. %@AS@%  #endif%@AE@%%@NL@%
  5704. %@NL@%
  5705. The code includes the file XT.H if the name %@AS@% XT %@AE@% is defined as 1 and it
  5706. includes the file AT.H if the name %@AS@% AT %@AE@% is defined as 1. If both %@AS@% XT %@AE@% and %@AS@%
  5707. %@AS@%AT %@AE@% are undefined, the third conditional block executes, causing QuickC to
  5708. include the file PS2.H.  %@NL@%
  5709. %@NL@%
  5710. You can nest conditional directives in the same way as you would conditional
  5711. C language statements.  %@NL@%
  5712. %@NL@%
  5713. %@NL@%
  5714. %@3@%%@CR:C6A00070009 @%%@AB@%The defined Operator%@AE@%%@EH@%%@NL@%
  5715. %@NL@%
  5716. %@AU@% The defined operator  tests whether a name  has been defined.%@AE@%  %@NL@%
  5717. %@NL@%
  5718. The test expression of an %@AB@%#if%@AE@% or %@AB@%#elif%@AE@% directive can use the %@AB@%defined%@AE@%
  5719. operator to test whether a name has been defined. You can use this feature,
  5720. along with %@AB@%#define%@AE@% and %@AB@%#undef%@AE@%, to turn various parts of a program on and
  5721. off, compiling different parts under different conditions.  %@NL@%
  5722. %@NL@%
  5723. The %@AB@%defined%@AE@% operator is true if its argument has been defined and false
  5724. otherwise. A name is considered defined if it has been created with %@AB@%#define%@AE@%
  5725. (and not later removed with %@AB@%#undef%@AE@%).  %@NL@%
  5726. %@NL@%
  5727. The DEFINED.C program below prints %@AS@% Hi %@AE@% because the name %@AS@% DEBUG %@AE@% is defined
  5728. when the compiler encounters the %@AB@%#if defined%@AE@% directive.  %@NL@%
  5729. %@NL@%
  5730. %@AS@%  /* DEFINED.C: Demonstrate defined operator. */
  5731. %@AS@%  
  5732. %@AS@%  #define DEBUG 12345
  5733. %@AS@%  
  5734. %@AS@%  main()
  5735. %@AS@%  {
  5736. %@AS@%     #if defined( DEBUG )
  5737. %@AS@%        printf( "Hi\n" );
  5738. %@AS@%     #endif
  5739. %@AS@%  }%@AE@%%@NL@%
  5740. %@NL@%
  5741. The %@AB@%defined%@AE@% operator tests only whether a name is defined, not whether it
  5742. has a certain value. Thus, the DEFINED.C program will print %@AS@% Hi %@AE@% no matter
  5743. what value is assigned %@AS@% DEBUG%@AE@%. You could substitute the directive  %@NL@%
  5744. %@NL@%
  5745. %@AS@%  #define DEBUG 0%@AE@%%@NL@%
  5746. %@NL@%
  5747. to define %@AS@% DEBUG %@AE@% as 0, or the directive  %@NL@%
  5748. %@NL@%
  5749. %@AS@%  #define DEBUG%@AE@%%@NL@%
  5750. %@NL@%
  5751. to define %@AS@% DEBUG %@AE@% as having no value at all. Both directives define the name
  5752. %@AS@% DEBUG%@AE@%, so the program would print %@AS@% Hi %@AE@% in both cases.  %@NL@%
  5753. %@NL@%
  5754. You can use the logical NOT operator (%@AB@%!%@AE@%) to reverse the logic of an %@AB@%#if
  5755. %@AB@%defined%@AE@% directive. (Logical operators are explained in Chapter 6.) The code
  5756. %@NL@%
  5757. %@NL@%
  5758. %@AS@%  #if !defined( DEBUG )
  5759. %@AS@%     printf( "Hi\n");
  5760. %@AS@%  #endif%@AE@%%@NL@%
  5761. %@NL@%
  5762. prints %@AS@% Hi %@AE@% if %@AS@% DEBUG %@AE@% is not currently defined.  %@NL@%
  5763. %@NL@%
  5764. A plain %@AB@%#if%@AE@% directive treats undefined names a little differently than does
  5765. an %@AB@%#if defined%@AE@% directive. If a name is not currently defined, the %@AB@%#if%@AE@%
  5766. directive treats the name as having the value 0.  %@NL@%
  5767. %@NL@%
  5768. In the following code, the %@AB@%#if%@AE@% directive explicitly tests whether %@AS@% DEBUG %@AE@%
  5769. equals 0.  %@NL@%
  5770. %@NL@%
  5771. %@AS@%  #undef DEBUG
  5772. %@AS@%  #if DEBUG == 0
  5773. %@AS@%     printf( "Hi\n" );
  5774. %@AS@%  #endif%@AE@%%@NL@%
  5775. %@NL@%
  5776. The result is the same as that of the previous example.  %@NL@%
  5777. %@NL@%
  5778. ────────────────────────────────────────────────────────────────────────────%@NL@%
  5779. NOTE
  5780.  
  5781. %@AI@%The %@AB@%defined%@AE@%%@AI@% operator is new under the ANSI C standard. You may see older
  5782. %@AI@%programs that use the older directives %@AE@%%@AI@%%@AB@%#ifdef %@AE@%%@AE@%%@AI@%and %@AE@%%@AI@%%@AB@%#ifndef %@AE@%%@AE@%%@AI@%for the same
  5783. %@AI@%purpose. These directives are obsolete, but QuickC version 2.5 supports them
  5784. %@AI@%for the sake of compatibility. The #%@AE@%%@AI@%%@AB@%ifdef %@AE@%%@AE@%%@AI@%directive is followed by a name
  5785. %@AI@%(not in parentheses) and works the same as %@AE@%%@AI@%%@AB@%#if %@AE@%%@AE@%%@AI@%with %@AE@%%@AI@%%@AB@%defined%@AE@%%@AE@%%@AI@%. If the given
  5786. %@AI@%name has been defined, %@AE@%%@AI@%%@AB@%#ifdef %@AE@%%@AE@%%@AI@%is true. The %@AE@%%@AI@%%@AB@%#ifndef %@AE@%%@AE@%%@AI@%directive is the opposite
  5787. %@AI@%of %@AE@%%@AI@%%@AB@%#ifdef%@AE@%%@AE@%%@AI@%. It is true if the given name is not currently defined.%@AE@%%@AE@%%@NL@%
  5788. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  5789. %@NL@%
  5790. %@NL@%
  5791. %@2@%%@CR:C6A00070010 @%%@AB@%Pragmas%@AE@%%@EH@%%@NL@%
  5792. %@NL@%
  5793. %@AU@%  Pragmas are implementationspecific compiler commands.%@AE@%  %@NL@%
  5794. %@NL@%
  5795. Although portability is a hallmark of C, the language's creators recognized
  5796. that every C compiler will need to support some features unique to its host
  5797. machine. The "%@AB@%#pragma%@AE@% directive" offers a way for each C compiler to offer
  5798. machine-specific features while retaining overall compatibility with the C
  5799. language. Since pragmas are machine-specific by definition, they can be─and
  5800. usually are─different for every C compiler.  %@NL@%
  5801. %@NL@%
  5802. Pragmas have the same general syntax as preprocessor directives. The pragma
  5803. must begin with a number sign (%@AB@%#%@AE@%) and it can't share a line with other
  5804. directives or statements except a comment, which must appear to the right of
  5805. the pragma.  %@NL@%
  5806. %@NL@%
  5807. QuickC supports four pragmas: %@AB@%check_stack%@AE@%, %@AB@%check_pointer%@AE@%, %@AB@%message%@AE@%, and %@AB@%pack%@AE@%.
  5808. Each of these pragmas is described in online help.  %@NL@%
  5809. %@NL@%
  5810. Some pragmas take arguments, which come after the %@AB@%#pragma%@AE@% keyword. In the
  5811. following code, the %@AB@%message%@AE@% pragma displays different messages during
  5812. compilation depending on the outcome of an %@AB@%#if%@AE@% test:  %@NL@%
  5813. %@NL@%
  5814. %@AS@%  #if XT == 1
  5815. %@AS@%     #pragma message( "Building XT version" )
  5816. %@AS@%  #elif AT == 1
  5817. %@AS@%     #pragma message( "Building AT version" )
  5818. %@AS@%  #endif%@AE@%%@NL@%
  5819. %@NL@%
  5820. The message displayed by the %@AB@%message%@AE@% pragma is visible only if you compile
  5821. from the DOS command line with the QCL command.  %@NL@%
  5822. %@NL@%
  5823. %@NL@%
  5824. %@NL@%
  5825. %@NL@%
  5826. %@NL@%
  5827. %@NL@%
  5828. %@CR:C6A00080001 @%%@1@%%@AB@%Chapter 8  Pointers%@AE@%%@EH@%%@NL@%
  5829. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  5830. %@NL@%
  5831. The next two chapters explain pointers─a large and important topic in C.
  5832. This chapter explains fundamental techniques: how to use pointers with
  5833. various data types and pass them to functions. In Chapter 9, "Advanced
  5834. Pointers," we'll explore more advanced pointer techniques, such as multiple
  5835. indirection.  %@NL@%
  5836. %@NL@%
  5837. If you have never used pointers before, you may want to read this chapter
  5838. now and then turn to Chapter 9 after you have had some practice using
  5839. pointers in your own programs.  %@NL@%
  5840. %@NL@%
  5841. %@AU@% Don't panic!%@AE@%  %@NL@%
  5842. %@NL@%
  5843. There's a lot of new information in these two chapters. Don't be discouraged
  5844. if you don't grasp it all on a first reading. The idea behind a pointer is
  5845. simple, but some advanced pointer techniques are not so easy to follow at
  5846. first.  %@NL@%
  5847. %@NL@%
  5848. %@NL@%
  5849. %@2@%%@CR:C6A00080002 @%%@AB@%Using Pointers in C%@AE@%%@EH@%%@NL@%
  5850. %@NL@%
  5851. Almost every real-world C program uses pointers in some way or another. Much
  5852. of the usefulness of pointers stems from the fact that in C all function
  5853. arguments are passed by value. Because a function only receives local copies
  5854. of such arguments, it can't change the original values that the arguments
  5855. represent. Pointers make this possible.  %@NL@%
  5856. %@NL@%
  5857. Here are some common uses of pointers:  %@NL@%
  5858. %@NL@%
  5859. %@NL@%
  5860.   ■   Manipulating strings%@NL@%
  5861. %@NL@%
  5862.   ■   Passing command-line arguments to a program at run time%@NL@%
  5863. %@NL@%
  5864.   ■   Returning more than one value from a function%@NL@%
  5865. %@NL@%
  5866.   ■   Accessing variables that wouldn't otherwise be visible to a function%@NL@%
  5867. %@NL@%
  5868.   ■   Manipulating an array by moving pointers to its elements instead of
  5869.       using array subscripting%@NL@%
  5870. %@NL@%
  5871.   ■   Accessing the address of a memory area that your program allocates at
  5872.       run time%@NL@%
  5873. %@NL@%
  5874.   ■   Passing the address of one function to another function%@NL@%
  5875. %@NL@%
  5876. %@NL@%
  5877. %@NL@%
  5878. %@2@%%@CR:C6A00080003 @%%@AB@%Pointers to Simple Variables%@AE@%%@EH@%%@NL@%
  5879. %@NL@%
  5880. %@AU@% A pointer variable contains the address of a data object.%@AE@%  %@NL@%
  5881. %@NL@%
  5882. Although pointers have many different uses, it takes only a few words to say
  5883. what a pointer is. A "pointer" is a variable that contains the address of
  5884. some other data object─usually a variable. Because a pointer contains the
  5885. other variable's address, it is said to "point to" that variable.  %@NL@%
  5886. %@NL@%
  5887. This section uses the program POINTER.C to demonstrate the basic mechanics
  5888. of pointers─how to declare and initialize a pointer and use it to access a
  5889. simple variable:  %@NL@%
  5890. %@NL@%
  5891. %@AS@%  /* POINTER.C: Demonstrate pointer basics. */
  5892. %@AS@%  
  5893. %@AS@%  #include <stdio.h>
  5894. %@AS@%  
  5895. %@AS@%  main()
  5896. %@AS@%  {
  5897. %@AS@%     int val = 25;
  5898. %@AS@%     int *ptr;
  5899. %@AS@%     ptr = &val;
  5900. %@AS@%     printf( " val = %d\n", val );
  5901. %@AS@%     printf( "*ptr = %d\n\n", *ptr );
  5902. %@AS@%     printf( "&val = %u\n", &val );
  5903. %@AS@%     printf( " ptr = %d\n", ptr );
  5904. %@AS@%  }%@AE@%%@NL@%
  5905. %@NL@%
  5906. Here is the output from POINTER.C:  %@NL@%
  5907. %@NL@%
  5908. %@AS@%  val = 25
  5909. %@AS@%  *ptr = 25
  5910. %@AS@%  
  5911. %@AS@%  &val = 5308
  5912. %@AS@%   ptr = 5308%@AE@%%@NL@%
  5913. %@NL@%
  5914. (The third and fourth output lines show addresses. These may differ when you
  5915. run POINTER.C depending on factors such as available memory.)  %@NL@%
  5916. %@NL@%
  5917. POINTER.C creates a pointer variable named %@AS@% ptr %@AE@% and makes %@AS@% ptr %@AE@% point to an
  5918. %@AB@%int%@AE@% variable named %@AS@% val%@AE@%. Then it prints the two values to show that %@AS@% ptr %@AE@%
  5919. can access the value stored in %@AS@% val%@AE@%. The program goes on to print the
  5920. address where %@AS@% val %@AE@% is stored and the address contained in %@AS@% ptr%@AE@%, to show
  5921. they are the same.  %@NL@%
  5922. %@NL@%
  5923. %@NL@%
  5924. %@3@%%@CR:C6A00080004 @%%@AB@%Declaring a Pointer Variable%@AE@%%@EH@%%@NL@%
  5925. %@NL@%
  5926. Like any variable, a pointer variable must be declared before it is used,
  5927. and its value can change in the course of a program. A pointer variable can
  5928. have any legal variable name. Here is the pointer declaration from
  5929. POINTER.C:  %@NL@%
  5930. %@NL@%
  5931. %@AS@%  int *ptr;%@AE@%%@NL@%
  5932. %@NL@%
  5933. This declaration states the program has a pointer variable named %@AS@% ptr %@AE@% that
  5934. can point to a data object of the %@AB@%int%@AE@% type.  %@NL@%
  5935. %@NL@%
  5936. Notice the similarity to a simple variable declaration. As in other cases,
  5937. the declaration gives a type (%@AB@%int%@AE@%) and name (%@AS@% ptr %@AE@%) for the variable.  %@NL@%
  5938. %@NL@%
  5939. %@AU@% Use the indirection  operator (%@AE@% *) to declare  a pointer variable.  %@NL@%
  5940. %@NL@%
  5941. The indirection operator (%@AB@%*%@AE@%) in front of the name %@AS@% ptr %@AE@% shows this variable
  5942. is a pointer. This operator has two different uses in C. In declarations,
  5943. such as the one above, it simply means "this is a pointer." In other
  5944. contexts, as we'll elaborate throughout this chapter, it means
  5945. indirection─using the data object that a pointer points to.  %@NL@%
  5946. %@NL@%
  5947. %@AU@% A pointer declaration shows %@AE@%%@AB@%what%@AE@% type of data object a pointer references.
  5948. %@NL@%
  5949. %@NL@%
  5950. A pointer doesn't have a type in the same sense as other variables. When you
  5951. declare a simple variable, the type specifier shows what type of value the
  5952. variable stores. When you declare a pointer variable, the type specifier
  5953. shows what type of data object the pointer %@AI@%points to%@AE@%.  %@NL@%
  5954. %@NL@%
  5955. Thus, in POINTER.C the declaration of the variable %@AS@% val %@AE@% indicates %@AS@% val %@AE@%
  5956. stores a value of the type %@AB@%int%@AE@%,  %@NL@%
  5957. %@NL@%
  5958. %@AS@%  int val = 25;%@AE@%%@NL@%
  5959. %@NL@%
  5960. while the declaration of the variable %@AS@% ptr %@AE@% indicates it %@AI@%points to%@AE@% a data
  5961. object of the type %@AB@%int%@AE@%:  %@NL@%
  5962. %@NL@%
  5963. %@AS@%  int *ptr;%@AE@%%@NL@%
  5964. %@NL@%
  5965. To declare pointers to other types of variables, you can use whatever type
  5966. specifier is appropriate. These statements, for instance, declare pointers
  5967. to %@AB@%char%@AE@% and %@AB@%float%@AE@% variables:  %@NL@%
  5968. %@NL@%
  5969. %@AS@%  char *c_ptr, *ch;
  5970. %@AS@%  float *f_pointer;%@AE@%%@NL@%
  5971. %@NL@%
  5972. Note that if you declare more than one pointer variable in the same line,
  5973. each name must be preceded by the indirection operator. The first line in
  5974. the previous example declares two pointer variables: %@AS@% c_ptr %@AE@% and %@AS@% ch%@AE@%. Each
  5975. pointer can point to an object of the %@AB@%char%@AE@% type. If you omit the second
  5976. indirection operator from the first line,  %@NL@%
  5977. %@NL@%
  5978. %@AS@%  char *c_ptr, ch;%@AE@%%@NL@%
  5979. %@NL@%
  5980. the line declares a pointer variable named %@AS@% c_ptr %@AE@% and an ordinary %@AB@%char%@AE@%
  5981. variable named %@AS@% ch%@AE@%.  %@NL@%
  5982. %@NL@%
  5983. %@AU@% A pointer declared with type %@AE@%%@AB@%void%@AE@% can point to any type of data object.  %@NL@%
  5984. %@NL@%
  5985. In most cases a pointer points to a particular type of object, such as an
  5986. %@AB@%int%@AE@%. You can also declare a pointer with type %@AB@%void%@AE@%, which allows it to point
  5987. to any type of object.  %@NL@%
  5988. %@NL@%
  5989. One use of %@AB@%void%@AE@% pointers is to write a general-purpose function, such as a
  5990. sort, that can operate on data of more than one type. Each time you use a
  5991. %@AB@%void%@AE@% pointer, you must perform an explicit type cast to show what type of
  5992. object it points to on that occasion.  %@NL@%
  5993. %@NL@%
  5994. Figure 8.1 shows the relationship between %@AS@% val %@AE@% and %@AS@% ptr %@AE@% in POINTER.C,
  5995. immediately after %@AS@% ptr %@AE@% has been declared. The figure shows that the
  5996. variable %@AS@% val %@AE@% is stored at memory location 5308, as in the output shown
  5997. above. Again, the actual address may differ when you run POINTER.C.  %@NL@%
  5998. %@NL@%
  5999. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  6000. %@NL@%
  6001. Figure 8.1 uses question marks to show that the contents of %@AS@% ptr %@AE@% are
  6002. undefined at this stage in the program. Like any other variable that has
  6003. been declared but not initialized, the contents of %@AS@% ptr %@AE@% are unknown. You
  6004. must take special care not to use pointers that have not been initialized,
  6005. since an uninitialized pointer might point anywhere in memory─including
  6006. sensitive operating-system addresses.  %@NL@%
  6007. %@NL@%
  6008. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6009. %@AU@%WARNING%@AE@%%@NL@%
  6010. %@NL@%
  6011. Because a pointer can potentially access any memory address, using an
  6012. uninitialized pointer can have drastic consequences.%@NL@%
  6013. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6014. %@NL@%
  6015. %@NL@%
  6016. %@3@%%@CR:C6A00080005 @%%@AB@%How Pointers Are Stored%@AE@%%@EH@%%@NL@%
  6017. %@NL@%
  6018. Figure 8.1 also shows that while a pointer is a special kind of variable, it
  6019. is not a mysterious entity floating in limbo. A pointer is a true variable
  6020. whose contents are stored at a specific memory address.  %@NL@%
  6021. %@NL@%
  6022. In POINTER.C we don't care precisely where the pointer's contents are
  6023. stored─the compiler handles that detail for us, as it does so many others.
  6024. So Figure 8.1 does not include the address of the storage for %@AS@% ptr%@AE@%. It does
  6025. show, however, that the pointer is stored in two bytes, the same amount of
  6026. memory needed to store an %@AB@%int%@AE@% value.  %@NL@%
  6027. %@NL@%
  6028. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6029. NOTE
  6030.  
  6031. %@AI@%The actual amount of memory needed to store a pointer variable depends on
  6032. %@AI@%the current "memory model." In the %@AI@%small%@AE@%%@AI@% memory model─the default for QuickC
  6033. %@AI@%version 2.5─a pointer is stored in two bytes. In some larger memory models,
  6034. %@AI@%a pointer is stored in four bytes. For purposes of discussion, this chapter
  6035. %@AI@%and the following chapter assume the small memory model. Appendix B,
  6036. %@AI@%"Working with QuickC Memory Models," in the Microsoft QuickC Tool Kit%@AE@%%@AI@%
  6037. %@AI@%discusses memory models.%@AE@%%@AE@%%@NL@%
  6038. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  6039. %@NL@%
  6040. %@NL@%
  6041. %@3@%%@CR:C6A00080006 @%%@AB@%Initializing a Pointer Variable%@AE@%%@EH@%%@NL@%
  6042. %@NL@%
  6043. The next step in the POINTER.C program is to initialize the pointer variable
  6044. %@AS@% ptr%@AE@%, making it point to some meaningful address in memory:  %@NL@%
  6045. %@NL@%
  6046. %@AS@%  ptr = &val;%@AE@%%@NL@%
  6047. %@NL@%
  6048. The "address-of operator" (%@AB@%&%@AE@%) gives the address of the name it precedes. So
  6049. in plain English the above statement says, "assign the address of %@AS@% val %@AE@% to %@AS@%
  6050. %@AS@%ptr%@AE@%."  %@NL@%
  6051. %@NL@%
  6052. After its initialization, the variable %@AS@% ptr %@AE@% points to %@AS@% val %@AE@% in the sense
  6053. that it contains the address where %@AS@% val %@AE@% is stored.  %@NL@%
  6054. %@NL@%
  6055. The output from POINTER.C shows that %@AS@% ptr %@AE@% contains the address of %@AS@% val%@AE@%.
  6056. First it prints the address of %@AS@% val %@AE@% using the address-of operator to
  6057. directly obtain the variable's address,  %@NL@%
  6058. %@NL@%
  6059. %@AS@%  &val = 5308%@AE@%%@NL@%
  6060. %@NL@%
  6061. then it prints the contents of %@AS@% ptr%@AE@%: %@AS@%  %@AE@%%@NL@%
  6062. %@NL@%
  6063. %@AS@%  ptr = 5308%@AE@%%@NL@%
  6064. %@NL@%
  6065. The two values are identical. Figure 8.2 shows the relationship of %@AS@% val %@AE@% and
  6066. %@AS@% ptr %@AE@% at this stage in the POINTER.C program.  %@NL@%
  6067. %@NL@%
  6068. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  6069. %@NL@%
  6070. Initialization is especially important for pointers because, as noted
  6071. earlier, they have the potential to point anywhere in memory. If you forget
  6072. to initialize it, or make it point to the wrong place, a pointer can wreak
  6073. havoc with your program or even the operating system itself.  %@NL@%
  6074. %@NL@%
  6075. %@AU@% The target of a pointer  must be present in  memory at run time.%@AE@%  %@NL@%
  6076. %@NL@%
  6077. The pointer in POINTER.C points to a simple %@AB@%int%@AE@% variable. As a general rule,
  6078. pointers can point to any data object that is present in memory at run time.
  6079. This category mainly includes objects for which the program allocates (sets
  6080. aside) memory. Memory can be allocated implicitly, by defining a variable or
  6081. function, or explicitly, by calling a memory-allocating library function
  6082. such as %@AB@%malloc%@AE@%.  %@NL@%
  6083. %@NL@%
  6084. A pointer can't point to program elements such as expressions or %@AB@%register%@AE@%
  6085. variables, which aren't present in addressable memory.  %@NL@%
  6086. %@NL@%
  6087. POINTER.C initializes the pointer %@AS@% ptr %@AE@% by assigning it an address constant
  6088. (the address of %@AS@% val%@AE@%, obtained with the address-of operator). You can also
  6089. assign the value of one pointer to another, as shown here:  %@NL@%
  6090. %@NL@%
  6091. %@AS@%  ptr = ptr1;%@AE@%%@NL@%
  6092. %@NL@%
  6093. If %@AS@% ptr %@AE@% and %@AS@% ptr1 %@AE@% are both pointers, this statement assigns the address
  6094. contained in %@AS@% ptr1 %@AE@% to %@AS@% ptr%@AE@%.  %@NL@%
  6095. %@NL@%
  6096. %@NL@%
  6097. %@3@%%@CR:C6A00080007 @%%@AB@%Using a Pointer Variable%@AE@%%@EH@%%@NL@%
  6098. %@NL@%
  6099. Once %@AS@% ptr %@AE@% points to %@AS@% val%@AE@%, we have two ways to access the %@AB@%int%@AE@% value stored
  6100. in %@AS@% val%@AE@%. The usual way is direct, using the name of %@AS@% val%@AE@%:  %@NL@%
  6101. %@NL@%
  6102. %@AS@%  printf( " val = %d\n", val );%@AE@%%@NL@%
  6103. %@NL@%
  6104. The second way to access %@AS@% val %@AE@% is indirect, using the pointer variable %@AS@% ptr %@AE@%
  6105. and the indirection operator:  %@NL@%
  6106. %@NL@%
  6107. %@AS@%  printf( "*ptr = %d\n\n", *ptr );%@AE@%%@NL@%
  6108. %@NL@%
  6109. Both of the preceding statements print the value of %@AS@% val%@AE@%, confirming that
  6110. you can access the contents of %@AS@% val %@AE@% indirectly as well as directly. Once %@AS@%
  6111. %@AS@%ptr %@AE@% points to %@AS@% val %@AE@% you can use %@AS@% *ptr %@AE@% anywhere that you would use %@AS@% val%@AE@%. %@AS@%  %@AE@%%@NL@%
  6112. %@NL@%
  6113. %@AU@% The indirection operator can obtain the value to which a pointer points.%@AE@%  %@NL@%
  6114. %@NL@%
  6115. Using the indirection operator to access the contents of %@AS@% val %@AE@% is the second
  6116. use of this operator (the first is in declaring pointer variables, as
  6117. explained earlier). When the asterisk appears in front of the name %@AS@% ptr%@AE@%, the
  6118. expression states that you want to use the %@AI@%value the pointer points to%@AE@%, not
  6119. the value of %@AS@% ptr %@AE@% itself.  %@NL@%
  6120. %@NL@%
  6121. The second %@AB@%printf%@AE@% statement in POINTER.C uses the expression %@AS@% *ptr %@AE@% to
  6122. access the value stored in %@AS@% val%@AE@%.  %@NL@%
  6123. %@NL@%
  6124. This use of a pointer is analogous to the %@AB@%PEEK%@AE@% function in QuickBASIC. You
  6125. can just as easily use %@AS@% ptr %@AE@% to change the data in %@AS@% val%@AE@%, an operation that
  6126. somewhat resembles a QuickBASIC %@AB@%POKE%@AE@% statement.  %@NL@%
  6127. %@NL@%
  6128. For instance, if you add the following statements to the end of POINTER.C,  %@NL@%
  6129. %@NL@%
  6130. %@AS@%  *ptr = 3301;
  6131. %@AS@%  printf( "%d\n", val );%@AE@%%@NL@%
  6132. %@NL@%
  6133. the program prints %@AS@% 3301%@AE@%.  %@NL@%
  6134. %@NL@%
  6135. Figure 8.3 shows the relationship between %@AS@% ptr %@AE@% and %@AS@% val %@AE@% after executing
  6136. the previous two statements.  %@NL@%
  6137. %@NL@%
  6138. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  6139. %@NL@%
  6140. As Figure 8.3 shows, the value stored in %@AS@% val %@AE@% has changed from 25 to 3301.
  6141. The contents of %@AS@% val %@AE@% were changed indirectly, through the pointer %@AS@% ptr%@AE@%.  %@NL@%
  6142. %@NL@%
  6143. %@NL@%
  6144. %@3@%%@CR:C6A00080008 @%%@AB@%Summary of Pointer Basics%@AE@%%@EH@%%@NL@%
  6145. %@NL@%
  6146. In the preceding sections, you have seen how to do these operations:  %@NL@%
  6147. %@NL@%
  6148. %@NL@%
  6149.   ■   Declare a pointer to a simple variable%@NL@%
  6150. %@NL@%
  6151.   ■   Initialize a pointer, making it point to a variable%@NL@%
  6152. %@NL@%
  6153.   ■   Use a pointer to get the value of a variable%@NL@%
  6154. %@NL@%
  6155.   ■   Use a pointer to change the contents of a variable%@NL@%
  6156. %@NL@%
  6157. %@NL@%
  6158. It's important for you to be comfortable with these basic ideas before
  6159. reading about the more advanced uses of pointers. If you're not sure you
  6160. understand these concepts, you may want to experiment with the POINTER.C
  6161. program to reinforce what you know. For instance, you might add some new
  6162. variables of different types and create new pointers to access them.  %@NL@%
  6163. %@NL@%
  6164. %@NL@%
  6165. %@2@%%@CR:C6A00080009 @%%@AB@%Pointers to Arrays%@AE@%%@EH@%%@NL@%
  6166. %@NL@%
  6167. Pointers and arrays are closely related in C─a major theme we'll elaborate
  6168. throughout the rest of this chapter and Chapter 9, "Advanced Pointers." This
  6169. section explains one of the simpler ways to use pointers with arrays.  %@NL@%
  6170. %@NL@%
  6171. A pointer to an array, or "array pointer," combines two powerful language
  6172. features─the pointer's ability to provide indirect access and the
  6173. convenience of accessing array elements through numerical subscripts.  %@NL@%
  6174. %@NL@%
  6175. %@AU@% An array pointer can point to any element in a given array.%@AE@%  %@NL@%
  6176. %@NL@%
  6177. A pointer to an array is not much different than a pointer to a simple
  6178. variable. In both cases, the pointer can point only to a single object at
  6179. any given time. An array pointer, however, can reference any individual
  6180. element within an array (but just one at a time).  %@NL@%
  6181. %@NL@%
  6182. The program PARRAY.C shows how to access the elements of an %@AB@%int%@AE@% array
  6183. through a pointer:  %@NL@%
  6184. %@NL@%
  6185. %@AS@%  /* PARRAY.C: Demonstrate pointer to array. */
  6186. %@AS@%  
  6187. %@AS@%  #include <stdio.h>
  6188. %@AS@%  
  6189. %@AS@%  int i_array[] = { 25, 300, 2, 12 };
  6190. %@AS@%  
  6191. %@AS@%  main()
  6192. %@AS@%  {
  6193. %@AS@%     int *ptr;
  6194. %@AS@%     int count;
  6195. %@AS@%     ptr = &i_array[0];%@AE@%%@NL@%
  6196. %@NL@%
  6197. %@AS@%  for( count = 0; count < 4 ; count++ )   {
  6198. %@AS@%        printf( "i_array[%d] = %d\n", count, *ptr );
  6199. %@AS@%        ptr++;
  6200. %@AS@%     }
  6201. %@AS@%  }%@AE@%%@NL@%
  6202. %@NL@%
  6203. Here is the output from PARRAY.C:  %@NL@%
  6204. %@NL@%
  6205. %@AS@%  i_array[0] = 25
  6206. %@AS@%  i_array[1] = 300
  6207. %@AS@%  i_array[2] = 2
  6208. %@AS@%  i_array[3] = 12%@AE@%%@NL@%
  6209. %@NL@%
  6210. The PARRAY.C program creates a four-element %@AB@%int%@AE@% array named %@AS@% i_array%@AE@%. Then
  6211. it declares a pointer named %@AS@% ptr %@AE@% and uses %@AS@% ptr %@AE@% in a %@AB@%for%@AE@% loop to access
  6212. each of the elements in %@AS@% i_array%@AE@%.  %@NL@%
  6213. %@NL@%
  6214. Notice the similarity between PARRAY.C and the previous example (POINTER.C).
  6215. The pointer is declared in the same way:  %@NL@%
  6216. %@NL@%
  6217. %@AS@%  int *ptr;%@AE@%%@NL@%
  6218. %@NL@%
  6219. As noted before, this declaration states that %@AS@% ptr %@AE@% can point to any object
  6220. of the %@AB@%int%@AE@% type, which includes an element in an %@AB@%int%@AE@% array as well as a
  6221. simple %@AB@%int%@AE@%. The initialization of %@AS@% ptr %@AE@% looks similar, too:  %@NL@%
  6222. %@NL@%
  6223. %@AS@%  ptr = &i_array[0];%@AE@%%@NL@%
  6224. %@NL@%
  6225. This statement assigns %@AS@% ptr %@AE@% the address of the first element of %@AS@% i_array%@AE@%,
  6226. which is %@AS@% i_array[0]%@AE@%. (There's a more compact way to initialize this
  6227. pointer, but we'll defer that discussion for a moment.) Figure 8.4 shows the
  6228. relationship between %@AS@% ptr %@AE@% and %@AS@% i_array %@AE@% immediately after %@AS@% ptr %@AE@% is
  6229. initialized.  %@NL@%
  6230. %@NL@%
  6231. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  6232. %@NL@%
  6233. %@NL@%
  6234. %@3@%%@CR:C6A00080010 @%%@AB@%Arrays and Pointer Arithmetic%@AE@%%@EH@%%@NL@%
  6235. %@NL@%
  6236. Once a pointer points to an array, it can access any of the array's
  6237. elements. By adding or subtracting from the pointer's value (using "pointer
  6238. arithmetic") you can access any element in the array, just as you can access
  6239. it with array subscripts.  %@NL@%
  6240. %@NL@%
  6241. So in PARRAY.C, just as in POINTER.C, we can use %@AS@% *ptr %@AE@% to access the %@AB@%int%@AE@%
  6242. value that %@AS@% ptr %@AE@% references. The only difference is now %@AS@% ptr %@AE@% points to an
  6243. array element instead of a simple variable.  %@NL@%
  6244. %@NL@%
  6245. When the %@AB@%for%@AE@% loop in PARRAY.C executes the first time, %@AS@% ptr %@AE@% points to the
  6246. first element of %@AS@% i_array%@AE@%, which is %@AS@% i_array[0]%@AE@%. The second statement in the
  6247. loop body,  %@NL@%
  6248. %@NL@%
  6249. %@AS@%  ptr++;%@AE@%%@NL@%
  6250. %@NL@%
  6251. increments the pointer. Now %@AS@% ptr %@AE@% points to the next element in %@AS@% i_array%@AE@%,
  6252. which is %@AS@% i_array[1]%@AE@%. Figure 8.5 shows the relationship of %@AS@% ptr %@AE@% and %@AS@%
  6253. %@AS@%i_array %@AE@% after the first iteration of the %@AB@%for%@AE@% loop in PARRAY.C.  %@NL@%
  6254. %@NL@%
  6255. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  6256. %@NL@%
  6257. Figures 8.4 and 8.5 illustrate another important fact about pointers.
  6258. Pointer arithmetic is automatically scaled to the size of the object that a
  6259. pointer references. As explained above, incrementing %@AS@% ptr %@AE@% with the
  6260. statement %@AS@%  %@AE@%%@NL@%
  6261. %@NL@%
  6262. %@AS@%  ptr++;%@AE@%%@NL@%
  6263. %@NL@%
  6264. %@AU@% Pointer arithmetic is scaled to the size of  elements in an array.%@AE@%  %@NL@%
  6265. %@NL@%
  6266. moves the pointer forward to the next %@AI@%element%@AE@% in %@AS@% i_array%@AE@%. Since each
  6267. element of an %@AB@%int%@AE@% array contains two bytes, this operation actually adds 2
  6268. to the address stored in %@AS@% ptr%@AE@%, but you don't have to worry about that
  6269. detail. The compiler knows the size of the elements in the array and adjusts
  6270. the pointer accordingly.  %@NL@%
  6271. %@NL@%
  6272. Incrementing a pointer adds 1 if it points to a %@AB@%char%@AE@% array, 4 if it points
  6273. to a %@AB@%float%@AE@% array, and so on.  %@NL@%
  6274. %@NL@%
  6275. You can also decrement an array pointer. If %@AS@% ptr %@AE@% points to %@AS@% i_array[2]%@AE@%,
  6276. this statement moves the pointer back one element, to %@AS@% i_array[1]%@AE@%:  %@NL@%
  6277. %@NL@%
  6278. %@AS@%  ptr--;%@AE@%%@NL@%
  6279. %@NL@%
  6280. Although the previous expressions increment and decrement %@AS@% ptr %@AE@% by 1, you
  6281. can add or subtract any integer value from a pointer. For instance, the
  6282. following statement moves %@AS@% ptr %@AE@% forward three elements in %@AS@% i_array%@AE@%:  %@NL@%
  6283. %@NL@%
  6284. %@AS@%  ptr += 3;%@AE@%%@NL@%
  6285. %@NL@%
  6286. Be careful not to overrun the bounds of an array when accessing its elements
  6287. with a pointer. As noted in Chapter 4, "Data Types," the C language doesn't
  6288. check array subscripts. This rule applies equally when you access an array
  6289. with a pointer, which can potentially reference any address in memory.  %@NL@%
  6290. %@NL@%
  6291. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6292. %@AU@%WARNING%@AE@%%@NL@%
  6293. %@NL@%
  6294. The C language does not check array pointer references. If you increment or
  6295. decrement a pointer past the limits of an array, you can corrupt other parts
  6296. of your program or cause other unexpected results.%@NL@%
  6297. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6298. %@NL@%
  6299. It's your job to make sure an increment or decrement doesn't move a pointer
  6300. outside the memory where an array is stored. For instance, if you decrement %@AS@%
  6301. %@AS@%ptr %@AE@% when it points to %@AS@% i_array[0]%@AE@%, it will point to whatever happens to be
  6302. stored in the %@AB@%int%@AE@%-size memory area %@AI@%below%@AE@% the element %@AS@% i_array[0]%@AE@%.  %@NL@%
  6303. %@NL@%
  6304. Most pointer arithmetic occurs in connection with arrays, where a numerical
  6305. index has obvious utility. It's not illegal to do pointer arithmetic on
  6306. nonarray pointers, but such operations normally serve no purpose. For
  6307. instance, if you increment a pointer to a simple variable, the pointer no
  6308. longer points to the variable and becomes useless.  %@NL@%
  6309. %@NL@%
  6310. %@NL@%
  6311. %@3@%%@CR:C6A00080011 @%%@AB@%Comparing Pointers%@AE@%%@EH@%%@NL@%
  6312. %@NL@%
  6313. The special nature of a pointer variable─the fact that it contains an
  6314. address─ precludes most operations that are legal for other variables.
  6315. There's no such thing as a fractional memory address, for example. So it
  6316. wouldn't make sense to divide a pointer, or add a floating-point number to
  6317. it. The most common pointer operations are assignment, incrementing, and
  6318. decrementing, as described earlier. You can also compare one pointer to
  6319. another.  %@NL@%
  6320. %@NL@%
  6321. If a program allocates memory for a stack, for instance, you might create
  6322. two pointers that point to different parts of the stack. One pointer can
  6323. show where the stack begins and the other where it ends. To see how much of
  6324. the stack is in use, you can subtract the pointers. (A "stack" is a memory
  6325. area used for temporary storage.)  %@NL@%
  6326. %@NL@%
  6327. %@AU@% You can compare pointer variables with relational operators or by
  6328. %@AU@%subtraction.%@AE@%  %@NL@%
  6329. %@NL@%
  6330. Pointer comparisons can be done with relational operators (such as %@AB@%%@AE@% ) or by
  6331. subtracting one pointer from another. Of course, pointer comparisons are
  6332. meaningful only for pointers that point to the same data object or related
  6333. objects of the same type.  %@NL@%
  6334. %@NL@%
  6335. %@NL@%
  6336. %@3@%%@CR:C6A00080012 @%%@AB@%PARRAY.C Revisited%@AE@%%@EH@%%@NL@%
  6337. %@NL@%
  6338. Before leaving the PARRAY.C program, we should note that most C programmers
  6339. would write it more compactly (PARRAY1.C):  %@NL@%
  6340. %@NL@%
  6341. %@AS@%  /* PARRAY1.C: Compact version of PARRAY.C. */
  6342. %@AS@%  
  6343. %@AS@%  #include <stdio.h>
  6344. %@AS@%  
  6345. %@AS@%  int i_array[] = { 25, 300, 2, 12 };
  6346. %@AS@%  
  6347. %@AS@%  main()
  6348. %@AS@%  {
  6349. %@AS@%     int count;
  6350. %@AS@%     int *ptr = i_array;
  6351. %@AS@%     for( count = 0; count < 4 ; count++ )
  6352. %@AS@%        printf( "i_array[%d] = %d\n", count, *ptr++ );
  6353. %@AS@%  }%@AE@%%@NL@%
  6354. %@NL@%
  6355. %@AU@% You can declare and initialize a pointer variable  in one statement.%@AE@%  %@NL@%
  6356. %@NL@%
  6357. The PARRAY1.C program uses several shorthand techniques you can expect to
  6358. see in C programs. Like other variables, pointers can be initialized at the
  6359. same time they are declared. The following statement in PARRAY1.C performs
  6360. both operations:  %@NL@%
  6361. %@NL@%
  6362. %@AS@%  int *ptr = i_array;%@AE@%%@NL@%
  6363. %@NL@%
  6364. The statement above is equivalent to these statements:  %@NL@%
  6365. %@NL@%
  6366. %@AS@%  int *ptr;
  6367. %@AS@%  ptr = i_array;%@AE@%%@NL@%
  6368. %@NL@%
  6369. You may have noticed another difference in the way %@AS@% ptr %@AE@% is initialized. The
  6370. PARRAY1.C program omits the address-of operator and array subscript that
  6371. PARRAY.C used to signify the address of the first element of %@AS@% i_array%@AE@%.
  6372. Instead of %@NL@%
  6373. %@NL@%
  6374. %@AS@%  &i_array[0]%@AE@%%@NL@%
  6375. %@NL@%
  6376. the program uses  %@NL@%
  6377. %@NL@%
  6378. %@AS@%  i_array%@AE@%%@NL@%
  6379. %@NL@%
  6380. %@AU@% An array name is a pointer.%@AE@%  %@NL@%
  6381. %@NL@%
  6382. In fact, the two expressions are equivalent. In the C language, the name of
  6383. an array is actually a pointer. Any array name that doesn't have a subscript
  6384. is interpreted as a pointer to the base address of the array. (The "base
  6385. address" is the address of the array's first element.) We'll explore this
  6386. equivalence further in the following sections and in Chapter 9, "Advanced
  6387. Pointers."  %@NL@%
  6388. %@NL@%
  6389. Finally, PARRAY1.C uses the expression %@AS@% *ptr++ %@AE@% to perform two jobs:
  6390. accessing the value %@AS@% ptr %@AE@% points to and incrementing %@AS@% ptr%@AE@%. Note the order in
  6391. which the two operators in this expression take effect. The indirection
  6392. operator takes effect first, accessing the value of the array element that %@AS@%
  6393. %@AS@%ptr %@AE@% currently points to. Then the increment operator (%@AB@%++%@AE@%) adds 1 to %@AS@% ptr%@AE@%,
  6394. making it point to the next element in %@AS@% i_array%@AE@%.  %@NL@%
  6395. %@NL@%
  6396. %@NL@%
  6397. %@2@%%@CR:C6A00080013 @%%@AB@%Pointers and Strings%@AE@%%@EH@%%@NL@%
  6398. %@NL@%
  6399. %@AU@% String pointers are handled like other array pointers.%@AE@%  %@NL@%
  6400. %@NL@%
  6401. Because a string is an array of characters, pointers to strings are handled
  6402. much like other array pointers. The program PSTRING.C is similar to the
  6403. examples that demonstrated array pointers (PARRAY.C and PARRAY1.C). It uses
  6404. a pointer to access a %@AB@%char%@AE@% array:  %@NL@%
  6405. %@NL@%
  6406. %@AS@%  /* PSTRING.C: Demonstrate pointer to a string. */
  6407. %@AS@%  
  6408. %@AS@%  #include <stdio.h>
  6409. %@AS@%  
  6410. %@AS@%  main()
  6411. %@AS@%  {
  6412. %@AS@%     int count;
  6413. %@AS@%     char name[] = "john";
  6414. %@AS@%     char *ptr = name;
  6415. %@AS@%     for( count = 0; count < 4; count++ )
  6416. %@AS@%     {
  6417. %@AS@%        printf( "name[%d]: %c\n", count, *ptr++ );
  6418. %@AS@%     }
  6419. %@AS@%  }%@AE@%%@NL@%
  6420. %@NL@%
  6421. The PSTRING.C program steps through the %@AS@% name %@AE@% array, printing each
  6422. character in turn:  %@NL@%
  6423. %@NL@%
  6424. %@AS@%  name[0]: j
  6425. %@AS@%  name[1]: o
  6426. %@AS@%  name[2]: h
  6427. %@AS@%  name[3]: n%@AE@%%@NL@%
  6428. %@NL@%
  6429. The notable difference between PARRAY.C and PSTRING.C is that PSTRING.C has
  6430. a %@AB@%char%@AE@% array instead of an %@AB@%int%@AE@% array. Again, incrementing an array pointer
  6431. moves the pointer to the next array element. So in PSTRING.C each iteration
  6432. of the %@AB@%for%@AE@% loop moves the pointer to the next %@AB@%char%@AE@% in the string.  %@NL@%
  6433. %@NL@%
  6434. The first time through the loop, %@AS@% ptr %@AE@% points to %@AS@% name[0]%@AE@%. The second time
  6435. it points to %@AS@% name[1]%@AE@%, and so on.  %@NL@%
  6436. %@NL@%
  6437. As mentioned in Chapter 4, "Data Types," one difference between strings and
  6438. noncharacter arrays is that strings end with a null character. The string in
  6439. PSTRING.C actually contains five characters: four letters and a null
  6440. character. We can exploit this fact to simplify the program, as we do below
  6441. in PSTRING.C.  %@NL@%
  6442. %@NL@%
  6443. %@AS@%  /* PSTRING1.C: Look for null at string's end.  */
  6444. %@AS@%  
  6445. %@AS@%  #include <stdio.h>
  6446. %@AS@%  
  6447. %@AS@%  main()
  6448. %@AS@%  {
  6449. %@AS@%     char name[] = "john";
  6450. %@AS@%     char *ptr = name;
  6451. %@AS@%     while( *ptr )
  6452. %@AS@%        printf( "*ptr = %c\n", *ptr++ );
  6453. %@AS@%  }%@AE@%%@NL@%
  6454. %@NL@%
  6455. Here is the output from PSTRING1.C:  %@NL@%
  6456. %@NL@%
  6457. %@AS@%  *ptr = j
  6458. %@AS@%  *ptr = o
  6459. %@AS@%  *ptr = h
  6460. %@AS@%  *ptr = n%@AE@%%@NL@%
  6461. %@NL@%
  6462. Like PSTRING.C, the PSTRING1.C program steps through the array one character
  6463. at a time. However, it replaces the %@AB@%for%@AE@% loop with a simpler %@AB@%while%@AE@% loop. The
  6464. test expression in the %@AB@%while%@AE@% loop,  %@NL@%
  6465. %@NL@%
  6466. %@AS@%  while( *ptr )%@AE@%%@NL@%
  6467. %@NL@%
  6468. is evaluated as true until %@AS@% ptr %@AE@% points to the null character that
  6469. terminates the string. It's a more compact way of writing this expression:  %@NL@%
  6470. %@NL@%
  6471. %@AS@%  while( *ptr != 0 )%@AE@%%@NL@%
  6472. %@NL@%
  6473. %@AU@% Any operation done with array subscripts can also be done with pointer
  6474. %@AU@%notation.%@AE@%  %@NL@%
  6475. %@NL@%
  6476. This is an ideal time to elaborate on the relationship between arrays and
  6477. pointers. Any operation you can do with conventional array notation
  6478. (subscripts) can also be done with pointers. This is possible because an
  6479. array name, as we noted earlier, is itself a pointer.  %@NL@%
  6480. %@NL@%
  6481. To illustrate, the PSTRING2.C program uses only array notation:  %@NL@%
  6482. %@NL@%
  6483. %@AS@%  /* PSTRING2.C: Demonstrate strings and array notation. */
  6484. %@AS@%  
  6485. %@AS@%  #include <stdio.h>
  6486. %@AS@%  #include <string.h>%@AE@%%@NL@%
  6487. %@NL@%
  6488. %@AS@%  main()
  6489. %@AS@%  {
  6490. %@AS@%     int count;
  6491. %@AS@%     char name[] = "john";
  6492. %@AS@%     for( count = 0; count < strlen( name ); count++ )
  6493. %@AS@%        printf( "name[%d]: %c\n", count, name[count] );
  6494. %@AS@%  }%@AE@%%@NL@%
  6495. %@NL@%
  6496. PSTRING2.C gives the same output as PSTRING.C. In this program, the
  6497. expression  %@NL@%
  6498. %@NL@%
  6499. %@AS@%  name[count]%@AE@%%@NL@%
  6500. %@NL@%
  6501. uses %@AS@% count %@AE@% as in an index to the %@AS@% name %@AE@% array.  %@NL@%
  6502. %@NL@%
  6503. PSTRING3.C is the same program written with pointer notation:  %@NL@%
  6504. %@NL@%
  6505. %@AS@%  /* PSTRING3.C: Strings and pointer notation.  */
  6506. %@AS@%  
  6507. %@AS@%  #include <stdio.h>
  6508. %@AS@%  #include <string.h>
  6509. %@AS@%  
  6510. %@AS@%  main()
  6511. %@AS@%  {
  6512. %@AS@%     int count;
  6513. %@AS@%     char name[] = "john";
  6514. %@AS@%     for( count = 0; count < strlen( name ); count++ )
  6515. %@AS@%        printf( "*(name+%d) = %c\n", count,*(name+count) );
  6516. %@AS@%  }%@AE@%%@NL@%
  6517. %@NL@%
  6518. Here is the output from PSTRING3.C:  %@NL@%
  6519. %@NL@%
  6520. %@AS@%  *(name+0) = j
  6521. %@AS@%  *(name+1) = o
  6522. %@AS@%  *(name+2) = h
  6523. %@AS@%  *(name+3) = n%@AE@%%@NL@%
  6524. %@NL@%
  6525. Notice how PSTRING3.C replaces the expression  %@NL@%
  6526. %@NL@%
  6527. %@AS@%  name[count]%@AE@%%@NL@%
  6528. %@NL@%
  6529. with the expression:  %@NL@%
  6530. %@NL@%
  6531. %@AS@%  *(name+count)%@AE@%%@NL@%
  6532. %@NL@%
  6533. Both expressions use the variable %@AS@% count %@AE@% as an offset from the base address
  6534. of the array. The parentheses in the second expression are important. They
  6535. are necessary because the indirection operator takes effect before the
  6536. addition operator. If you omit the parentheses, as in  %@NL@%
  6537. %@NL@%
  6538. %@AS@%  *name+count%@AE@%%@NL@%
  6539. %@NL@%
  6540. the expression has the same effect as  %@NL@%
  6541. %@NL@%
  6542. %@AS@%  (*name)+count%@AE@%%@NL@%
  6543. %@NL@%
  6544. which adds the value of %@AS@% count %@AE@% to the object %@AS@% name %@AE@% references.  %@NL@%
  6545. %@NL@%
  6546. In summary, the examples in this section show three alternative ways to
  6547. access a character inside a string. In the %@AB@%printf%@AE@% statements in the
  6548. examples, these expressions are equivalent:  %@NL@%
  6549. %@NL@%
  6550. %@AS@%  *ptr %@AE@%%@NL@%
  6551. %@NL@%
  6552. %@AS@%  name[count]%@AE@%%@NL@%
  6553. %@NL@%
  6554. %@AS@%  *(name+count)%@AE@%%@NL@%
  6555. %@NL@%
  6556. Many C programmers prefer pointer notation to array notation because
  6557. pointers are faster for some operations. In other cases─including the one
  6558. above─the choice is entirely one of taste. There's more to say about the
  6559. relationship between pointers and arrays. We'll return to this topic later
  6560. in this chapter and in Chapter 9, "Advanced Pointers."  %@NL@%
  6561. %@NL@%
  6562. %@NL@%
  6563. %@2@%%@CR:C6A00080014 @%%@AB@%Passing Pointers to Functions%@AE@%%@EH@%%@NL@%
  6564. %@NL@%
  6565. %@AU@% A function that receives  pointers can access  variables that are local  to
  6566. %@AU@%other functions.%@AE@%  %@NL@%
  6567. %@NL@%
  6568. One of the most common uses of pointers is to pass them as arguments to
  6569. functions. Functions that receive variables as parameters get local copies
  6570. of those variables, not the originals. In contrast, functions that receive
  6571. pointers to variables gain access to the original variables associated with
  6572. the pointers. This allows the functions to  %@NL@%
  6573. %@NL@%
  6574. %@NL@%
  6575.   ■   Return more than one value%@NL@%
  6576. %@NL@%
  6577.   ■   Read and change values in variables─including arrays and
  6578.       structures─that otherwise aren't visible to the function%@NL@%
  6579. %@NL@%
  6580. %@NL@%
  6581. The first item listed above relates to the %@AB@%return%@AE@% statement. As we noted in
  6582. Chapter 2, "Functions," a function can return only one value through %@AB@%return%@AE@%.
  6583. How-ever, it's not difficult to imagine a useful function─a sort, for
  6584. instance─that would return more than one value. Pointers offer an elegant
  6585. solution.  %@NL@%
  6586. %@NL@%
  6587. The second item involves visibility. Most variables in C programs are local
  6588. to the functions where they are defined, and a function normally can't
  6589. access local variables in other functions. There are times, however, when
  6590. you want a function to have access to a local variable defined elsewhere in
  6591. the program. By passing the function a pointer to the local variable, you
  6592. can give it access to the variable  itself.  %@NL@%
  6593. %@NL@%
  6594. The PFUNC.C program illustrates both ideas. It has a function that returns
  6595. more than one value and uses pointers to alter variables that aren't visible
  6596. within the function:  %@NL@%
  6597. %@NL@%
  6598. %@AS@%  /* PFUNC.C: Pass pointers to a function. */
  6599. %@AS@%  
  6600. %@AS@%  #include <stdio.h>
  6601. %@AS@%  
  6602. %@AS@%  void swap( int *ptr1, int *ptr2 );
  6603. %@AS@%  
  6604. %@AS@%  main()
  6605. %@AS@%  {
  6606. %@AS@%     int first = 1, second = 3;
  6607. %@AS@%     int *ptr = &second;
  6608. %@AS@%     printf( "first: %d  second: %d\n", first, *ptr );
  6609. %@AS@%     swap( &first, ptr );
  6610. %@AS@%     printf( "first: %d  second: %d\n", first, *ptr );
  6611. %@AS@%  }
  6612. %@AS@%  
  6613. %@AS@%  void swap( int *ptr1, int *ptr2 )
  6614. %@AS@%  {
  6615. %@AS@%     int temp;
  6616. %@AS@%     temp = *ptr1;
  6617. %@AS@%     *ptr1 = *ptr2;
  6618. %@AS@%     *ptr2 = temp;
  6619. %@AS@%  }%@AE@%%@NL@%
  6620. %@NL@%
  6621. Here is the output from PFUNC.C:  %@NL@%
  6622. %@NL@%
  6623. %@AS@%  first: 1  second: 3
  6624. %@AS@%  first: 3  second: 1%@AE@%%@NL@%
  6625. %@NL@%
  6626. %@AU@%  Pointers can eliminate the need for external variables.%@AE@%  %@NL@%
  6627. %@NL@%
  6628. The PFUNC.C program swaps the values of two %@AB@%int%@AE@% variables named %@AS@% first %@AE@% and %@AS@%
  6629. %@AS@%second%@AE@%, using a function named %@AS@% swap%@AE@%. Since the exchange involves two
  6630. values, the %@AS@% swap %@AE@% function can't use %@AB@%return%@AE@% to communicate its results.
  6631. More-over, the variables %@AS@% first %@AE@% and %@AS@% second %@AE@% are defined only in the %@AB@%main%@AE@%
  6632. function, and as good C programmers, we want to exchange their values
  6633. without making them externally visible.  %@NL@%
  6634. %@NL@%
  6635. The prototype for the %@AS@% swap %@AE@% function shows that %@AS@% swap %@AE@% expects to receive
  6636. two pointers to %@AB@%int%@AE@% variables:  %@NL@%
  6637. %@NL@%
  6638. %@AS@%  void swap( int *ptr1, int *ptr2 );%@AE@%%@NL@%
  6639. %@NL@%
  6640. Notice the use of %@AB@%void%@AE@% in the prototype and function definition. The %@AB@%void%@AE@%
  6641. specifier shows that the %@AS@% swap %@AE@% function doesn't return any value through a
  6642. %@AB@%return%@AE@% statement. Instead, %@AS@%swap %@AE@% returns its results indirectly, through the
  6643. action of pointers.  %@NL@%
  6644. %@NL@%
  6645. The variables we want to exchange are defined only in %@AB@%main%@AE@%:  %@NL@%
  6646. %@NL@%
  6647. %@AS@%  int first = 1, second = 3;%@AE@%%@NL@%
  6648. %@NL@%
  6649. No other function in the program can access these variables directly by
  6650. using the variable names %@AS@% first %@AE@% and %@AS@% second%@AE@%. We must pass these variables
  6651. as arguments; but since the C language passes arguments by value, we need to
  6652. pass pointers to the variables.  %@NL@%
  6653. %@NL@%
  6654. The %@AB@%main%@AE@% function calls %@AS@% swap %@AE@% with the following statement:  %@NL@%
  6655. %@NL@%
  6656. %@AS@%  swap( &first, ptr );%@AE@%%@NL@%
  6657. %@NL@%
  6658. This statement shows two different ways to pass a pointer to a function. The
  6659. first argument in the function call, %@AS@%  %@AE@%%@NL@%
  6660. %@NL@%
  6661. %@AS@%  &first %@AE@%%@NL@%
  6662. %@NL@%
  6663. passes the address of first as a constant, using the address-of operator.
  6664. The second argument,%@AS@%  %@AE@%%@NL@%
  6665. %@NL@%
  6666. %@AS@%  ptr%@AE@%%@NL@%
  6667. %@NL@%
  6668. passes the address of %@AS@% second %@AE@% with a pointer variable. Earlier in PFUNC.C
  6669. we declared %@AS@% ptr %@AE@% as a pointer to an %@AB@%int%@AE@% and assigned it the address of %@AS@%
  6670. %@AS@%second%@AE@%:  %@NL@%
  6671. %@NL@%
  6672. %@AS@%  int *ptr = &second;%@AE@%%@NL@%
  6673. %@NL@%
  6674. Both arguments pass the same kind of data─the address of a local variable─to
  6675. the function. We'll return to this idea after we see how the rest of PFUNC.C
  6676. works.  %@NL@%
  6677. %@NL@%
  6678. When the %@AS@% swap %@AE@% function executes, it creates two %@AB@%int%@AE@% pointers named %@AS@% ptr1 %@AE@%
  6679. and %@AS@% ptr2 %@AE@% and assigns the passed addresses to them:  %@NL@%
  6680. %@NL@%
  6681. %@AS@%  void swap( int *ptr1, int *ptr2 )%@AE@%%@NL@%
  6682. %@NL@%
  6683. Since there's a one-to-one correspondence between arguments and parameters,
  6684. the pointer %@AS@% ptr1 %@AE@% receives the address of %@AS@% first %@AE@% and %@AS@% ptr2 %@AE@% receives the
  6685. address of %@AS@% second%@AE@%. The %@AS@% swap %@AE@% function exchanges the values of %@AS@% first %@AE@% and %@AS@%
  6686. %@AS@%second%@AE@%, using the two pointers and a temporary %@AB@%int%@AE@% variable named %@AS@% temp%@AE@%:  %@NL@%
  6687. %@NL@%
  6688. %@AS@%  int temp;
  6689. %@AS@%  temp = *ptr1;
  6690. %@AS@%  *ptr1 = *ptr2;
  6691. %@AS@%  *ptr2 = temp;%@AE@%%@NL@%
  6692. %@NL@%
  6693. Within the %@AS@% swap %@AE@% function, PFUNC.C uses the indirection operator to access
  6694. the values that %@AS@% ptr1 %@AE@% and %@AS@% ptr2 %@AE@% reference. The expression %@AS@% *ptr1 %@AE@% accesses
  6695. the value stored in %@AS@% first%@AE@%. Likewise, the expression %@AS@% *ptr2 %@AE@% accesses the
  6696. value stored in %@AS@% second%@AE@%.  %@NL@%
  6697. %@NL@%
  6698. Through the addresses contained in the pointers, the %@AS@% swap %@AE@% function can
  6699. indirectly access variables that are local to the %@AB@%main%@AE@% function.  %@NL@%
  6700. %@NL@%
  6701. %@NL@%
  6702. %@3@%%@CR:C6A00080015 @%%@AB@%Passing Address Constants Versus Passing Pointer Variables%@AE@%%@EH@%%@NL@%
  6703. %@NL@%
  6704. Now that you know how the %@AS@% swap %@AE@% function works, we can elaborate on the two
  6705. methods that PFUNC.C uses to pass the address of %@AS@% first %@AE@% and %@AS@% second %@AE@% to %@AS@%
  6706. %@AS@%swap%@AE@%.  %@NL@%
  6707. %@NL@%
  6708. %@AU@% When you pass a pointer  to a function, the function actually receives an
  6709. %@AU@%address.%@AE@%  %@NL@%
  6710. %@NL@%
  6711. Earlier, we said the %@AS@% swap %@AE@% function expects to receive two pointers as
  6712. parameters. While it's common to say pointers in this context, it would be
  6713. more accurate to say the function expects addresses, since that's what it
  6714. actually receives.  %@NL@%
  6715. %@NL@%
  6716. To work correctly, %@AS@% swap %@AE@% only needs the addresses of two variables. Once it
  6717. has the addresses, it assigns them to its own local pointers and proceeds to
  6718. do its work─modifying the original variables at long distance, as it were.
  6719. The %@AS@% swap %@AE@% function doesn't care whether you pass the addresses as constants
  6720. or pointer variables, since it receives the same kind of value in either
  6721. case. The address is all the function needs to change the value of a
  6722. variable defined elsewhere.  %@NL@%
  6723. %@NL@%
  6724. The first argument in the function call to %@AS@% swap %@AE@% shows a straightforward
  6725. way to pass an address. Inside the %@AB@%main%@AE@% function of PFUNC.C, the expression %@AS@%
  6726. %@AS@%&first %@AE@% equals the address of %@AS@% first%@AE@%. When you pass this argument to %@AS@% swap%@AE@%,
  6727. the function clearly receives an address.  %@NL@%
  6728. %@NL@%
  6729. The second argument is an address, too. Since %@AB@%main%@AE@% assigns the address of %@AS@%
  6730. %@AS@%second %@AE@% to the pointer variable %@AS@% ptr%@AE@%, the expression %@AS@% ptr %@AE@% equals the
  6731. address of %@AS@%second%@AE@%. When you pass this argument to %@AS@% swap%@AE@%, the function also
  6732. receives an address. (Remember, the value contained in a pointer variable is
  6733. an address.)  %@NL@%
  6734. %@NL@%
  6735. Some beginning programmers get confused by functions that expect to receive
  6736. pointers, thinking they must always pass pointer %@AI@%variables%@AE@% to such
  6737. functions. As PFUNC.C shows, if the function expects an address you can
  6738. simply pass the address as a constant, using the address-of operator.  %@NL@%
  6739. %@NL@%
  6740. ────────────────────────────────────────────────────────────────────────────%@NL@%
  6741. NOTE
  6742.  
  6743. %@AI@%When a function expects to receive an address as a parameter, you can pass
  6744. %@AI@%either an address constant or a pointer variable, whichever is more
  6745. %@AI@%suitable.%@AE@%%@NL@%
  6746. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  6747. %@NL@%
  6748. Why, then, would you ever go to the trouble of passing a pointer variable to
  6749. this kind of function? In a real program, the function that calls %@AS@% swap %@AE@%
  6750. might well use pointers to process %@AS@% first %@AE@% and %@AS@% second %@AE@% for some other
  6751. purpose. In such a case you might prefer to use pointers in the function
  6752. call, too.  %@NL@%
  6753. %@NL@%
  6754. %@NL@%
  6755. %@2@%%@CR:C6A00080016 @%%@AB@%Arrays of Pointers%@AE@%%@EH@%%@NL@%
  6756. %@NL@%
  6757. Pointers, like other variables, can be stored in arrays. This feature allows
  6758. you to create a variety of useful data structures.  %@NL@%
  6759. %@NL@%
  6760. %@AU@% In an array of pointers, each array element is  a pointer variable.%@AE@%  %@NL@%
  6761. %@NL@%
  6762. If you find an array of pointers hard to picture, begin with the idea that
  6763. an array is a group of variables of the same type. An "array of pointers" is
  6764. also a group of variables, but instead of simple variables, it contains a
  6765. group of pointer variables.  %@NL@%
  6766. %@NL@%
  6767. Each element in an array of pointers, then, is a pointer that contains an
  6768. address. Like other array elements, each element can be accessed with a
  6769. numerical subscript.  %@NL@%
  6770. %@NL@%
  6771. Pointer arrays are often used to speed up sorts. The QCSORT.C program shows
  6772. the basic idea behind such a sort:  %@NL@%
  6773. %@NL@%
  6774. %@AS@%  /* QCSORT.C: Demonstrate sorting array of pointers. */
  6775. %@AS@%  
  6776. %@AS@%  #include <stdio.h>
  6777. %@AS@%  #define SIZE 4
  6778. %@AS@%  
  6779. %@AS@%  void sort( int size, double *p[] );
  6780. %@AS@%  void show( int size, double *p[], double dd[] );
  6781. %@AS@%  
  6782. %@AS@%  main()
  6783. %@AS@%  {
  6784. %@AS@%     int x;
  6785. %@AS@%     double d[] = { 3.333, 1.111, 2.222, 4.444 };
  6786. %@AS@%     double *d_ptr[SIZE];
  6787. %@AS@%     for( x = 0; x < SIZE; x++ )
  6788. %@AS@%        d_ptr[x] = &d[x];
  6789. %@AS@%     show( SIZE, d_ptr, d );
  6790. %@AS@%     sort( SIZE, d_ptr );
  6791. %@AS@%     show( SIZE, d_ptr, d );
  6792. %@AS@%  }
  6793. %@AS@%  
  6794. %@AS@%  void sort( int size, double *p[] )
  6795. %@AS@%  {
  6796. %@AS@%     int x, x1;
  6797. %@AS@%     double *temp;
  6798. %@AS@%     for( x = 0; x < size - 1; x++ )
  6799. %@AS@%        for( x1 = x + 1; x1 < size; x1++ )
  6800. %@AS@%        {
  6801. %@AS@%           if( *p[x] > *p[x1] )
  6802. %@AS@%           {
  6803. %@AS@%              temp = p[x1];
  6804. %@AS@%              p[x1] = p[x];
  6805. %@AS@%              p[x] = temp;
  6806. %@AS@%           }
  6807. %@AS@%        }
  6808. %@AS@%  }%@AE@%%@NL@%
  6809. %@NL@%
  6810. %@AS@%  void show( int size, double *p[], double dd[] )
  6811. %@AS@%  {
  6812. %@AS@%     int x;
  6813. %@AS@%     printf( "------------------------" );
  6814. %@AS@%     printf( "------------------------\n" );
  6815. %@AS@%     for( x = 0; x < size; x++ )
  6816. %@AS@%     {
  6817. %@AS@%        printf( "*d_ptr[%d] = %1.3f   ", x, *p[x]);
  6818. %@AS@%        printf( "d_ptr[%d] = %u ", x, p[x]);
  6819. %@AS@%        printf( "  d[%d] = %1.3f\n", x, dd[x] );
  6820. %@AS@%     }
  6821. %@AS@%  }%@AE@%%@NL@%
  6822. %@NL@%
  6823. Here is the output from QCSORT.C:  %@NL@%
  6824. %@NL@%
  6825. %@AS@%  ------------------------------------------------
  6826. %@AS@%  *d_ptr[0] = 3.333   d_ptr[0] = 66   d[0] = 3.333
  6827. %@AS@%  *d_ptr[1] = 1.111   d_ptr[1] = 74   d[1] = 1.111
  6828. %@AS@%  *d_ptr[2] = 2.222   d_ptr[2] = 82   d[2] = 2.222
  6829. %@AS@%  *d_ptr[3] = 4.444   d_ptr[3] = 90   d[3] = 4.444
  6830. %@AS@%  ------------------------------------------------
  6831. %@AS@%  *d_ptr[0] = 1.111   d_ptr[0] = 74   d[0] = 3.333
  6832. %@AS@%  *d_ptr[1] = 2.222   d_ptr[1] = 82   d[1] = 1.111
  6833. %@AS@%  *d_ptr[2] = 3.333   d_ptr[2] = 66   d[2] = 2.222
  6834. %@AS@%  *d_ptr[3] = 4.444   d_ptr[3] = 90   d[3] = 4.444%@AE@%%@NL@%
  6835. %@NL@%
  6836. Since the purpose of QCSORT.C is to demonstrate pointers, not sorting
  6837. methods, it uses a simple bubble sort. This method isn't efficient but has
  6838. the advantage of being short and easy to follow.  %@NL@%
  6839. %@NL@%
  6840. The QCSORT.C program creates a %@AB@%double%@AE@% array named %@AS@% d %@AE@% and an array of
  6841. pointers named %@AS@% d_ptr%@AE@%. Each array has four elements. To illustrate the sort,
  6842. the elements of %@AS@% d %@AE@% are initialized out of order.  %@NL@%
  6843. %@NL@%
  6844. The goal of QCSORT.C is to display a sorted list of the values in %@AS@% d%@AE@%. You
  6845. could do this by sorting the elements of %@AS@% d %@AE@% itself, but that solution is
  6846. not efficient. Every %@AB@%double%@AE@% value contains eight bytes, and sorting a large
  6847. number of %@AB@%double%@AE@% values requires that you move a lot of memory.  %@NL@%
  6848. %@NL@%
  6849. Instead of moving the %@AB@%double%@AE@% values themselves, QCSORT.C creates an array of
  6850. pointers that point to the elements of the %@AS@% d %@AE@% array, then sorts the
  6851. pointers. This saves time because a pointer is stored in only two bytes.
  6852. Figure 8.6 shows the relationship between the %@AS@% d %@AE@% and %@AS@% d_ptr %@AE@% arrays
  6853. immediately after both are initialized.  %@NL@%
  6854. %@NL@%
  6855. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  6856. %@NL@%
  6857. At the stage shown in Figure 8.6, the pointers in the %@AS@% d_ptr %@AE@% array have
  6858. been initialized to point to the %@AB@%double%@AE@% elements in the %@AS@% d %@AE@% array. (The
  6859. array element %@AS@% d_ptr[0] %@AE@% points to %@AS@% d[0]%@AE@%, %@AS@% d_ptr[1] %@AE@% points to %@AS@% d[1]%@AE@%, and so
  6860. on.) The function %@AS@% show %@AE@% displays three sets of data:  %@NL@%
  6861. %@NL@%
  6862. %@NL@%
  6863.   ■   The value each pointer references%@NL@%
  6864. %@NL@%
  6865.   ■   The address assigned to each pointer%@NL@%
  6866. %@NL@%
  6867.   ■   The value of each element in the %@AS@% d %@AE@% array%@NL@%
  6868. %@NL@%
  6869. %@NL@%
  6870. After calling the %@AS@% show %@AE@% function, QCSORT.C calls the %@AS@% sort %@AE@% function, which
  6871. sorts the pointers in %@AS@% d_ptr%@AE@%.  %@NL@%
  6872. %@NL@%
  6873. The declaration of %@AS@% sort %@AE@% contains something new. In the declaration  %@NL@%
  6874. %@NL@%
  6875. %@AS@%  void sort( int size, double *p[] );%@AE@%%@NL@%
  6876. %@NL@%
  6877. the expression %@AS@% *p[] %@AE@% shows that the %@AS@% sort %@AE@% function expects to receive a
  6878. %@AI@%pointer to an array of pointers%@AE@%. When the program calls %@AS@% sort%@AE@%, it passes the
  6879. size of the array to be sorted (first argument) and a pointer to the array
  6880. of pointers (second argument):  %@NL@%
  6881. %@NL@%
  6882. %@AS@%  sort( SIZE, d_ptr );%@AE@%%@NL@%
  6883. %@NL@%
  6884. Now the %@AS@% sort %@AE@% function has all the information it needs to sort the
  6885. pointers in the %@AS@% d_ptr %@AE@% array, making each pointer point to the correct
  6886. element in the %@AS@% d %@AE@% array.  %@NL@%
  6887. %@NL@%
  6888. After the sort is complete, QCSORT.C calls %@AS@% show %@AE@% again to display the
  6889. results of the sort. Now that the pointers have been sorted, they can be
  6890. used to display a sorted list of %@AB@%double%@AE@% values. Figure 8.7 shows the
  6891. relationship between the %@AS@% d %@AE@% and %@AS@% d_ptr %@AE@% arrays after the sort is complete.
  6892. %@NL@%
  6893. %@NL@%
  6894. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  6895. %@NL@%
  6896. Of course, the array in QCSORT.C is so small that the time savings from
  6897. using pointers is negligible. In a real program, however, which might sort
  6898. thousands of values instead of four, the difference between moving eight
  6899. bytes and two bytes can be dramatic. The advantage of sorting pointers is
  6900. even greater when sorting large data objects such as strings or structures.
  6901. %@NL@%
  6902. %@NL@%
  6903. %@AU@%  The elements in a  pointer array can point  to any type of data.%@AE@%  %@NL@%
  6904. %@NL@%
  6905. The QCSORT.C example section uses a fairly simple array of pointers. But you
  6906. can use such arrays to create quite complex data structures. The basic form
  6907. of the array is always the same─it is a group of pointer variables, each
  6908. pointer accessible through a subscript─but the pointers in an array can
  6909. point to any kind of data object. You can have an array of pointers to
  6910. structures, an array of pointers to strings, and so on. The only difference
  6911. is in what the pointers reference.  %@NL@%
  6912. %@NL@%
  6913. Don't confuse an array of pointers with a pointer to an array. A pointer to
  6914. an array (or "array pointer") is a single pointer variable that points to an
  6915. array element. The single pointer can access any element of the array, but
  6916. only one pointer is involved.  %@NL@%
  6917. %@NL@%
  6918. In contrast, an array of pointers is a group of related pointer variables
  6919. stored in an array. Each element in the array is a pointer, and you can
  6920. access individual pointers with the array name and subscript. Each pointer
  6921. in the array points, in turn, to some other object.  %@NL@%
  6922. %@NL@%
  6923. %@NL@%
  6924. %@2@%%@CR:C6A00080017 @%%@AB@%A Pause for Reflection%@AE@%%@EH@%%@NL@%
  6925. %@NL@%
  6926. If this is your first exposure to pointers, you may want to reflect on what
  6927. you have learned before reading the next chapter. This chapter has explained
  6928. the basic uses of pointers, and you can write a great many useful programs
  6929. using only these techniques. If you're not comfortable with all these ideas,
  6930. you may want to experiment with them before reading more about pointers.  %@NL@%
  6931. %@NL@%
  6932. The next chapter, "Advanced Pointers," examines further uses of pointers,
  6933. including multiple indirection and pointers to structures.  %@NL@%
  6934. %@NL@%
  6935. %@NL@%
  6936. %@NL@%
  6937. %@NL@%
  6938. %@NL@%
  6939. %@NL@%
  6940. %@CR:C6A00090001 @%%@1@%%@AB@%Chapter 9  Advanced Pointers%@AE@%%@EH@%%@NL@%
  6941. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  6942. %@NL@%
  6943. The preceding chapter, "Pointers," explained the basics of using pointers─
  6944. how to declare and initialize pointer variables and use them to access basic
  6945. data types. This chapter explores more advanced pointer techniques,
  6946. including multiple indirection, pointers to structures, and pointers to
  6947. functions.  %@NL@%
  6948. %@NL@%
  6949. %@NL@%
  6950. %@2@%%@CR:C6A00090002 @%%@AB@%Pointers to Pointers%@AE@%%@EH@%%@NL@%
  6951. %@NL@%
  6952. In Chapter 8, "Pointers," we stated a pointer can point to any kind of
  6953. variable. Since a pointer is a variable, you can make it the target of
  6954. another pointer, creating a pointer to a pointer. This concept is useful in
  6955. itself and is also important for understanding the equivalence of array
  6956. notation and pointer notation, which is explained in the next section.  %@NL@%
  6957. %@NL@%
  6958. The program PTRPTR.C demonstrates a pointer to a pointer insimple terms:  %@NL@%
  6959. %@NL@%
  6960. %@AS@%  /* PTRPTR.C: Demonstrate a pointer to a pointer. */
  6961. %@AS@%  
  6962. %@AS@%  #include <stdio.h>
  6963. %@AS@%  
  6964. %@AS@%  main()
  6965. %@AS@%  {
  6966. %@AS@%     int val = 501;
  6967. %@AS@%     int *ptr = &val;
  6968. %@AS@%     int **ptr_ptr = &ptr;
  6969. %@AS@%     printf( "val = %d\n", **ptr_ptr );
  6970. %@AS@%  }%@AE@%%@NL@%
  6971. %@NL@%
  6972. Here is the output from PTRPTR.C:  %@NL@%
  6973. %@NL@%
  6974. %@AS@%  val = 501%@AE@%%@NL@%
  6975. %@NL@%
  6976. The first two statements in PTRPTR.C should look familiar by now. They
  6977. create an %@AB@%int%@AE@% variable named %@AS@% val %@AE@% and an %@AB@%int%@AE@% pointer named %@AS@% ptr%@AE@%. The third
  6978. line, however, requires some explanation:  %@NL@%
  6979. %@NL@%
  6980. %@AS@%  int **ptr_ptr = &ptr;%@AE@%%@NL@%
  6981. %@NL@%
  6982. This statement uses double indirection to create a variable named %@AS@% ptr_ptr%@AE@%,
  6983. which is a pointer to a pointer. This pointer is assigned the address of the
  6984. first pointer, %@AS@% ptr%@AE@%. The pointer %@AS@% ptr %@AE@% references %@AS@% val%@AE@%, and the pointer %@AS@%
  6985. %@AS@%ptr_ptr %@AE@% references %@AS@% ptr%@AE@%. Figure 9.1 illustrates the relationship between %@AS@%
  6986. %@AS@%ptr %@AE@% and %@AS@% ptr_ptr%@AE@%.  %@NL@%
  6987. %@NL@%
  6988. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  6989. %@NL@%
  6990. Once we have initialized both pointers, we can use %@AS@% ptr_ptr %@AE@% to access %@AS@% val%@AE@%:
  6991. %@NL@%
  6992. %@NL@%
  6993. %@AS@%  **ptr_ptr%@AE@%%@NL@%
  6994. %@NL@%
  6995. %@AU@% The double indirection operator (%@AE@%%@AB@% %@AE@%%@AB@%** %@AE@%) is used with a pointer to a pointer.
  6996. %@NL@%
  6997. %@NL@%
  6998. The double indirection operator (%@AB@%**%@AE@%) in front of %@AS@% ptr_ptr %@AE@% tells two things
  6999. about %@AS@%ptr_ptr%@AE@%: that %@AS@% ptr_ptr %@AE@% is itself a pointer and it points to a second
  7000. pointer. Both asterisks are needed to access the contents of %@AS@% val%@AE@%. If you
  7001. use only one, as in  %@NL@%
  7002. %@NL@%
  7003. %@AS@%  *ptr_ptr%@AE@%%@NL@%
  7004. %@NL@%
  7005. then %@AS@% ptr_ptr %@AE@% accesses the contents of %@AS@% ptr%@AE@%, which is the address of %@AS@% val%@AE@%.
  7006. This statement, for instance, prints the address stored in %@AS@% ptr%@AE@%:  %@NL@%
  7007. %@NL@%
  7008. %@AS@%  printf( "ptr = %u", *ptr_ptr );%@AE@%%@NL@%
  7009. %@NL@%
  7010. Using pointers to pointers is known as "multiple indirection." One pointer
  7011. points to a second pointer, which in turn accesses a third data object. In
  7012. theory, there's no limit to how far you can take multiple indirection. You
  7013. can create pointers to pointers, pointers to pointers to pointers, and so
  7014. on. However, there's rarely any practical reason to carry indirection beyond
  7015. two levels (a pointer to a pointer).  %@NL@%
  7016. %@NL@%
  7017. %@NL@%
  7018. %@3@%%@CR:C6A00090003 @%%@AB@%Equivalence of Array and Pointer Notation%@AE@%%@EH@%%@NL@%
  7019. %@NL@%
  7020. In previous sections we noted, more or less in passing, two important facts
  7021. about arrays and pointers:  %@NL@%
  7022. %@NL@%
  7023. %@NL@%
  7024.   1.  An array name is actually a pointer.%@NL@%
  7025. %@NL@%
  7026.   2.  Array notation (subscripts) and pointer notation are interchangeable.%@NL@%
  7027. %@NL@%
  7028. %@NL@%
  7029. These ideas are significant enough to warrant an explicit demonstration.
  7030. Let's rewrite the QCSORT.C program using pointer notation:  %@NL@%
  7031. %@NL@%
  7032. %@AS@%  /* QCSORT1.C: Demonstrate sort with pointer notation. */
  7033. %@AS@%  
  7034. %@AS@%  #include <stdio.h>
  7035. %@AS@%  #define SIZE 4
  7036. %@AS@%  
  7037. %@AS@%  void sort( int size, double **p );
  7038. %@AS@%  void show( int size, double **p, double dd[] );
  7039. %@AS@%  
  7040. %@AS@%  main()
  7041. %@AS@%  {
  7042. %@AS@%     int x;
  7043. %@AS@%     double d[] = { 3.333, 1.111, 2.222, 4.444 };
  7044. %@AS@%     double *d_ptr[SIZE];
  7045. %@AS@%     for( x = 0; x < SIZE; x++ )
  7046. %@AS@%        d_ptr[x] = &d[x];
  7047. %@AS@%     show( SIZE, d_ptr, d );
  7048. %@AS@%     sort( SIZE, d_ptr );
  7049. %@AS@%     show( SIZE, d_ptr, d );
  7050. %@AS@%  }%@AE@%%@NL@%
  7051. %@NL@%
  7052. %@AS@%  void sort( int size, double **p )
  7053. %@AS@%  {
  7054. %@AS@%     int x, x1;
  7055. %@AS@%     double *temp;
  7056. %@AS@%     for( x = 0; x < size - 1; x++ )
  7057. %@AS@%        for( x1 = x + 1; x1 < size; x1++ )
  7058. %@AS@%        {
  7059. %@AS@%           if( **(p+x) > **(p+x1) )
  7060. %@AS@%           {
  7061. %@AS@%              temp = *(p+x1);
  7062. %@AS@%              *(p+x1) = *(p+x);
  7063. %@AS@%              *(p+x) = temp;
  7064. %@AS@%           }
  7065. %@AS@%        }
  7066. %@AS@%  }
  7067. %@AS@%  
  7068. %@AS@%  void show( int size, double **p, double dd[] )
  7069. %@AS@%  {
  7070. %@AS@%     int x;
  7071. %@AS@%     printf( "------------------------" );
  7072. %@AS@%     printf( "------------------------\n" );
  7073. %@AS@%     for( x = 0; x < size; x++ )
  7074. %@AS@%     {
  7075. %@AS@%        printf( "*d_ptr[%d] = %1.3f   ", x, **(p+x) );
  7076. %@AS@%        printf( "d_ptr[%d] = %u ", x, *(p+x) );
  7077. %@AS@%        printf( "  d[%d] = %1.3f\n", x, dd[x] );
  7078. %@AS@%     }
  7079. %@AS@%  }%@AE@%%@NL@%
  7080. %@NL@%
  7081. The QCSORT1.C program works like its predecessor, QCSORT.C. (It sorts an
  7082. array of pointers that point to elements in an %@AB@%int%@AE@% array.) The only
  7083. difference is QCSORT1.C uses pointer notation instead of array notation.  %@NL@%
  7084. %@NL@%
  7085. Let's look at how the change affects the %@AS@% sort %@AE@% function, beginning with its
  7086. prototype. In the previous program, QCSORT.C, the prototype  %@NL@%
  7087. %@NL@%
  7088. %@AS@%  void sort( int size, double *p[] );%@AE@%%@NL@%
  7089. %@NL@%
  7090. uses array notation to show we'll pass the name of an array of pointers to %@AS@%
  7091. %@AS@%sort%@AE@%. Since an array name is a pointer, we can rewrite the prototype using
  7092. pointer notation, as in QCSORT1.C:  %@NL@%
  7093. %@NL@%
  7094. %@AS@%  void sort( int size, double **p );%@AE@%%@NL@%
  7095. %@NL@%
  7096. The %@AS@% sort %@AE@% function definition is rewritten in the same way. Here is the
  7097. definition of %@AS@% sort %@AE@% in the original program (QCSORT.C):  %@NL@%
  7098. %@NL@%
  7099. %@AS@%  void sort( int size, double *p[] )
  7100. %@AS@%  {
  7101. %@AS@%     int x, x1;
  7102. %@AS@%     double *temp;
  7103. %@AS@%     for( x = 0; x < size - 1; x++ )
  7104. %@AS@%        for( x1 = x + 1; x1 < size; x1++ )
  7105. %@AS@%        {
  7106. %@AS@%           if( *p[x] > *p[x1] )
  7107. %@AS@%           {
  7108. %@AS@%           temp = p[x1];
  7109. %@AS@%           p[x1] = p[x];
  7110. %@AS@%           p[x] = temp;
  7111. %@AS@%           }
  7112. %@AS@%        }
  7113. %@AS@%  }%@AE@%%@NL@%
  7114. %@NL@%
  7115. The same function using pointers looks like this in QCSORT1.C:  %@NL@%
  7116. %@NL@%
  7117. %@AS@%  void sort( int size, double **p )
  7118. %@AS@%  {
  7119. %@AS@%     int x, x1;
  7120. %@AS@%     double *temp;
  7121. %@AS@%     for( x = 0; x < size - 1; x++ )
  7122. %@AS@%        for( x1 = x + 1; x1 < size; x1++ )
  7123. %@AS@%        {
  7124. %@AS@%           if( **(p+x) > **(p+x1) )
  7125. %@AS@%           {
  7126. %@AS@%              temp = *(p+x1);
  7127. %@AS@%              *(p+x1) = *(p+x);
  7128. %@AS@%              *(p+x) = temp;
  7129. %@AS@%           }
  7130. %@AS@%        }
  7131. %@AS@%  }%@AE@%%@NL@%
  7132. %@NL@%
  7133. Within the %@AS@% sort %@AE@% function, the variable %@AS@% p %@AE@% is a pointer to a pointer. When
  7134. we use a single asterisk, as in,  %@NL@%
  7135. %@NL@%
  7136. %@AS@%  *(p+x1)%@AE@%%@NL@%
  7137. %@NL@%
  7138. we access the contents of the %@AS@% x1 %@AE@% pointer, which is an address. When we
  7139. place a double asterisk in front of an address value, as in,  %@NL@%
  7140. %@NL@%
  7141. %@AS@%  **(p+x)%@AE@%%@NL@%
  7142. %@NL@%
  7143. we access the contents of this address.  %@NL@%
  7144. %@NL@%
  7145. Using pointer notation in place of array notation, QCSORT1.C achieves the
  7146. same result as QCSORT.C. In many cases─including this one─it doesn't really
  7147. matter which notation you use. If you're still more comfortable with array
  7148. notation, you may prefer to use it sometimes. Since many C programs use
  7149. pointers to manipulate arrays, however, it's worth taking the time to learn
  7150. pointer notation, too.  %@NL@%
  7151. %@NL@%
  7152. %@NL@%
  7153. %@3@%%@CR:C6A00090004 @%%@AB@%Getting Command-Line Arguments%@AE@%%@EH@%%@NL@%
  7154. %@NL@%
  7155. %@AU@%  Command-line arguments are passed to programs through argv, an array of
  7156. %@AU@%pointers.%@AE@%  %@NL@%
  7157. %@NL@%
  7158. Arrays of pointers have one very common use─accessing command-line
  7159. arguments. When a C program begins execution, DOS passes two arguments to
  7160. it. The first argument, normally called %@AS@% argc%@AE@%, is an %@AB@%int%@AE@% variable that
  7161. indicates the number of command-line arguments. The second, normally called %@AS@%
  7162. %@AS@%argv%@AE@%, is a pointer to an array of strings. Each string in the array contains
  7163. one of the command-line arguments.  %@NL@%
  7164. %@NL@%
  7165. Even if you don't plan to use %@AS@% argc %@AE@% and %@AS@% argv %@AE@% in your programs, you can
  7166. expect to see them often in other C programs, so it's useful to know how
  7167. they're used. The ARGV.C program uses %@AS@% argc %@AE@% and %@AS@% argv%@AE@%.  %@NL@%
  7168. %@NL@%
  7169. %@AS@%  /* ARGV.C: Demonstrate accessing command-line arguments. */
  7170. %@AS@%  
  7171. %@AS@%  #include <stdio.h>
  7172. %@AS@%  
  7173. %@AS@%  void show_args( char *argument );
  7174. %@AS@%  
  7175. %@AS@%  int main( int argc, char *argv[] )
  7176. %@AS@%  {
  7177. %@AS@%     int count;
  7178. %@AS@%     for( count=0; count < argc; count++ )
  7179. %@AS@%        show_args( argv[count] );
  7180. %@AS@%     return 0;
  7181. %@AS@%  }
  7182. %@AS@%  
  7183. %@AS@%  void show_args( char *argument )
  7184. %@AS@%  {
  7185. %@AS@%     printf( "%s\n", argument );
  7186. %@AS@%  }%@AE@%%@NL@%
  7187. %@NL@%
  7188. To make ARGV.C produce output, you must give it some command-line arguments.
  7189. (If you run ARGV.C in the QuickC environment, select Run/Debug from the
  7190. Options menu and type the command-line arguments at the Command Line
  7191. prompt.) The program prints each argument on the screen.  %@NL@%
  7192. %@NL@%
  7193. If you use this command line, for instance,  %@NL@%
  7194. %@NL@%
  7195. %@AS@%  argv harpo chico groucho zeppo%@AE@%%@NL@%
  7196. %@NL@%
  7197. then ARGV.C gives this output:  %@NL@%
  7198. %@NL@%
  7199. %@AS@%  C:\SOURCES\ARGV.EXE
  7200. %@AS@%  harpo
  7201. %@AS@%  chico
  7202. %@AS@%  groucho
  7203. %@AS@%  zeppo%@AE@%%@NL@%
  7204. %@NL@%
  7205. The first argument may have surprised you. In DOS versions 3.0 and higher,
  7206. the first string in the %@AS@% argv %@AE@% array ( %@AS@%argv[0]%@AE@% ) contains the drive
  7207. specification and full pathname to the program that is executing. The drive
  7208. and path you see will depend on how your system is configured. In the
  7209. example the ARGV.EXE program is located in the SOURCES directory of drive C.
  7210. %@NL@%
  7211. %@NL@%
  7212. Thus, the value of %@AS@% argc %@AE@% actually is one greater than the number of
  7213. command-line arguments, and the first argument typed on the command line is
  7214. the second string in the array (%@AS@% argv[1] %@AE@%). If you type the arguments shown
  7215. above, the value of %@AS@% argc %@AE@% is 5 and %@AS@% argv[1] %@AE@% contains the argument %@AS@% harpo%@AE@%.
  7216. %@NL@%
  7217. %@NL@%
  7218. %@NL@%
  7219. %@3@%%@CR:C6A00090005 @%%@AB@%Null Pointers%@AE@%%@EH@%%@NL@%
  7220. %@NL@%
  7221. We can use the ARGV.C program to illustrate another handy property of
  7222. pointers: null pointers. Consider this modification (ARGV1.C):  %@NL@%
  7223. %@NL@%
  7224. %@AS@%  /* ARGV1.C: Demonstrate null pointers. */
  7225. %@AS@%  
  7226. %@AS@%  #include <stdio.h>
  7227. %@AS@%  
  7228. %@AS@%  void show_args( char *argument );
  7229. %@AS@%  
  7230. %@AS@%  int main( int argc, char **argv )
  7231. %@AS@%  {
  7232. %@AS@%     while( *argv )
  7233. %@AS@%        show_args( *(argv++) );
  7234. %@AS@%     return 0;
  7235. %@AS@%  }
  7236. %@AS@%  
  7237. %@AS@%  void show_args( char *argument )
  7238. %@AS@%  {
  7239. %@AS@%     printf( "%s\n", argument );
  7240. %@AS@%  }%@AE@%%@NL@%
  7241. %@NL@%
  7242. The ARGV1.C program gives the same output as the previous program but it
  7243. uses a %@AB@%while%@AE@% loop instead of a %@AB@%for%@AE@% loop. The test expression in this loop,  %@NL@%
  7244. %@NL@%
  7245. %@AS@%  while( *argv )%@AE@%%@NL@%
  7246. %@NL@%
  7247. is equivalent to this test expression:  %@NL@%
  7248. %@NL@%
  7249. %@AS@%  while( *argv != 0 )%@AE@%%@NL@%
  7250. %@NL@%
  7251. The loop in ARGV1.C continues until it finds a "null pointer," a pointer
  7252. that contains 0. In this case, the null pointer means we have reached the
  7253. end of the array: no more strings are available.  %@NL@%
  7254. %@NL@%
  7255. %@AU@% Null pointers can be used to show success or failure and as markers in a
  7256. %@AU@%series.%@AE@%  %@NL@%
  7257. %@NL@%
  7258. Many C library functions use null pointers to signal the success or failure
  7259. of an operation that returns a pointer. For instance, the library function
  7260. %@AB@%malloc%@AE@% normally returns a pointer to the beginning address of the memory
  7261. area it allocates. If no memory is available, %@AB@%malloc%@AE@% returns a null pointer
  7262. to show the operation failed. Similarly, the %@AB@%fopen%@AE@% function usually returns
  7263. a pointer to a %@AB@%FILE%@AE@% structure, but returns a null pointer when it fails.  %@NL@%
  7264. %@NL@%
  7265. Null pointers can also be used to mark the end of a list of pointers, such
  7266. as the %@AS@% argv %@AE@% array or a linked list.  %@NL@%
  7267. %@NL@%
  7268. %@NL@%
  7269. %@2@%%@CR:C6A00090006 @%%@AB@%Pointers to Structures%@AE@%%@EH@%%@NL@%
  7270. %@NL@%
  7271. %@AU@% A structure pointer can access any member of a structure.%@AE@%  %@NL@%
  7272. %@NL@%
  7273. A pointer to a structure, or "structure pointer," is conceptually similar to
  7274. an array pointer. Just as an array pointer can point to any element in an
  7275. array, a structure pointer can reference any member in a structure. The
  7276. major difference is one of notation.  %@NL@%
  7277. %@NL@%
  7278. In case you're not yet an expert on structure notation, let's review it very
  7279. briefly. First recall that each element in an array has the same type, so
  7280. you refer to individual array elements with subscripts:  %@NL@%
  7281. %@NL@%
  7282. %@AS@%  i_array[3]%@AE@%%@NL@%
  7283. %@NL@%
  7284. Because members of a structure can have different types, you can't use
  7285. numerical subscripts to refer to them based on their order. Instead, each
  7286. structure member has a symbolic name. You refer to a member with a structure
  7287. name and member name, separating the two names with the member-of operator
  7288. (%@AB@%.%@AE@%):  %@NL@%
  7289. %@NL@%
  7290. %@AS@%  jones.name%@AE@%%@NL@%
  7291. %@NL@%
  7292. The notation for structure pointers follows the same pattern, with only two
  7293. differences. You must  %@NL@%
  7294. %@NL@%
  7295. %@NL@%
  7296.   1.  Replace the structure name with the name of the pointer%@NL@%
  7297. %@NL@%
  7298.   2.  Replace the member-of operator with a two-character operator called
  7299.       the "pointer-member" operator (%@AB@%->%@AE@%)%@NL@%
  7300. %@NL@%
  7301. %@NL@%
  7302. The pointer-member operator is formed by a dash and a right-angle bracket.
  7303. The following name uses the pointer-member operator:  %@NL@%
  7304. %@NL@%
  7305. %@AS@%  jones_ptr->name%@AE@%%@NL@%
  7306. %@NL@%
  7307. Here %@AS@% jones_ptr %@AE@% is the name of a pointer to a structure, and %@AS@% name %@AE@% is a
  7308. member of the structure that %@AS@% jones_ptr %@AE@% points to.  %@NL@%
  7309. %@NL@%
  7310. The EMPLOY1.C program is a revision of the EMPLOYEE.C program that
  7311. demonstrates structures in Chapter 4, "Data Types." This program illustrates
  7312. how to manipulate a structure through a pointer:  %@NL@%
  7313. %@NL@%
  7314. %@AS@%  /* EMPLOY1.C: Demonstrate structure pointers. */
  7315. %@AS@%  
  7316. %@AS@%  #include <stdio.h>
  7317. %@AS@%  
  7318. %@AS@%  struct employee
  7319. %@AS@%  {
  7320. %@AS@%     char name[10];
  7321. %@AS@%     int months;
  7322. %@AS@%     float wage;
  7323. %@AS@%  };
  7324. %@AS@%  
  7325. %@AS@%  void display( struct employee *e_ptr  );
  7326. %@AS@%  
  7327. %@AS@%  main()
  7328. %@AS@%  {
  7329. %@AS@%     struct employee jones =
  7330. %@AS@%     {
  7331. %@AS@%        "Jones, J",
  7332. %@AS@%        77,
  7333. %@AS@%        13.68
  7334. %@AS@%     };
  7335. %@AS@%  
  7336. %@AS@%     display( &jones );
  7337. %@AS@%  }
  7338. %@AS@%  
  7339. %@AS@%  void display( struct employee *e_ptr )
  7340. %@AS@%  {
  7341. %@AS@%     printf( "Name: %s\n", e_ptr->name );
  7342. %@AS@%     printf( "Months of service: %d\n", e_ptr->months );
  7343. %@AS@%     printf( "Hourly wage: %6.2f\n", e_ptr->wage );
  7344. %@AS@%  }%@AE@%%@NL@%
  7345. %@NL@%
  7346. %@AU@% Structure pointers allow  functions to access  structures that are local
  7347. %@AU@%to other functions.%@AE@%  %@NL@%
  7348. %@NL@%
  7349. The EMPLOY1.C program gives the same output as the earlier version. But
  7350. instead of passing the entire structure to the %@AS@% display %@AE@% function, this
  7351. program passes a structure pointer. This method conserves memory, since the %@AS@%
  7352. %@AS@%display %@AE@% function doesn't create a local copy of the structure. It also
  7353. allows %@AS@% display %@AE@% to change members in the original structure, which is local
  7354. to the %@AB@%main%@AE@% function.  %@NL@%
  7355. %@NL@%
  7356. The header of the %@AS@% display %@AE@% function shows that the function expects to
  7357. receive a structure pointer:  %@NL@%
  7358. %@NL@%
  7359. %@AS@%  void display( struct employee *e_ptr  )%@AE@%%@NL@%
  7360. %@NL@%
  7361. The expression in parentheses specifies what type of value the function
  7362. expects. This expression is a bit complex, so let's look at each part
  7363. individually. The expression %@AS@% *e_ptr %@AE@% indicates the function expects to
  7364. receive a pointer, which it names %@AS@% e_ptr%@AE@%. It is preceded by  %@NL@%
  7365. %@NL@%
  7366. %@AS@%  struct employee%@AE@%%@NL@%
  7367. %@NL@%
  7368. which states what type of pointer %@AS@% e_ptr %@AE@% is. The %@AB@%struct%@AE@% keyword indicates %@AS@%
  7369. %@AS@%e_ptr %@AE@% is a pointer to a structure, and the tag %@AS@% employee %@AE@% specifies the
  7370. structure type.  %@NL@%
  7371. %@NL@%
  7372. The next item of interest in EMPLOY1.C is the function call that passes the
  7373. structure pointer:  %@NL@%
  7374. %@NL@%
  7375. %@AS@%  display( &jones );%@AE@%%@NL@%
  7376. %@NL@%
  7377. This statement uses the address-of operator to pass the address of the %@AS@%
  7378. %@AS@%jones %@AE@% structure to the %@AS@% display %@AE@% function. The address-of operator is not
  7379. optional. Since we want the function to access the original structure─not a
  7380. local copy─we must pass the structure's address.  %@NL@%
  7381. %@NL@%
  7382. When the %@AS@% display %@AE@% function executes, it creates a pointer variable named %@AS@%
  7383. %@AS@%e_ptr %@AE@% and assigns to it the address passed in the function call. Now the %@AS@%
  7384. %@AS@%display %@AE@% function can refer to any member of the structure indirectly
  7385. through the pointer %@AS@% e_ptr%@AE@%. Within the %@AS@% display %@AE@% function, the statement  %@NL@%
  7386. %@NL@%
  7387. %@AS@%  printf( "%s\n", e_ptr->name );%@AE@%%@NL@%
  7388. %@NL@%
  7389. has the same effect that the statement  %@NL@%
  7390. %@NL@%
  7391. %@AS@%  printf( "%s\n", jones.name );%@AE@%%@NL@%
  7392. %@NL@%
  7393. has in the %@AB@%main%@AE@% function. Figure 9.2 illustrates the relationship between
  7394. the structure pointer and structure members in EMPLOY1.C.  %@NL@%
  7395. %@NL@%
  7396. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  7397. %@NL@%
  7398. Just to confirm that the %@AS@% display %@AE@% function can access the original
  7399. structure in EMPLOY1.C, try adding this statement to the end of the %@AS@% display
  7400. %@AS@%%@AE@% function:  %@NL@%
  7401. %@NL@%
  7402. %@AS@%  strcpy( e_ptr->name, "King, M" );%@AE@%%@NL@%
  7403. %@NL@%
  7404. and this statement to the end of the %@AB@%main%@AE@% function:  %@NL@%
  7405. %@NL@%
  7406. %@AS@%  printf( "%s\n", jones.name );%@AE@%%@NL@%
  7407. %@NL@%
  7408. These changes cause EMPLOY1.C to print:  %@NL@%
  7409. %@NL@%
  7410. %@AS@%  King, M%@AE@%%@NL@%
  7411. %@NL@%
  7412. Acting indirectly through a structure pointer, the %@AS@% display %@AE@% function was
  7413. able to change a structure defined elsewhere in the program.  %@NL@%
  7414. %@NL@%
  7415. %@NL@%
  7416. %@2@%%@CR:C6A00090007 @%%@AB@%Pointers to Functions%@AE@%%@EH@%%@NL@%
  7417. %@NL@%
  7418. At the beginning of the previous chapter we stated that a pointer can point
  7419. to any object present in memory at run time. Since functions themselves are
  7420. located in memory, you can assign the address of a function to a pointer,
  7421. creating a "function pointer."  %@NL@%
  7422. %@NL@%
  7423. %@AU@% A function pointer makes it possible to pass a function as a function
  7424. %@AU@%argument.%@AE@%  %@NL@%
  7425. %@NL@%
  7426. Function pointers provide a way─in fact, the only practical way─to pass a
  7427. function as an argument to another function. This permits the second
  7428. function to call the first function indirectly through the pointer.  %@NL@%
  7429. %@NL@%
  7430. While function pointers may sound rather obscure, they have some common
  7431. practical uses:  %@NL@%
  7432. %@NL@%
  7433. %@NL@%
  7434.   ■   Some QuickC run-time library functions, such as %@AB@%qsort%@AE@%, expect to
  7435.       receive a pointer to a user-defined function in your program. (Online
  7436.       help includes an example program that uses %@AB@%qsort%@AE@%.)%@NL@%
  7437. %@NL@%
  7438.   ■   Function pointers are used extensively in Windows and OS/2
  7439.       Presentation Manager programs. %@NL@%
  7440. %@NL@%
  7441.   ■   Using an array of function pointers, you can create a "dispatch
  7442.       table." A dispatch table is a list of related functions that can be
  7443.       called based on some choice made at run time. It is similar to an %@AB@%ON
  7444. %@AB@%      GOSUB%@AE@% statement in BASIC or a call table in assembly language.%@NL@%
  7445. %@NL@%
  7446. %@NL@%
  7447. The syntax for function pointers is a bit complex, so let's start with a
  7448. simple example. The FUNCPTR.C program creates a pointer to our old friend,
  7449. %@AB@%printf%@AE@%, and calls %@AB@%printf%@AE@% through the pointer:  %@NL@%
  7450. %@NL@%
  7451. %@AS@%  /* FUNCPTR.C: Demonstrate function pointers. */
  7452. %@AS@%  
  7453. %@AS@%  #include <stdio.h>
  7454. %@AS@%  
  7455. %@AS@%  main()
  7456. %@AS@%  {
  7457. %@AS@%     int (*func_ptr) ();
  7458. %@AS@%     func_ptr = printf;
  7459. %@AS@%     (*func_ptr) ( "Curiouser and curiouser...\n" );
  7460. %@AS@%  }%@AE@%%@NL@%
  7461. %@NL@%
  7462. Here is the output from FUNCPTR.C:  %@NL@%
  7463. %@NL@%
  7464. %@AS@%  Curiouser and curiouser...%@AE@%%@NL@%
  7465. %@NL@%
  7466. This line from FUNCPTR.C declares %@AS@% func_ptr %@AE@% as a pointer to a function:  %@NL@%
  7467. %@NL@%
  7468. %@AS@%  int (*func_ptr) ();%@AE@%%@NL@%
  7469. %@NL@%
  7470. The declaration of a function pointer must use the same type specifier as
  7471. the function it references. If the function returns a %@AB@%float%@AE@% value, the
  7472. pointer uses type %@AB@%float%@AE@%, and so on. Since the %@AB@%printf%@AE@% function returns an %@AB@%int%@AE@%
  7473. value showing how many characters it displays, the declaration of %@AS@% func_ptr %@AE@%
  7474. uses the type %@AB@%int%@AE@%.  %@NL@%
  7475. %@NL@%
  7476. %@AU@% A function-pointer declaration must have two pairs of parentheses.%@AE@%  %@NL@%
  7477. %@NL@%
  7478. Function-pointer declarations may look complex, but all the parentheses are
  7479. essential. The empty parentheses at the end of the declaration are needed to
  7480. show the pointer points to a function.  %@NL@%
  7481. %@NL@%
  7482. The parentheses enclosing the function name itself are mandatory, too.
  7483. Notice what happens if you omit them:  %@NL@%
  7484. %@NL@%
  7485. %@AS@%  void *func_ptr(); /* Error! Not a function pointer. */%@AE@%%@NL@%
  7486. %@NL@%
  7487. Instead of declaring a pointer to a function, this statement declares a
  7488. function that returns a pointer─not at all what we want in FUNCPTR.C.  %@NL@%
  7489. %@NL@%
  7490. The next program line initializes the function pointer, assigning it the
  7491. address of the %@AB@%printf%@AE@% function:  %@NL@%
  7492. %@NL@%
  7493. %@AS@%  func_ptr = printf;%@AE@%%@NL@%
  7494. %@NL@%
  7495. This line has two important features. First, notice the name %@AB@%printf%@AE@% isn't
  7496. followed by parentheses, as it would be when you call %@AB@%printf%@AE@% directly. We
  7497. want to obtain the address of %@AB@%printf%@AE@%, not call it.  %@NL@%
  7498. %@NL@%
  7499. Second, note that it's not necessary to place the address-of operator before
  7500. the name %@AB@%printf%@AE@%. Because %@AS@% func_ptr %@AE@% was declared as a function pointer, the
  7501. compiler knows it should use the address of %@AB@%printf%@AE@% here. If you like,
  7502. however, you can add the address-of operator to make the statement a little
  7503. more readable:  %@NL@%
  7504. %@NL@%
  7505. %@AS@%  func_ptr = &printf;%@AE@%%@NL@%
  7506. %@NL@%
  7507. The next line calls the %@AB@%printf%@AE@% function indirectly through the pointer %@AS@%
  7508. %@AS@%func_ptr%@AE@%:  %@NL@%
  7509. %@NL@%
  7510. %@AS@%  (*func_ptr) ( "Curiouser and curiouser...\n" );%@AE@%%@NL@%
  7511. %@NL@%
  7512. Note the similarity between this statement and a normal call to %@AB@%printf%@AE@%. It's
  7513. equivalent to this line:  %@NL@%
  7514. %@NL@%
  7515. %@AS@%  printf( "Curiouser and curiouser...\n" );%@AE@%%@NL@%
  7516. %@NL@%
  7517. To call %@AB@%printf%@AE@% indirectly through %@AS@% func_ptr%@AE@%, you supply the same arguments
  7518. as when you call %@AB@%printf%@AE@% directly.  %@NL@%
  7519. %@NL@%
  7520. %@NL@%
  7521. %@3@%%@CR:C6A00090008 @%%@AB@%Passing Function Pointers as Arguments%@AE@%%@EH@%%@NL@%
  7522. %@NL@%
  7523. %@AU@% Function pointers are usually passed as function arguments.%@AE@%  %@NL@%
  7524. %@NL@%
  7525. Like other pointers, function pointers can be passed as arguments to
  7526. functions. Normally, in fact, this is the only reason to use a function
  7527. pointer.  %@NL@%
  7528. %@NL@%
  7529. The FUNCPTR.C program in the previous section is easy to follow but not very
  7530. practical. In a real program, you wouldn't go to the trouble of creating a
  7531. function pointer just to call %@AB@%printf%@AE@% from the %@AB@%main%@AE@% function.  %@NL@%
  7532. %@NL@%
  7533. The FUNCPTR1.C program demonstrates how to pass a function pointer as an
  7534. argument. It has a function named %@AS@% gimme_func %@AE@% that expects to be passed a
  7535. function pointer:  %@NL@%
  7536. %@NL@%
  7537. %@AS@%  /* FUNCPTR1.C: Passing function pointers as arguments. */%@AE@%%@NL@%
  7538. %@NL@%
  7539. %@AS@%  #include <stdio.h>
  7540. %@AS@%  
  7541. %@AS@%  void gimme_func( void (*func_ptr) () );
  7542. %@AS@%  
  7543. %@AS@%  main()
  7544. %@AS@%  {
  7545. %@AS@%     gimme_func( puts );
  7546. %@AS@%     gimme_func( printf );
  7547. %@AS@%  }
  7548. %@AS@%  
  7549. %@AS@%  void gimme_func( void (*func_ptr) () )
  7550. %@AS@%  {
  7551. %@AS@%     (*func_ptr) ( "Ausgezeichnet!" );
  7552. %@AS@%  }%@AE@%%@NL@%
  7553. %@NL@%
  7554. Here is the output from FUNCPTR1.C:  %@NL@%
  7555. %@NL@%
  7556. %@AS@%  Ausgezeichnet!
  7557. %@AS@%  Ausgezeichnet!%@AE@%%@NL@%
  7558. %@NL@%
  7559. In the interests of brevity, the function %@AS@% gimme_func %@AE@% does a very simple
  7560. job. It expects to receive a pointer to a function that can display a string
  7561. and uses that pointer to print the string. The first call to %@AS@% gimme_func %@AE@%
  7562. passes a pointer to the library function %@AB@%puts%@AE@%, and the second passes a
  7563. pointer to %@AB@%printf%@AE@%.  %@NL@%
  7564. %@NL@%
  7565. Since the declaration of %@AS@% gimme_func %@AE@% states it takes a pointer to a
  7566. function, the address-of operator is optional in a call to %@AS@% gimme_func%@AE@%. The
  7567. following statements are equivalent:  %@NL@%
  7568. %@NL@%
  7569. %@AS@%  gimme_func( puts );
  7570. %@AS@%  gimme_func( &puts );%@AE@%%@NL@%
  7571. %@NL@%
  7572. %@NL@%
  7573. %@2@%%@CR:C6A00090009 @%%@AB@%A Parting Word on Pointers%@AE@%%@EH@%%@NL@%
  7574. %@NL@%
  7575. If you have read the previous two chapters from beginning to end, you may be
  7576. suffering from a mild─or perhaps not so mild─case of information overload.
  7577. Pointers have so many different uses that it's difficult to learn everything
  7578. about them at once.  %@NL@%
  7579. %@NL@%
  7580. Don't be discouraged if some uses of pointers still aren't clear to you. The
  7581. latter parts of this chapter cover some rather esoteric techniques, which
  7582. you probably won't use often. When needed, however, these techniques offer
  7583. some very powerful capabilities.  %@NL@%
  7584. %@NL@%
  7585. Like other programming concepts, pointers are best learned through practice,
  7586. so use them at every sensible opportunity. Remember, you don't need to know
  7587. everything about pointers in order to do %@AI@%something%@AE@% with them. The more you
  7588. use pointers in everyday programming, the sooner all the pieces of the
  7589. puzzle will fall into place.  %@NL@%
  7590. %@NL@%
  7591. %@NL@%
  7592. %@NL@%
  7593. %@NL@%
  7594. %@NL@%
  7595. %@NL@%
  7596. %@CR:C6A00100001 @%%@1@%%@AB@%Chapter 10  Programming Pitfalls%@AE@%%@EH@%%@NL@%
  7597. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  7598. %@NL@%
  7599. In C, as in every language, it's rare for any program to work perfectly the
  7600. first time. An important part of knowing a language is recognizing what %@AI@%not%@AE@%
  7601. to do and why certain problems occur.  %@NL@%
  7602. %@NL@%
  7603. This chapter describes common C programming pitfalls and how to avoid them.
  7604. It is organized under broad topics, such as "Pointer Problems," with a
  7605. category for miscellaneous problems at the end. The description of each
  7606. error gives a code example, explains why the error occurs, and offers a
  7607. solution.  %@NL@%
  7608. %@NL@%
  7609. %@NL@%
  7610. %@2@%%@CR:C6A00100002 @%%@AB@%Operator Problems%@AE@%%@EH@%%@NL@%
  7611. %@NL@%
  7612. The most common operator problems involve operators unique to C. Others
  7613. involve questions of precedence, which can cause problems in any language.  %@NL@%
  7614. %@NL@%
  7615. %@NL@%
  7616. %@3@%%@CR:C6A00100003 @%%@AB@%Confusing Assignment and Equality Operators%@AE@%%@EH@%%@NL@%
  7617. %@NL@%
  7618. A common error is to confuse the assignment operator (%@AB@%=%@AE@%) with the equality
  7619. operator (%@AB@%==%@AE@%). The mistake often occurs in decision-making statements:  %@NL@%
  7620. %@NL@%
  7621. %@AS@%  int val = 555;
  7622. %@AS@%  if( val = 20 ) /* Error! */
  7623. %@AS@%     printf( "val equals 20\n" );%@AE@%%@NL@%
  7624. %@NL@%
  7625. The above code prints %@AS@% val equals 20 %@AE@% even though it's clear %@AS@% val %@AE@% doesn't
  7626. equal 20 when the %@AB@%if%@AE@% statement begins. Instead of testing whether %@AS@% x %@AE@% equals
  7627. 20, the expression %@AS@% val = 20 %@AE@% %@AI@%assigns%@AE@% the value 20 to %@AS@% val%@AE@%.  %@NL@%
  7628. %@NL@%
  7629. Remember, the single equal sign (=) performs an assignment in C. This
  7630. particular assignment results in a nonzero value, so the %@AB@%if%@AE@% test is
  7631. evaluated as true, causing the %@AB@%printf%@AE@% statement to execute.  %@NL@%
  7632. %@NL@%
  7633. To correct the problem, use the double equal sign (%@AB@%==%@AE@%) to test equality:  %@NL@%
  7634. %@NL@%
  7635. %@AS@%  if( x == 20 )
  7636. %@AS@%     printf( "x equals 20\n" );%@AE@%%@NL@%
  7637. %@NL@%
  7638. Once you're in the habit of using the equality operator, you might make the
  7639. opposite mistake of using two equal signs where you should use only one:  %@NL@%
  7640. %@NL@%
  7641. %@AS@%  main()
  7642. %@AS@%  {
  7643. %@AS@%     int val;
  7644. %@AS@%     for( val == 0; val < 5; val++ )  /* Error! */
  7645. %@AS@%        printf( "val = %d\n", val );
  7646. %@AS@%  }%@AE@%%@NL@%
  7647. %@NL@%
  7648. Here the error appears in the initializing expression of the %@AB@%for%@AE@% statement.
  7649. It's the reverse of what happened in the first example. Instead of assigning
  7650. the value 0 to %@AS@% val%@AE@%, the expression %@AS@% val == 0 %@AE@% evaluates whether or not %@AS@% val
  7651. %@AS@%%@AE@% equals 0. The expression doesn't change the value of %@AS@% val %@AE@% at all. Since %@AS@%
  7652. %@AS@%val %@AE@% is an uninitialized variable, the %@AB@%for%@AE@% loop is unpredictable.  %@NL@%
  7653. %@NL@%
  7654. %@NL@%
  7655. %@3@%%@CR:C6A00100004 @%%@AB@%Confusing Operator Precedence%@AE@%%@EH@%%@NL@%
  7656. %@NL@%
  7657. Peculiar things can happen if you ignore operator precedence:  %@NL@%
  7658. %@NL@%
  7659. %@AS@%  main()
  7660. %@AS@%  {
  7661. %@AS@%     int ch;
  7662. %@AS@%     while( ch = getch() != '\r' )
  7663. %@AS@%        printf( "%d\n", ch );
  7664. %@AS@%  }%@AE@%%@NL@%
  7665. %@NL@%
  7666. Instead of assigning the result of the %@AB@%getch%@AE@% library-function call to %@AS@% ch%@AE@%,
  7667. the above code assigns the value 0 to %@AS@% ch %@AE@% when you press the ENTER key and
  7668. the value 1 when you press any other key. (The values 1 and 0 represent true
  7669. and false.)  %@NL@%
  7670. %@NL@%
  7671. The error occurs because the inequality operator (%@AB@%!=%@AE@%) has higher precedence
  7672. than the assignment operator (%@AB@%=%@AE@%). The expression  %@NL@%
  7673. %@NL@%
  7674. %@AS@%  ch = getch() != '\r'%@AE@%%@NL@%
  7675. %@NL@%
  7676. is the same as  %@NL@%
  7677. %@NL@%
  7678. %@AS@%  ch = (getch() != '\r')%@AE@%%@NL@%
  7679. %@NL@%
  7680. Both expressions compare the result of the %@AB@%getch%@AE@% call to the character
  7681. constant %@AB@%\r%@AE@%. The result of that comparison is then assigned to %@AS@% ch%@AE@%.  %@NL@%
  7682. %@NL@%
  7683. For the program to work correctly, these operations must happen in the
  7684. reverse order. The result of the function call must be assigned to the
  7685. variable %@AI@%before%@AE@% the variable is compared to the constant. We can solve the
  7686. problem by adding parentheses:  %@NL@%
  7687. %@NL@%
  7688. %@AS@%  main()
  7689. %@AS@%  {
  7690. %@AS@%     int ch;
  7691. %@AS@%     while( (ch = getch()) != '\r')
  7692. %@AS@%      printf( "%d\n", ch );
  7693. %@AS@%  }%@AE@%%@NL@%
  7694. %@NL@%
  7695. Parentheses have the highest precedence of any operator, so the expression  %@NL@%
  7696. %@NL@%
  7697. %@AS@%  (ch = getch()) != '\r'%@AE@%%@NL@%
  7698. %@NL@%
  7699. works correctly. It assigns the result of the %@AB@%getch%@AE@% call to %@AS@% ch %@AE@% before
  7700. comparing %@AS@% ch %@AE@% to the constant.  %@NL@%
  7701. %@NL@%
  7702. The list of precedence-related errors is almost endless. Fortunately, QuickC
  7703. makes it unnecessary to memorize precedence rules. To view a complete table
  7704. of operator precedences, see Appendix A, "C Language Guide," and online help
  7705. in the QuickC environment.  %@NL@%
  7706. %@NL@%
  7707. %@AU@% Use parentheses  to avoid operator  precedence problems.%@AE@%  %@NL@%
  7708. %@NL@%
  7709. When in doubt, use extra parentheses to make the order of operations
  7710. absolutely clear. Extra parentheses don't degrade performance, and they can
  7711. improve readability as well as minimize precedence problems.  %@NL@%
  7712. %@NL@%
  7713. %@NL@%
  7714. %@3@%%@CR:C6A00100005 @%%@AB@%Confusing Structure-Member Operators%@AE@%%@EH@%%@NL@%
  7715. %@NL@%
  7716. Two different operators are used to access the members of a structure. Use
  7717. the structure-member operator (%@AB@%.%@AE@%) to access a structure member directly, and
  7718. the pointer-member operator (%@AB@%->%@AE@%) to access a structure member indirectly
  7719. through a pointer.  %@NL@%
  7720. %@NL@%
  7721. For instance, you may create a pointer to a structure of the %@AS@% employee %@AE@%
  7722. type,  %@NL@%
  7723. %@NL@%
  7724. %@AS@%  struct employee *p_ptr;%@AE@%%@NL@%
  7725. %@NL@%
  7726. and initialize the pointer to point to the %@AS@% jones %@AE@% structure:  %@NL@%
  7727. %@NL@%
  7728. %@AS@%  p_ptr = &jones;%@AE@%%@NL@%
  7729. %@NL@%
  7730. If you use the structure-member operator to access a structure member
  7731. through the pointer,  %@NL@%
  7732. %@NL@%
  7733. %@AS@%  p_ptr.months = 78; /* Error! */%@AE@%%@NL@%
  7734. %@NL@%
  7735. QuickC issues this error message:  %@NL@%
  7736. %@NL@%
  7737. %@AS@%  C2040: '.' requires struct/union name%@AE@%%@NL@%
  7738. %@NL@%
  7739. Use the pointer-member operator to access a structure member through a
  7740. pointer:  %@NL@%
  7741. %@NL@%
  7742. %@AS@%  p_ptr->months = 78;%@AE@%%@NL@%
  7743. %@NL@%
  7744. %@NL@%
  7745. %@2@%%@CR:C6A00100006 @%%@AB@%Array Problems%@AE@%%@EH@%%@NL@%
  7746. %@NL@%
  7747. The most common errors associated with arrays involve indexing errors. The
  7748. problems described in this section all concern indexing errors of one form
  7749. or another.  %@NL@%
  7750. %@NL@%
  7751. %@NL@%
  7752. %@3@%%@CR:C6A00100007 @%%@AB@%Array Indexing Errors%@AE@%%@EH@%%@NL@%
  7753. %@NL@%
  7754. %@AU@% The first C array subscript is 0.%@AE@%  %@NL@%
  7755. %@NL@%
  7756. If you're used to a language that has different subscripting rules, it's
  7757. easy to forget that the first subscript of a C array is 0 and the last
  7758. subscript is 1 less than the number used to declare the array. Here's an
  7759. example:  %@NL@%
  7760. %@NL@%
  7761. %@AS@%  int i_array[4] = { 3, 55, 600, 12 };
  7762. %@AS@%  main()
  7763. %@AS@%  {
  7764. %@AS@%     int count;
  7765. %@AS@%     for( count = 1; count < 5; count++ )  /* Error! */
  7766. %@AS@%        printf( "i_array[%d] = %d\n", i_array[count] );
  7767. %@AS@%  }%@AE@%%@NL@%
  7768. %@NL@%
  7769. The %@AB@%for%@AE@% loop in the above program starts at %@AS@% i_array[1] %@AE@% and ends at %@AS@%
  7770. %@AS@%i_array[4]%@AE@%. It should begin with the first element, %@AS@% i_array[0] %@AE@% and end at
  7771. the last,%@AS@% i_array[3]%@AE@%. The following corrects the error.  %@NL@%
  7772. %@NL@%
  7773. %@AS@%  for( count = 0; count < 4; count++ )
  7774. %@AS@%     printf( "i_array[%d] = %d\n", i_array[count] );%@AE@%%@NL@%
  7775. %@NL@%
  7776. %@NL@%
  7777. %@3@%%@CR:C6A00100008 @%%@AB@%Omitting an Array Subscript in Multidimensional Arrays%@AE@%%@EH@%%@NL@%
  7778. %@NL@%
  7779. %@AU@% Enclose each subscript  in its own set of brackets.%@AE@%  %@NL@%
  7780. %@NL@%
  7781. Programmers who know QuickBASIC, QuickPascal, or FORTRAN may be tempted to
  7782. place more than one array subscript in the same pair of brackets. In C, each
  7783. subscript of a multidimensional array is enclosed in its own pair of
  7784. brackets:  %@NL@%
  7785. %@NL@%
  7786. %@AS@%  int i_array[2][2] = { { 12, 2 }, { 6, 55 } };
  7787. %@AS@%  main()
  7788. %@AS@%  {
  7789. %@AS@%     printf( "%d\n", i_array[ 0, 1 ] ); /* Error! */
  7790. %@AS@%  }%@AE@%%@NL@%
  7791. %@NL@%
  7792. In the preceding example, the expression  %@NL@%
  7793. %@NL@%
  7794. %@AS@%  i_array[ 0, 1 ]%@AE@%%@NL@%
  7795. %@NL@%
  7796. does not access element 0,1 of %@AS@% i_array %@AE@%. Here is the correct way to refer
  7797. to that array element:  %@NL@%
  7798. %@NL@%
  7799. %@AS@%  i_array[0][1]%@AE@%%@NL@%
  7800. %@NL@%
  7801. Interestingly, the deviant array reference doesn't cause a syntax error. As
  7802. mentioned in Chapter 6, "Operators," it's legal to separate multiple
  7803. expressions with a comma operator, and the final value of such a series is
  7804. the value of the rightmost expression in the group. Thus, the expression  %@NL@%
  7805. %@NL@%
  7806. %@AS@%  i_array[ 0, 1 ]%@AE@%%@NL@%
  7807. %@NL@%
  7808. is equivalent to this one:  %@NL@%
  7809. %@NL@%
  7810. %@AS@%  i_array[ 1 ];%@AE@%%@NL@%
  7811. %@NL@%
  7812. Both expressions give an address, not the value of an array element.  %@NL@%
  7813. %@NL@%
  7814. %@NL@%
  7815. %@3@%%@CR:C6A00100009 @%%@AB@%Overrunning Array Boundaries%@AE@%%@EH@%%@NL@%
  7816. %@NL@%
  7817. Since C doesn't check array subscripts for validity, you must keep track of
  7818. array boundaries on your own. For instance, if you initialize a
  7819. five-character array,  %@NL@%
  7820. %@NL@%
  7821. %@AS@%  char sample[] = "ABCD";%@AE@%%@NL@%
  7822. %@NL@%
  7823. and refer to a nonexistent array element,  %@NL@%
  7824. %@NL@%
  7825. %@AS@%  sample[9] = 'X';%@AE@%%@NL@%
  7826. %@NL@%
  7827. QuickC doesn't signal an error, although the second statement overwrites
  7828. memory outside the array. It stores a character in element 9 of an array
  7829. that contains only 5 elements.  %@NL@%
  7830. %@NL@%
  7831. The same problem can occur when accessing an array through a pointer:  %@NL@%
  7832. %@NL@%
  7833. %@AS@%  char sample[] = "ABCD";
  7834. %@AS@%  char *ptr = sample;
  7835. %@AS@%  *--ptr = 'X';  /* Error! */%@AE@%%@NL@%
  7836. %@NL@%
  7837. The code overwrites the byte in memory below the array. To avoid such
  7838. problems, confine all array operations within the range used to declare the
  7839. array.  %@NL@%
  7840. %@NL@%
  7841. %@NL@%
  7842. %@2@%%@CR:C6A00100010 @%%@AB@%String Problems%@AE@%%@EH@%%@NL@%
  7843. %@NL@%
  7844. Strings are handled a little differently in C than most languages─a fact
  7845. that can cause problems. The following errors are common to programs that
  7846. use strings.  %@NL@%
  7847. %@NL@%
  7848. %@NL@%
  7849. %@3@%%@CR:C6A00100011 @%%@AB@%Confusing Character Constants and Character Strings%@AE@%%@EH@%%@NL@%
  7850. %@NL@%
  7851. Remember the difference between a character constant, which has one byte,
  7852. and a character string, which is a series of characters ending with a null
  7853. character:  %@NL@%
  7854. %@NL@%
  7855. %@AS@%  char ch = 'Y';
  7856. %@AS@%  if( ch == "Y" )  /* Error! */
  7857. %@AS@%     printf( "The ayes have it..." );%@AE@%%@NL@%
  7858. %@NL@%
  7859. The example above mistakenly compares the %@AB@%char%@AE@% variable %@AS@% ch %@AE@% to a
  7860. twocharacter string (%@AS@% "Y" %@AE@%) instead of a single character constant (%@AS@% 'Y' %@AE@%).
  7861. Since the comparison is false, the %@AB@%printf%@AE@% statement never executes─no matter
  7862. what %@AS@% ch %@AE@% equals.  %@NL@%
  7863. %@NL@%
  7864. The %@AB@%if%@AE@% statement needs to use single quotes. This code correctly tests
  7865. whether %@AS@% ch %@AE@% equals the character %@AS@% 'Y'%@AE@%:  %@NL@%
  7866. %@NL@%
  7867. %@AS@%  char ch = 'Y';
  7868. %@AS@%  if( ch == 'Y' )
  7869. %@AS@%     printf( "The ayes have it..." );%@AE@%%@NL@%
  7870. %@NL@%
  7871. %@NL@%
  7872. %@3@%%@CR:C6A00100012 @%%@AB@%Forgetting the Null Character That Terminates Strings%@AE@%%@EH@%%@NL@%
  7873. %@NL@%
  7874. Remember that strings end with a null character in C. If you declare this
  7875. five-character array,  %@NL@%
  7876. %@NL@%
  7877. %@AS@%  char sample[5];%@AE@%%@NL@%
  7878. %@NL@%
  7879. the compiler allocates five bytes of memory for the array. If you try to
  7880. store the string %@AS@%"Hello" %@AE@% in the array like this,  %@NL@%
  7881. %@NL@%
  7882. %@AS@%  strcpy( sample, "Hello" );%@AE@%%@NL@%
  7883. %@NL@%
  7884. you'll overrun the array's bounds. The string %@AS@%"Hello" %@AE@% contains six
  7885. characters (five letters and a null character), so it's one byte too big to
  7886. fit in the %@AS@% sample %@AE@% array. The %@AB@%strcpy%@AE@% overwrites one byte of memory outside
  7887. the array's storage.  %@NL@%
  7888. %@NL@%
  7889. It's easy to make this error when allocating memory for a string, too:  %@NL@%
  7890. %@NL@%
  7891. %@AS@%  char str[] = "Hello";
  7892. %@AS@%  char *ptr;
  7893. %@AS@%  ptr = malloc( strlen( str ) ); /* Error! */
  7894. %@AS@%  if( ptr == NULL )
  7895. %@AS@%     exit( 1 );
  7896. %@AS@%  else
  7897. %@AS@%     strcpy( ptr, str );%@AE@%%@NL@%
  7898. %@NL@%
  7899. This time the error occurs in the call to the %@AB@%malloc%@AE@% function, which
  7900. allocates memory to a pointer prior to a string copy. The %@AB@%strlen%@AE@% function
  7901. returns the length of a string not including the null character that ends
  7902. the string. Since the amount of memory allocated is one byte too small, the
  7903. %@AB@%strcpy%@AE@% operation overwrites memory, just as in the previous example.  %@NL@%
  7904. %@NL@%
  7905. To avoid the problem, add 1 to the value returned by %@AB@%strlen%@AE@%:  %@NL@%
  7906. %@NL@%
  7907. %@AS@%  ptr = malloc( strlen( str ) + 1 );%@AE@%%@NL@%
  7908. %@NL@%
  7909. %@NL@%
  7910. %@3@%%@CR:C6A00100013 @%%@AB@%Forgetting to Allocate Memory for a String%@AE@%%@EH@%%@NL@%
  7911. %@NL@%
  7912. If you declare a string as a pointer, don't forget to allocate memory for
  7913. it. This example tries to create a %@AB@%char%@AE@% pointer named %@AS@% ptr %@AE@% and initialize
  7914. it with a string:  %@NL@%
  7915. %@NL@%
  7916. %@AS@%  main()
  7917. %@AS@%  {
  7918. %@AS@%     char *ptr;
  7919. %@AS@%     strcpy( ptr, "Ashby" );  /* Error! */
  7920. %@AS@%  }%@AE@%%@NL@%
  7921. %@NL@%
  7922. The pointer declaration %@AS@% char *ptr; %@AE@% creates a pointer variable but nothing
  7923. else. It allocates enough memory for the pointer to store an address but
  7924. doesn't allocate any memory to store the object to which %@AS@% ptr %@AE@% will point.
  7925. The %@AB@%strcpy%@AE@% operation in the next line overwrites memory by copying the
  7926. string into an area not used by the program.  %@NL@%
  7927. %@NL@%
  7928. One way to allocate memory is by declaring a %@AB@%char%@AE@% array large enough to hold
  7929. the string:  %@NL@%
  7930. %@NL@%
  7931. %@AS@%  main()
  7932. %@AS@%  {
  7933. %@AS@%     char c_array[10];
  7934. %@AS@%     strcpy( c_array, "Randleman" );
  7935. %@AS@%  }%@AE@%%@NL@%
  7936. %@NL@%
  7937. You can also call the %@AB@%malloc%@AE@% library function to allocate memory at run
  7938. time:  %@NL@%
  7939. %@NL@%
  7940. %@AS@%  #define BUFFER_SIZE 30
  7941. %@AS@%  #include <malloc.h>
  7942. %@AS@%  
  7943. %@AS@%  main()
  7944. %@AS@%  {
  7945. %@AS@%     char *ptr;
  7946. %@AS@%     if( ptr = (char *) malloc( BUFFER_SIZE ) )
  7947. %@AS@%     {
  7948. %@AS@%        strcpy( ptr, "Duvall" );
  7949. %@AS@%        printf( ptr );
  7950. %@AS@%        free( ptr );
  7951. %@AS@%     }
  7952. %@AS@%  }%@AE@%%@NL@%
  7953. %@NL@%
  7954. %@NL@%
  7955. %@2@%%@CR:C6A00100014 @%%@AB@%Pointer Problems%@AE@%%@EH@%%@NL@%
  7956. %@NL@%
  7957. Every experienced C programmer has a collection of favorite pointer-induced
  7958. bugs. Pointer errors can wreak havoc because pointers can change the
  7959. contents of any addressable memory location. If a pointer writes to an
  7960. unexpected address, the results can be disastrous.  %@NL@%
  7961. %@NL@%
  7962. %@NL@%
  7963. %@3@%%@CR:C6A00100015 @%%@AB@%Using the Wrong Address Operator to Initialize a Pointer%@AE@%%@EH@%%@NL@%
  7964. %@NL@%
  7965. If you're still learning about pointers, it's easy to forget which address
  7966. operator to use when initializing a pointer variable. For example, you might
  7967. want to create a pointer to a simple %@AB@%int%@AE@% variable:  %@NL@%
  7968. %@NL@%
  7969. %@AS@%  int val = 25;
  7970. %@AS@%  int *ptr;
  7971. %@AS@%  ptr = val; /* Error! */%@AE@%%@NL@%
  7972. %@NL@%
  7973. The code above doesn't initialize %@AS@% ptr %@AE@% correctly. Instead of assigning to %@AS@%
  7974. %@AS@%ptr %@AE@% the address of %@AS@% val%@AE@%, the statement  %@NL@%
  7975. %@NL@%
  7976. %@AS@%  ptr = val;%@AE@%%@NL@%
  7977. %@NL@%
  7978. tries to assign %@AS@% ptr %@AE@% the contents of %@AS@% val%@AE@%, causing an error message:  %@NL@%
  7979. %@NL@%
  7980. %@AS@%  warning C4047: '=' : different levels of indirection%@AE@%%@NL@%
  7981. %@NL@%
  7982. Because %@AS@% val %@AE@% is an %@AB@%int%@AE@% variable, its contents can't form a meaningful
  7983. address for %@AS@%ptr%@AE@%. You must use the address-of operator to initialize %@AS@% ptr%@AE@%:  %@NL@%
  7984. %@NL@%
  7985. %@AS@%  ptr = &val;%@AE@%%@NL@%
  7986. %@NL@%
  7987. Here's another pointer initialization error:  %@NL@%
  7988. %@NL@%
  7989. %@AS@%  int val = 25;
  7990. %@AS@%  int *ptr;
  7991. %@AS@%  *ptr = &val; /* Error! */%@AE@%%@NL@%
  7992. %@NL@%
  7993. The last line doesn't initialize %@AS@% ptr %@AE@% to point to the variable %@AS@% val%@AE@%. The
  7994. expression to the left of the equal sign, %@AS@% *ptr%@AE@%, stands for the object %@AS@% ptr %@AE@%
  7995. points to. Instead of assigning %@AS@% ptr %@AE@% the address of %@AS@% val%@AE@%, the line tries to
  7996. assign the address of %@AS@% val %@AE@% to the place where %@AS@% ptr %@AE@% points. Because %@AS@% ptr %@AE@%
  7997. has never been initialized, the assignment triggers a run-time error:  %@NL@%
  7998. %@NL@%
  7999. %@AS@%  run-time error R6001
  8000. %@AS@%  -null pointer assignment%@AE@%%@NL@%
  8001. %@NL@%
  8002. Here is the correct way to initialize this pointer:  %@NL@%
  8003. %@NL@%
  8004. %@AS@%  ptr = &val;%@AE@%%@NL@%
  8005. %@NL@%
  8006. %@NL@%
  8007. %@3@%%@CR:C6A00100016 @%%@AB@%Declaring a Pointer with the Wrong Type%@AE@%%@EH@%%@NL@%
  8008. %@NL@%
  8009. You should make sure the type used to declare a pointer matches the type of
  8010. data object it points to:  %@NL@%
  8011. %@NL@%
  8012. %@AS@%  main()
  8013. %@AS@%  {
  8014. %@AS@%     int *ptr;
  8015. %@AS@%     .
  8016. %@AS@%     .
  8017. %@AS@%     .
  8018. %@AS@%     float val = 3.333333;
  8019. %@AS@%     ptr = val;  /* Error! */
  8020. %@AS@%     printf( "val = %f\n", *ptr );
  8021. %@AS@%  }%@AE@%%@NL@%
  8022. %@NL@%
  8023. The program declares %@AS@% ptr %@AE@% as a pointer to an %@AB@%int%@AE@%. Later on, forgetting what
  8024. type we used when declaring %@AS@% ptr%@AE@%, we assign it the address of the
  8025. floating-point variable %@AS@% val%@AE@%.  %@NL@%
  8026. %@NL@%
  8027. %@AU@% Declaring a pointer with the wrong type can cause unwanted type
  8028. %@AU@%conversions.%@AE@%  %@NL@%
  8029. %@NL@%
  8030. Since C allows you to assign any address to a pointer, the assignment
  8031. doesn't cause an error. But accessing %@AS@% val %@AE@% through %@AS@% ptr %@AE@% creates problems.
  8032. Because %@AS@% ptr %@AE@% is declared as a pointer to an %@AB@%int%@AE@%, the compiler does a type
  8033. conversion on the %@AB@%float%@AE@% it points to, converting the %@AB@%float%@AE@% value to an %@AB@%int%@AE@%.
  8034. The output is garbage:  %@NL@%
  8035. %@NL@%
  8036. %@AS@%  val = 11242989923343410000000000000000000000000000000000000
  8037. %@AS@%  000000000000000000000000000000000000000000000000000.000000%@AE@%%@NL@%
  8038. %@NL@%
  8039. The following program cures the error by declaring %@AS@% ptr %@AE@% as a pointer to a
  8040. %@AB@%float%@AE@% data type:  %@NL@%
  8041. %@NL@%
  8042. %@AS@%  main()
  8043. %@AS@%  {
  8044. %@AS@%     float *ptr;
  8045. %@AS@%     float val = 3.333333;
  8046. %@AS@%     ptr = &val;
  8047. %@AS@%     printf( "%f\n", *ptr );
  8048. %@AS@%  }%@AE@%%@NL@%
  8049. %@NL@%
  8050. Now it gives the correct output:  %@NL@%
  8051. %@NL@%
  8052. %@AS@%  val = 3.333333%@AE@%%@NL@%
  8053. %@NL@%
  8054. %@NL@%
  8055. %@3@%%@CR:C6A00100017 @%%@AB@%Using Dangling Pointers%@AE@%%@EH@%%@NL@%
  8056. %@NL@%
  8057. A "dangling pointer" is one that points to a memory area no longer in use by
  8058. your program. Dangling pointers, like uninitialized pointers, can be very
  8059. dangerous to use.  %@NL@%
  8060. %@NL@%
  8061. For instance, say you allocate a block of memory with the %@AB@%malloc%@AE@% library
  8062. function:  %@NL@%
  8063. %@NL@%
  8064. %@AS@%  #define BUFSIZE 1000
  8065. %@AS@%  char *ptr;
  8066. %@AS@%  if( ptr = (char *) malloc( BUFSIZE ) )
  8067. %@AS@%     /* do something */ ;%@AE@%%@NL@%
  8068. %@NL@%
  8069. After the memory block has been allocated with %@AB@%malloc%@AE@%, the pointer %@AS@% ptr %@AE@%
  8070. points to a valid data object. Once you're done using allocated memory, you
  8071. normally return it to the heap:  %@NL@%
  8072. %@NL@%
  8073. %@AS@%  free( ptr );%@AE@%%@NL@%
  8074. %@NL@%
  8075. After you free the memory it points to, %@AS@% ptr %@AE@% is a dangling pointer. It
  8076. still points to a valid machine address, but that address is no longer in
  8077. use by the program. You shouldn't use the pointer at this stage, just as you
  8078. shouldn't use it before it has been initialized.  %@NL@%
  8079. %@NL@%
  8080. Dangling pointers can also be created by a function that returns a pointer
  8081. to a local variable:  %@NL@%
  8082. %@NL@%
  8083. %@AS@%  int *boo_boo( void )
  8084. %@AS@%  {
  8085. %@AS@%     int object;
  8086. %@AS@%     .
  8087. %@AS@%     .
  8088. %@AS@%     .
  8089. %@AS@%     return &object; /* Error! */
  8090. %@AS@%  }%@AE@%%@NL@%
  8091. %@NL@%
  8092. The %@AS@% boo_boo %@AE@% function returns the address of the local variable %@AS@% object%@AE@%,
  8093. forgetting the storage for %@AS@% object %@AE@% is no longer part of the program after
  8094. the function ends.  %@NL@%
  8095. %@NL@%
  8096. Here's a variant of the previous example involving a string pointer:  %@NL@%
  8097. %@NL@%
  8098. %@AS@%  char *boo_boo( void )
  8099. %@AS@%  {
  8100. %@AS@%     char *c_ptr;
  8101. %@AS@%     c_ptr = "Hello";
  8102. %@AS@%     .
  8103. %@AS@%     .
  8104. %@AS@%     .
  8105. %@AS@%     return c_ptr; /* Error! */
  8106. %@AS@%  }%@AE@%%@NL@%
  8107. %@NL@%
  8108. Since the string constant %@AS@% "Hello" %@AE@% is local to the function, it evaporates
  8109. when the function ends, leaving the pointer %@AS@% c_ptr %@AE@% dangling.  %@NL@%
  8110. %@NL@%
  8111. %@NL@%
  8112. %@2@%%@CR:C6A00100018 @%%@AB@%Library-Function Problems%@AE@%%@EH@%%@NL@%
  8113. %@NL@%
  8114. Once you've learned enough about C to write practical programs, you can
  8115. begin to explore the rich function library supplied with QuickC. This
  8116. section outlines a few common problems related to using library functions.
  8117. Again, you can use online help to get information about specific library
  8118. functions.  %@NL@%
  8119. %@NL@%
  8120. %@NL@%
  8121. %@3@%%@CR:C6A00100019 @%%@AB@%Failing to Check Return Values from Library Functions%@AE@%%@EH@%%@NL@%
  8122. %@NL@%
  8123. %@AU@% Always check library function return values.%@AE@%  %@NL@%
  8124. %@NL@%
  8125. Almost all library functions return some value─either the result of
  8126. processing or an error code showing success or failure. You should always
  8127. check libraryfunction return values, even if you're confident of the result.
  8128. %@NL@%
  8129. %@NL@%
  8130. This rule is critical when calling a library function such as %@AB@%malloc%@AE@%, which
  8131. allocates memory at run time:  %@NL@%
  8132. %@NL@%
  8133. %@AS@%  char *ptr;
  8134. %@AS@%  ptr = (char *) malloc( BUFSIZE );  /* Error! */%@AE@%%@NL@%
  8135. %@NL@%
  8136. If the call to %@AB@%malloc%@AE@% fails, the pointer %@AS@% ptr %@AE@% is assigned a null (0) value.
  8137. Using %@AS@% ptr %@AE@% under these circumstances can overwrite unexpected memory
  8138. addresses or cause a run-time error. The following code checks the return
  8139. value from %@AB@%malloc%@AE@%:  %@NL@%
  8140. %@NL@%
  8141. %@AS@%  #define NULL 0
  8142. %@AS@%  #define BUFSIZE 32768
  8143. %@AS@%     .
  8144. %@AS@%     .
  8145. %@AS@%     .
  8146. %@AS@%  char *ptr;
  8147. %@AS@%  if( (ptr = (char *) malloc( BUFSIZE ) ) != NULL )
  8148. %@AS@%  {
  8149. %@AS@%     printf( "Copacetic.\n" );
  8150. %@AS@%     /* Do something useful... */
  8151. %@AS@%  }
  8152. %@AS@%  else
  8153. %@AS@%     printf( "Not enough memory!\n" );%@AE@%%@NL@%
  8154. %@NL@%
  8155. %@NL@%
  8156. %@3@%%@CR:C6A00100020 @%%@AB@%Duplicating Library-Function Names%@AE@%%@EH@%%@NL@%
  8157. %@NL@%
  8158. There are so many functions in the QuickC run-time library that it's
  8159. sometimes difficult to avoid duplicating function names. For instance, if
  8160. you write a function that reads data from a buffer, the name %@AS@% read %@AE@% may
  8161. strike you as short and descriptive.  %@NL@%
  8162. %@NL@%
  8163. The only problem is that %@AB@%read%@AE@% is the name of a QuickC library function. A
  8164. program that defines its own %@AS@% read %@AE@% function may work correctly at first,
  8165. but if you later include the header file that declares the %@AB@%read%@AE@% library
  8166. function,  %@NL@%
  8167. %@NL@%
  8168. %@AS@%  #include <io.h>%@AE@%%@NL@%
  8169. %@NL@%
  8170. then redefinition errors occur. You can't use the same name for two
  8171. different functions. The solution here is to rename the user-defined
  8172. function.  %@NL@%
  8173. %@NL@%
  8174. %@AU@% Use online help to check  for function-name conflicts.%@AE@%  %@NL@%
  8175. %@NL@%
  8176. QuickC's online help lets you check for such name conflicts on the spot. Put
  8177. the cursor on the function name you wish to use, then press F1. If the name
  8178. is already used for a library function, online help displays information
  8179. about the function. If the name isn't in online help, it's not used in the
  8180. QuickC function library and is a safe choice.  %@NL@%
  8181. %@NL@%
  8182. Unless you're writing your own library functions, it's a good rule to avoid
  8183. declaring names that begin with an underscore ( _ ), since many of the
  8184. system-defined names in QuickC start with that character. (Non-ANSI library
  8185. functions begin with a single underscore. Predefined identifiers such as
  8186. %@AB@%TIME%@AE@% start with two underscores, and routines internal to the C run-time
  8187. library can begin with either one or two underscores.)  %@NL@%
  8188. %@NL@%
  8189. %@NL@%
  8190. %@3@%%@CR:C6A00100021 @%%@AB@%Forgetting to Include Header Files for Library Functions%@AE@%%@EH@%%@NL@%
  8191. %@NL@%
  8192. Because they contain needed function prototypes, it's important to include
  8193. the correct header files when using QuickC library functions:  %@NL@%
  8194. %@NL@%
  8195. %@AS@%  main()
  8196. %@AS@%  {
  8197. %@AS@%     double val = sqrt( (double) 10 );
  8198. %@AS@%     printf( "square root of 10 = %le\n", val );
  8199. %@AS@%  }%@AE@%%@NL@%
  8200. %@NL@%
  8201. The program above calls the library function %@AB@%sqrt%@AE@%, which calculates a square
  8202. root. Most of the program is correct. When passing the value 10 to %@AB@%sqrt%@AE@%, it
  8203. casts the argument as a %@AB@%double%@AE@%, the type %@AB@%sqrt%@AE@% expects. The return value from
  8204. %@AB@%sqrt%@AE@% is assigned to a %@AB@%double%@AE@% variable, too.  %@NL@%
  8205. %@NL@%
  8206. Unfortunately, the program still gives the wrong output. The square root of
  8207. 10 is not 171 (1.710000e+002 in exponential notation):  %@NL@%
  8208. %@NL@%
  8209. %@AS@%  square root of 10 = 1.710000e+002%@AE@%%@NL@%
  8210. %@NL@%
  8211. %@AU@% Function prototypes can prevent unexpected type conversions.%@AE@%  %@NL@%
  8212. %@NL@%
  8213. Because the program has no prototype for the %@AB@%sqrt%@AE@% function, %@AB@%sqrt%@AE@% has the %@AB@%int%@AE@%
  8214. return type by default. The value returned by %@AB@%sqrt%@AE@% undergoes an unexpected
  8215. type conversion─from type %@AB@%double%@AE@% to %@AB@%int%@AE@%─and becomes garbage.  %@NL@%
  8216. %@NL@%
  8217. This problem is easily solved. Simply include the standard header file that
  8218. contains the prototype for %@AB@%sqrt%@AE@%:  %@NL@%
  8219. %@NL@%
  8220. %@AS@%  #include <stdio.h>
  8221. %@AS@%  #include <math.h>
  8222. %@AS@%  main()
  8223. %@AS@%  {
  8224. %@AS@%     double val = sqrt( (double) 10 );
  8225. %@AS@%     printf( "square root of 10 = %le\n", val );
  8226. %@AS@%  }%@AE@%%@NL@%
  8227. %@NL@%
  8228. Now the program works correctly:  %@NL@%
  8229. %@NL@%
  8230. %@AS@%  square root of 10 = 3.162278e+000%@AE@%%@NL@%
  8231. %@NL@%
  8232. If you're not sure which header file a library function needs, take
  8233. advantage of QuickC's online help. (Put the cursor on the function name and
  8234. press F1.) If the function needs a header file, the file name appears in an
  8235. %@AB@%#include%@AE@% directive above the function prototype.  %@NL@%
  8236. %@NL@%
  8237. %@NL@%
  8238. %@3@%%@CR:C6A00100022 @%%@AB@%Omitting the Address-Of Operator When Calling scanf%@AE@%%@EH@%%@NL@%
  8239. %@NL@%
  8240. Don't forget to put the address-of operator in front of arguments when using
  8241. the %@AB@%scanf%@AE@% library function (the %@AB@%scanf%@AE@% function accesses keyboard input; see
  8242. Chapter 11, "Input and Output")%@AB@%:%@AE@%  %@NL@%
  8243. %@NL@%
  8244. %@AS@%  main()
  8245. %@AS@%  {
  8246. %@AS@%     int val;
  8247. %@AS@%     printf( "Type a number: " );
  8248. %@AS@%     scanf( "%d", val ); /* Error! */
  8249. %@AS@%     printf( "%d", val );
  8250. %@AS@%  }%@AE@%%@NL@%
  8251. %@NL@%
  8252. When the program calls %@AB@%scanf%@AE@%, it omits the address-of operator that should
  8253. precede the second argument:  %@NL@%
  8254. %@NL@%
  8255. %@AS@%  scanf( "%d", val );  /* Error! */%@AE@%%@NL@%
  8256. %@NL@%
  8257. The %@AB@%scanf%@AE@% function expects to be passed a pointer to a variable (in this
  8258. case, a pointer to %@AS@% val %@AE@%) so it can assign an input value to the variable.
  8259. But because the address-of operator is missing, the program passes the value
  8260. of %@AS@% val%@AE@%, not its address.  %@NL@%
  8261. %@NL@%
  8262. Instead of storing an input value in %@AS@% val %@AE@% as intended, %@AB@%scanf%@AE@% uses the
  8263. uninitialized value of %@AS@% val %@AE@% as a pointer and assigns the input value to an
  8264. unpredictable address. As a result, %@AS@% val %@AE@% remains uninitialized and the
  8265. program overwrites memory elsewhere─two very undesirable events.  %@NL@%
  8266. %@NL@%
  8267. Here is the correct way to call %@AB@%scanf%@AE@% in this program:  %@NL@%
  8268. %@NL@%
  8269. %@AS@%  scanf( "%d", &val );%@AE@%%@NL@%
  8270. %@NL@%
  8271. %@NL@%
  8272. %@2@%%@CR:C6A00100023 @%%@AB@%Macro Problems%@AE@%%@EH@%%@NL@%
  8273. %@NL@%
  8274. Function-like macros─macro definitions that take arguments─share many of the
  8275. advantages of functions. They can cause unwanted side effects, however, if
  8276. you fail to put parentheses around their arguments or carelessly supply an
  8277. argument that uses an increment or decrement operator.  %@NL@%
  8278. %@NL@%
  8279. %@NL@%
  8280. %@3@%%@CR:C6A00100024 @%%@AB@%Omitting Parentheses from Macro Arguments%@AE@%%@EH@%%@NL@%
  8281. %@NL@%
  8282. A macro definition that doesn't enclose its arguments in parentheses can
  8283. create precedence problems:  %@NL@%
  8284. %@NL@%
  8285. %@AS@%  #include <stdio.h>
  8286. %@AS@%  
  8287. %@AS@%  #define FOURX(arg)  ( arg * 4 )
  8288. %@AS@%  
  8289. %@AS@%  main()
  8290. %@AS@%  {
  8291. %@AS@%     int val;
  8292. %@AS@%     val = FOURX( 2 + 3 );
  8293. %@AS@%     printf( "val = %d\n", val );
  8294. %@AS@%  }%@AE@%%@NL@%
  8295. %@NL@%
  8296. The %@AS@% FOURX %@AE@% macro in the program multiplies its argument by 4. The macro
  8297. works fine if you pass it a single value, as in  %@NL@%
  8298. %@NL@%
  8299. %@AS@%  val = FOURX( 2 );%@AE@%%@NL@%
  8300. %@NL@%
  8301. but returns the wrong result if you pass it this expression:  %@NL@%
  8302. %@NL@%
  8303. %@AS@%  val = FOURX( 2 + 3 );%@AE@%%@NL@%
  8304. %@NL@%
  8305. QuickC expands the above line to this line:  %@NL@%
  8306. %@NL@%
  8307. %@AS@%  val = 2 + 3 * 4;%@AE@%%@NL@%
  8308. %@NL@%
  8309. %@AU@% Use parentheses to  avoid precedence  problems in macros.%@AE@%  %@NL@%
  8310. %@NL@%
  8311. Because the multiplication operator has higher precedence than the addition
  8312. operator, this line assigns %@AS@% val %@AE@% the value 14 (or 2 + 12) rather than the
  8313. correct value 20 (or 5 * 4).  %@NL@%
  8314. %@NL@%
  8315. You can avoid the problem by enclosing the macro argument in parentheses
  8316. each time it appears in the macro definition:  %@NL@%
  8317. %@NL@%
  8318. %@AS@%  #include <stdio.h>
  8319. %@AS@%  
  8320. %@AS@%  #define FOURX(arg)  ( (arg) * 4 )
  8321. %@AS@%  
  8322. %@AS@%  main()
  8323. %@AS@%  {
  8324. %@AS@%     int val;
  8325. %@AS@%     val = FOURX(2 + 3);
  8326. %@AS@%     printf( "val = %d\n", val );
  8327. %@AS@%  }%@AE@%%@NL@%
  8328. %@NL@%
  8329. Now the program expands this line  %@NL@%
  8330. %@NL@%
  8331. %@AS@%  val = FOURX(2 + 3);%@AE@%%@NL@%
  8332. %@NL@%
  8333. into this one:  %@NL@%
  8334. %@NL@%
  8335. %@AS@%  val = (2 + 3) * 4;%@AE@%%@NL@%
  8336. %@NL@%
  8337. The extra parentheses assure that the addition is performed before the
  8338. multiplication, giving the desired result.  %@NL@%
  8339. %@NL@%
  8340. %@NL@%
  8341. %@3@%%@CR:C6A00100025 @%%@AB@%Using Increment and Decrement Operators in Macro Arguments%@AE@%%@EH@%%@NL@%
  8342. %@NL@%
  8343. If a function-like macro evaluates an argument more than once, you should
  8344. avoid passing it an expression that contains an increment or decrement
  8345. operator:  %@NL@%
  8346. %@NL@%
  8347. %@AS@%  #include <stdio.h>
  8348. %@AS@%  #define ABS(value)  ( (value) >= 0 ? (value) : -(value) )
  8349. %@AS@%  
  8350. %@AS@%  main()
  8351. %@AS@%  {
  8352. %@AS@%     int array[4] = {3, -20, -555, 6};
  8353. %@AS@%     int *ptr = array;
  8354. %@AS@%     int val, count;
  8355. %@AS@%     for( count = 0; count < 4; count++ )
  8356. %@AS@%     {
  8357. %@AS@%        val = ABS(*ptr++); /* Error! */
  8358. %@AS@%        printf( "abs of array[%d] = %d\n", count, val );
  8359. %@AS@%     }
  8360. %@AS@%  }%@AE@%%@NL@%
  8361. %@NL@%
  8362. The program uses the %@AS@% ABS %@AE@% macro that was used to explain macros in Chapter
  8363. 7, "Preprocessor Directives." The macro returns the absolute value of the
  8364. argument you pass to it.  %@NL@%
  8365. %@NL@%
  8366. The goal in this program is to display the absolute value of every element
  8367. in %@AS@% array%@AE@%. It uses a %@AB@%for%@AE@% loop to step through the array and a pointer named %@AS@%
  8368. %@AS@%ptr %@AE@% to access each array element in turn. Instead of the output you would
  8369. expect,  %@NL@%
  8370. %@NL@%
  8371. %@AS@%  abs of array[0] = 3
  8372. %@AS@%  abs of array[1] = 20
  8373. %@AS@%  abs of array[2] = 555
  8374. %@AS@%  abs of array[3] = 6%@AE@%%@NL@%
  8375. %@NL@%
  8376. the program gives this output:  %@NL@%
  8377. %@NL@%
  8378. %@AS@%  abs of array[0] = -20
  8379. %@AS@%  abs of array[1] = -6
  8380. %@AS@%  abs of array[2] = 8307
  8381. %@AS@%  abs of array[3] = 24864%@AE@%%@NL@%
  8382. %@NL@%
  8383. (The last two array values may differ if you run the program. They are the
  8384. contents of memory not used by the program.)  %@NL@%
  8385. %@NL@%
  8386. The error occurs in this line,  %@NL@%
  8387. %@NL@%
  8388. %@AS@%  val = ABS(*ptr++); /* Error! */%@AE@%%@NL@%
  8389. %@NL@%
  8390. which QuickC expands as shown here:  %@NL@%
  8391. %@NL@%
  8392. %@AS@%  val = ( (*ptr++) >= 0 ? (*ptr++) : -(*ptr++) ); /* Error! */%@AE@%%@NL@%
  8393. %@NL@%
  8394. Because it uses the conditional operator, the %@AS@% ABS %@AE@% macro always evaluates
  8395. its argument at least twice. This isn't a problem when the argument is a
  8396. constant or simple variable. In the example, however, the argument is the
  8397. expression %@AS@% *ptr++%@AE@%. Each time the macro evaluates this expression, the
  8398. increment operator takes effect, causing %@AS@% ptr %@AE@% to point to the next element
  8399. of %@AS@% array%@AE@%.  %@NL@%
  8400. %@NL@%
  8401. The first time the program invokes the macro, %@AS@% ptr %@AE@% points to the first
  8402. array element, %@AS@% array[0]%@AE@%. Since this element contains a nonnegative value
  8403. (3) the macro evaluates the argument twice. The first evaluation takes the
  8404. value that %@AS@% ptr %@AE@% points to and then increments %@AS@% ptr%@AE@%. Now %@AS@% ptr %@AE@% points to the
  8405. second element, %@AS@% array[1]%@AE@%. The second evaluation takes the value of %@AS@%
  8406. %@AS@%array[1] %@AE@% and increments %@AS@% ptr %@AE@% again.  %@NL@%
  8407. %@NL@%
  8408. The first macro invocation not only returns an incorrect value (-20, the
  8409. value of %@AS@% array[1]%@AE@% ). It also leaves %@AS@% ptr %@AE@% pointing to the third array
  8410. element, making the results of later invocations unpredictable. (The pointer
  8411. eventually moves past the last element of %@AS@% array %@AE@% and points to unknown
  8412. data.)  %@NL@%
  8413. %@NL@%
  8414. To avoid the problem, don't use the increment or decrement operators in
  8415. arguments you pass to a macro. This revision removes the error by
  8416. incrementing %@AS@%ptr %@AE@% in the %@AB@%for%@AE@% statement instead of the macro invocation:  %@NL@%
  8417. %@NL@%
  8418. %@AS@%  #include <stdio.h>
  8419. %@AS@%  #define ABS(value)  ( (value) >= 0 ? (value) : -(value) )
  8420. %@AS@%  
  8421. %@AS@%  main()
  8422. %@AS@%  {
  8423. %@AS@%     int array[4] = {3, -20, -555, 6};
  8424. %@AS@%     int *ptr = array;
  8425. %@AS@%     int val, count;
  8426. %@AS@%     for( count = 0; count < 4; count++, ptr++ )
  8427. %@AS@%     {
  8428. %@AS@%        val = ABS(*ptr);
  8429. %@AS@%        printf( "abs of array[%d] = %d\n", count, val );
  8430. %@AS@%     }
  8431. %@AS@%  }%@AE@%%@NL@%
  8432. %@NL@%
  8433. This advice applies generally to QuickC library routines as well as macros
  8434. you write. Remember, some run-time library routines are implemented as
  8435. macros rather than C functions. If you're not sure whether a library routine
  8436. is actually a macro, look it up in online help.  %@NL@%
  8437. %@NL@%
  8438. %@NL@%
  8439. %@2@%%@CR:C6A00100026 @%%@AB@%Miscellaneous Problems%@AE@%%@EH@%%@NL@%
  8440. %@NL@%
  8441. This section describes C programming problems that don't fit into any
  8442. convenient category.  %@NL@%
  8443. %@NL@%
  8444. %@NL@%
  8445. %@3@%%@CR:C6A00100027 @%%@AB@%Mismatching if and else Statements%@AE@%%@EH@%%@NL@%
  8446. %@NL@%
  8447. In nested %@AB@%if%@AE@% statements, each %@AB@%else%@AE@% is associated with the closest preceding
  8448. %@AB@%if%@AE@% statement that does not have an %@AB@%else%@AE@%. Although indentation can make
  8449. nested constructs more readable, it has no syntactical effect:  %@NL@%
  8450. %@NL@%
  8451. %@AS@%  if( val > 5 )
  8452. %@AS@%     if( count == 10 )
  8453. %@AS@%        val = sample;
  8454. %@AS@%  else
  8455. %@AS@%     val = 0;%@AE@%%@NL@%
  8456. %@NL@%
  8457. The indentation suggests that the %@AB@%else%@AE@% associates with the first %@AB@%if%@AE@%. In
  8458. fact, the %@AB@%else%@AE@% is part of the second %@AB@%if%@AE@%, as shown more clearly here:  %@NL@%
  8459. %@NL@%
  8460. %@AS@%  if( val > 5 )
  8461. %@AS@%     if( count == 10 )
  8462. %@AS@%        val = sample;
  8463. %@AS@%     else
  8464. %@AS@%        val = 0;%@AE@%%@NL@%
  8465. %@NL@%
  8466. The %@AB@%else%@AE@% is part of the second %@AB@%if%@AE@% statement─the closest preceding %@AB@%if%@AE@% that
  8467. doesn't have a matching %@AB@%else%@AE@%. To tie the %@AB@%else%@AE@% to the first %@AB@%if%@AE@%, you must use
  8468. braces:  %@NL@%
  8469. %@NL@%
  8470. %@AS@%  if( val > 5 )
  8471. %@AS@%  {
  8472. %@AS@%     if( count == 10 )
  8473. %@AS@%        val = sample;
  8474. %@AS@%  }
  8475. %@AS@%  else
  8476. %@AS@%     val = 0;%@AE@%%@NL@%
  8477. %@NL@%
  8478. %@AU@% Indentation makes  programs easier to read, but  is ignored by the
  8479. %@AU@%compiler.%@AE@%  %@NL@%
  8480. %@NL@%
  8481. Now the %@AB@%else%@AE@% belongs with the outermost %@AB@%if%@AE@%. Remember, indentation is
  8482. meaningful only to humans. The compiler relies strictly on punctuation when
  8483. it translates the source file.  %@NL@%
  8484. %@NL@%
  8485. %@NL@%
  8486. %@3@%%@CR:C6A00100028 @%%@AB@%Misplacing Semicolons%@AE@%%@EH@%%@NL@%
  8487. %@NL@%
  8488. Misplaced semicolons can cause subtle bugs:  %@NL@%
  8489. %@NL@%
  8490. %@AS@%  #include <stdio.h>
  8491. %@AS@%  
  8492. %@AS@%  main()
  8493. %@AS@%  {
  8494. %@AS@%     int count;
  8495. %@AS@%     for( count = 0; count < 500; count++ ); /* Error! */
  8496. %@AS@%     {
  8497. %@AS@%        printf( "count = %d\n", count );
  8498. %@AS@%        printf( "And the beat goes on...\n" );
  8499. %@AS@%     }
  8500. %@AS@%  }%@AE@%%@NL@%
  8501. %@NL@%
  8502. You might expect the program to print the value of %@AS@% count %@AE@% 500 times, but
  8503. this is all it prints:  %@NL@%
  8504. %@NL@%
  8505. %@AS@%  count = 500
  8506. %@AS@%  And the beat goes on...%@AE@%%@NL@%
  8507. %@NL@%
  8508. The culprit is the extra semicolon immediately after the parentheses of the
  8509. %@AB@%for%@AE@% statement. Its effect is more evident if we reformat the statement:  %@NL@%
  8510. %@NL@%
  8511. %@AS@%  #include <stdio.h>
  8512. %@AS@%  
  8513. %@AS@%  main()
  8514. %@AS@%  {
  8515. %@AS@%     int count;
  8516. %@AS@%     for( count = 0; count < 500; count++ )
  8517. %@AS@%        ; /* Null statement */
  8518. %@AS@%     {
  8519. %@AS@%        printf( "count = %d\n", count );
  8520. %@AS@%        printf( "And the beat goes on...\n" );
  8521. %@AS@%     }
  8522. %@AS@%  }%@AE@%%@NL@%
  8523. %@NL@%
  8524. Instead of printing the value of %@AS@% count %@AE@% 500 times, the program executes the
  8525. null statement (%@AS@%;%@AE@%) 500 times. Null statements are perfectly legal in C, so
  8526. the compiler has no way to tell this is a mistake.  %@NL@%
  8527. %@NL@%
  8528. Since the null statement is interpreted as the loop body, the %@AB@%printf%@AE@%
  8529. statements inside curly braces are interpreted as a statement block and
  8530. executed once. Statement blocks usually appear as part of a loop, function
  8531. definition, or decision- making statement, but it's legal to enclose any
  8532. series of statements in braces.  %@NL@%
  8533. %@NL@%
  8534. The program works as intended if you remove the extra semicolon:  %@NL@%
  8535. %@NL@%
  8536. %@AS@%  #include <stdio.h>
  8537. %@AS@%  
  8538. %@AS@%  main()
  8539. %@AS@%  {
  8540. %@AS@%     int count;
  8541. %@AS@%     for( count = 0; count < 500; count++ )
  8542. %@AS@%     {
  8543. %@AS@%        printf( "count = %d\n", count );
  8544. %@AS@%        printf( "And the beat goes on...\n" );
  8545. %@AS@%     }
  8546. %@AS@%  }%@AE@%%@NL@%
  8547. %@NL@%
  8548. Here's another one. If you know QuickPascal, you might be tempted to put a
  8549. semicolon after the parentheses of a function definition:  %@NL@%
  8550. %@NL@%
  8551. %@AS@%  void func( void );
  8552. %@AS@%  
  8553. %@AS@%  void func( void ); /* Error! No semicolon here. */
  8554. %@AS@%  {
  8555. %@AS@%     printf( "C is not Pascal\n" );
  8556. %@AS@%  }%@AE@%%@NL@%
  8557. %@NL@%
  8558. The function header causes a syntax error. While a function declaration
  8559. requires a semicolon after its parentheses, a function definition does not.
  8560. This code corrects the error:  %@NL@%
  8561. %@NL@%
  8562. %@AS@%  void func( void );
  8563. %@AS@%  
  8564. %@AS@%  void func( void )
  8565. %@AS@%  {
  8566. %@AS@%     printf( "C is not Pascal\n" );
  8567. %@AS@%  }%@AE@%%@NL@%
  8568. %@NL@%
  8569. %@NL@%
  8570. %@3@%%@CR:C6A00100029 @%%@AB@%Omitting Double Backslashes in DOS Path Specifications%@AE@%%@EH@%%@NL@%
  8571. %@NL@%
  8572. Because C uses the backslash (%@AB@%\%@AE@%) as an escape character, it's easy to create
  8573. garbled path specifications:  %@NL@%
  8574. %@NL@%
  8575. %@AS@%  fp = fopen( "c:\temp\bodkin.txt", "w" );%@AE@%%@NL@%
  8576. %@NL@%
  8577. At first glance, the path specification in the string  %@NL@%
  8578. %@NL@%
  8579. %@AS@%  "c:\temp\bodkin.txt"%@AE@%%@NL@%
  8580. %@NL@%
  8581. looks good because that's how you would type it on the DOS command line. In
  8582. a quoted string, however, the backslash is interpreted as an escape
  8583. character. In this string the sequences %@AB@%\t%@AE@% and %@AB@%\b%@AE@% are interpreted as the tab
  8584. and backspace character, respectively, garbling the path and file name. Even
  8585. if the indicated file exists, this call to %@AB@%fopen%@AE@% is sure to fail.  %@NL@%
  8586. %@NL@%
  8587. In a quoted string the escape sequence for a backslash character is a double
  8588. backslash (%@AB@%\\%@AE@%). This statement solves the problem:  %@NL@%
  8589. %@NL@%
  8590. %@AS@%  fp = fopen( "c:\\temp\\bodkin.txt", "w" );%@AE@%%@NL@%
  8591. %@NL@%
  8592. %@NL@%
  8593. %@3@%%@CR:C6A00100030 @%%@AB@%Omitting break Statements from a switch Statement%@AE@%%@EH@%%@NL@%
  8594. %@NL@%
  8595. Don't forget to include %@AB@%break%@AE@% statements when using the %@AB@%switch%@AE@% statement:  %@NL@%
  8596. %@NL@%
  8597. %@AS@%  switch( ch )
  8598. %@AS@%  {
  8599. %@AS@%     case 'e':
  8600. %@AS@%        printf( "Bye bye\n" );
  8601. %@AS@%        break;
  8602. %@AS@%     case 'l':
  8603. %@AS@%        printf( "Loading the file\n" );
  8604. %@AS@%        load_file( fp );
  8605. %@AS@%        break;%@AE@%%@NL@%
  8606. %@NL@%
  8607. %@AS@%  case 's':
  8608. %@AS@%        printf( "Saving the file\n" );
  8609. %@AS@%        write_file( fp );  /* Error! Missing break. */
  8610. %@AS@%     case 'd':
  8611. %@AS@%        printf( "Deleting the file\n" );
  8612. %@AS@%        kill_file( fp );
  8613. %@AS@%        break;
  8614. %@AS@%     default:
  8615. %@AS@%        break;
  8616. %@AS@%  }%@AE@%%@NL@%
  8617. %@NL@%
  8618. In this code a %@AB@%break%@AE@% statement is missing from the statements following the
  8619. third case label (the statements that print %@AS@% Saving the file %@AE@%). After those
  8620. statements execute, execution falls through to the next case label, deleting
  8621. the newly saved file.  %@NL@%
  8622. %@NL@%
  8623. To avoid this problem, place a %@AB@%break%@AE@% at the end of every case item:  %@NL@%
  8624. %@NL@%
  8625. %@AS@%  case 's':
  8626. %@AS@%     printf( "Saving the file.\n" );
  8627. %@AS@%     write_file( fp );
  8628. %@AS@%     break;%@AE@%%@NL@%
  8629. %@NL@%
  8630. It's legal, of course, to write a program in which execution deliberately
  8631. falls through from one case label to the next. In such cases you may want to
  8632. add a comment to prevent confusion.  %@NL@%
  8633. %@NL@%
  8634. %@NL@%
  8635. %@3@%%@CR:C6A00100031 @%%@AB@%Mixing Signed and Unsigned Values%@AE@%%@EH@%%@NL@%
  8636. %@NL@%
  8637. If you explicitly compare two values of different types, the compiler
  8638. normally catches the error. Some type mismatches aren't easy to spot,
  8639. however, even for humans:  %@NL@%
  8640. %@NL@%
  8641. %@AS@%  #define CHARVAL '\xff'
  8642. %@AS@%  
  8643. %@AS@%  main()
  8644. %@AS@%  {
  8645. %@AS@%     unsigned char uc;
  8646. %@AS@%     uc = CHARVAL;
  8647. %@AS@%     if( uc == CHARVAL )
  8648. %@AS@%        printf( "Eureka!" );
  8649. %@AS@%     else
  8650. %@AS@%        printf( "Oops..." );
  8651. %@AS@%  }%@AE@%%@NL@%
  8652. %@NL@%
  8653. The program prints %@AS@% Oops... %@AE@% which probably wasn't expected. The comparison
  8654. between %@AS@% CHARVAL %@AE@% and %@AS@% uc %@AE@% is false even though both are clearly %@AB@%char%@AE@%
  8655. values.  %@NL@%
  8656. %@NL@%
  8657. The answer lies in the way the compiler converts %@AB@%signed%@AE@% and %@AB@%unsigned char%@AE@%
  8658. values into %@AB@%int%@AE@% values for internal use. The %@AB@%#define%@AE@% directive,  %@NL@%
  8659. %@NL@%
  8660. %@AS@%  #define CHARVAL '\xff'%@AE@%%@NL@%
  8661. %@NL@%
  8662. defines %@AS@% CHARVAL %@AE@% as the constant 0xff. Since no sign is specified, the
  8663. compiler treats the constant as a %@AB@%signed char%@AE@% value by default. When it
  8664. converts the %@AB@%char%@AE@% to an %@AB@%int%@AE@% for internal use, as it does all character
  8665. values, the compiler extends the value's sign. The result is an %@AB@%int%@AE@% with the
  8666. value 0xffff.  %@NL@%
  8667. %@NL@%
  8668. The variable %@AS@% uc %@AE@% undergoes the same internal conversion, with an important
  8669. difference. Since %@AS@% uc %@AE@% is explicitly declared as %@AB@%unsigned%@AE@%, its value is
  8670. converted to an %@AB@%int%@AE@% value of 0x00ff.  %@NL@%
  8671. %@NL@%
  8672. When the two %@AB@%int%@AE@% values are compared, the result is false (0xffff does not
  8673. equal 0x00ff). One solution is to explicitly cast %@AS@% CHARVAL %@AE@% to the desired
  8674. type:  %@NL@%
  8675. %@NL@%
  8676. %@AS@%  #define CHARVAL (unsigned char)'\xff'%@AE@%%@NL@%
  8677. %@NL@%
  8678. Now the compiler compares two %@AB@%unsigned char%@AE@% values, giving the desired
  8679. result. Another solution is to make %@AS@% CHARVAL %@AE@% an %@AB@%int%@AE@% instead of a %@AB@%char%@AE@%
  8680. constant:  %@NL@%
  8681. %@NL@%
  8682. %@AS@%  #define CHARVAL 0xff%@AE@%%@NL@%
  8683. %@NL@%
  8684. Both solutions give the desired result, although the second is slightly less
  8685. efficient. It creates word-size, rather than byte-size, machine-code
  8686. instructions.  %@NL@%
  8687. %@NL@%
  8688. %@NL@%
  8689. %@NL@%
  8690. %@NL@%
  8691. %@NL@%
  8692. %@NL@%
  8693. %@CR:C6A-Part 02 @%%@1@%%@AB@%PART II  Using C%@AE@%%@EH@%%@NL@%
  8694. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8695. %@NL@%
  8696. Part 2 of %@AI@%C for Yourself%@AE@%  is called "Using C" and should be read after you
  8697. are familiar with basic C concepts. It covers practical topics that make it
  8698. possible for you to write real programs. The features discussed in these
  8699. chapters are provided in the QuickC run-time library, which, as you may
  8700. recall from Part 1, is not part of the C language itself.  %@NL@%
  8701. %@NL@%
  8702. While Part 1 was designed to be read sequentially, Part 2 is topical. So you
  8703. don't need to read its chapters in any particular order. If you are new to
  8704. C, however, it is recommended that you begin with Chapter 11, "Input and
  8705. Output," which describes how to read and write data, and process files.
  8706. Similarly, if you're not familiar with QuickC graphics, you should read
  8707. Chapters 13-15 in order.  %@NL@%
  8708. %@NL@%
  8709. %@NL@%
  8710. %@NL@%
  8711. %@NL@%
  8712. %@NL@%
  8713. %@NL@%
  8714. %@CR:C6A00110001 @%%@1@%%@AB@%Chapter 11  Input and Output%@AE@%%@EH@%%@NL@%
  8715. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8716. %@NL@%
  8717. The first part of this book explored the fundamentals of the C language. In
  8718. the second part (starting with this chapter), the topics include more
  8719. complex and powerful functions: accessing disk files, creating
  8720. high-resolution graphics, creating graphs, manipulating fonts, and adding
  8721. assembly-language routines to your C programs.  %@NL@%
  8722. %@NL@%
  8723. Program examples in previous chapters used %@AB@%printf%@AE@% to print to the screen. In
  8724. this chapter, we'll cover %@AB@%printf%@AE@% in more detail, moving on to other I/O
  8725. functions such as %@AB@%fprintf%@AE@%, which prints to a file, instead of to the screen.
  8726. %@NL@%
  8727. %@NL@%
  8728. This chapter covers three broad topics: keyboard and screen input/output
  8729. (I/O), reading and writing standard disk files, and low-level disk access.
  8730. It also introduces several common string-handling functions.  %@NL@%
  8731. %@NL@%
  8732. %@NL@%
  8733. %@2@%%@CR:C6A00110002 @%%@AB@%Input and Output Streams%@AE@%%@EH@%%@NL@%
  8734. %@NL@%
  8735. Books about C often refer to "input streams" and "output streams." A stream
  8736. is a sequence of bytes flowing into the program (input) or flowing out
  8737. (output). The data might have originally come from the keyboard, a modem, a
  8738. disk file, or some other peripheral device. The outgoing data might be sent
  8739. out to the screen, a modem, or a disk file.  %@NL@%
  8740. %@NL@%
  8741. Thus, when you see a phrase such as "opening a stream," it means opening a
  8742. line of communication to the disk drive or to some other peripheral.  %@NL@%
  8743. %@NL@%
  8744. %@AU@% Peripherals and files are called "streams" in C.%@AE@%  %@NL@%
  8745. %@NL@%
  8746. The five streams always open and available for input or output are shown in
  8747. Table 11.1.  %@NL@%
  8748. %@NL@%
  8749. %@AB@%Table 11.1  %@AB@%Standard I/O Streams%@AE@%%@AE@%
  8750.  
  8751. %@TH:   8   537 02 16 60 @%
  8752. Name            Stream
  8753. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8754. %@AB@%stdin%@AE@%           Standard input (keyboard)
  8755. %@AB@%stdout%@AE@%          Standard output (screen)
  8756. %@AB@%stderr%@AE@%          Standard error channel (screen)
  8757. %@AB@%stdprn%@AE@%          Standard printer (parallel port)
  8758. %@AB@%stdaux%@AE@%          Standard auxiliary device (serial port)
  8759. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8760. %@TE:   8   537 02 16 60 @%
  8761.  
  8762. %@NL@%
  8763. %@2@%%@CR:C6A00110003 @%%@AB@%Screen and Keyboard I/O%@AE@%%@EH@%%@NL@%
  8764. %@NL@%
  8765. Imagine an application program that doesn't ever send output to the screen
  8766. or accept input from the keyboard. It's possible to write such a program,
  8767. but it's unlikely you'd ever want to.  %@NL@%
  8768. %@NL@%
  8769. In most situations, you need to display various kinds of data on the screen
  8770. and to accept input from the keyboard. "Manipulating and Printing Strings"
  8771. introduces the functions commonly used to communicate back and forth.  %@NL@%
  8772. %@NL@%
  8773. %@NL@%
  8774. %@3@%%@CR:C6A00110004 @%%@AB@%Manipulating and Printing Strings%@AE@%%@EH@%%@NL@%
  8775. %@NL@%
  8776. %@AU@%  Always pass at least one  string to the printf function.%@AE@%  %@NL@%
  8777. %@NL@%
  8778. Previous chapters have used the %@AB@%printf%@AE@% function to display results on the
  8779. screen. By now you should be accustomed to how it works. There's one rule
  8780. you must always follow when using %@AB@%printf%@AE@%: pass it at least one format
  8781. string, which may be a literal string or a pointer to a string. The string
  8782. may or may not include format specifiers, which are defined below.  %@NL@%
  8783. %@NL@%
  8784. The %@AB@%printf%@AE@% function always prints to the %@AB@%stdout%@AE@% device. Unless the output
  8785. has been redirected, the standard output device is the screen.  %@NL@%
  8786. %@NL@%
  8787. The following program illustrates some typical ways to manipulate strings
  8788. and to print them:  %@NL@%
  8789. %@NL@%
  8790. %@AS@%  /* PRTSTR.C: Print strings. */
  8791. %@AS@%  
  8792. %@AS@%  #include <stdio.h>
  8793. %@AS@%  #include <string.h>
  8794. %@AS@%  
  8795. %@AS@%  main()
  8796. %@AS@%  {
  8797. %@AS@%     char aline[80], more[80];
  8798. %@AS@%     char *strptr;
  8799. %@AS@%  
  8800. %@AS@%     /* aline = "Another line."; */
  8801. %@AS@%     /* Note: This causes a compiler error */
  8802. %@AS@%  
  8803. %@AS@%     strcpy( aline, "Another line." );
  8804. %@AS@%     strcpy( more, aline );
  8805. %@AS@%     strptr = aline;
  8806. %@AS@%     strcat( aline, "dog" );
  8807. %@AS@%     printf( "A line of text." );
  8808. %@AS@%     printf( aline );
  8809. %@AS@%     printf( more );
  8810. %@AS@%     printf( strptr );
  8811. %@AS@%  }%@AE@%%@NL@%
  8812. %@NL@%
  8813. The declarations come first:  %@NL@%
  8814. %@NL@%
  8815. %@AS@%  char aline[80], more[80];
  8816. %@AS@%  char *strptr;%@AE@%%@NL@%
  8817. %@NL@%
  8818. The variables %@AS@% aline %@AE@% and %@AS@% more %@AE@% are arrays of characters. In this program,
  8819. they act as strings. Although these arrays have 80 characters each (numbered
  8820. 0-79), the maximum string length is 79 characters, because strings must end
  8821. with a null character. The variable %@AS@% strptr %@AE@% is a pointer to a string.  %@NL@%
  8822. %@NL@%
  8823. If you've previously programmed in BASIC, you might expect to use the equal
  8824. sign to assign a value to a string variable. The program won't compile if
  8825. you remove the comment symbols from the following line:  %@NL@%
  8826. %@NL@%
  8827. %@AS@%  /* aline = "Another line."; */%@AE@%%@NL@%
  8828. %@NL@%
  8829. Faced with this line, QuickC prints the error message:  %@NL@%
  8830. %@NL@%
  8831. %@AS@%  2106: '=' : Left operand must be lvalue%@AE@%%@NL@%
  8832. %@NL@%
  8833. (an "lvalue" is a value allowed on the left side of an equal sign).  %@NL@%
  8834. %@NL@%
  8835. %@AU@% Use the strcpy function─ not the equal sign─ to copy a string.%@AE@%  %@NL@%
  8836. %@NL@%
  8837. You can use the equal sign to assign a value to a numeric variable. When
  8838. you're using strings, however, you almost always use the library function
  8839. %@AB@%strcpy%@AE@%, which copies a string to a character array from either a string
  8840. constant or another array:  %@NL@%
  8841. %@NL@%
  8842. %@AS@%  strcpy( aline, "Another line." );
  8843. %@AS@%  strcpy( more, aline );%@AE@%%@NL@%
  8844. %@NL@%
  8845. The %@AB@%strcpy%@AE@% function makes an exact copy of a string. The first argument is
  8846. the address of the destination string. The second is the address of the
  8847. source string. The first %@AB@%strcpy%@AE@% above copies %@AS@%" Another line." %@AE@% to the %@AS@% aline
  8848. %@AS@%%@AE@% string. The second copies %@AS@% aline %@AE@% to %@AS@% more%@AE@%.  %@NL@%
  8849. %@NL@%
  8850. Note that the first argument must be the address of an array, but the second
  8851. is either a string constant (enclosed in quotation marks) or the address of
  8852. a character array.  %@NL@%
  8853. %@NL@%
  8854. The 80-character arrays have more than enough room for the 13 characters of
  8855. %@AS@%"Another line." %@AE@% and a null character. In your own programs, you should be
  8856. aware of the declared size of an array and avoid overrunning the bounds of
  8857. the array. See Chapter 10, "Programming Pitfalls," for more information
  8858. about this programming mistake.  %@NL@%
  8859. %@NL@%
  8860. It is possible to assign the address of a string to a pointer:  %@NL@%
  8861. %@NL@%
  8862. %@AS@%  strptr = aline;%@AE@%%@NL@%
  8863. %@NL@%
  8864. Notice that both %@AS@% strptr %@AE@% and %@AS@% aline %@AE@% point to the same string. There's one
  8865. object in memory, but it has two different names. If %@AS@% aline %@AE@% changes, the
  8866. same change occurs in the string referenced by %@AS@% strptr%@AE@%, because they're the
  8867. same string. Below, the word %@AS@%"dog" %@AE@% is added to the end of the string %@AS@%
  8868. %@AS@%aline%@AE@%:  %@NL@%
  8869. %@NL@%
  8870. %@AS@%  strcat( aline, "dog" );%@AE@%%@NL@%
  8871. %@NL@%
  8872. The %@AB@%strcat%@AE@% function concatenates one string to the end of a second string.
  8873. In the line above, both %@AS@% aline %@AE@% and the string referenced by %@AS@% strptr %@AE@% have
  8874. been changed from %@AS@% "Another line." %@AE@% to %@AS@% "Another line.dog".%@AE@%  %@NL@%
  8875. %@NL@%
  8876. Now four %@AB@%printf%@AE@% statements execute:  %@NL@%
  8877. %@NL@%
  8878. %@AS@%  printf( "A line of text." );
  8879. %@AS@%  printf( aline );
  8880. %@AS@%  printf( more );
  8881. %@AS@%  printf( strptr );%@AE@%%@NL@%
  8882. %@NL@%
  8883. The screen should look like this:  %@NL@%
  8884. %@NL@%
  8885. %@AS@%  A line of text.Another line.dogAnother line.Another line.dog%@AE@%%@NL@%
  8886. %@NL@%
  8887. To the first %@AB@%printf%@AE@% we passed a string constant. To the other three we
  8888. passed names of strings. Concatenating %@AS@% aline %@AE@% and %@AS@% "dog" %@AE@% also affected the
  8889. string referenced by %@AS@% strptr%@AE@%, because they both point to the same string in
  8890. memory. The contents of %@AS@% more %@AE@% weren't affected, however, because the %@AB@%strcpy%@AE@%
  8891. function makes a complete and unique copy of the source string at the memory
  8892. location referenced by %@AS@% more%@AE@%.  %@NL@%
  8893. %@NL@%
  8894. Unfortunately, the strings ran together. As we saw in Chapter 1, "Anatomy of
  8895. a C Program," %@AB@%printf%@AE@% is unlike QuickBASIC's %@AB@%PRINT%@AE@% command or Pascal's %@AB@%
  8896. %@AB@%Writeln%@AE@% procedure in one respect: it does not automatically move the cursor
  8897. to the beginning of the next line. You need to include the newline character
  8898. (%@AB@%\n%@AE@%), which is one of a series of available escape codes discussed in
  8899. Chapter 4, "Data Types." The program below includes a few examples of escape
  8900. codes, each of which begins with the backslash character:  %@NL@%
  8901. %@NL@%
  8902. %@AS@%  /* PRTESC.C: Print escape characters \",\n, and \t. */
  8903. %@AS@%  
  8904. %@AS@%  #include <stdio.h>
  8905. %@AS@%  #include <string.h>
  8906. %@AS@%  
  8907. %@AS@%  main()
  8908. %@AS@%  {
  8909. %@AS@%     char b[80];
  8910. %@AS@%     int i,j;
  8911. %@AS@%  
  8912. %@AS@%     strcpy( b, "and seven years ago\n" );
  8913. %@AS@%     printf( "\"Four score\n" );
  8914. %@AS@%     printf( b );
  8915. %@AS@%     printf( "\tone tab\n\t\ttwo tabs\n\t\t\tthree tabs\n" );
  8916. %@AS@%     i = sizeof( b );
  8917. %@AS@%     j = strlen( b );
  8918. %@AS@%     printf( "Size is %d\nLength is %d.\n", i, j );
  8919. %@AS@%  }%@AE@%%@NL@%
  8920. %@NL@%
  8921. If you compile and run the PRTESC.C program, the following text prints on
  8922. the screen:  %@NL@%
  8923. %@NL@%
  8924. %@AS@%  "Four score
  8925. %@AS@%  and seven years ago
  8926. %@AS@%   one tab
  8927. %@AS@%    two tabs
  8928. %@AS@%     three tabs
  8929. %@AS@%  Size is 80
  8930. %@AS@%  Length is 20.%@AE@%%@NL@%
  8931. %@NL@%
  8932. To print a newline character in a string, type a backslash and the letter n
  8933. (%@AB@%\n%@AE@%). For a quotation mark, use %@AB@%\"%@AE@%. For tabs, use %@AB@%\t%@AE@%. Escape sequences can
  8934. appear anywhere within a string:  %@NL@%
  8935. %@NL@%
  8936. %@AS@%  printf( "\tone tab\n\t\ttwo tabs\n\t\t\tthree tabs\n" );%@AE@%%@NL@%
  8937. %@NL@%
  8938. You'll find complete lists of escape characters in Appendix A, "C Language
  8939. Guide," and in online help.  %@NL@%
  8940. %@NL@%
  8941. %@NL@%
  8942. %@4@%%@AB@%Finding the Size%@AE@%%@EH@%%@NL@%
  8943. %@NL@%
  8944. The last call to %@AB@%printf%@AE@% in PRTESC.C provides two pieces of information: the
  8945. size of the character array and the length of the string inside the array.  %@NL@%
  8946. %@NL@%
  8947. The variable %@AS@% b %@AE@% was declared to be an 80-character array, but the string
  8948. inside %@AS@%b %@AE@% contains only 20 characters; it holds 19 letters plus one newline
  8949. character. Although typing %@AB@%\n%@AE@% takes two characters, it's stored in memory as
  8950. one character─ the ASCII value 10. As we'll see later in this chapter, the
  8951. newline character is sometimes expanded to two characters (a carriage return
  8952. and a linefeed) when it is written to disk. But while it's in memory, it's a
  8953. single character.  %@NL@%
  8954. %@NL@%
  8955. %@AU@% The sizeof operator examines array size; the %@AE@%%@AB@%strlen%@AE@% function returns the
  8956. length of a string.  %@NL@%
  8957. %@NL@%
  8958. There are two methods available to find the size of arrays and strings. The
  8959. %@AB@%sizeof %@AE@%operator returns the size (in bytes) of an identifier or type. The
  8960. string-handling function %@AB@%strlen%@AE@% counts the number of characters in a string,
  8961. up to but not including the null that marks the end of the string:  %@NL@%
  8962. %@NL@%
  8963. %@AS@%  i = sizeof( b );
  8964. %@AS@%  j = strlen( b );
  8965. %@AS@%  printf( "Size is %d\nLength is %d.\n", i, j );%@AE@%%@NL@%
  8966. %@NL@%
  8967. The final line of the program PRTESC.C prints out two integer values, which
  8968. follow the format string. When %@AB@%printf%@AE@% evaluates the format string, it
  8969. substitutes the two values for the %@AB@%%d%@AE@% specifiers:  %@NL@%
  8970. %@NL@%
  8971. %@AS@%  Size is 80
  8972. %@AS@%  Length is 20%@AE@%%@NL@%
  8973. %@NL@%
  8974. The %@AB@%sizeof%@AE@% operator is part of the C language. In this example, it evaluates
  8975. to the value 80, which is the size of the array. The %@AB@%strlen%@AE@% function is a
  8976. library function for measuring strings (up to, but not including the null at
  8977. the end). It returns a 20 because that's the length of the string.  %@NL@%
  8978. %@NL@%
  8979. %@NL@%
  8980. %@3@%%@CR:C6A00110005 @%%@AB@%Printing Numeric Values%@AE@%%@EH@%%@NL@%
  8981. %@NL@%
  8982. %@AU@% The printf format string  may hold one or more  format specifiers.%@AE@%  %@NL@%
  8983. %@NL@%
  8984. We've seen how %@AB@%printf%@AE@% requires at least one string (or a pointer to a
  8985. string). To print variables and values, place a comma and the name of the
  8986. variable or value after the format string. Then, within the format string,
  8987. include a format specification. See Table 11.2.  %@NL@%
  8988. %@NL@%
  8989. %@AB@%Table 11.2  %@AB@%Common Format Specifications%@AE@%%@AE@%
  8990.  
  8991. %@TH:  10   675 02 22 54 @%
  8992. Specification         Format
  8993. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  8994. %@AB@%%c%@AE@%                    Print a character
  8995. %@AB@%%d%@AE@%                    Print a decimal integer
  8996. %@AB@%%f%@AE@%                    Print a floating-point number
  8997. %@AB@%%i%@AE@%                    Print a decimal integer (same as %@AB@%%d%@AE@%)
  8998. %@AB@%%s%@AE@%                    Print a string
  8999. %@AB@%%u%@AE@%                    Print an unsigned integer
  9000. %@AB@%%x%@AE@%                    Print in hexadecimal format
  9001. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9002. %@TE:  10   675 02 22 54 @%
  9003.  
  9004. The percent sign (%@AB@%%%@AE@%) always marks the beginning of a format specification.
  9005. The letters %@AB@%c%@AE@%, %@AB@%d%@AE@%, %@AB@%f%@AE@%, %@AB@%i%@AE@%, %@AB@%s%@AE@%, %@AB@%u%@AE@%, and %@AB@%x%@AE@% are called the "type." Between the
  9006. percent sign and the type, you may include optional specifications for
  9007. flags, width, or precision values.  %@NL@%
  9008. %@NL@%
  9009. At the very least, you must include the type, as in the program below:  %@NL@%
  9010. %@NL@%
  9011. %@AS@%  /* NFORMAT.C: Print numbers and a string. */
  9012. %@AS@%  
  9013. %@AS@%  #include <stdio.h>
  9014. %@AS@%  #include <string.h>
  9015. %@AS@%  
  9016. %@AS@%  main()
  9017. %@AS@%  {
  9018. %@AS@%     int    a = -765,
  9019. %@AS@%            b = 1,
  9020. %@AS@%            c = 44000,
  9021. %@AS@%            d = 33;
  9022. %@AS@%     float  e = 1.33E8,
  9023. %@AS@%            f = -0.1234567,
  9024. %@AS@%            g = 12345.6789,
  9025. %@AS@%            h = 1.0;
  9026. %@AS@%     char   i[80];
  9027. %@AS@%  
  9028. %@AS@%     strcpy( i, "word 1, word 2, word 3, word 4, word 5" );
  9029. %@AS@%  
  9030. %@AS@%     printf( "Unformatted:\n%d %d %d %d\n", a, b, c, d );
  9031. %@AS@%     printf( "%f %f %f %f\n", e, f, g, h );
  9032. %@AS@%     printf( "%s\n", i );
  9033. %@AS@%  }%@AE@%%@NL@%
  9034. %@NL@%
  9035. The output looks like this:  %@NL@%
  9036. %@NL@%
  9037. %@AS@%  Unformatted:
  9038. %@AS@%  -765 1 -21536 33
  9039. %@AS@%  133000000.000000 -0.123457 12345.678711 1.000000
  9040. %@AS@%  word 1, word 2, word 3, word 4, word 5%@AE@%%@NL@%
  9041. %@NL@%
  9042. If you carefully compare NFORMAT.C with its output, you'll notice some
  9043. unexpected results. For example, the variable %@AS@% c%@AE@%, which was initialized to
  9044. 44000, has somehow changed to -21536.  %@NL@%
  9045. %@NL@%
  9046. The %@AB@%%d%@AE@% format specification applies to signed integers in the range -32768
  9047. to +32767. The value of %@AS@% c %@AE@% (44000) is outside that range, but still within
  9048. the realm of unsigned integers, which can hold values up to +65535. The
  9049. proper format specification would be %@AB@%%u%@AE@% (where %@AS@% u %@AE@% represents the unsigned
  9050. type).  %@NL@%
  9051. %@NL@%
  9052. Two of the floating-point values have changed, too. The %@AB@%%f%@AE@% specification
  9053. defaults to 6 digits of precision to the right of the decimal point. The
  9054. value of %@AS@% f %@AE@% (.1234567) is therefore rounded off to a precision of 6 digits:
  9055. .123457. Also, the limitations of floating-point accuracy transform the
  9056. value of %@AS@% g %@AE@% from 12345.6789 to 12345.678711. If you modify the program,
  9057. changing the %@AS@% float %@AE@% declarations to %@AS@% double%@AE@%, the second problem disappears.
  9058. The variable %@AS@% g %@AE@% prints correctly as 12345.67.  %@NL@%
  9059. %@NL@%
  9060. Between the%@AB@%%%@AE@% and the type character, you may include two numbers separated
  9061. by a period. The first number is called the "width;" the second is the
  9062. "precision." The width and precision affect integers, floating-point
  9063. numbers, and strings in different ways. For example, we could specify a
  9064. width of 2 and precision of 3 for each of the above variables:  %@NL@%
  9065. %@NL@%
  9066. %@AS@%  printf( "\nWidth 2, Precision 3:\n" );
  9067. %@AS@%  printf( "%2.3d %2.3d %2.3u %2.3d\n", a, b, c, d );
  9068. %@AS@%  printf( "%2.3f %2.3f %2.3f %2.3f\n", e, f, g, h );
  9069. %@AS@%  printf( "%2.3s\n", i );%@AE@%%@NL@%
  9070. %@NL@%
  9071. (Note that the variable %@AS@% c %@AE@% has a format specifier of %@AS@% %2.3u %@AE@% instead of %@AS@%
  9072. %@AS@%%2.3d%@AE@%.) The screen displays the following lines:  %@NL@%
  9073. %@NL@%
  9074. %@AS@%  Width 2, Precision 3:
  9075. %@AS@%  -765 001 44000 033
  9076. %@AS@%  133000000.000 -0.123 12345.679 1.000
  9077. %@AS@%  wor%@AE@%%@NL@%
  9078. %@NL@%
  9079. For integers, the precision of 3 causes at least 3 digits to print, preceded
  9080. by leading zeros. For floating-point numbers, the precision of 3 truncates
  9081. fractions to 3 digits to the right of the decimal point. For strings, the
  9082. precision of 3 causes only 3 characters to print. The string output is
  9083. truncated to the right. Numbers are never truncated, however.  %@NL@%
  9084. %@NL@%
  9085. We can change the width to 8 and the precision to 1:  %@NL@%
  9086. %@NL@%
  9087. %@AS@%  printf( "\nWidth 8, Precision 1:\n" );
  9088. %@AS@%  printf( "%8.1d %8.1d %8.1u %8.1d\n", a, b, c, d );
  9089. %@AS@%  printf( "%8.1e %8.1f %8.1f %8.1f\n", e, f, g, h );
  9090. %@AS@%  printf( "%8.1s\n", i );%@AE@%%@NL@%
  9091. %@NL@%
  9092. We made an additional modification by printing the variable %@AS@% e %@AE@% as an %@AB@%%e%@AE@%
  9093. type instead of an %@AB@%%f%@AE@% type. This prints the value of %@AS@% e %@AE@% (1.33E8) in
  9094. exponential format:  %@NL@%
  9095. %@NL@%
  9096. %@AS@%  Width 8, Precision 1:
  9097. %@AS@%      -765        1    44000       33
  9098. %@AS@%  1.3e+008     -0.1  12345.7      1.0
  9099. %@AS@%         w%@AE@%%@NL@%
  9100. %@NL@%
  9101. The width controls the printing area: all 3 variable types are printed in
  9102. fields 8 characters wide. The precision of 1 affects different data types in
  9103. different ways: the integers print at least 1 digit; the floating-point
  9104. numbers print only the first number to the right of the decimal point; and
  9105. the string prints as the first character only. Each value prints flush right
  9106. in its field.  %@NL@%
  9107. %@NL@%
  9108. Between the %@AB@%%%@AE@% and the width, you may also insert a flag. The plus flag (%@AB@%+%@AE@%),
  9109. for example, forces numbers to print with a leading sign:  %@NL@%
  9110. %@NL@%
  9111. %@AS@%  printf( "\nForced signs, Width 10, Precision 2:\n" );
  9112. %@AS@%  printf( "%+10.2d %+10.2d %+10.2u %+10.2d\n", a, b, c, d );
  9113. %@AS@%  printf( "%+10.2e %+10.2f %+10.2f %+10.2f\n", e, f, g, h );
  9114. %@AS@%  printf( "%+10.2s\n", i );%@AE@%%@NL@%
  9115. %@NL@%
  9116. Note that the plus flag has no effect on strings or on unsigned integers:  %@NL@%
  9117. %@NL@%
  9118. %@AS@%  Forced signs, Width 10, Precision 2:
  9119. %@AS@%        -765        +01      44000        +33
  9120. %@AS@%  +1.33e+008      -0.12  +12345.68      +1.00
  9121. %@AS@%          wo%@AE@%%@NL@%
  9122. %@NL@%
  9123. Another flag is the number 0, which forces leading zeros to print within the
  9124. limits of the width. If you only specify the width, the system default is
  9125. used for the precision. You can use the type %@AB@%%x%@AE@% to represent hexadecimal; it
  9126. displays the letters a-f in lowercase. If you prefer uppercase, you can use
  9127. %@AB@%%X%@AE@% instead.  %@NL@%
  9128. %@NL@%
  9129. %@AS@%  printf( "\nHexadecimal, Forced Zeros, Width 6:\n" );
  9130. %@AS@%  printf( "%06x %06x %06x %06x\n", a, b, c, d );%@AE@%%@NL@%
  9131. %@NL@%
  9132. The %@AB@%printf%@AE@% statements above display these lines:  %@NL@%
  9133. %@NL@%
  9134. %@AS@%  Hexadecimal, Forced Zeros, Width 6:
  9135. %@AS@%  00fd03 000001 00abe0 000021%@AE@%%@NL@%
  9136. %@NL@%
  9137. For strings, the width and precision specifiers describe the field width and
  9138. the number of characters printed. Note the minus sign in the final line,
  9139. which forces the truncated string to print from the left:  %@NL@%
  9140. %@NL@%
  9141. %@AS@%  printf( "\nWidth 40, Precision 10:\n" );
  9142. %@AS@%  printf( "%40.10s\n", i );
  9143. %@AS@%  
  9144. %@AS@%  printf( "\nWidth 40, Precision 20:\n" );
  9145. %@AS@%  printf( "%40.20s\n", i );
  9146. %@AS@%  
  9147. %@AS@%  printf( "\nFlush left, Width 40, Precision 20:\n" );
  9148. %@AS@%  printf( "%-40.20s\n", i );%@AE@%%@NL@%
  9149. %@NL@%
  9150. The lines are displayed on the screen as follows:  %@NL@%
  9151. %@NL@%
  9152. %@AS@%  Width 40, Precision 10:
  9153. %@AS@%                                word 1, wo
  9154. %@AS@%  
  9155. %@AS@%  Width 40, Precision 20:
  9156. %@AS@%                      word 1, word 2, word
  9157. %@AS@%  
  9158. %@AS@%  Flush left, Width 40, Precision 20:
  9159. %@AS@%  word 1, word 2, word                    %@AE@%%@NL@%
  9160. %@NL@%
  9161. %@NL@%
  9162. %@3@%%@CR:C6A00110006 @%%@AB@%Using scanf for Keyboard Input%@AE@%%@EH@%%@NL@%
  9163. %@NL@%
  9164. %@AU@%   Pass a variable address to scanf, not a variable value.%@AE@%  %@NL@%
  9165. %@NL@%
  9166. While %@AB@%printf%@AE@% is the most widely used output function, %@AB@%scanf %@AE@%is the most
  9167. popular for input. The arguments and format strings passed to%@AB@% scanf%@AE@% resemble
  9168. the arguments for %@AB@%printf%@AE@%, except for one requirement: the %@AB@%scanf%@AE@% function
  9169. always takes pointers. You never pass a variable value to %@AB@%scanf%@AE@%, you always
  9170. pass the variable address so that %@AB@%scanf%@AE@% can store data in the memory
  9171. location that contains the input variable.  %@NL@%
  9172. %@NL@%
  9173. The first argument for %@AB@%scanf%@AE@% is always a format string. Additional arguments
  9174. include the addresses of variables to which values will be assigned.  %@NL@%
  9175. %@NL@%
  9176. The program below demonstrates several ways to use %@AB@%scanf%@AE@% and various other
  9177. I/O functions:  %@NL@%
  9178. %@NL@%
  9179. %@AS@%  /* INPUT.C: Read keyboard. */
  9180. %@AS@%  
  9181. %@AS@%  #include <stdio.h>
  9182. %@AS@%  #include <conio.h>
  9183. %@AS@%  #include <ctype.h>%@AE@%%@NL@%
  9184. %@NL@%
  9185. %@AS@%  main()
  9186. %@AS@%  {
  9187. %@AS@%     int num;
  9188. %@AS@%     char c;
  9189. %@AS@%     char name[80];
  9190. %@AS@%     float rb;
  9191. %@AS@%  
  9192. %@AS@%     puts( "** Type \"Name:\" and your name" );
  9193. %@AS@%     scanf( "Name: %40s", name );
  9194. %@AS@%     printf( "** You typed this:\n%s", name );
  9195. %@AS@%     puts( "\n\n** Try again, with the gets function." );
  9196. %@AS@%     fflush( stdin );
  9197. %@AS@%     gets( name );
  9198. %@AS@%     printf( "** You typed this:\n%s\n", name );
  9199. %@AS@%  
  9200. %@AS@%     printf( "\n** Now type an integer.\n" );
  9201. %@AS@%     scanf( "%i", &num );
  9202. %@AS@%     sprintf( name, "** You typed this number: %i\n", num );
  9203. %@AS@%     puts( name );
  9204. %@AS@%  
  9205. %@AS@%     fflush( stdin );
  9206. %@AS@%     printf( "** Enter a floating-point value.\n" );
  9207. %@AS@%     scanf( "%f", &rb );
  9208. %@AS@%     printf( "** The answer is %f or %e\n", rb, rb );
  9209. %@AS@%  
  9210. %@AS@%     printf( "** Continue? Y or N\n" );
  9211. %@AS@%     do
  9212. %@AS@%     {
  9213. %@AS@%        c = getch();
  9214. %@AS@%        c = tolower( c );
  9215. %@AS@%     } while( c != 'y' && c != 'n' );
  9216. %@AS@%  }%@AE@%%@NL@%
  9217. %@NL@%
  9218. First, the %@AB@%puts%@AE@% function prints a string that requests input from the user.
  9219. Then %@AB@%scanf%@AE@% reads the input:  %@NL@%
  9220. %@NL@%
  9221. %@AS@%  puts( "** Type \"Name:\" and your name" );
  9222. %@AS@%  scanf( "Name: %40s", name );%@AE@%%@NL@%
  9223. %@NL@%
  9224. Unfortunately, the use of %@AB@%scanf%@AE@% for string input creates some difficulties.
  9225. For one thing, you're forced to type %@AS@% Name: %@AE@% before typing the rest of the
  9226. string. (If you don't type %@AS@% Name:%@AE@%, %@AB@%scanf%@AE@% won't put a value into the %@AS@% name %@AE@%
  9227. variable.)  %@NL@%
  9228. %@NL@%
  9229. A second problem is that %@AB@%scanf%@AE@% reads the input stream until it finds a
  9230. white-space character: a SPACE, TAB, or ENTER.  %@NL@%
  9231. %@NL@%
  9232. The prompt below appears on the screen:  %@NL@%
  9233. %@NL@%
  9234. %@AS@%  ** Type "Name:" and your name%@AE@%%@NL@%
  9235. %@NL@%
  9236. You might type this (you must begin the line with %@AS@%"Name:" %@AE@%):  %@NL@%
  9237. %@NL@%
  9238. %@AS@%  Name: F. Scott Fitzgerald%@AE@%%@NL@%
  9239. %@NL@%
  9240. The next line takes effect:  %@NL@%
  9241. %@NL@%
  9242. %@AS@%  printf( "** You typed this:\n%s", name );%@AE@%%@NL@%
  9243. %@NL@%
  9244. Which prints the following line:  %@NL@%
  9245. %@NL@%
  9246. %@AS@%  ** You typed this:
  9247. %@AS@%  F.%@AE@%%@NL@%
  9248. %@NL@%
  9249. The string passed to the %@AB@%scanf%@AE@% function told it to expect %@AS@% "Name:" %@AE@% and then
  9250. to read a string, storing it in the %@AS@% name %@AE@% variable.  %@NL@%
  9251. %@NL@%
  9252. Since the %@AB@%scanf%@AE@% function reads strings until it finds a white-space
  9253. character, the value of %@AS@% name %@AE@% is " %@AS@% F%@AE@%." In addition, the words %@AS@% Scott
  9254. %@AS@%Fitzgerald %@AE@% are waiting in the input stream. To clear any stream, use the
  9255. %@AB@%fflush%@AE@% function:  %@NL@%
  9256. %@NL@%
  9257. %@AS@%  puts( "\n\n** Now try it again, with the gets function." );
  9258. %@AS@%  fflush( stdin );
  9259. %@AS@%  gets( name );%@AE@%%@NL@%
  9260. %@NL@%
  9261. To clear the buffer associated with a stream (including disk files), call
  9262. %@AB@%fflush%@AE@%, passing the pointer to the file or stream. In the example above, %@AS@%
  9263. %@AS@%stdin %@AE@% is the standard input device, the keyboard.  %@NL@%
  9264. %@NL@%
  9265. The %@AB@%puts%@AE@% function acts like a limited version of %@AB@%printf%@AE@%. It prints a string
  9266. to the standard output device, but can't insert formatted variable values.
  9267. You pass it a string constant or the name of a string. Also, it always adds
  9268. a newline to the end of the string it prints.  %@NL@%
  9269. %@NL@%
  9270. %@AU@% It is usually preferable to  use gets when working  with string input.%@AE@%  %@NL@%
  9271. %@NL@%
  9272. The %@AB@%gets%@AE@% function receives an entire line from the standard input device and
  9273. places the line in an array of characters. It does not include the newline
  9274. character typed by the user. It does, however, add a null to the end of the
  9275. line, to make the series of characters into a string. When you're working
  9276. with string input, %@AB@%gets%@AE@% is generally preferable to %@AB@%scanf%@AE@%.  %@NL@%
  9277. %@NL@%
  9278. For numeric values, %@AB@%scanf%@AE@% is the function of choice:  %@NL@%
  9279. %@NL@%
  9280. %@AS@%  printf( "\n** Now type an integer.\n" );
  9281. %@AS@%  scanf( "%i", &num );
  9282. %@AS@%  sprintf( name, "** You typed the number: %i\n", num );
  9283. %@AS@%  puts( name );%@AE@%%@NL@%
  9284. %@NL@%
  9285. The format string %@AB@%%i%@AE@% forces %@AB@%scanf%@AE@% to treat the input as an integer. The
  9286. second argument is the address of the variable %@AS@% num%@AE@%.  %@NL@%
  9287. %@NL@%
  9288. The letter %@AB@%s%@AE@% in %@AB@%sprintf%@AE@% marks it as a string function. (There is also a
  9289. %@AB@%sscanf%@AE@% function that handles strings, but we won't discuss it here.) Instead
  9290. of printing the format string to the screen, as %@AB@%printf%@AE@% would do, %@AB@%sprintf%@AE@%
  9291. prints the results to another string. Note that %@AB@%scanf%@AE@% requires the address
  9292. of %@AS@% num%@AE@%, but %@AB@%sprintf%@AE@% uses its value.  %@NL@%
  9293. %@NL@%
  9294. The next %@AB@%scanf%@AE@% in program INPUT.C treats the input as a floating-point
  9295. number:  %@NL@%
  9296. %@NL@%
  9297. %@AS@%  scanf( "%f", &rb );
  9298. %@AS@%  printf( "** The answer is %f or %e\n", rb, rb );%@AE@%%@NL@%
  9299. %@NL@%
  9300. If you enter -555.12, the computer responds:  %@NL@%
  9301. %@NL@%
  9302. %@AS@%  ** The answer is -555.119995 or -5.551200e+002%@AE@%%@NL@%
  9303. %@NL@%
  9304. Finally, the program uses %@AB@%getch%@AE@% to receive a character from the input
  9305. stream:  %@NL@%
  9306. %@NL@%
  9307. %@AS@%  printf( "** Continue? Y or N\n" );
  9308. %@AS@%  
  9309. %@AS@%     do
  9310. %@AS@%     {
  9311. %@AS@%        c = getch();
  9312. %@AS@%        c = tolower( c );
  9313. %@AS@%     } while( c != 'y' && c != 'n' );%@AE@%%@NL@%
  9314. %@NL@%
  9315. The %@AB@%getch%@AE@% function returns a character. That value, in turn, is passed to
  9316. %@AB@%tolower%@AE@%, which converts any uppercase characters to lowercase (in case the
  9317. CAPS LOCK key is on). Then, the byte is assigned to the variable %@AS@% c%@AE@%. The %@AB@%do%@AE@%
  9318. loop continues processing characters until you press %@AS@% y %@AE@% or %@AS@% n%@AE@%. The program
  9319. then ends. This simple example ends no matter which key ( %@AS@% y %@AE@% or %@AS@% n %@AE@%) you
  9320. press. A real program would take some action based on the value returned by
  9321. the %@AB@%getch%@AE@% function.  %@NL@%
  9322. %@NL@%
  9323. %@NL@%
  9324. %@2@%%@CR:C6A00110007 @%%@AB@%Standard Disk I/O%@AE@%%@EH@%%@NL@%
  9325. %@NL@%
  9326. If you can read input from the keyboard and write output to the screen,
  9327. you'll find standard disk files relatively easy to manipulate. There are
  9328. three rules to remember:  %@NL@%
  9329. %@NL@%
  9330. %@NL@%
  9331.   1.  You can't do anything with a disk file until you open it. The act of
  9332.       opening a file gives you a %@AB@%FILE%@AE@% pointer through which you can access
  9333.       the file.%@NL@%
  9334. %@NL@%
  9335.   2.  While the file is open, you can use most of the screen and keyboard
  9336.       I/O functions if you precede them with the letter %@AB@%f%@AE@% (%@AB@%fprintf%@AE@% instead
  9337.       of %@AB@%printf%@AE@%, for example). The file-handling functions work the same as
  9338.       their counterparts, but you must add the %@AB@%FILE%@AE@% pointer.%@NL@%
  9339. %@NL@%
  9340.   3.  When you're finished with a file, it's good programming practice to
  9341.       close it. When %@AB@%exit%@AE@% ends the execution of a program, all previously
  9342.       open files are closed (if you'd rather leave them open, use %@AB@%_exit%@AE@%
  9343.       instead of %@AB@%exit%@AE@%).%@NL@%
  9344. %@NL@%
  9345. %@NL@%
  9346. %@NL@%
  9347. %@3@%%@CR:C6A00110008 @%%@AB@%Creating and Writing to a Text File%@AE@%%@EH@%%@NL@%
  9348. %@NL@%
  9349. The WRFILE.C program opens a text file, writes a string to it, and closes
  9350. the file.  %@NL@%
  9351. %@NL@%
  9352. %@AS@%  /* WRFILE.C: Create and write to a disk file. */
  9353. %@AS@%  
  9354. %@AS@%  #include <stdio.h>
  9355. %@AS@%  
  9356. %@AS@%  main()
  9357. %@AS@%  {
  9358. %@AS@%     FILE *fp;
  9359. %@AS@%  
  9360. %@AS@%     if( (fp = fopen( "c:\\testfile.asc","w" )) != NULL )
  9361. %@AS@%     {
  9362. %@AS@%        fputs( "Example string", fp );
  9363. %@AS@%        fputc( '\n', fp );
  9364. %@AS@%        fclose( fp );
  9365. %@AS@%     }
  9366. %@AS@%     else
  9367. %@AS@%        printf( "error message\n" );
  9368. %@AS@%  }%@AE@%%@NL@%
  9369. %@NL@%
  9370. You must include the standard I/O header file (%@AS@% #include <stdio.h> %@AE@%)
  9371. whenever you plan to call input or output functions. It contains essential
  9372. definitions and prototypes that you need.  %@NL@%
  9373. %@NL@%
  9374. The only variable in this program is %@AS@% fp %@AE@% which is declared as a pointer to
  9375. a %@AB@%FILE%@AE@%. %@AB@%FILE%@AE@% is defined in STDIO.H as a structure of %@AB@%_iobuf%@AE@% type, but we
  9376. don't need to know the specifics. We will refer to the variable %@AS@% fp %@AE@% as a
  9377. "%@AB@%FILE%@AE@% pointer."  %@NL@%
  9378. %@NL@%
  9379. The first statement combines several operations in one line:  %@NL@%
  9380. %@NL@%
  9381. %@AS@%  if( (fp = fopen( "c:\\testfile.asc", "w" )) != NULL )%@AE@%%@NL@%
  9382. %@NL@%
  9383. The %@AB@%fopen%@AE@% function opens a file. It expects two parameters, both of which
  9384. are literal strings or pointers to strings. You provide the name of the file
  9385. to be opened and the type (read, write, or append). The six types of files
  9386. are listed in Table 11.3.  %@NL@%
  9387. %@NL@%
  9388. %@AB@%Table 11.3  %@AB@%Disk File Types %@AE@%%@AE@%
  9389.  
  9390. %@TH:  24  1319 02 34 42 @%
  9391. Type                              Action
  9392. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9393. %@AB@%r%@AE@%                                 Open an existing file for reading.
  9394.  
  9395. %@AB@%w%@AE@%                                 Create and open a file for writing. Any 
  9396.                                   existing file is replaced. If the file 
  9397.                                   doesn't exist, a new file is created.
  9398.  
  9399. %@AB@%a%@AE@%                                 Open a file for appending. Data is added
  9400.                                   to the end of an existing file or 
  9401.                                   a new file is created.
  9402.  
  9403. %@AB@%r+%@AE@%                                Open an existing file for reading and 
  9404.                                   writing. %@AS@%%@AE@%
  9405.  
  9406. %@AB@%w+%@AE@%                                Create and open a file for reading and 
  9407.                                   writing. An existing file is replaced.
  9408.  
  9409. %@AB@%a+%@AE@%                                Open a file for reading and appending. 
  9410.                                   Data is added to the end of an 
  9411.                                   existing file or a new file is created.
  9412.  
  9413. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9414.  
  9415. %@TE:  24  1319 02 34 42 @%
  9416.  
  9417. In WRFILE.C, the file called %@AS@% c:\testfile.asc %@AE@% is opened for writing with
  9418. type %@AS@%"w" %@AE@% (a string, not the character %@AS@% 'w' %@AE@% in single quotes). We plan to
  9419. write to it.  %@NL@%
  9420. %@NL@%
  9421. Notice that the file-name string as it appears in the %@AB@%fopen%@AE@% statement
  9422. contains two backslashes: %@AS@%"c:\\testfile.asc"%@AE@%. If you tried to use the string
  9423. %@AS@%"c:\testfile. asc"%@AE@%, which looks correct, the character sequence %@AS@% \t %@AE@% would
  9424. be incorrectly interpreted as a tab character. C automatically converts the
  9425. two backslashes in the string to a single backslash. %@AS@%  %@AE@%%@NL@%
  9426. %@NL@%
  9427. %@NL@%
  9428. %@4@%%@AB@%Getting a FILE Pointer%@AE@%%@EH@%%@NL@%
  9429. %@NL@%
  9430. The %@AB@%fopen%@AE@% function returns the address of a %@AB@%FILE%@AE@%. This value is assigned to %@AS@%
  9431. %@AS@%fp%@AE@%, which is the %@AB@%FILE%@AE@% pointer used in all subsequent file operations.  %@NL@%
  9432. %@NL@%
  9433. If something goes wrong─if the disk is full or not in the drive or
  9434. write-protected or whatever─%@AB@%fopen%@AE@% doesn't return a %@AB@%FILE%@AE@% pointer. When %@AB@%fopen%@AE@%
  9435. fails, it returns a null value.  %@NL@%
  9436. %@NL@%
  9437. What we're looking for is any %@AB@%FILE%@AE@% pointer that's not null:  %@NL@%
  9438. %@NL@%
  9439. %@AS@%  if( (fp = fopen( "c:\\testfile.asc","w" )) != NULL )%@AE@%%@NL@%
  9440. %@NL@%
  9441. %@NL@%
  9442. %@4@%%@AB@%Writing to the File%@AE@%%@EH@%%@NL@%
  9443. %@NL@%
  9444. As we saw earlier, %@AB@%puts%@AE@% displays a string on the screen. Add an %@AB@%f%@AE@% to it and
  9445. the result is %@AB@%fputs%@AE@%, which works similarly. It sends the string to a
  9446. specified stream (a file) instead of to the standard output device:  %@NL@%
  9447. %@NL@%
  9448. %@AS@%  fputs( "Example string", fp );%@AE@%%@NL@%
  9449. %@NL@%
  9450. The function %@AB@%fputs%@AE@% takes two parameters: a pointer to the string and the
  9451. %@AB@%FILE%@AE@% pointer. In this and other I/O functions, you refer to the file by name
  9452. only once (when you use %@AB@%fopen%@AE@%). Thereafter, you use its %@AB@%FILE%@AE@% pointer.  %@NL@%
  9453. %@NL@%
  9454. The %@AB@%fputs%@AE@% function writes the entire string to the file but does not include
  9455. the null that marks the end of the string. Nor does it write a newline
  9456. character─unless the string already contains a newline.  %@NL@%
  9457. %@NL@%
  9458. The %@AB@%fputc%@AE@% function writes a character to a file. In the following line, the
  9459. newline character is sent to the file:  %@NL@%
  9460. %@NL@%
  9461. %@AS@%  fputc( '\n', fp );%@AE@%%@NL@%
  9462. %@NL@%
  9463. %@NL@%
  9464. %@4@%%@AB@%Closing the File%@AE@%%@EH@%%@NL@%
  9465. %@NL@%
  9466. When the writing is done, %@AB@%fclose%@AE@% closes the file:  %@NL@%
  9467. %@NL@%
  9468. %@AS@%  fclose( fp );%@AE@%%@NL@%
  9469. %@NL@%
  9470. Conceptually, you can imagine that file I/O functions such as %@AB@%fputs%@AE@% and
  9471. %@AB@%fputc%@AE@% write directly to the disk file. In reality, they're storing strings
  9472. and characters in an intermediate area (called a "memory buffer"). When the
  9473. buffer fills up, the entire chunk of memory is sent to the file. The process
  9474. of emptying the buffer is called "flushing." You may forcibly flush the
  9475. buffer with the %@AB@%fflush%@AE@% and %@AB@%fclose%@AE@% functions. If you do not close the file
  9476. before exiting the program, the buffer is not flushed and you may lose data
  9477. that might remain there.  %@NL@%
  9478. %@NL@%
  9479. The %@AB@%else%@AE@% clause in WRFILE.C should execute only if something has gone wrong
  9480. with the %@AB@%fopen%@AE@% function:  %@NL@%
  9481. %@NL@%
  9482. %@AS@%  else
  9483. %@AS@%     printf( "error message\n" );%@AE@%%@NL@%
  9484. %@NL@%
  9485. This line executes if an error occurs when %@AB@%fopen%@AE@% tries to create the file.
  9486. Handling errors is covered in more detail later in this chapter.  %@NL@%
  9487. %@NL@%
  9488. %@NL@%
  9489. %@3@%%@CR:C6A00110009 @%%@AB@%Reading a Text File in Binary Mode%@AE@%%@EH@%%@NL@%
  9490. %@NL@%
  9491. The WRFILE.C program that created and wrote to a file was fairly simple.
  9492. Here's an equally simple program to read the file just created:  %@NL@%
  9493. %@NL@%
  9494. %@AS@%  /* RDFILE.C: Read a file and print characters to the screen. */
  9495. %@AS@%  
  9496. %@AS@%  #include <stdio.h>
  9497. %@AS@%  
  9498. %@AS@%  main()
  9499. %@AS@%  {
  9500. %@AS@%     int c;
  9501. %@AS@%     FILE *fp;
  9502. %@AS@%  
  9503. %@AS@%     if( fp = fopen( "c:\\testfile.asc", "rb" ) )
  9504. %@AS@%     {
  9505. %@AS@%        while( (c = fgetc( fp )) != EOF )
  9506. %@AS@%           printf( " %c\t%d\n", c, c );
  9507. %@AS@%        printf( "\nEnd of file marker: %d", c );
  9508. %@AS@%        fclose( fp );
  9509. %@AS@%     }
  9510. %@AS@%     else
  9511. %@AS@%        printf( "Error in opening file\n" );
  9512. %@AS@%  }%@AE@%%@NL@%
  9513. %@NL@%
  9514. Although we plan to read the characters as eight-bit entities, the variable %@AS@%
  9515. %@AS@%c %@AE@% should be declared as an %@AB@%int%@AE@% instead of a %@AB@%char%@AE@%. All of the incoming
  9516. characters will be bytes the size of a %@AB@%char%@AE@%, except one.  %@NL@%
  9517. %@NL@%
  9518. When the file has been read from beginning to end, the end-of-file (%@AB@%EOF%@AE@%)
  9519. marker appears on the stream. Within QuickC, an integer value of -1 (0xFFFF)
  9520. represents %@AB@%EOF%@AE@%. To correctly identify this value, the variable %@AS@% c %@AE@% must be
  9521. an integer.  %@NL@%
  9522. %@NL@%
  9523. %@NL@%
  9524. %@4@%%@AB@%Opening a File for Binary Reading%@AE@%%@EH@%%@NL@%
  9525. %@NL@%
  9526. In the line below, the %@AB@%fopen%@AE@% function attempts to open a file. The first
  9527. argument is the file name; the second is the type and mode, both of which
  9528. may be literal strings or pointers to strings:  %@NL@%
  9529. %@NL@%
  9530. %@AS@%  if( fp = fopen( "c:\\testfile.asc", "rb" ) )%@AE@%%@NL@%
  9531. %@NL@%
  9532. The single backslash character used in path specifications must once again
  9533. be represented by two backslashes. The file type is %@AB@%r%@AE@% for read-only. The
  9534. additional %@AB@%b%@AE@% character forces the file to be read in binary mode instead of
  9535. text mode. The differences between binary and text files are discussed later
  9536. in this chapter.  %@NL@%
  9537. %@NL@%
  9538. The %@AB@%fopen%@AE@% function returns a pointer to a %@AB@%FILE%@AE@%. If %@AB@%fopen%@AE@% fails, it returns a
  9539. %@AB@%NULL%@AE@% pointer.  %@NL@%
  9540. %@NL@%
  9541. Finally, the %@AB@%if%@AE@% expression tests for a null value. The original WRFILE.C
  9542. program included the %@AS@% != NULL %@AE@% test for inequality. Within the test
  9543. expression of an %@AB@%if%@AE@% or a %@AB@%while%@AE@%, a 0 value is always false and any other
  9544. value is considered true. In other words, should %@AS@% fp %@AE@% receive a valid
  9545. nonzero address from %@AB@%fopen%@AE@%, the program continues. If something goes wrong,
  9546. the remaining lines don't execute and the program drops through to the %@AB@%else%@AE@%.
  9547. %@NL@%
  9548. %@NL@%
  9549. Note that the expression above uses an assignment operator (%@AB@%=%@AE@%), not an
  9550. equality operator (%@AB@%==%@AE@%). The value returned by %@AB@%fopen%@AE@% is always assigned to %@AS@%
  9551. %@AS@%fp %@AE@%; they aren't being compared to each other. Then the %@AB@%if%@AE@% expression tests
  9552. that value for truth or falsity.  %@NL@%
  9553. %@NL@%
  9554. %@NL@%
  9555. %@4@%%@AB@%Getting a Character%@AE@%%@EH@%%@NL@%
  9556. %@NL@%
  9557. The key to the next line in RDFILE.C is the %@AB@%fgetc%@AE@% function, to which you
  9558. pass a %@AB@%FILE%@AE@% pointer. It returns the next character from the given file:  %@NL@%
  9559. %@NL@%
  9560. %@AS@%  while( (c = fgetc( fp )) != EOF )%@AE@%%@NL@%
  9561. %@NL@%
  9562. The character is assigned to the integer variable %@AS@% c%@AE@%. As long as the
  9563. character doesn't equal %@AB@%EOF%@AE@%, the %@AB@%while%@AE@% loop continues.  %@NL@%
  9564. %@NL@%
  9565. The end-of-file marker equals -1, but it's preferable to use the symbolic
  9566. constant %@AB@%EOF%@AE@%. If the program is transported to another computer, you might
  9567. find %@AB@%EOF%@AE@% has another value. Using the symbolic constant allows you to
  9568. maintain compatibility between computers and operating systems.  %@NL@%
  9569. %@NL@%
  9570. For the same reason, it's preferable to test for %@AB@%NULL%@AE@% instead of assuming
  9571. that %@AB@%NULL%@AE@% will always equal 0.  %@NL@%
  9572. %@NL@%
  9573. %@NL@%
  9574. %@4@%%@AB@%Viewing the File%@AE@%%@EH@%%@NL@%
  9575. %@NL@%
  9576. Since there's only one line inside the %@AB@%while%@AE@% loop, it's not necessary to
  9577. enclose it in curly braces. The variable %@AS@% c %@AE@% contains the character read
  9578. from the file. It then can be printed:  %@NL@%
  9579. %@NL@%
  9580. %@AS@%  printf( " %c\t%d\n", c, c );%@AE@%%@NL@%
  9581. %@NL@%
  9582. The characters from the file print twice, once as a character (%@AB@%%c%@AE@%) and once
  9583. as a decimal number (%@AB@%%d%@AE@%), separated by a tab stop. This %@AB@%printf%@AE@% statement
  9584. repeats until %@AB@%fgetc%@AE@% (inside the %@AB@%while%@AE@% loop) finds no more characters in the
  9585. file.  %@NL@%
  9586. %@NL@%
  9587. %@NL@%
  9588. %@3@%%@CR:C6A00110010 @%%@AB@%Binary and Text Files%@AE@%%@EH@%%@NL@%
  9589. %@NL@%
  9590. Normally, you wouldn't write a file in text mode and then read it in binary
  9591. mode. As a general rule, you pick whichever mode is more appropriate (text
  9592. mode for text or binary mode for data) and stick with it.  %@NL@%
  9593. %@NL@%
  9594. A somewhat baffling thing happened in the example above, however. The
  9595. WRFILE.C program wrote %@AS@%"Example string" %@AE@% to a disk file and then added a
  9596. newline character. That should be a total of 15 characters. But if you
  9597. examine the directory, you'll see the file uses 16 bytes.  %@NL@%
  9598. %@NL@%
  9599. Where did the extra byte come from?  %@NL@%
  9600. %@NL@%
  9601. %@NL@%
  9602. %@4@%%@AB@%Testing Text Mode%@AE@%%@EH@%%@NL@%
  9603. %@NL@%
  9604. If you ran the RDFILE.C program, you probably noticed two characters
  9605. followed the line: a carriage return (ASCII 13) and a linefeed (ASCII 10).
  9606. If you make the following change to the program, the output of RDFILE.C is
  9607. different:  %@NL@%
  9608. %@NL@%
  9609. %@AS@%  if( (fp = fopen( "c:\\testfile.asc","rt" )) != NULL )%@AE@%%@NL@%
  9610. %@NL@%
  9611. The only modification is that the second string is %@AS@%"rt" %@AE@% instead of %@AS@%"rb"%@AE@%.
  9612. The %@AB@%t%@AE@% represents text mode; the %@AB@%b%@AE@% is binary mode. If you don't specify a
  9613. mode, the %@AB@%fopen%@AE@% function defaults to text mode.  %@NL@%
  9614. %@NL@%
  9615. The list below shows the output of the two programs.  %@NL@%
  9616. %@NL@%
  9617. %@TH:  20  1313 02 33 43 @%
  9618. RDFILE.C  (binary mode)          RDFILE.C  (text mode)
  9619. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9620. %@AS@%E69%@AE@%                              %@AS@%E69%@AE@%
  9621. %@AS@%x120%@AE@%                             %@AS@%x120%@AE@%
  9622. %@AS@%a97%@AE@%                              %@AS@%a97%@AE@%
  9623. %@AS@%m109%@AE@%                             %@AS@%m109%@AE@%
  9624. %@AS@%p112%@AE@%                             %@AS@%p112%@AE@%
  9625. %@AS@%l108%@AE@%                             %@AS@%l108%@AE@%
  9626. %@AS@%e101%@AE@%                             %@AS@%e101%@AE@%
  9627. %@AS@%32%@AE@%                               %@AS@%32%@AE@%
  9628. %@AS@%s115%@AE@%                             %@AS@%s115%@AE@%
  9629. %@AS@%t116%@AE@%                             %@AS@%t116%@AE@%
  9630. %@AS@%r114%@AE@%                             %@AS@%r114%@AE@%
  9631. %@AS@%i105%@AE@%                             %@AS@%i105%@AE@%
  9632. %@AS@%n110%@AE@%                             %@AS@%n110%@AE@%
  9633. %@AS@%g103%@AE@%                             %@AS@%g103%@AE@%
  9634. %@AS@%13 %@AE@%                              %@AS@%10%@AE@%
  9635. %@AS@%10 %@AE@%                              %@AS@%End-of-file marker: -1%@AE@%
  9636. %@AS@%End-of-file marker: -1%@AE@% 
  9637. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  9638. %@TE:  20  1313 02 33 43 @%
  9639.  
  9640. In binary mode there seems to be two characters after the string. In text
  9641. mode there's only one.  %@NL@%
  9642. %@NL@%
  9643. %@NL@%
  9644. %@4@%%@AB@%Ends-of-Lines, Ends-of-Files%@AE@%%@EH@%%@NL@%
  9645. %@NL@%
  9646. The two modes─binary and text─treat end-of-line (%@AB@%EOL%@AE@%) characters and
  9647. end-of-file (%@AB@%EOF%@AE@%) characters in different ways.  %@NL@%
  9648. %@NL@%
  9649. In DOS, a line of text ends with a carriage return (CR) and a linefeed (LF),
  9650. which appear above as ASCII 13 plus ASCII 10. In the UNIX operating system,
  9651. which has close ties to the C language, a single ASCII 10 (the newline
  9652. character) marks the end of a line.  %@NL@%
  9653. %@NL@%
  9654. The once-popular CP/M operating system signals the end of files with a
  9655. CTRL+Z character (ASCII 26, 0x1A)─a tradition that carried forward to DOS.
  9656. This is not the case with UNIX (and C), which don't use a unique %@AB@%EOF%@AE@%
  9657. character.  %@NL@%
  9658. %@NL@%
  9659. %@NL@%
  9660. %@4@%%@AB@%Text Mode Translations%@AE@%%@EH@%%@NL@%
  9661. %@NL@%
  9662. It's important to understand the differences between text mode and binary
  9663. mode when writing and reading disk files. No translations are made in binary
  9664. mode. In text mode, however, the end-of-line and end-of-file characters are
  9665. translated.  %@NL@%
  9666. %@NL@%
  9667. When you read a file in text mode and a CR-LF combination appears in the
  9668. stream, the two characters are translated to one newline character. The
  9669. opposite translation occurs when you write a file in text mode: each CR-LF
  9670. combination is translated to one newline character. In other words, the
  9671. newline is represented by two characters on disk and one character in
  9672. memory. These translations do not occur when you read and write a file in
  9673. binary mode.  %@NL@%
  9674. %@NL@%
  9675. When you read a file in text mode and a CTRL+Z (0x1A) character appears in
  9676. the stream, the character is interpreted as the end-of-file character.
  9677. However, when you're in text mode and you close a file to which you've been
  9678. writing, a CTRL+Z is not placed in the file as the last character. In binary
  9679. mode, the CTRL+Z character has no special meaning (it is not interpreted as
  9680. the end-of-file character).  %@NL@%
  9681. %@NL@%
  9682. The difference between text mode and binary mode is relatively minor when
  9683. you're handling strings, but it's important when you're writing numeric
  9684. values to disk files.  %@NL@%
  9685. %@NL@%
  9686. %@NL@%
  9687. %@3@%%@CR:C6A00110011 @%%@AB@%Text Format for Numeric Variables%@AE@%%@EH@%%@NL@%
  9688. %@NL@%
  9689. Many programs, of course, use numeric as well as character data. When you
  9690. wish to save numbers, you have two choices: text mode or binary mode. The
  9691. SVTEXT.C program below illustrates the less desirable way of creating files
  9692. for numeric variables.  %@NL@%
  9693. %@NL@%
  9694. %@AS@%  /* SVTEXT.C: Save integer variables as text. */
  9695. %@AS@%  
  9696. %@AS@%  #include <stdio.h>
  9697. %@AS@%  
  9698. %@AS@%  int list[] = { 53, -23456, 50, 500, 5000, -99 };
  9699. %@AS@%  extern int errno;
  9700. %@AS@%  char fname[] = "numtext";
  9701. %@AS@%  char temp[81];
  9702. %@AS@%  
  9703. %@AS@%  main()
  9704. %@AS@%  {
  9705. %@AS@%     FILE *fptr;
  9706. %@AS@%     int i;
  9707. %@AS@%  
  9708. %@AS@%     if( (fptr = fopen( "numtext","wt" )) != NULL )
  9709. %@AS@%     {
  9710. %@AS@%        for( i=0; i<6; i++ )
  9711. %@AS@%           fprintf( fptr, "Item %d: %6d \n", i, list[i] );
  9712. %@AS@%        fclose( fptr );
  9713. %@AS@%     }
  9714. %@AS@%     else
  9715. %@AS@%        printf( "Error: Couldn't create file.\n" );
  9716. %@AS@%  
  9717. %@AS@%     if( (fptr = fopen( "badname", "rt" )) != NULL )
  9718. %@AS@%     {
  9719. %@AS@%        /* do nothing */
  9720. %@AS@%     }
  9721. %@AS@%     else
  9722. %@AS@%     {
  9723. %@AS@%        printf( "Error number: %d\n\t", errno );
  9724. %@AS@%        perror( "Couldn't open file BADNAME\n\t" );
  9725. %@AS@%     }
  9726. %@AS@%  
  9727. %@AS@%     if( (fptr = fopen( fname, "rt" )) != NULL )
  9728. %@AS@%     {
  9729. %@AS@%        list[0] = 0;
  9730. %@AS@%        fscanf( fptr, "Item %d: %d \n", &i, &list[0] );
  9731. %@AS@%        printf( "Values read from file:\t %d %d\n", i, list[0] );
  9732. %@AS@%        fgets( temp, 80, fptr );
  9733. %@AS@%        printf( "String from file: \t%s\n", temp );
  9734. %@AS@%        while( (i = fgetc( fptr )) != '\n' )
  9735. %@AS@%           printf( "char: %c \t ASCII: %d \n", i, i );
  9736. %@AS@%        rewind( fptr );
  9737. %@AS@%        printf( "Rewind to start -->\t%s", fgets( temp, 80, fptr ) );
  9738. %@AS@%        fclose( fptr );
  9739. %@AS@%     }
  9740. %@AS@%     else      printf( "Trouble opening %s \n", fname );
  9741. %@AS@%  }%@AE@%%@NL@%
  9742. %@NL@%
  9743. The SVTEXT.C program does three things:  %@NL@%
  9744. %@NL@%
  9745. %@NL@%
  9746.   1.  First, it creates a text file called NUMTEXT. If you TYPE NUMTEXT from
  9747.       the DOS prompt or load the NUMTEXT file into a word processor, it
  9748.       looks like this:
  9749. %@NL@%
  9750. %@AS@%      Item 0:     53 
  9751. %@AS@%      Item 1: -23456 
  9752. %@AS@%      Item 2:     50 
  9753. %@AS@%      Item 3:    500 
  9754. %@AS@%      Item 4:   5000 
  9755. %@AS@%      Item 5:    -99%@AE@%%@NL@%
  9756. %@NL@%
  9757. %@NL@%
  9758.   2.  Next, SVTEXT.C deliberately attempts to open a nonexistent file called
  9759.       BADNAME, to cause a disk error. This section serves no purpose except
  9760.       to illustrate error handling.%@NL@%
  9761. %@NL@%
  9762.   3.  Finally, it reads parts of NUMTEXT, using several file-input
  9763.       functions.%@NL@%
  9764. %@NL@%
  9765. %@NL@%
  9766. %@NL@%
  9767. %@4@%%@AB@%Opening the File for Writing%@AE@%%@EH@%%@NL@%
  9768. %@NL@%
  9769. By now, the %@AB@%fopen%@AE@% function should look familiar to you. The only change in
  9770. the block below is the %@AS@%"wt" %@AE@% mode. The %@AB@%fopen%@AE@% function returns a %@AB@%NULL%@AE@% if any
  9771. errors occur, so the block after the %@AB@%if%@AE@% should execute if %@AB@%fopen%@AE@% succeeds.  %@NL@%
  9772. %@NL@%
  9773. %@AS@%  if( (fptr = fopen( "numtext","wt" )) != NULL )
  9774. %@AS@%  {
  9775. %@AS@%     for( i=0; i<6; i++ )
  9776. %@AS@%        fprintf( fptr, "Item %d: %6d \n", i, list[i] );
  9777. %@AS@%     fclose( fptr );
  9778. %@AS@%  }
  9779. %@AS@%  else
  9780. %@AS@%     printf( "Error: Couldn't create file.\n" );%@AE@%%@NL@%
  9781. %@NL@%
  9782. The %@AB@%for%@AE@% loop counts from 0 to 5, printing 6 strings to the file. The %@AB@%fprintf%@AE@%
  9783. function works the same as %@AB@%printf%@AE@% with one change. You must place the %@AB@%FILE%@AE@%
  9784. pointer before the format string.  %@NL@%
  9785. %@NL@%
  9786. %@NL@%
  9787. %@4@%%@AB@%Error Handling%@AE@%%@EH@%%@NL@%
  9788. %@NL@%
  9789. To illustrate what happens when something goes wrong, the next line creates
  9790. a disk error (as long as you don't have a file called BADNAME in your
  9791. working directory).  %@NL@%
  9792. %@NL@%
  9793. %@AS@%  if( (fptr = fopen( "badname", "rt" )) != NULL )%@AE@%%@NL@%
  9794. %@NL@%
  9795. The %@AB@%if%@AE@% block is empty, because we expect the program to drop through to the
  9796. %@AB@%else%@AE@% clause that handles errors:  %@NL@%
  9797. %@NL@%
  9798. %@AS@%  else
  9799. %@AS@%  {
  9800. %@AS@%     printf( "Error number: %d\n\t", errno );
  9801. %@AS@%     perror( "Couldn't open file BADNAME\n\t" );
  9802. %@AS@%  }%@AE@%%@NL@%
  9803. %@NL@%
  9804. The %@AB@%else%@AE@% block shows two ways you can deal with errors. Note that the %@AB@%errno%@AE@%
  9805. variable, which was declared as an external integer, has never been assigned
  9806. a value. QuickC automatically puts error numbers into %@AB@%errno%@AE@%. In this
  9807. program, the error number is printed to the screen. In your own programs,
  9808. you might wish to branch to various error-handling routines, based on the
  9809. value in the system variable %@AB@%errno%@AE@%. For a list of values for %@AB@%errno%@AE@%, see the
  9810. individual online help entries for file-handling functions.  %@NL@%
  9811. %@NL@%
  9812. It's important to remember that the standard output device is the screen and
  9813. that %@AB@%printf%@AE@% sends messages to %@AB@%stdout%@AE@%. However, if you redirect output to a
  9814. disk file, using a command line such as %@AS@% SVTEXT > MYFILE%@AE@%, the %@AB@%printf%@AE@%
  9815. statement prints the error message to MYFILE. In most cases, you'd prefer to
  9816. see the error message on the screen.  %@NL@%
  9817. %@NL@%
  9818. The second, and better, way to handle I/O errors is the %@AB@%perror%@AE@% function,
  9819. which prints two strings: one that you pass to it and one that spells out─in
  9820. English─the error message. This message goes to the standard error stream
  9821. (%@AB@%stderr%@AE@%), which is always the screen, regardless of whether you've
  9822. redirected output or not. For this reason, %@AB@%perror%@AE@% is preferable to %@AB@%printf%@AE@%
  9823. for printing error messages.  %@NL@%
  9824. %@NL@%
  9825. The error messages should look like this on your screen:  %@NL@%
  9826. %@NL@%
  9827. %@AS@%  Error number: 2
  9828. %@AS@%     Couldn't open file BADNAME
  9829. %@AS@%     : No such file or directory%@AE@%%@NL@%
  9830. %@NL@%
  9831. %@NL@%
  9832. %@4@%%@AB@%Reading Text with fscanf%@AE@%%@EH@%%@NL@%
  9833. %@NL@%
  9834. The final %@AB@%fopen%@AE@% in SVTEXT.C opens the file created earlier:  %@NL@%
  9835. %@NL@%
  9836. %@AS@%  if( (fptr = fopen( fname, "rt" )) != NULL )%@AE@%%@NL@%
  9837. %@NL@%
  9838. Note that we passed the name of a string rather than a literal string.  %@NL@%
  9839. %@NL@%
  9840. Below, %@AB@%fscanf%@AE@% reads in two numeric variables from the first string in the
  9841. file. Note that it works the same as %@AB@%scanf%@AE@%, but you add the %@AB@%FILE%@AE@% pointer as
  9842. the first argument:  %@NL@%
  9843. %@NL@%
  9844. %@AS@%  fscanf( fptr, "Item %d: %d \n", &i, &list[0] );
  9845. %@AS@%  printf( "Values read from file:\t %d %d\n", i, list[0] );%@AE@%%@NL@%
  9846. %@NL@%
  9847. %@NL@%
  9848. %@4@%%@AB@%Reading Text with fgets and fgetc%@AE@%%@EH@%%@NL@%
  9849. %@NL@%
  9850. At this point, the first line in the file has been read and converted to two
  9851. integer values. The file is straight text, so you can treat the second line
  9852. as a string:  %@NL@%
  9853. %@NL@%
  9854. %@AS@%  fgets( temp, 80, fptr );
  9855. %@AS@%  printf( "String from file: \t%s\n", temp );%@AE@%%@NL@%
  9856. %@NL@%
  9857. The %@AB@%fgets%@AE@% function requires three arguments: a pointer to a string, the
  9858. maximum number of characters to read, and the %@AB@%FILE%@AE@% pointer. The function
  9859. stops reading characters when it encounters a newline character or when it
  9860. reaches the maximum number of characters or the end of the file.  %@NL@%
  9861. %@NL@%
  9862. If you prefer, you can input the characters one by one:  %@NL@%
  9863. %@NL@%
  9864. %@AS@%  while( (i = fgetc( fptr )) != '\n' )
  9865. %@AS@%     printf( "char: %c \t ASCII: %d \n", i, i );%@AE@%%@NL@%
  9866. %@NL@%
  9867. The %@AB@%printf%@AE@% inside the %@AB@%while%@AE@% loop prints each character as a character (%@AB@%%c%@AE@%)
  9868. and also as a decimal value (%@AB@%%d%@AE@%). The %@AB@%while%@AE@% loop continues reading
  9869. characters until it finds the end of the line.  %@NL@%
  9870. %@NL@%
  9871. %@NL@%
  9872. %@4@%%@AB@%Back to the Beginning%@AE@%%@EH@%%@NL@%
  9873. %@NL@%
  9874. The %@AB@%rewind%@AE@% function resets the position pointer to the beginning of the
  9875. file. In the program line below, the first line from the file is printed:  %@NL@%
  9876. %@NL@%
  9877. %@AS@%  rewind( fptr );
  9878. %@AS@%  printf( "Rewind to start -->\t%s", fgets( temp, 80, fptr ) );%@AE@%%@NL@%
  9879. %@NL@%
  9880. The screen output looks like this:  %@NL@%
  9881. %@NL@%
  9882. %@AS@%  Error number: 2
  9883. %@AS@%          Couldn't open file BADNAME
  9884. %@AS@%          : No such file or directory
  9885. %@AS@%  Values read from file:         0 53
  9886. %@AS@%  String from file:         Item 1: -23456 
  9887. %@AS@%  
  9888. %@AS@%  char: I          ASCII: 73 
  9889. %@AS@%  char: t          ASCII: 116 
  9890. %@AS@%  char: e          ASCII: 101 
  9891. %@AS@%  char: m          ASCII: 109 
  9892. %@AS@%  char:            ASCII: 32 
  9893. %@AS@%  char: 2          ASCII: 50 
  9894. %@AS@%  char: :          ASCII: 58 
  9895. %@AS@%  char:            ASCII: 32 
  9896. %@AS@%  char:            ASCII: 32 
  9897. %@AS@%  char:            ASCII: 32 
  9898. %@AS@%  char:            ASCII: 32 
  9899. %@AS@%  char:            ASCII: 32 
  9900. %@AS@%  char: 5          ASCII: 53 
  9901. %@AS@%  char: 0          ASCII: 48 
  9902. %@AS@%  char:            ASCII: 32 
  9903. %@AS@%  Rewind to start -->        Item 0:     53%@AE@%%@NL@%
  9904. %@NL@%
  9905. %@AU@% It is inefficient to store  numeric data in text format.%@AE@%  %@NL@%
  9906. %@NL@%
  9907. There seem to be quite a few white-space characters in the text file. Text
  9908. files are great for text, but they store numeric values in a wasteful way.
  9909. Binary format offers several advantages.  %@NL@%
  9910. %@NL@%
  9911. %@NL@%
  9912. %@3@%%@CR:C6A00110012 @%%@AB@%Using Binary Format%@AE@%%@EH@%%@NL@%
  9913. %@NL@%
  9914. When you're processing strings of ASCII characters and writing them to disk
  9915. files, it matters little whether you use text mode or binary mode, as long
  9916. as you're consistent. The advantage of text mode is that it translates
  9917. newlines to the carriage-return-line-feed combination, making it possible to
  9918. use the DOS TYPE command to view the file.  %@NL@%
  9919. %@NL@%
  9920. When you're processing numeric values (integers and floating-point numbers),
  9921. however, you may wish to save your variables in binary mode files, in binary
  9922. format, for the following reasons:  %@NL@%
  9923. %@NL@%
  9924. %@NL@%
  9925.   ■   Binary format almost always saves disk space. In text mode, the number
  9926.       12345.678 would require eight bytes for the ASCII numerals, one byte
  9927.       for the decimal point, and one or more bytes for a separator between
  9928.       variables. In binary format, a floating-point number uses four bytes,
  9929.       regardless of its value. Short integers use only two bytes.%@NL@%
  9930. %@NL@%
  9931.   ■   Binary format generally saves computer time. When you use %@AB@%fprintf%@AE@% to
  9932.       print a numeric value to disk, the computer must translate the
  9933.       internal binary representation to a series of characters. Likewise,
  9934.       when %@AB@%fscanf%@AE@% reads characters into memory, the ASCII values must be
  9935.       translated to the internal binary format. In binary format, none of
  9936.       these translations takes place.%@NL@%
  9937. %@NL@%
  9938.   ■   Binary format preserves the precision of floating-point numbers. The
  9939.       translation from binary to decimal ASCII and back to binary affects
  9940.       the precision of the value.%@NL@%
  9941. %@NL@%
  9942.   ■   A binary save of arrays or structures is fast. It's not necessary to
  9943.       read through an array of 100 items and print each one to the disk
  9944.       file. Instead, you call the %@AB@%fwrite%@AE@% function (discussed below) once,
  9945.       passing it the size of the array to be saved.%@NL@%
  9946. %@NL@%
  9947. %@STUB@%      %@AI@%NOTE  %@AE@%Binary mode is separate from binary format. The modes (binary
  9948.       and text) are parameters you pass to the %@AB@%fopen%@AE@% function. They affect
  9949.       the translation of newlines and the placing of %@AI@%EOF%@AE@% markers. The
  9950.       formats (binary and text) are ways of representing numeric values. An
  9951.       integer in binary format always occupies two bytes on disk. An integer
  9952.       in text format uses a variable number of bytes: it might contain one
  9953.       character (5) or six (-10186).%@NL@%
  9954. %@NL@%
  9955. %@NL@%
  9956. %@NL@%
  9957. %@4@%%@AB@%Opening a Binary File%@AE@%%@EH@%%@NL@%
  9958. %@NL@%
  9959. The SVBIN.C program below creates two binary mode files with the variables
  9960. saved in binary format:  %@NL@%
  9961. %@NL@%
  9962. %@AS@%  /* SVBIN.C: Save integer variables in binary format. */
  9963. %@AS@%  
  9964. %@AS@%  #include <stdio.h>
  9965. %@AS@%  #define ASIZE 10
  9966. %@AS@%  
  9967. %@AS@%  main()
  9968. %@AS@%  {
  9969. %@AS@%     FILE *ap;
  9970. %@AS@%     int zebra[ASIZE], acopy[ASIZE], bcopy[ASIZE];
  9971. %@AS@%     int i;
  9972. %@AS@%  
  9973. %@AS@%     for( i = 0; i < ASIZE; i++ )
  9974. %@AS@%        zebra[i] = 7700 + i;
  9975. %@AS@%  
  9976. %@AS@%     if( (ap = fopen( "binfile", "wb" )) != NULL )
  9977. %@AS@%     {
  9978. %@AS@%        fwrite( zebra, sizeof(zebra), 1, ap );
  9979. %@AS@%        fclose( ap );
  9980. %@AS@%     }
  9981. %@AS@%     else
  9982. %@AS@%        perror( "Write error" );
  9983. %@AS@%  
  9984. %@AS@%     if( (ap = fopen( "morebin", "wb" )) != NULL )
  9985. %@AS@%     {
  9986. %@AS@%        fwrite( &zebra[0], sizeof(zebra[0]), ASIZE, ap );
  9987. %@AS@%        fclose( ap );
  9988. %@AS@%     }
  9989. %@AS@%     else
  9990. %@AS@%        perror( "Write error" );
  9991. %@AS@%  
  9992. %@AS@%     if( (ap = fopen( "binfile", "rb" )) != NULL )
  9993. %@AS@%     {
  9994. %@AS@%        printf( "Hexadecimal values in binfile:\n" );
  9995. %@AS@%        while( (i = fgetc( ap )) != EOF )
  9996. %@AS@%           printf( "%02X ", i );
  9997. %@AS@%        rewind( ap );
  9998. %@AS@%        fread( acopy, sizeof(acopy), 1, ap );
  9999. %@AS@%        rewind( ap );
  10000. %@AS@%        fread( &bcopy[0], sizeof( bcopy[0] ), ASIZE, ap);
  10001. %@AS@%        for( i=0; i<ASIZE; i++ )
  10002. %@AS@%           printf( "\nItem %d = %d\t%d", i, acopy[i], bcopy[i] );
  10003. %@AS@%        fclose( ap );
  10004. %@AS@%  
  10005. %@AS@%     }
  10006. %@AS@%     else
  10007. %@AS@%        perror( "Read error" );
  10008. %@AS@%  
  10009. %@AS@%  }%@AE@%%@NL@%
  10010. %@NL@%
  10011. Focus your attention on the %@AS@% zebra %@AE@% array. It contains 10 integers, because
  10012. the array size %@AS@% ASIZE %@AE@% was defined as 10. First, some values are stored in %@AS@%
  10013. %@AS@%zebra %@AE@% (in a moment, we'll see why 7700-7709 are significant):  %@NL@%
  10014. %@NL@%
  10015. %@AS@%  for( i = 0; i < ASIZE; i++ )
  10016. %@AS@%     zebra[i] = 7700 + i;%@AE@%%@NL@%
  10017. %@NL@%
  10018. Next, we open a file and use %@AB@%fwrite%@AE@% to write the entire array to disk:  %@NL@%
  10019. %@NL@%
  10020. %@AS@%  if( (ap = fopen( "binfile", "wb" )) != NULL )
  10021. %@AS@%  {
  10022. %@AS@%     fwrite( zebra, sizeof(zebra), 1, ap );
  10023. %@AS@%     fclose( ap );
  10024. %@AS@%  }%@AE@%%@NL@%
  10025. %@NL@%
  10026. %@NL@%
  10027. %@4@%%@AB@%Writing an Array in One Line%@AE@%%@EH@%%@NL@%
  10028. %@NL@%
  10029. The %@AB@%fwrite%@AE@% function requires four pieces of information:  %@NL@%
  10030. %@NL@%
  10031. %@NL@%
  10032.   1.  The address of the item (a variable, array, or structure)%@NL@%
  10033. %@NL@%
  10034.   2.  The size of the item in bytes%@NL@%
  10035. %@NL@%
  10036.   3.  The number of items to be written%@NL@%
  10037. %@NL@%
  10038.   4.  The %@AB@%FILE%@AE@% pointer for a previously opened binary mode file%@NL@%
  10039. %@NL@%
  10040. %@NL@%
  10041. In this example, the first argument, %@AS@% zebra %@AE@% is an array and, as you may
  10042. remember from Chapter 8, "Pointers," the name of an array is the address of
  10043. the array.  %@NL@%
  10044. %@NL@%
  10045. To provide the second argument for %@AB@%fwrite%@AE@%, SVBIN.C uses the %@AB@%sizeof%@AE@% operator,
  10046. which returns the number of bytes a variable requires. Because %@AS@% zebra %@AE@% is an
  10047. array of 10 integers and integers use 2 bytes each, the size of %@AS@% zebra %@AE@%
  10048. should be 20. If you view a directory of your disk after running this
  10049. program, you'll notice that the file BINFILE is exactly 20 bytes long.  %@NL@%
  10050. %@NL@%
  10051. The third argument tells %@AB@%fwrite%@AE@% how many items to write to the file. We have
  10052. 1 array, so this parameter is 1.  %@NL@%
  10053. %@NL@%
  10054. The fourth argument is the %@AB@%FILE%@AE@% pointer returned by %@AB@%fopen%@AE@%.  %@NL@%
  10055. %@NL@%
  10056. There's another way to copy the 20 bytes of %@AS@% zebra %@AE@% to the file. After
  10057. writing to BINFILE, the program uses the %@AB@%fopen%@AE@% function to create a second
  10058. file called MOREBIN. The following %@AB@%fwrite%@AE@% line writes 10 integers instead of
  10059. 1 array:  %@NL@%
  10060. %@NL@%
  10061. %@AS@%  fwrite( &zebra[0], sizeof(zebra[0]), ASIZE, ap );%@AE@%%@NL@%
  10062. %@NL@%
  10063. The second and third arguments have changed. Instead of passing the size of
  10064. the array (20) and writing 1 copy of the array, we're accessing the size of
  10065. 1 element (2 bytes) and writing 10 of them (using the symbolic constant
  10066. %@AB@%ASIZE%@AE@%). The contents of this disk file should match, byte for byte, the
  10067. contents of BINFILE.  %@NL@%
  10068. %@NL@%
  10069. %@NL@%
  10070. %@4@%%@AB@%Examining the Binary Contents%@AE@%%@EH@%%@NL@%
  10071. %@NL@%
  10072. Finally, we look at what's inside the file BINFILE. It is opened for reading
  10073. as a binary file:  %@NL@%
  10074. %@NL@%
  10075. %@AS@%  if( (ap = fopen( "binfile", "rb" )) != NULL )%@AE@%%@NL@%
  10076. %@NL@%
  10077. A short %@AB@%while%@AE@% loop reads the bytes from BINFILE and displays them in
  10078. hexadecimal notation:  %@NL@%
  10079. %@NL@%
  10080. %@AS@%  printf( "Hexadecimal values in binfile:\n" );
  10081. %@AS@%  while( (i = fgetc( ap )) != EOF )
  10082. %@AS@%     printf( "%02X ", i );%@AE@%%@NL@%
  10083. %@NL@%
  10084. After running SVBIN.C, the screen displays these values:  %@NL@%
  10085. %@NL@%
  10086. %@AS@%  14 1E 15 1E 16 1E 17 1E 18 1E
  10087. %@AS@%  19 1E 1A 1E 1B 1E 1C 1E 1D 1E%@AE@%%@NL@%
  10088. %@NL@%
  10089. The low byte precedes the high byte, so the first two bytes represent the
  10090. number 0x1E14, which is 7700 in decimal. The next two bytes equal 7701, and
  10091. so on.  %@NL@%
  10092. %@NL@%
  10093. A curious thing happens when you run SVBIN.C and then try to treat the
  10094. 20-byte file as text. If you TYPE BINFILE from the DOS command line, the
  10095. file appears as gibberish (of course), and you see only 12 of the 20
  10096. characters on the screen. Where did the other characters go? Recall the
  10097. previous discussion of binary and text files. In DOS, a CTRL+Z (0x1A) marks
  10098. the end of a text file. And in the midst of our binary file is one of those
  10099. %@AB@%EOF%@AE@% characters. It's not acting as an %@AB@%EOF%@AE@%; it's part of the number 0x1E1A.
  10100. But if you ever open this file in text mode, you'll be unable to read past
  10101. the twelfth byte.  %@NL@%
  10102. %@NL@%
  10103. %@NL@%
  10104. %@4@%%@AB@%Retrieving the Values from Disk%@AE@%%@EH@%%@NL@%
  10105. %@NL@%
  10106. Most of the time, you won't want to read a binary file one byte at a time.
  10107. Instead, you call %@AB@%fread%@AE@%, which reads a disk file and stores the values in a
  10108. variable, an array, or a structure. The %@AB@%fread%@AE@% function complements %@AB@%fwrite%@AE@%.
  10109. It takes four parameters:  %@NL@%
  10110. %@NL@%
  10111. %@NL@%
  10112.   1.  The address of the variable%@NL@%
  10113. %@NL@%
  10114.   2.  The size of the variable in bytes%@NL@%
  10115. %@NL@%
  10116.   3.  The number of values to read%@NL@%
  10117. %@NL@%
  10118.   4.  The %@AB@%FILE%@AE@% pointer that references a binary file opened for reading%@NL@%
  10119. %@NL@%
  10120. %@NL@%
  10121. Here's one way to read values into an array:  %@NL@%
  10122. %@NL@%
  10123. %@AS@%  rewind( ap );
  10124. %@AS@%  fread( acopy, sizeof( acopy ), 1, ap );%@AE@%%@NL@%
  10125. %@NL@%
  10126. The %@AB@%rewind%@AE@% command is necessary because we've already read through the file
  10127. once. The %@AS@% acopy %@AE@% and %@AS@% bcopy %@AE@% arrays are the same size as our original %@AS@%
  10128. %@AS@%zebra %@AE@%array. To fill an array with this technique, pass the address, the
  10129. size of the entire array, a number 1, and the %@AB@%FILE%@AE@% pointer.  %@NL@%
  10130. %@NL@%
  10131. A second way to fill an array is to pass the size of a single element and
  10132. the number of elements you want to read:  %@NL@%
  10133. %@NL@%
  10134. %@AS@%  rewind( ap );
  10135. %@AS@%  fread( &bcopy[0], sizeof( bcopy[0] ), ASIZE, ap );%@AE@%%@NL@%
  10136. %@NL@%
  10137. In the first example of %@AB@%fread%@AE@%, we pass the information that the array %@AS@% acopy
  10138. %@AS@%%@AE@% is 20 bytes long and we want to read it once. In the second example, we
  10139. pass the size of an integer (2 bytes) and ask for 10 of them. In either
  10140. case, 20 bytes are transferred.  %@NL@%
  10141. %@NL@%
  10142. Just to make sure both arrays are equal, we can print them out:  %@NL@%
  10143. %@NL@%
  10144. %@AS@%  for( i = 0; i < ASIZE; i++ )
  10145. %@AS@%  printf( "\nItem %d = %d\t%d", i, acopy[i], bcopy[i] );
  10146. %@AS@%  fclose( ap );%@AE@%%@NL@%
  10147. %@NL@%
  10148. The screen displays the values 7700 through 7709, which survived the trek
  10149. from %@AS@% zebra %@AE@% to BINFILE and back again. These values were stored in the %@AS@%
  10150. %@AS@%zebra %@AE@% array, written to a binary file, then read back into the %@AS@% acopy %@AE@% and %@AS@%
  10151. %@AS@%bcopy %@AE@% arrays.  %@NL@%
  10152. %@NL@%
  10153. %@NL@%
  10154. %@2@%%@CR:C6A00110013 @%%@AB@%Low-Level Input and Output%@AE@%%@EH@%%@NL@%
  10155. %@NL@%
  10156. The file-handling routines such as %@AB@%fopen%@AE@%, %@AB@%fprintf%@AE@%, and %@AB@%fclose%@AE@% are called
  10157. "standard" because they're defined in the ANSI standard. Code that uses the
  10158. standard routines will generally be portable from one machine to another.  %@NL@%
  10159. %@NL@%
  10160. In addition to the standard file-handling functions, the QuickC library
  10161. includes some low-level I/O functions, which allow more direct access to
  10162. disk files.  %@NL@%
  10163. %@NL@%
  10164. The low-level I/O routines (also called "system-level") are generally not
  10165. portable. They work in DOS and OS/2, but they may not work elsewhere.
  10166. They're also a little more difficult to use. Instead of declaring a pointer
  10167. to a %@AB@%FILE%@AE@% structure, you must allocate your own buffer and manage transfer
  10168. of the bytes yourself. You move values into the buffer, then send the
  10169. contents of the buffer to disk.  %@NL@%
  10170. %@NL@%
  10171. %@AU@% Low-level routines can be  more efficient, but they  usually aren't
  10172. %@AU@%portable.%@AE@%  %@NL@%
  10173. %@NL@%
  10174. Low-level routines have some advantages, though. One is that you have more
  10175. control over the machine. Another is that low-level I/O can be faster than
  10176. standard I/O, if you know what you're doing. The choice is up to you:
  10177. portability versus efficiency. You should choose one or the other; it's not
  10178. a good idea to mix standard and system-level routines.  %@NL@%
  10179. %@NL@%
  10180. %@NL@%
  10181. %@3@%%@CR:C6A00110014 @%%@AB@%Low-Level Reading and Writing%@AE@%%@EH@%%@NL@%
  10182. %@NL@%
  10183. The program RWFILE.C illustrates some of the low-level, file-handling
  10184. commands. It creates a file, writes to it, and closes it. Then the file is
  10185. opened for reading and the contents of the file are displayed on the screen.
  10186. %@NL@%
  10187. %@NL@%
  10188. %@AS@%  /* RWFILE.C: Read and write a file. */
  10189. %@AS@%  
  10190. %@AS@%  #include <stdio.h>
  10191. %@AS@%  #include <string.h>
  10192. %@AS@%  #include <fcntl.h>
  10193. %@AS@%  #include <sys\types.h>
  10194. %@AS@%  #include <sys\stat.h>
  10195. %@AS@%  #include <io.h>
  10196. %@AS@%  
  10197. %@AS@%  #define BUFF 512
  10198. %@AS@%  
  10199. %@AS@%  main()
  10200. %@AS@%  {
  10201. %@AS@%     char inbuffer[BUFF];
  10202. %@AS@%     char outbuffer[BUFF];
  10203. %@AS@%     int infile, outfile, length, num;
  10204. %@AS@%  
  10205. %@AS@%     strcpy( outbuffer, "Happy Birthday." );
  10206. %@AS@%     length = strlen( outbuffer );
  10207. %@AS@%     length++;
  10208. %@AS@%  
  10209. %@AS@%     if( (outfile = open( "testfile.bin",
  10210. %@AS@%        O_CREAT | O_WRONLY | O_BINARY,  S_IWRITE )) != -1 )
  10211. %@AS@%     {
  10212. %@AS@%        if( (num = write( outfile, outbuffer, length )) == -1 )
  10213. %@AS@%           perror( "Error in writing" );
  10214. %@AS@%        printf( "\nBytes written to file: %d\n", num );
  10215. %@AS@%        close( outfile );
  10216. %@AS@%     }
  10217. %@AS@%     else
  10218. %@AS@%        perror( "Error opening outfile" );%@AE@%%@NL@%
  10219. %@NL@%
  10220. %@AS@%  if( (infile = open( "testfile.bin", O_RDONLY | O_BINARY )) != -1  )
  10221. %@AS@%     {
  10222. %@AS@%        while( length = read( infile, inbuffer, BUFF ) )
  10223. %@AS@%           printf( "%d bytes received so far.\n", length );
  10224. %@AS@%        close( infile );
  10225. %@AS@%        printf( "%s\n", inbuffer );
  10226. %@AS@%     }
  10227. %@AS@%     else
  10228. %@AS@%        perror( "Error opening infile" );
  10229. %@AS@%  }%@AE@%%@NL@%
  10230. %@NL@%
  10231. Several header files must be included:  %@NL@%
  10232. %@NL@%
  10233. %@AS@%  #include <stdio.h>
  10234. %@AS@%  #include <fcntl.h>
  10235. %@AS@%  #include <sys\types.h>
  10236. %@AS@%  #include <sys\stat.h>
  10237. %@AS@%  #include <io.h>%@AE@%%@NL@%
  10238. %@NL@%
  10239. The symbolic constant %@AS@% BUFF %@AE@% is defined as 512. This value is used
  10240. immediately in the declaration of two buffers:  %@NL@%
  10241. %@NL@%
  10242. %@AS@%  char inbuffer[BUFF];
  10243. %@AS@%  char outbuffer[BUFF];%@AE@%%@NL@%
  10244. %@NL@%
  10245. Note that we don't need %@AB@%FILE%@AE@% structures anywhere in the program. The
  10246. standard I/O routines automatically allocated space for a buffer. Since
  10247. we're operating closer to the DOS level, we must allocate our own buffers,
  10248. instead of relying on the system. If you set the buffer size to a
  10249. sufficiently large value, QuickC will run out of stack space. When this
  10250. happens, you may either make the buffers global variables or use the %@AB@%malloc%@AE@%
  10251. function to allocate an additional chunk of memory.  %@NL@%
  10252. %@NL@%
  10253. The %@AB@%open%@AE@% function takes three parameters:  %@NL@%
  10254. %@NL@%
  10255. %@AS@%  if( (outfile = open( "testfile.bin",
  10256. %@AS@%     O_CREAT | O_WRONLY | O_BINARY, S_IWRITE )) != -1 )%@AE@%%@NL@%
  10257. %@NL@%
  10258. The first parameter is the file name. The second is a sequence of "oflags"
  10259. that are combined with the OR operator. The oflags determine which type of
  10260. file will be opened: it will be created (%@AS@% O_CREAT%@AE@% ), it will be write-only (%@AS@%
  10261. %@AS@%O_WRONLY%@AE@% ), and it will be a binary─not a text─file (%@AS@% O_BINARY%@AE@% ). When you
  10262. create a new file, you must include the third parameter: %@AS@% S_IWRITE%@AE@%.  %@NL@%
  10263. %@NL@%
  10264. The %@AB@%open%@AE@% function returns a file handle, which is assigned to the integer
  10265. variable %@AS@% outfile%@AE@%. Note that this is an integer, not a pointer to a %@AB@%FILE%@AE@%
  10266. structure. If anything goes wrong, a value of -1 is returned by %@AB@%open%@AE@%, and we
  10267. should test for this.  %@NL@%
  10268. %@NL@%
  10269. Table 11.4 summarizes the differences between %@AB@%fopen%@AE@% and %@AB@%open%@AE@%.  %@NL@%
  10270. %@NL@%
  10271. %@AB@%Table 11.4  %@AB@%Standard vs. Low-Level%@AE@%%@AE@%
  10272.  
  10273. %@TH:  11   674 02 10 27 18 21 @%
  10274. Function  Error Parameters           Returns           Condition
  10275. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10276. %@AB@%fopen%@AE@%     File name,  type           Pointer to %@AB@%FILE %@AE@%  NULL
  10277.           (%@AB@%r%@AE@%, %@AB@%w%@AE@%, %@AB@%a%@AE@%), and mode                          
  10278.           (%@AB@%t%@AE@%,%@AB@% b%@AE@%)                                       
  10279.  
  10280. %@AB@%open%@AE@%      File name, oflags          File handle       -1
  10281.                                      (integer)         
  10282.  
  10283. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10284.  
  10285. %@TE:  11   674 02 10 27 18 21 @%
  10286.  
  10287. %@NL@%
  10288. %@4@%%@AB@%Low-Level Writing%@AE@%%@EH@%%@NL@%
  10289. %@NL@%
  10290. The %@AB@%write%@AE@% function takes three parameters:  %@NL@%
  10291. %@NL@%
  10292. %@NL@%
  10293.   1.  The file handle returned by %@AB@%open%@AE@%%@NL@%
  10294. %@NL@%
  10295.   2.  The address of the buffer%@NL@%
  10296. %@NL@%
  10297.   3.  The number of bytes to write%@NL@%
  10298. %@NL@%
  10299. %@NL@%
  10300. You, the programmer, are responsible for filling up the buffer. The %@AB@%write%@AE@%
  10301. function returns the number of bytes actually written to the file.  %@NL@%
  10302. %@NL@%
  10303. %@AS@%  if( (num = write( outfile, outbuffer, length )) == -1 )
  10304. %@AS@%     perror( "Error in writing" );
  10305. %@AS@%  printf( "\nBytes written to file: %d\n", num );
  10306. %@AS@%  close( outfile );%@AE@%%@NL@%
  10307. %@NL@%
  10308. %@NL@%
  10309. %@4@%%@AB@%Low-Level Reading%@AE@%%@EH@%%@NL@%
  10310. %@NL@%
  10311. Next, we open the file for reading. Again, the oflags are required:  %@NL@%
  10312. %@NL@%
  10313. %@AS@%  if( (infile = open( "testfile.bin", O_RDONLY | O_BINARY )) != -1 )
  10314. %@AS@%  {
  10315. %@AS@%     while( length = read( infile, inbuffer, BUFF ) )
  10316. %@AS@%        printf( "%d bytes received so far.\n", length );
  10317. %@AS@%     close( infile );
  10318. %@AS@%     printf( "%s\n", inbuffer );
  10319. %@AS@%  }%@AE@%%@NL@%
  10320. %@NL@%
  10321. The %@AB@%read%@AE@% function takes three parameters:  %@NL@%
  10322. %@NL@%
  10323. %@NL@%
  10324.   1.  The file handle%@NL@%
  10325. %@NL@%
  10326.   2.  The address of the buffer%@NL@%
  10327. %@NL@%
  10328.   3.  The size of the buffer%@NL@%
  10329. %@NL@%
  10330. %@NL@%
  10331. The value returned is the number of bytes read. The %@AB@%while%@AE@% loop continues as
  10332. long as there are characters in the stream. In a real application, you'll
  10333. have to handle the bytes stored in the buffer.  %@NL@%
  10334. %@NL@%
  10335. The low-level file functions are unbuffered. When you call %@AB@%write%@AE@%, the bytes
  10336. are written directly to the disk file. The standard file function %@AB@%fwrite%@AE@%
  10337. doesn't write data to disk; it writes to a buffer. The buffer is transferred
  10338. to disk when the buffer fills up, when the %@AB@%fflush%@AE@% function is called, or
  10339. when the file is closed. As a gen-eral rule, you should not mix buffered and
  10340. unbuffered routines. Use the standard routines or the low-level routines,
  10341. but not both.  %@NL@%
  10342. %@NL@%
  10343. This chapter started with keyboard input and screen output and led into
  10344. discussions of file I/O. The following chapters cover in greater depth
  10345. assembly language routines and some specialized types of screen output,
  10346. including high-resolution graphics, fonts, and presentation graphics.  %@NL@%
  10347. %@NL@%
  10348. %@NL@%
  10349. %@NL@%
  10350. %@NL@%
  10351. %@NL@%
  10352. %@NL@%
  10353. %@CR:C6A00120001 @%%@1@%%@AB@%Chapter 12  Dynamic Memory Allocation%@AE@%%@EH@%%@NL@%
  10354. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10355. %@NL@%
  10356. A program that allocates memory "dynamically" (as it runs) can respond
  10357. flexibly to a user's needs, creating new data structures when the need
  10358. arises and discarding them when their job is done.  %@NL@%
  10359. %@NL@%
  10360. As you read this chapter you'll learn how to allocate memory with the %@AB@%malloc%@AE@%
  10361. library function and free memory with the %@AB@%free%@AE@% function. We'll also look at
  10362. two related functions, %@AB@%calloc%@AE@% and %@AB@%realloc%@AE@%.  %@NL@%
  10363. %@NL@%
  10364. Memory allocation requires the use of pointers. If you're not familiar with
  10365. pointers, read Chapter 8, "Pointers," before tackling this chapter.  %@NL@%
  10366. %@NL@%
  10367. %@NL@%
  10368. %@2@%%@CR:C6A00120002 @%%@AB@%Why Allocate?%@AE@%%@EH@%%@NL@%
  10369. %@NL@%
  10370. %@AU@% The malloc family of library functions can allocate memory during run time.%@AE@%
  10371. %@NL@%
  10372. %@NL@%
  10373. The %@AB@%malloc%@AE@% (memory allocate) family of library functions enables you to
  10374. allocate blocks of memory dynamically. The capability to create new data
  10375. structures on the fly lets you tailor a program's behavior precisely to the
  10376. user's needs.  %@NL@%
  10377. %@NL@%
  10378. For simple programs, such as the examples in Part 1, memory allocation is
  10379. largely automatic. When you declare variables, as in the lines  %@NL@%
  10380. %@NL@%
  10381. %@AS@%  int count;
  10382. %@AS@%  char buffer[160];%@AE@%%@NL@%
  10383. %@NL@%
  10384. QuickC allocates enough memory to store each variable (2 bytes for the first
  10385. variable and 160 for the second). This method works fine if you know each
  10386. vari-able's size in advance. Some program memory needs aren't easy to
  10387. predict, however.  %@NL@%
  10388. %@NL@%
  10389. To take a simple example, say you write an address-book program that stores
  10390. addresses in an array of structures. A novice programmer might begin by
  10391. declaring an array of, say, 100 structures, in the following manner,  %@NL@%
  10392. %@NL@%
  10393. %@AS@%  struct address list[100];%@AE@%%@NL@%
  10394. %@NL@%
  10395. but this approach is needlessly limiting. If your list contains only a few
  10396. addresses, most of the memory in the array is wasted. And if you want to
  10397. enter more than 100 addresses, you're out of luck.  %@NL@%
  10398. %@NL@%
  10399. A better approach is to allocate memory for the array dynamically. This way,
  10400. the program can use only as much memory as needed for the current address
  10401. list. Each time you add an address, or delete one, the program can expand or
  10402. shrink the array as needed.  %@NL@%
  10403. %@NL@%
  10404. %@NL@%
  10405. %@2@%%@CR:C6A00120003 @%%@AB@%Memory Allocation Basics%@AE@%%@EH@%%@NL@%
  10406. %@NL@%
  10407. We'll use a simple example program, COPYFILE.C, to demonstrate the basics of
  10408. dynamic memory allocation─how to allocate a memory block, access its
  10409. contents, and free the block when its purpose is served.  %@NL@%
  10410. %@NL@%
  10411. The COPYFILE.C program, shown below, dynamically allocates a buffer that it
  10412. uses to store file data.  %@NL@%
  10413. %@NL@%
  10414. %@AS@%  /* COPYFILE.C: Demonstrate malloc and free functions. */
  10415. %@AS@%  
  10416. %@AS@%  #include <stdio.h>     /* printf function and NULL */
  10417. %@AS@%  #include <io.h>        /* low-level I/O functions */
  10418. %@AS@%  #include <conio.h>     /* getch function */
  10419. %@AS@%  #include <sys\types.h> /* struct members used in stat.h */
  10420. %@AS@%  #include <sys\stat.h>  /* S_ constants */
  10421. %@AS@%  #include <fcntl.h>     /* O_ constants */
  10422. %@AS@%  #include <malloc.h>    /* malloc function */
  10423. %@AS@%  #include <errno.h>     /* errno global variable */
  10424. %@AS@%  
  10425. %@AS@%  int copyfile( char *source, char *destin );
  10426. %@AS@%  
  10427. %@AS@%  main( int argc, char *argv[] )
  10428. %@AS@%  {
  10429. %@AS@%     if( argc == 3 )
  10430. %@AS@%        if( copyfile( argv[1], argv[2] ) )
  10431. %@AS@%           printf( "Copy failed\n" );
  10432. %@AS@%        else
  10433. %@AS@%           printf( "Copy successful\n" );
  10434. %@AS@%     else
  10435. %@AS@%        printf( "  SYNTAX: COPYFILE <source> <target>\n" );
  10436. %@AS@%  
  10437. %@AS@%     return 0;
  10438. %@AS@%  }
  10439. %@AS@%  
  10440. %@AS@%  int copyfile( char *source, char *target )
  10441. %@AS@%  {
  10442. %@AS@%     char *buf;
  10443. %@AS@%     int hsource, htarget, ch;
  10444. %@AS@%     unsigned count = 50000;
  10445. %@AS@%  
  10446. %@AS@%     if( (hsource = open( source, O_BINARY | O_RDONLY )) == - 1 )
  10447. %@AS@%        return errno;
  10448. %@AS@%     htarget = open( target, O_BINARY | O_WRONLY | O_CREAT | O_EXCL,
  10449. %@AS@%                             S_IREAD | S_IWRITE );
  10450. %@AS@%     if( errno == EEXIST )
  10451. %@AS@%     {
  10452. %@AS@%        cputs( "Target exists. Overwrite? " );
  10453. %@AS@%        ch = getch();
  10454. %@AS@%        if( (ch == 'y') || (ch == 'Y') )
  10455. %@AS@%           htarget = open( target, O_BINARY | O_WRONLY | O_CREAT | O_TRUNC,
  10456. %@AS@%                                   S_IREAD | S_IWRITE );
  10457. %@AS@%        printf( "\n" );
  10458. %@AS@%     }
  10459. %@AS@%     if( htarget == -1 )
  10460. %@AS@%        return errno;
  10461. %@AS@%  
  10462. %@AS@%     if( filelength( hsource ) < count )
  10463. %@AS@%        count = (int)filelength( hsource );
  10464. %@AS@%  
  10465. %@AS@%     buf = (char *)malloc( (size_t)count );
  10466. %@AS@%  
  10467. %@AS@%     if( buf == NULL )
  10468. %@AS@%     {
  10469. %@AS@%        count = _memmax();
  10470. %@AS@%        buf = (char *)malloc( (size_t)count );
  10471. %@AS@%        if( buf == NULL )
  10472. %@AS@%           return ENOMEM;
  10473. %@AS@%     }
  10474. %@AS@%  
  10475. %@AS@%     while( !eof( hsource ) )
  10476. %@AS@%     {
  10477. %@AS@%        if( (count = read( hsource, buf, count )) == -1 )
  10478. %@AS@%           return errno;
  10479. %@AS@%        if( (count = write( htarget, buf, count )) == - 1 )
  10480. %@AS@%           return errno;
  10481. %@AS@%     }
  10482. %@AS@%  
  10483. %@AS@%     close( hsource );
  10484. %@AS@%     close( htarget );
  10485. %@AS@%     free( buf );
  10486. %@AS@%     return 0;
  10487. %@AS@%  }%@AE@%%@NL@%
  10488. %@NL@%
  10489. Before we look at how COPYFILE.C works, let's note what it does. Unlike the
  10490. DOS COPY command, the COPYFILE.C program asks for confirmation before
  10491. overwriting an existing file. The program expects to receive two file names
  10492. as command-line parameters: the name of the file to copy and the name of the
  10493. new file. For instance, the following command copies the file SAMPLE.EXE to
  10494. the new file EXAMPLE.EXE:  %@NL@%
  10495. %@NL@%
  10496. %@AS@%  copyfile sample.exe example.exe%@AE@%%@NL@%
  10497. %@NL@%
  10498. If the target file already exists, COPYFILE.C displays:  %@NL@%
  10499. %@NL@%
  10500. %@AS@%  Target exists. Overwrite?%@AE@%%@NL@%
  10501. %@NL@%
  10502. COPYFILE.C overwrites an existing file only if the user presses the Y key in
  10503. response.  %@NL@%
  10504. %@NL@%
  10505. %@NL@%
  10506. %@3@%%@CR:C6A00120004 @%%@AB@%Preparing to Allocate Memory%@AE@%%@EH@%%@NL@%
  10507. %@NL@%
  10508. The COPYFILE.C program copies the source file in chunks, using an allocated
  10509. memory block as a buffer for file data. The following program lines are the
  10510. ones involved in allocating and freeing the memory block. (These are taken
  10511. from the program in order, but are not consecutive.)  %@NL@%
  10512. %@NL@%
  10513. %@AS@%  #include <malloc.h>    /* malloc function */
  10514. %@AS@%  char *buf;
  10515. %@AS@%  unsigned count = 50000;
  10516. %@AS@%  buf = (char *)malloc( (size_t)count );
  10517. %@AS@%  free( buf );%@AE@%%@NL@%
  10518. %@NL@%
  10519. The first of these,  %@NL@%
  10520. %@NL@%
  10521. %@AS@%  #include <malloc.h>  /* malloc function */%@AE@%%@NL@%
  10522. %@NL@%
  10523. includes the standard include file MALLOC.H, which contains declarations for
  10524. %@AB@%malloc%@AE@% and other memory-allocating functions.  %@NL@%
  10525. %@NL@%
  10526. The %@AB@%malloc%@AE@% function, which the program will call to allocate a memory block,
  10527. returns the address where the block begins. COPYFILE.C declares the pointer
  10528. variable %@AS@% buf %@AE@% to store this address:  %@NL@%
  10529. %@NL@%
  10530. %@AS@%  char *buf;%@AE@%%@NL@%
  10531. %@NL@%
  10532. As you'll see shortly, the pointer %@AS@% buf %@AE@% will be initialized to point to the
  10533. allocated block. Once this is done, the program can access the block's
  10534. contents through the pointer.  %@NL@%
  10535. %@NL@%
  10536. The COPYFILE.C program declares another variable, %@AS@% count%@AE@%, which is used to
  10537. tell %@AB@%malloc%@AE@% how much memory (in bytes) to allocate. The program initially
  10538. sets this value to 50,000:  %@NL@%
  10539. %@NL@%
  10540. %@AS@%  unsigned count = 50000;%@AE@%%@NL@%
  10541. %@NL@%
  10542. If the source file is smaller than 50,000 bytes, COPYFILE.C later resets %@AS@%
  10543. %@AS@%count %@AE@% to the smaller value.  %@NL@%
  10544. %@NL@%
  10545. %@NL@%
  10546. %@3@%%@CR:C6A00120005 @%%@AB@%Specifying the Size of the Allocated Block%@AE@%%@EH@%%@NL@%
  10547. %@NL@%
  10548. Now we're ready to allocate the block. The statement  %@NL@%
  10549. %@NL@%
  10550. %@AS@%  buf = (char *)malloc( (size_t)count) );%@AE@%%@NL@%
  10551. %@NL@%
  10552. in COPYFILE.C calls the %@AB@%malloc%@AE@% function, passing the value of %@AS@% count %@AE@% as an
  10553. argument. This argument indicates the size of the desired block in bytes. In
  10554. COPYFILE.C this value is 50,000 or the size of the source file, whichever is
  10555. smaller.  %@NL@%
  10556. %@NL@%
  10557. Look at the type cast preceding the function argument:  %@NL@%
  10558. %@NL@%
  10559. %@AS@%  (size_t)%@AE@%%@NL@%
  10560. %@NL@%
  10561. The cast is performed for ANSI compatibility (%@AB@%malloc%@AE@% is part of the ANSI
  10562. standard). Under ANSI, %@AB@%malloc%@AE@% is declared as taking an argument of the type %@AS@%
  10563. %@AS@%size_t%@AE@%. To ensure the portability of your programs, the value passed to
  10564. %@AB@%malloc%@AE@% should be either declared or cast as type %@AS@% size_t%@AE@%.  %@NL@%
  10565. %@NL@%
  10566. %@NL@%
  10567. %@3@%%@CR:C6A00120006 @%%@AB@%A Graphic Illustration%@AE@%%@EH@%%@NL@%
  10568. %@NL@%
  10569. Figures 12.1 and 12.2 show how the COPYFILE.C program allocates a memory
  10570. block. The figures are simplified and are not drawn to scale. They represent
  10571. the program's "data segment," which is the memory area available for the
  10572. program's data storage.  %@NL@%
  10573. %@NL@%
  10574. ────────────────────────────────────────────────────────────────────────────%@NL@%
  10575. NOTE
  10576.  
  10577. %@AI@%The details of data storage differ depending on the current "memory model,"
  10578. %@AI@%an advanced concept that goes beyond the scope of this book. For purposes of
  10579. %@AI@%discussion, this book assumes the small memory model, which is the default
  10580. %@AI@%for QuickC.%@AE@%%@NL@%
  10581. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  10582. %@NL@%
  10583. Figure 12.1 represents the program's data segment before COPYFILE.C
  10584. allocates a block of memory. The shaded area labeled "Declared data"
  10585. contains the program's declared variables and "stack," which is used for
  10586. temporary storage. The unshaded area labeled "Heap" contains the memory
  10587. available for allocation by COPYFILE.C.  %@NL@%
  10588. %@NL@%
  10589. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  10590. %@NL@%
  10591. Figure 12.2 shows COPYFILE.C immediately after the program calls the %@AB@%malloc%@AE@%
  10592. function to allocate a block of memory. The allocated block is taken from
  10593. heap memory and lies directly above the program. If COPYFILE.C allocated a
  10594. second memory block, that block would lie above the first, further
  10595. diminishing heap memory.  %@NL@%
  10596. %@NL@%
  10597. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  10598. %@NL@%
  10599. While it's common to say the %@AB@%malloc%@AE@% function "creates" a memory block, that
  10600. terminology is a bit misleading. As Figures 12.1 and 12.2 show, %@AB@%malloc%@AE@%
  10601. simply gives your program control over memory that's already present.  %@NL@%
  10602. %@NL@%
  10603. %@AU@% The malloc function does not initialize the  memory it allocates.%@AE@%  %@NL@%
  10604. %@NL@%
  10605. Since the allocated block has been present in memory all along, it may
  10606. contain random values or values left over from some previous use. The %@AB@%malloc%@AE@%
  10607. function doesn't initialize allocated memory. Substitute the %@AB@%calloc%@AE@% function
  10608. for %@AB@%malloc%@AE@% if you want to clear an allocated block before use. (See the
  10609. section "The calloc Function" below.)  %@NL@%
  10610. %@NL@%
  10611. %@NL@%
  10612. %@3@%%@CR:C6A00120007 @%%@AB@%Assigning the Address that malloc Returns%@AE@%%@EH@%%@NL@%
  10613. %@NL@%
  10614. If the call to %@AB@%malloc%@AE@% succeeds, %@AB@%malloc%@AE@% returns the address of the memory
  10615. block it allocates. COPYFILE.C assigns that return value to the pointer
  10616. variable %@AS@% buf %@AE@% and then accesses the allocated block through %@AS@% buf%@AE@%.  %@NL@%
  10617. %@NL@%
  10618. Before assigning the address that %@AB@% malloc%@AE@% returns, COPYFILE.C performs a
  10619. type cast on the address  %@NL@%
  10620. %@NL@%
  10621. %@AS@%  (char *)%@AE@%%@NL@%
  10622. %@NL@%
  10623. The type cast indicates which type of memory you are allocating. Prior to
  10624. the ANSI standard, %@AB@%malloc%@AE@% was declared as returning a pointer to type %@AB@%char%@AE@%,
  10625. so it was necessary to cast the return value when assigning the value to any
  10626. other pointer type.  %@NL@%
  10627. %@NL@%
  10628. Under ANSI, %@AB@%malloc%@AE@% returns a pointer to type %@AB@%void%@AE@%. Since a %@AB@%void%@AE@% pointer can
  10629. be converted to any pointer type, it's not strictly necessary to cast the
  10630. return from %@AB@%malloc%@AE@%. (If you omit the cast, QuickC does a silent type
  10631. conversion.) The type cast improves readability, however.  %@NL@%
  10632. %@NL@%
  10633. %@NL@%
  10634. %@3@%%@CR:C6A00120008 @%%@AB@%Checking the Return from malloc%@AE@%%@EH@%%@NL@%
  10635. %@NL@%
  10636. If a call to %@AB@%malloc%@AE@% fails─usually because not enough memory is available─the
  10637. function returns a null pointer (defined as %@AS@% NULL %@AE@% in the standard include
  10638. file STDIO.H). You should always test this return value, even if you're
  10639. confident the allocation will succeed. If you ignore the return value and
  10640. access memory through a null pointer, your program may stop with a run-time
  10641. error or overwrite unpredictable memory addresses.  %@NL@%
  10642. %@NL@%
  10643. Thus, before attempting to use the allocated memory block, COPYFILE.C checks
  10644. to make sure the call to %@AB@%malloc%@AE@% succeeded:  %@NL@%
  10645. %@NL@%
  10646. %@AS@%  if( buf == NULL )
  10647. %@AS@%  {
  10648. %@AS@%  .
  10649. %@AS@%  .
  10650. %@AS@%  .
  10651. %@AS@%  }%@AE@%%@NL@%
  10652. %@NL@%
  10653. The %@AB@%if%@AE@% statement tests whether the pointer %@AS@% buf %@AE@% has been set to %@AS@% NULL%@AE@%,
  10654. which would signal failure. In that case, the program executes the code
  10655. within the braces of the %@AB@%if%@AE@% statement.  %@NL@%
  10656. %@NL@%
  10657. Sometimes there may be enough free memory to satisfy only part of your
  10658. memory request. Look at how COPYFILE.C handles this situation:  %@NL@%
  10659. %@NL@%
  10660. %@AS@%  buf = (char *)malloc( (size_t)count );
  10661. %@AS@%  
  10662. %@AS@%  if( buf == NULL )
  10663. %@AS@%  {
  10664. %@AS@%     count = _memmax();
  10665. %@AS@%     buf = (char *)malloc( (size_t)count );
  10666. %@AS@%     if( buf == NULL )
  10667. %@AS@%        return ENOMEM;
  10668. %@AS@%  }%@AE@%%@NL@%
  10669. %@NL@%
  10670. If fewer than %@AS@% count %@AE@% bytes of memory are available, the initial call to
  10671. %@AB@%malloc%@AE@% returns %@AS@% NULL%@AE@%, indicating failure. In that event, COPYFILE.C calls
  10672. the %@AB@%_memmax%@AE@% library routine to find how much memory is available and assigns
  10673. that value to the variable %@AS@% count%@AE@%:  %@NL@%
  10674. %@NL@%
  10675. %@AS@%  count = _memmax();%@AE@%%@NL@%
  10676. %@NL@%
  10677. Then COPYFILE.C calls %@AB@%malloc%@AE@% again, requesting a smaller amount of memory.
  10678. This request is bound to succeed unless no memory is available.  %@NL@%
  10679. %@NL@%
  10680. %@NL@%
  10681. %@3@%%@CR:C6A00120009 @%%@AB@%Accessing an Allocated Memory Block%@AE@%%@EH@%%@NL@%
  10682. %@NL@%
  10683. Once you have allocated a block of memory, you can access it through its
  10684. pointer (%@AS@% buf%@AE@%, in this example). COPYFILE.C uses its allocated block as a
  10685. file buffer, alternately reading in data from the source file, through the
  10686. statement  %@NL@%
  10687. %@NL@%
  10688. %@AS@%  if( (count = read( hsource, buf, count )) == -1 )
  10689. %@AS@%     return errno;%@AE@%%@NL@%
  10690. %@NL@%
  10691. and writing it to the target file, through the statement  %@NL@%
  10692. %@NL@%
  10693. %@AS@%  if( (count = write( htarget, buf, count )) == - 1 )
  10694. %@AS@%     return errno;%@AE@%%@NL@%
  10695. %@NL@%
  10696. The %@AB@%read%@AE@% and %@AB@%write%@AE@% function calls occur within %@AB@%if%@AE@% statements that compare
  10697. the function return values to -1, which would indicate failure.  %@NL@%
  10698. %@NL@%
  10699. COPYFILE.C treats its allocated block as a single chunk of memory. To access
  10700. individual data items in an allocated block, you can use either pointer or
  10701. array notation. Both of the following statements, for instance, refer to the
  10702. third byte in the block that %@AS@% buf %@AE@% points to:  %@NL@%
  10703. %@NL@%
  10704. %@AS@%  buf[2] = 'x';
  10705. %@AS@%  *(buf+2) = 'x';%@AE@%%@NL@%
  10706. %@NL@%
  10707. %@NL@%
  10708. %@3@%%@CR:C6A00120010 @%%@AB@%Allocating Memory for Different Data Types%@AE@%%@EH@%%@NL@%
  10709. %@NL@%
  10710. Since COPYFILE.C accesses its allocated block through a %@AB@%char%@AE@% pointer, the
  10711. program must treat the items in that block as %@AB@%char%@AE@% types. If you need to use
  10712. a different type of memory, simply change the pointer declaration and cast
  10713. the return from %@AB@%malloc%@AE@% accordingly. For instance, you could use the
  10714. following statements to allocate a block large enough to store 30 %@AB@%int%@AE@%
  10715. values:  %@NL@%
  10716. %@NL@%
  10717. %@AS@%  int *buf;
  10718. %@AS@%  
  10719. %@AS@%  buf = (int *)malloc( (size_t)sizeof( int ) * 30 );%@AE@%%@NL@%
  10720. %@NL@%
  10721. Here, the %@AB@%sizeof%@AE@% operator eliminates the need to calculate how many bytes of
  10722. storage 30 integers require. The expression  %@NL@%
  10723. %@NL@%
  10724. %@AS@%  sizeof( int )%@AE@%%@NL@%
  10725. %@NL@%
  10726. returns the size of an %@AB@%int%@AE@% type, which we then multiply by the desired
  10727. number of %@AB@%int%@AE@% items.  %@NL@%
  10728. %@NL@%
  10729. If the above call to %@AB@%malloc%@AE@% succeeds, you have, in effect, a 30-element
  10730. array of integers. And since pointer notation and array notation are
  10731. interchangeable, you can access any element of the array using the pointer
  10732. name and array notation. For instance, the expression  %@NL@%
  10733. %@NL@%
  10734. %@AS@%  ptr[2] = 50;%@AE@%%@NL@%
  10735. %@NL@%
  10736. assigns the value 50 to the third element of the array. Note that this
  10737. statement accesses the third %@AB@%int%@AE@% element in the array, not the third byte.
  10738. Pointer references, as explained in Chapter 8, "Pointers," are always scaled
  10739. by the size of the type used to declare the pointer.  %@NL@%
  10740. %@NL@%
  10741. Allocating memory for structures is equally straightforward. Say that you
  10742. want to allocate memory to store 10 structures of the type %@AS@% employee%@AE@%, which
  10743. is declared in the EMPLOYEE.C program in Chapter 4, "Data Types." The
  10744. EMPLOYEE.C program uses the following structure type:  %@NL@%
  10745. %@NL@%
  10746. %@AS@%  struct employee
  10747. %@AS@%  {
  10748. %@AS@%     char name[10];
  10749. %@AS@%     int months;
  10750. %@AS@%     float wage;
  10751. %@AS@%  };%@AE@%%@NL@%
  10752. %@NL@%
  10753. You could use the statement  %@NL@%
  10754. %@NL@%
  10755. %@AS@%  struct employee *e_ptr;%@AE@%%@NL@%
  10756. %@NL@%
  10757. to declare a pointer to an item of the %@AS@% employee %@AE@% type. Once you have a
  10758. suitable pointer, you could use the following statement to allocate enough
  10759. memory to store 10 structures of the same type:  %@NL@%
  10760. %@NL@%
  10761. %@AS@%  e_ptr = (struct employee *) malloc( (size_t)sizeof( struct employee ) * 10
  10762. %@AS@%  );%@AE@%%@NL@%
  10763. %@NL@%
  10764. Here, the %@AB@%sizeof%@AE@% operator  %@NL@%
  10765. %@NL@%
  10766. %@AS@%  sizeof( struct employee )%@AE@%%@NL@%
  10767. %@NL@%
  10768. returns the size of a structure of the %@AS@% employee %@AE@% type.  %@NL@%
  10769. %@NL@%
  10770. If the allocation succeeds, you have, in effect, an array of structures of
  10771. type %@AS@%employee%@AE@%. Using structure notation, you can access any structure member
  10772. in the block. The following statements, for instance, initialize the members
  10773. of the third structure in the array:  %@NL@%
  10774. %@NL@%
  10775. %@AS@%  strcpy( e_ptr[2].name, "Isaac, N." );
  10776. %@AS@%  e_ptr[2].months = 54;
  10777. %@AS@%  e_ptr[2].wage = (float) 12.21;%@AE@%%@NL@%
  10778. %@NL@%
  10779. %@NL@%
  10780. %@3@%%@CR:C6A00120011 @%%@AB@%Deallocating Memory with the free Function%@AE@%%@EH@%%@NL@%
  10781. %@NL@%
  10782. %@AU@% The free function deallocates an allocated memory block.%@AE@%  %@NL@%
  10783. %@NL@%
  10784. When you have finished using an allocated memory block, you should free
  10785. (deallocate) the block with the %@AB@%free%@AE@% library function. The %@AB@%free%@AE@% function
  10786. takes one argument: the address of the block you wish to free. The
  10787. COPYFILE.C program frees its allocated block with the statement:  %@NL@%
  10788. %@NL@%
  10789. %@AS@%  free( buf );%@AE@%%@NL@%
  10790. %@NL@%
  10791. It's your responsibility to pass a valid address to %@AB@%free%@AE@%. Unlike most
  10792. library functions, %@AB@%free%@AE@% doesn't return any value to indicate success or
  10793. failure. If you pass an invalid address, the memory block remains allocated
  10794. and can't be used for any other purpose.  %@NL@%
  10795. %@NL@%
  10796. Figure 12.3 shows COPYFILE.C after the program frees its allocated block.
  10797. The %@AB@%free%@AE@% function releases the block from the program's control, returning
  10798. it to the heap. The same memory is still present, of course. But since your
  10799. program no longer has control of that memory, you shouldn't attempt to use
  10800. it. (See "Using Dangling Pointers" in Chapter 10, "Programming Pitfalls,"
  10801. for more information on this point.)  %@NL@%
  10802. %@NL@%
  10803. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  10804. %@NL@%
  10805. %@NL@%
  10806. %@2@%%@CR:C6A00120012 @%%@AB@%Specialized Memory-Allocating Functions%@AE@%%@EH@%%@NL@%
  10807. %@NL@%
  10808. The C library contains two specialized versions of %@AB@%malloc%@AE@% that you may find
  10809. useful. The %@AB@%calloc%@AE@% function allocates memory for an array and sets the
  10810. block's contents to 0. The %@AB@%realloc%@AE@% function can expand or shrink an existing
  10811. memory block.  %@NL@%
  10812. %@NL@%
  10813. %@NL@%
  10814. %@3@%%@CR:C6A00120013 @%%@AB@%The calloc Function%@AE@%%@EH@%%@NL@%
  10815. %@NL@%
  10816. The %@AB@%calloc%@AE@% (calculated allocate) function is especially useful for
  10817. allocating memory for an array. It works like %@AB@%malloc%@AE@% but takes two
  10818. arguments:  %@NL@%
  10819. %@NL@%
  10820. %@NL@%
  10821.   ■   The number of data items for which you wish to allocate memory%@NL@%
  10822. %@NL@%
  10823.   ■   The size of each data item%@NL@%
  10824. %@NL@%
  10825. %@NL@%
  10826. This scheme eliminates the need for you to calculate the number of bytes
  10827. needed to store the desired array. For instance, the statement  %@NL@%
  10828. %@NL@%
  10829. %@AS@%  ptr = (int *) calloc( (size_t)30, (size_t)sizeof( int ) );%@AE@%%@NL@%
  10830. %@NL@%
  10831. allocates enough memory for a 30-element integer array, and  %@NL@%
  10832. %@NL@%
  10833. %@AS@%  e_ptr = (struct employee *) calloc( (size_t)30, sizeof( struct employee )
  10834. %@AS@%  );%@AE@%%@NL@%
  10835. %@NL@%
  10836. allocates enough memory for a 30-element array of structures of type
  10837. %@AS@%employee%@AE@%.  %@NL@%
  10838. %@NL@%
  10839. %@AU@% The calloc library function allocates memory and sets every byte in the
  10840. %@AU@%block to 0.%@AE@%  %@NL@%
  10841. %@NL@%
  10842. The %@AB@%calloc%@AE@% function also sets every byte in the requested block to 0. The
  10843. %@AB@%malloc%@AE@% function, as we noted earlier, doesn't change the contents of an
  10844. allocated block. If the block contained garbage values before allocation, it
  10845. contains garbage after allocation, too.  %@NL@%
  10846. %@NL@%
  10847. %@NL@%
  10848. %@3@%%@CR:C6A00120014 @%%@AB@%The realloc Function%@AE@%%@EH@%%@NL@%
  10849. %@NL@%
  10850. Sometimes you may need to adjust the size of an allocated memory block. The
  10851. %@AB@%realloc%@AE@% (reallocate) function can expand or shrink an existing memory block.
  10852. The function takes two arguments:  %@NL@%
  10853. %@NL@%
  10854. %@NL@%
  10855.   ■   The address of an existing allocated block%@NL@%
  10856. %@NL@%
  10857.   ■   The size (in bytes) you want to give the block%@NL@%
  10858. %@NL@%
  10859. %@NL@%
  10860. %@AU@% The realloc library function expands or shrinks an  existing allocated
  10861. %@AU@%block.%@AE@%  %@NL@%
  10862. %@NL@%
  10863. If enough memory is available to accommodate the resized block, %@AB@%realloc%@AE@%
  10864. allocates sufficient memory and copies as much of the existing block as the
  10865. new block will hold. If the new block is smaller than the original, data is
  10866. truncated.  %@NL@%
  10867. %@NL@%
  10868. For instance, if you had allocated a 30-element %@AB@%int%@AE@% array with the statement
  10869. %@NL@%
  10870. %@NL@%
  10871. %@AS@%  ptr = (int *) calloc( (size_t)30, (size_t)sizeof( int ) );%@AE@%%@NL@%
  10872. %@NL@%
  10873. the following statement would expand the block to contain 20 extra elements,
  10874. for a total of 50:  %@NL@%
  10875. %@NL@%
  10876. %@AS@%  ptr = (int *)realloc( ptr, (size_t)sizeof( int ) * 50 );%@AE@%%@NL@%
  10877. %@NL@%
  10878. The address you pass to %@AB@%realloc%@AE@% can be the address returned from a previous
  10879. call to any memory-allocation function: %@AB@%malloc%@AE@%, %@AB@%calloc%@AE@%, or %@AB@%realloc%@AE@% itself.  %@NL@%
  10880. %@NL@%
  10881. Like %@AB@%malloc%@AE@%, both %@AB@%calloc%@AE@% and %@AB@%realloc%@AE@% return a null address if they fail.
  10882. Remember to check the return value whenever you call a memory-allocating
  10883. function.  %@NL@%
  10884. %@NL@%
  10885. %@NL@%
  10886. %@2@%%@CR:C6A00120015 @%%@AB@%Keeping Out of Trouble%@AE@%%@EH@%%@NL@%
  10887. %@NL@%
  10888. Here are a few rules to help you avoid trouble when allocating memory
  10889. dynamically:  %@NL@%
  10890. %@NL@%
  10891. %@NL@%
  10892.   ■   Always check the return value when allocating memory.%@NL@%
  10893. %@NL@%
  10894.   ■   Be careful not to index past the boundaries of an allocated memory
  10895.       block.%@NL@%
  10896. %@NL@%
  10897.   ■   Free allocated memory as soon as you have finished using it.%@NL@%
  10898. %@NL@%
  10899.   ■   Make sure that the address you pass to the %@AB@%free%@AE@% function is valid.%@NL@%
  10900. %@NL@%
  10901.   ■   Don't use a pointer to an allocated block after freeing the block.%@NL@%
  10902. %@NL@%
  10903. %@NL@%
  10904. Most of these points were mentioned earlier, but the second deserves a
  10905. little elaboration. As you may recall from earlier chapters, the C language
  10906. doesn't check array subscripts or pointer references for validity. It's
  10907. important to remember this rule when using a pointer to access an allocated
  10908. block.  %@NL@%
  10909. %@NL@%
  10910. For instance, suppose that you allocate a 30-element integer array with the
  10911. statement  %@NL@%
  10912. %@NL@%
  10913. %@AS@%  ptr = (int *) malloc( (size_t)sizeof( int ) * 30 );%@AE@%%@NL@%
  10914. %@NL@%
  10915. and then execute either of these statements:  %@NL@%
  10916. %@NL@%
  10917. %@AS@%  ptr[32] = 80;
  10918. %@AS@%  *(ptr+32) = 80;%@AE@%%@NL@%
  10919. %@NL@%
  10920. Since the array has only 30 elements, both of the latter statements
  10921. overwrite memory outside the allocated memory block. The statements store
  10922. the value 80 in the address four bytes (two %@AB@%int%@AE@% elements) above the highest
  10923. element in the array.  %@NL@%
  10924. %@NL@%
  10925. While uncontrolled pointer operations always carry the potential for
  10926. disaster, they can create especially tricky program bugs if you write just
  10927. beyond an allocated memory block.  %@NL@%
  10928. %@NL@%
  10929. Near the beginning of each allocated block is a tiny "link" containing
  10930. information about the block. The memory-allocating functions use these links
  10931. to keep track of allocated memory, and the more blocks you have allocated,
  10932. the more important it is to keep all the links intact. If a bad pointer
  10933. reference overwrites a link, it can cause problems in an entirely unexpected
  10934. part of your program.  %@NL@%
  10935. %@NL@%
  10936. %@NL@%
  10937. %@NL@%
  10938. %@NL@%
  10939. %@NL@%
  10940. %@NL@%
  10941. %@CR:C6A00130001 @%%@1@%%@AB@%Chapter 13  Graphics%@AE@%%@EH@%%@NL@%
  10942. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  10943. %@NL@%
  10944. This chapter explains how to call graphics functions that set points, draw
  10945. lines, change colors, and draw shapes such as rectangles and circles. The
  10946. first section lists the three steps to using high-resolution graphics,
  10947. defines important graphics terms, and works through an example program step
  10948. by step, showing how to use the basic functions. The next sections explain
  10949. coordinate systems and show how to display graphics inside viewports and
  10950. windows.  %@NL@%
  10951. %@NL@%
  10952. %@NL@%
  10953. %@2@%%@CR:C6A00130002 @%%@AB@%Graphics Mode%@AE@%%@EH@%%@NL@%
  10954. %@NL@%
  10955. There are three steps to displaying graphics in QuickC:  %@NL@%
  10956. %@NL@%
  10957. %@NL@%
  10958.   1.  Use the %@AB@%_getvideoconfig%@AE@% function to determine which video adapter is
  10959.       installed. (See the section "Checking the Current Video Mode.")%@NL@%
  10960. %@NL@%
  10961.   2.  Use the %@AB@%_setvideomode%@AE@% function to set the desired graphics mode for
  10962.       the installed video adapter. (See the section "Setting the Video
  10963.       Mode.")%@NL@%
  10964. %@NL@%
  10965.   3.  Draw the graphics on the screen. (See the section "Writing a Graphics
  10966.       Program.")%@NL@%
  10967. %@NL@%
  10968. %@NL@%
  10969. There are several definitions you need to know before you can create
  10970. graphics programs. The following list explains the most useful terms:  %@NL@%
  10971. %@NL@%
  10972. %@NL@%
  10973.   ■   The "%@AI@%x%@AE@% axis" determines the horizontal position on the screen. The
  10974.       "origin" (point 0, 0) is in the upper left corner. The maximum number
  10975.       of horizontal "pixels" (picture elements) varies from 320 to 640 to
  10976.       720, depending on the graphics card installed and the graphics mode in
  10977.       effect.%@NL@%
  10978. %@NL@%
  10979.   ■   The "%@AI@%y%@AE@% axis" is the vertical position. The origin is the upper left
  10980.       corner. The number of vertical pixels ranges from 200 to 480.%@NL@%
  10981. %@NL@%
  10982.   ■   Each graphics mode offers a "palette" from which you may choose the
  10983.       colors to be displayed. You may have access to 2, 4, 8, 16, or 256
  10984.       "color indexes," depending on the graphics card in the computer and
  10985.       the graphics mode in effect.%@NL@%
  10986. %@NL@%
  10987.   ■   The CGA (Color Graphics Adapter) modes offer four fixed palettes
  10988.       containing predefined colors that may not be changed. In EGA (Enhanced
  10989.       Graphics Adapter), MCGA (Multicolor Graphics Array), and VGA (Video
  10990.       Graphics Array) graphics modes, you may change any of the color
  10991.       indexes by providing a color value that describes the mix of colors
  10992.       you wish to use. %@NL@%
  10993. %@NL@%
  10994.   ■   A color index is always a short integer. A color value is always a
  10995.       long integer. When you're calling graphics functions that require
  10996.       color-related parameters, you should be aware of the difference
  10997.       between color indexes and color values.%@NL@%
  10998. %@NL@%
  10999. %@NL@%
  11000. %@NL@%
  11001. %@3@%%@CR:C6A00130003 @%%@AB@%Checking the Current Video Mode%@AE@%%@EH@%%@NL@%
  11002. %@NL@%
  11003. Before or after entering graphics mode, you may inquire about the current
  11004. video configuration. This requires a special structure type called
  11005. %@AB@%videoconfig%@AE@%, which is defined in the GRAPH.H header file. You pass the
  11006. address of the structure to the function %@AB@%_getvideoconfig%@AE@%, which returns the
  11007. current video configuration information.  %@NL@%
  11008. %@NL@%
  11009. All graphics programs should include the graphics header file and declare a
  11010. structure of type %@AB@%videoconfig%@AE@%. The structure contains the following
  11011. elements:  %@NL@%
  11012. %@NL@%
  11013. %@AS@%  short numxpixels;   /*number of pixels on x axis*/
  11014. %@AS@%  short numypixels;   /*number of pixels on y axis*/
  11015. %@AS@%  short numtextcols;  /*number of text columns available*/
  11016. %@AS@%  short numtextrows;  /*number of text rows available*/
  11017. %@AS@%  short numcolors;    /*number of color indexes*/
  11018. %@AS@%  short bitsperpixel; /*number of bits per pixel*/
  11019. %@AS@%  short numvideopages;/*number of available video pages*/
  11020. %@AS@%  short mode;         /*current video mode*/
  11021. %@AS@%  short adapter;      /*active display adapter*/
  11022. %@AS@%  short monitor;      /*active display monitor*/
  11023. %@AS@%  short memory;       /*adapter video memory in K bytes*/%@AE@%%@NL@%
  11024. %@NL@%
  11025. These variables within the %@AB@%videoconfig%@AE@% structure are initialized when you
  11026. call %@AB@%_getvideoconfig%@AE@%.  %@NL@%
  11027. %@NL@%
  11028. %@NL@%
  11029. %@3@%%@CR:C6A00130004 @%%@AB@%Setting the Video Mode%@AE@%%@EH@%%@NL@%
  11030. %@NL@%
  11031. Before you can start drawing pictures on the screen, your program must tell
  11032. the graphics adapter to switch from video text mode to graphics mode. To do
  11033. this, call %@AB@%_setvideomode%@AE@%, passing it a single integer that tells it which
  11034. mode to display. The following constants are defined in the GRAPH.H file.
  11035. The dimensions are listed in pixels for graphics mode and in columns for
  11036. video text modes.  %@NL@%
  11037. %@NL@%
  11038. %@TH:  43  1718 02 16 30 30 @%
  11039. Constant        Video Mode                    Mode Type/Hardware
  11040. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11041. %@AB@%_DEFAULTMODE %@AE@%   Restores to original mode     Both/All
  11042.  
  11043. %@AB@%_ERESCOLOR%@AE@%      640 x  350, 4 or 16 color     Graphics/EGA
  11044.  
  11045. %@AB@%_ERESNOCOLOR%@AE@%    640 x  350, BW                Graphics/EGA
  11046.  
  11047. %@AB@%_HERCMONO%@AE@%       720 x 348, BW for HGC         Graphics/HGC
  11048.  
  11049. %@AB@%_HRES16COLOR%@AE@%    640 x  200, 16 color          Graphics/EGA
  11050.  
  11051. %@AB@%_HRESBW%@AE@%         640 x  200, BW                Graphics/CGA
  11052.  
  11053. %@AB@%_MRES4COLOR%@AE@%     320 x  200, 4 color           Graphics/CGA
  11054.  
  11055. %@AB@%_MRES16COLOR%@AE@%    320 x  200, 16 color          Graphics/EGA
  11056.  
  11057. %@AB@%_MRES256COLOR%@AE@%   320 x  200, 256 color         Graphics/VGA/
  11058.                                               MCGA
  11059.  
  11060. %@AB@%_MRESNOCOLOR%@AE@%    320 x  200, 4 gray            Graphics/CGA
  11061.  
  11062. %@AB@%_ORESCOLOR%@AE@%      640 x  400, 1 of 16 colors    Graphics/
  11063.                                               Olivetti(R)
  11064.  
  11065. %@AB@%_TEXTBW40%@AE@%       40-column text, 16 gray       Text/CGA
  11066.  
  11067. %@AB@%_TEXTBW80%@AE@%       80-column text, 16 gray       Text/CGA
  11068.  
  11069. %@AB@%_TEXTC40%@AE@%        40-column text, 16/8 color    Text/CGA
  11070.  
  11071. %@AB@%_TEXTC80%@AE@%        80-column text, 16/8 color    Text/CGA
  11072.  
  11073. %@AB@%_TEXTMONO%@AE@%       80-column text, BW            Text/MDA
  11074.  
  11075. %@AB@%_VRES2COLOR%@AE@%     640 x  480, BW                Graphics/VGA/
  11076.                                               MCGA
  11077.  
  11078. %@AB@%_VRES16COLOR%@AE@%    640 x  480, 16 color          Graphics/VGA
  11079.  
  11080. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11081.  
  11082. %@TE:  43  1718 02 16 30 30 @%
  11083.  
  11084. If %@AB@%_setvideomode%@AE@% returns a 0, it means the hardware does not support the
  11085. selected mode. You may continue to select alternate video modes until a
  11086. nonzero value is returned. If the hardware configuration doesn't support any
  11087. of the selected video modes, take the appropriate exit action.  %@NL@%
  11088. %@NL@%
  11089. %@NL@%
  11090. %@3@%%@CR:C6A00130005 @%%@AB@%Writing a Graphics Program%@AE@%%@EH@%%@NL@%
  11091. %@NL@%
  11092. The SINE.C program below graphs a sine curve. The program illustrates how to
  11093. call many of the important graphics functions. The %@AB@%main%@AE@% function calls five
  11094. other functions, which are defined later in this chapter. To view the
  11095. complete program, use online help.  %@NL@%
  11096. %@NL@%
  11097. ────────────────────────────────────────────────────────────────────────────%@NL@%
  11098. %@AU@%WARNING%@AE@%%@NL@%
  11099. %@NL@%
  11100. When you installed QuickC on your system, you may have chosen not to include
  11101. the graphics library. If this is the case, the programs in this chapter
  11102. won't compile unless you explicitly link the graphics library. See the
  11103. %@AI@%Microsoft QuickC Tool Kit %@AE@%for information about linking libraries.%@NL@%
  11104. ────────────────────────────────────────────────────────────────────────────%@NL@%
  11105. %@NL@%
  11106. %@AS@%  
  11107. %@AS@%  /* SINE.C: Basic graphics commands. */
  11108. %@AS@%  
  11109. %@AS@%  #include <stdio.h>
  11110. %@AS@%  #include <stdlib.h>
  11111. %@AS@%  #include <graph.h>
  11112. %@AS@%  #include <math.h>
  11113. %@AS@%  #include <conio.h>
  11114. %@AS@%  #define PI 3.14159
  11115. %@AS@%  
  11116. %@AS@%  void graphics_mode( void );
  11117. %@AS@%  void draw_lines( void );
  11118. %@AS@%  void sine_wave( void );
  11119. %@AS@%  void draw_shapes( void );
  11120. %@AS@%  void end_program( void );
  11121. %@AS@%  int newx( int );
  11122. %@AS@%  int newy( int );
  11123. %@AS@%  
  11124. %@AS@%  struct videoconfig myscreen;
  11125. %@AS@%  int maxx, maxy;
  11126. %@AS@%  unsigned char diagmask[8] =
  11127. %@AS@%  { 0x93, 0xC9, 0x64, 0xB2, 0x59, 0x2C, 0x96, 0x4B };
  11128. %@AS@%  unsigned char linemask[8] =
  11129. %@AS@%  { 0xFF, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0xCC };
  11130. %@AS@%  
  11131. %@AS@%  
  11132. %@AS@%  main()
  11133. %@AS@%  {
  11134. %@AS@%     graphics_mode();
  11135. %@AS@%     draw_lines();
  11136. %@AS@%     sine_wave();
  11137. %@AS@%     draw_shapes();
  11138. %@AS@%     end_program();
  11139. %@AS@%  }
  11140. %@AS@%  /*
  11141. %@AS@%  Definitions of functions go here
  11142. %@AS@%  */%@AE@%%@NL@%
  11143. %@NL@%
  11144. The SINE.C program's output is shown in Figure 13.1.  %@NL@%
  11145. %@NL@%
  11146. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  11147. %@NL@%
  11148. %@NL@%
  11149. %@4@%%@AB@%Turning on Graphics Mode%@AE@%%@EH@%%@NL@%
  11150. %@NL@%
  11151. Before you can display graphics, you must put the graphics adapter into a
  11152. graphics mode. The %@AB@%_setvideomode%@AE@% function performs this task. Before calling
  11153. %@AB@%_setvideomode%@AE@%, you must decide which graphics modes are acceptable for your
  11154. purposes. The first function in SINE.C is named %@AS@% graphics_mode%@AE@%. It selects
  11155. the highest possible resolution available, based on the graphics card
  11156. currently in use.  %@NL@%
  11157. %@NL@%
  11158. Four header files are included in the SINE.C program:  %@NL@%
  11159. %@NL@%
  11160. %@AS@%  #include <stdio.h>%@AE@%%@NL@%
  11161. %@NL@%
  11162. %@AS@%  #include <stdlib.h>%@AE@%%@NL@%
  11163. %@NL@%
  11164. %@AS@%  #include <graph.h>%@AE@%%@NL@%
  11165. %@NL@%
  11166. %@AS@%  #include <math.h>%@AE@%%@NL@%
  11167. %@NL@%
  11168. Although the MATH.H file is not required for graphics programs, we include
  11169. it in the SINE.C program because it contains floating-point math functions
  11170. such as %@AB@%sin%@AE@%.  %@NL@%
  11171. %@NL@%
  11172. Later in the program we'll need to get information about the screen size, so
  11173. the %@AB@%videoconfig%@AE@% structure called %@AS@% myscreen %@AE@% is declared:  %@NL@%
  11174. %@NL@%
  11175. %@AS@%  struct videoconfig myscreen;%@AE@%%@NL@%
  11176. %@NL@%
  11177. The functions called by %@AB@%main%@AE@% aren't in the standard library; they're defined
  11178. within SINE.C.  %@NL@%
  11179. %@NL@%
  11180. The first function is %@AS@% graphics_mode%@AE@%, which turns on graphics capabilities:
  11181. %@NL@%
  11182. %@NL@%
  11183. %@AS@%  void graphics_mode( void )
  11184. %@AS@%  {
  11185. %@AS@%     _getvideoconfig( &myscreen );
  11186. %@AS@%     switch( myscreen.adapter )
  11187. %@AS@%     {
  11188. %@AS@%        case _CGA:
  11189. %@AS@%           _setvideomode( _HRESBW );
  11190. %@AS@%           break;
  11191. %@AS@%        case _OCGA:
  11192. %@AS@%           _setvideomode( _ORESCOLOR );
  11193. %@AS@%           break;
  11194. %@AS@%        case _EGA:
  11195. %@AS@%        case _OEGA:
  11196. %@AS@%           if( myscreen.monitor == _MONO )
  11197. %@AS@%              _setvideomode( _ERESNOCOLOR );
  11198. %@AS@%           else
  11199. %@AS@%              _setvideomode( _ERESCOLOR );
  11200. %@AS@%           break;
  11201. %@AS@%        case _VGA:
  11202. %@AS@%        case _OVGA:
  11203. %@AS@%        case _MCGA:
  11204. %@AS@%           _setvideomode( _VRES2COLOR );
  11205. %@AS@%           break;
  11206. %@AS@%        case _HGC:
  11207. %@AS@%           _setvideomode( _HERCMONO );
  11208. %@AS@%           break;
  11209. %@AS@%        default:
  11210. %@AS@%           printf( "This program requires a CGA, EGA, VGA, or Hercules
  11211. %@AS@%card\n" );
  11212. %@AS@%           exit( 0 );
  11213. %@AS@%     }
  11214. %@AS@%     _getvideoconfig( &myscreen );
  11215. %@AS@%     maxx = myscreen.numxpixels - 1;
  11216. %@AS@%     maxy = myscreen.numypixels - 1;
  11217. %@AS@%  }%@AE@%%@NL@%
  11218. %@NL@%
  11219. ────────────────────────────────────────────────────────────────────────────%@NL@%
  11220. NOTE
  11221.  
  11222. %@AI@%If you use a Hercules(R) adapter, you must run the MSHERC.COM program before
  11223. %@AI@%attempting to display any graphics. Always run MSHERC.COM before running
  11224. %@AI@%QuickC (do not run it from QuickC's DOS shell).%@AE@%%@NL@%
  11225. ────────────────────────────────────────────────────────────────────────────%@NL@%%@NL@%
  11226. %@NL@%
  11227. The function begins by calling %@AB@%_getvideoconfig%@AE@%, passing the address of the
  11228. %@AB@%videoconfig%@AE@% structure. Within the structure a member called %@AB@%adapter%@AE@% tells us
  11229. the type of adapter currently in use. With that knowledge, and a switch
  11230. statement, we can enter the appropriate graphics mode.  %@NL@%
  11231. %@NL@%
  11232. But how much screen do we have to work with? The screen might be 720 x 348,
  11233. 640 x 480, 640 x 400, 640 x 350, or 640 x 200. Whenever you call
  11234. %@AB@%_setvideomode%@AE@%, you can ask for information about the currently displayed
  11235. screen with %@AB@%_getvideoconfig%@AE@%. Just pass it the address of the %@AB@%videoconfig%@AE@%
  11236. structure that was declared earlier:%@AB@%  %@AE@%%@NL@%
  11237. %@NL@%
  11238. %@AS@%  _getvideoconfig( &myscreen );
  11239. %@AS@%  maxx = myscreen.numxpixels - 1;
  11240. %@AS@%  maxy = myscreen.numypixels - 1;%@AE@%%@NL@%
  11241. %@NL@%
  11242. Let's say your computer has an EGA card, which means that at this point,
  11243. %@AB@%_ERESNOCOLOR%@AE@% is in effect. The horizontal screen size is 640 pixels and
  11244. vertical screen size is 350. The two assignments above assign these values
  11245. to %@AS@% maxx %@AE@% and %@AS@% maxy%@AE@%, less 1. The horizontal resolution might be 640, but the
  11246. pixels are numbered 0-639. Thus, the %@AS@% maxx %@AE@% variable─the highest available
  11247. pixel number─must be 1 less than the total number of pixels:  %@NL@%
  11248. %@NL@%
  11249. %@AS@%  myscreen.numxpixels - 1%@AE@%%@NL@%
  11250. %@NL@%
  11251. Two short functions perform conversions from an imaginary 1000 x 1000 screen
  11252. to whatever graphics mode is in effect. From this point forward, the program
  11253. will assume it has 1000 pixels in each direction, passing the values to %@AS@%
  11254. %@AS@%newx %@AE@% and %@AS@% newy %@AE@% for conversion to actual coordinates:  %@NL@%
  11255. %@NL@%
  11256. %@AS@%  int newx( int xcoord )
  11257. %@AS@%  {
  11258. %@AS@%     int nx;
  11259. %@AS@%     float tempx;
  11260. %@AS@%     tempx = ((float)maxx)/ 1000.0;
  11261. %@AS@%     tempx = ((float)xcoord) * tempx + 0.5;
  11262. %@AS@%     return( (int)tempx );
  11263. %@AS@%  }
  11264. %@AS@%  
  11265. %@AS@%  int newy( int ycoord )
  11266. %@AS@%  {
  11267. %@AS@%     int ny;
  11268. %@AS@%     float tempy;
  11269. %@AS@%     tempy = ((float)maxy)/ 1000.0;
  11270. %@AS@%     tempy = ((float)ycoord) * tempy + 0.5;
  11271. %@AS@%     return( (int)tempy );
  11272. %@AS@%  }%@AE@%%@NL@%
  11273. %@NL@%
  11274. %@NL@%
  11275. %@4@%%@AB@%Drawing Rectangles and Lines%@AE@%%@EH@%%@NL@%
  11276. %@NL@%
  11277. The next function called in SINE.C is %@AS@% draw_lines%@AE@%. As the name implies, the %@AS@%
  11278. %@AS@%draw_lines %@AE@% function draws several lines on the screen: a rectangle around
  11279. the outer edges of the screen and three horizontal lines that cut the screen
  11280. into quarters.  %@NL@%
  11281. %@NL@%
  11282. %@AS@%  void draw_lines( void )
  11283. %@AS@%  {
  11284. %@AS@%     _rectangle( _GBORDER, 0, 0, maxx, maxy );
  11285. %@AS@%     /* _setcliprgn( 20, 20, maxx - 20, maxy - 20 ); */
  11286. %@AS@%     _setvieworg( 0, newy( 500 ) );
  11287. %@AS@%  
  11288. %@AS@%     _moveto( 0, 0 );
  11289. %@AS@%     _lineto( newx( 1000 ), 0 );
  11290. %@AS@%     _setlinestyle( 0xAA3C );
  11291. %@AS@%     _moveto( 0, newy( -250) );
  11292. %@AS@%     _lineto( newx( 1000 ), newy( -250 ) );
  11293. %@AS@%     _setlinestyle( 0x8888 );
  11294. %@AS@%     _moveto( 0, newy( 250 ) );
  11295. %@AS@%     _lineto( newx( 1000 ), newy( 250 ) );
  11296. %@AS@%  }%@AE@%%@NL@%
  11297. %@NL@%
  11298. The call to the%@AB@% _rectangle%@AE@% function has five arguments. The first argument
  11299. is the fill flag, which may be either %@AB@%_GBORDER%@AE@% or %@AB@%_GFILLINTERIOR%@AE@%. Choose
  11300. %@AB@%_GBORDER%@AE@% if you want a rectangle of four lines (a border only, in the
  11301. current line style). Or you can choose %@AB@%_GFILLINTERIOR%@AE@% if you want a solid
  11302. rectangle (filled in with the current color and fill pattern). We will
  11303. discuss how to choose the color and fill pattern later in this chapter.  %@NL@%
  11304. %@NL@%
  11305. The second and third arguments are the %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinates of one corner of
  11306. the rectangle. The fourth and fifth arguments are the coordinates of the
  11307. opposite corner. Since the coordinates for the two corners are  (%@AS@% 0, 0 %@AE@%) and
  11308. (%@AS@% maxx%@AE@%, %@AS@%maxy %@AE@%) , the call to %@AB@%_rectangle%@AE@% frames the screen.  %@NL@%
  11309. %@NL@%
  11310. %@AS@%  _rectangle( _GBORDER, 0, 0, maxx, maxy );%@AE@%%@NL@%
  11311. %@NL@%
  11312. Drawing lines is a two-step process. Move to one location on the screen and
  11313. draw the line to another location, using the %@AB@%_moveto%@AE@% and %@AB@%_lineto%@AE@% functions:
  11314. %@NL@%
  11315. %@NL@%
  11316. %@AS@%  _setlinestyle( 0xAA3C );
  11317. %@AS@%  _moveto( 0, newy(-250) );
  11318. %@AS@%  _lineto( newx(1000), newy(-250) );%@AE@%%@NL@%
  11319. %@NL@%
  11320. Use the %@AB@%_setlinestyle%@AE@% function to change from a solid line to a dashed line
  11321. by passing it one integer value. In the example above, the number 0xAA3C
  11322. causes the line to become the graphics equivalent of binary 1010 1010 0011
  11323. 1100.  %@NL@%
  11324. %@NL@%
  11325. The %@AB@%_moveto%@AE@% function positions an imaginary pixel cursor at a spot on the
  11326. screen. Nothing visible appears on the screen. The %@AB@%_lineto%@AE@% function draws a
  11327. line. The negative value -250 might seem to be an impossible screen
  11328. coordinate. It would be, but the program has changed the viewport
  11329. organization of the screen with the %@AB@%_setvieworg%@AE@% function. The top half of
  11330. the screen now contains negative %@AI@%y%@AE@% coordinates, and the bottom half contains
  11331. positive %@AI@%y%@AE@% coordinates. Viewports are explained in more detail later in this
  11332. chapter.  %@NL@%
  11333. %@NL@%
  11334. %@NL@%
  11335. %@4@%%@AB@%Setting a Pixel%@AE@%%@EH@%%@NL@%
  11336. %@NL@%
  11337. The next step in the SINE.C program is to draw the sine curve. This requires
  11338. the %@AS@% sine_wave %@AE@% function which is shown below. This function calculates
  11339. positions for two sine waves and plots them on the screen:  %@NL@%
  11340. %@NL@%
  11341. %@AS@%  void sine_wave( void )
  11342. %@AS@%  {
  11343. %@AS@%   int locx, locy;
  11344. %@AS@%    double i, rad;
  11345. %@AS@%  
  11346. %@AS@%   for( i = 0; i < 1000; i += 3 )
  11347. %@AS@%     {
  11348. %@AS@%        rad = -sin( (PI * (float) i) / 250.0 );
  11349. %@AS@%        locx = newx( (int) i );
  11350. %@AS@%        locy = newy( (int) (rad * 250.0) );
  11351. %@AS@%        _setpixel( locx, locy );
  11352. %@AS@%     }
  11353. %@AS@%  }%@AE@%%@NL@%
  11354. %@NL@%
  11355. The only graphics function called is %@AB@%_setpixel%@AE@%, which takes two parameters,
  11356. an %@AI@%x%@AE@% and a %@AI@%y%@AE@% coordinate. The function turns on the pixel at that location.  %@NL@%
  11357. %@NL@%
  11358. %@NL@%
  11359. %@4@%%@AB@%Drawing Shapes%@AE@%%@EH@%%@NL@%
  11360. %@NL@%
  11361. After the sine curve is drawn, the SINE.C program calls the %@AS@% draw_shapes %@AE@%
  11362. function to draw two rectangles and two ellipses on the screen. The fill
  11363. mask alternates between %@AB@%_GBORDER%@AE@% and %@AB@%_GFILLINTERIOR%@AE@%:  %@NL@%
  11364. %@NL@%
  11365. %@AS@%  void draw_shapes( void )
  11366. %@AS@%  {
  11367. %@AS@%     _setlinestyle( 0xFFFF );
  11368. %@AS@%     _setfillmask( diagmask );
  11369. %@AS@%     _rectangle( _GBORDER, newx( 50 ), newy( -325 ), newx( 200 ), newy( -425
  11370. %@AS@%) );
  11371. %@AS@%     _rectangle(_GFILLINTERIOR,newx(550),newy(-325),newx(700),newy(-425));
  11372. %@AS@%  
  11373. %@AS@%     _setfillmask( linemask );
  11374. %@AS@%     _ellipse( _GBORDER, newx( 50 ), newy( 325 ), newx( 200 ), newy( 425 )
  11375. %@AS@%);
  11376. %@AS@%     _ellipse( _GFILLINTERIOR,newx( 550 ),newy( 325 ),newx( 700 ),newy( 425
  11377. %@AS@%) );
  11378. %@AS@%  }%@AE@%%@NL@%
  11379. %@NL@%
  11380. Note that %@AB@%_setlinestyle%@AE@% resets the line pattern to solid. If you omit this
  11381. function (or comment it out), the first rectangle would be drawn with dashes
  11382. instead of a solid line.  %@NL@%
  11383. %@NL@%
  11384. The %@AB@%_ellipse%@AE@% function draws an ellipse on the screen. Its parameters
  11385. resemble the parameters for %@AB@%_rectangle%@AE@%. Both functions require a fill flag
  11386. and two corners of a "bounding rectangle." When the ellipse is drawn, four
  11387. points touch the edges of the bounding rectangle.  %@NL@%
  11388. %@NL@%
  11389. The %@AB@%_GFILLINTERIOR%@AE@% flag fills the shape with the current fill pattern. To
  11390. select a pattern, you must first use the %@AB@%_setfillmask%@AE@% function, passing the
  11391. address of an eight-byte array of unsigned characters. Earlier in the
  11392. program %@AS@% diagmask %@AE@% was defined as the shape shown in Table 13.1 below.  %@NL@%
  11393. %@NL@%
  11394. %@AB@%Table 13.1  %@AB@%Fill Patterns%@AE@%%@AE@%
  11395.  
  11396. %@TH:  11   790 02 34 42 @%
  11397. Bit Pattern                       Value in diagmask
  11398. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11399.   ∙  ∙    ∙  ∙                %@AS@%diagmask[0] %@AE@%= 0x93
  11400.     ∙  ∙    ∙  ∙              %@AS@%diagmask[1] %@AE@%= 0xC9
  11401. ∙      ∙  ∙    ∙  ∙            %@AS@%diagmask[2] %@AE@%= 0x64
  11402.   ∙      ∙  ∙    ∙            %@AS@%diagmask[3] %@AE@%= 0xB2
  11403. ∙    ∙      ∙  ∙              %@AS@%diagmask[4] %@AE@%= 0x59
  11404. ∙  ∙    ∙      ∙  ∙            %@AS@%diagmask[5] %@AE@%= 0x2C
  11405.   ∙  ∙    ∙      ∙            %@AS@%diagmask[6] %@AE@%= 0x96
  11406. ∙    ∙  ∙    ∙                %@AS@%diagmask[7] %@AE@%= 0x4B
  11407. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11408. %@TE:  11   790 02 34 42 @%
  11409.  
  11410. %@NL@%
  11411. %@4@%%@AB@%Exiting Graphics Mode%@AE@%%@EH@%%@NL@%
  11412. %@NL@%
  11413. The final function to be called by the SINE.C program is %@AS@% end_program%@AE@%, which
  11414. waits for a key press and then sets the screen back to normal:  %@NL@%
  11415. %@NL@%
  11416. %@AS@%  void end_program( void )
  11417. %@AS@%  {
  11418. %@AS@%     getch();
  11419. %@AS@%     _setvideomode( _DEFAULTMODE );
  11420. %@AS@%  }%@AE@%%@NL@%
  11421. %@NL@%
  11422. %@NL@%
  11423. %@3@%%@CR:C6A00130006 @%%@AB@%Using Color Graphics Modes%@AE@%%@EH@%%@NL@%
  11424. %@NL@%
  11425. In this example, the program COLOR.C sets a mode with as many color choices
  11426. as possible for the available hardware:  %@NL@%
  11427. %@NL@%
  11428. %@AS@%  /* COLOR.C: Sets a medium resolution mode
  11429. %@AS@%     with maximum color choices. */
  11430. %@AS@%  
  11431. %@AS@%  #include <stdio.h>
  11432. %@AS@%  #include <stdlib.h>
  11433. %@AS@%  #include <graph.h>
  11434. %@AS@%  #include <conio.h>
  11435. %@AS@%  struct videoconfig vc;
  11436. %@AS@%  
  11437. %@AS@%  main()
  11438. %@AS@%  {
  11439. %@AS@%     if( _setvideomode( _MRES256COLOR ) );
  11440. %@AS@%     else if( _setvideomode( _MRES16COLOR ) );
  11441. %@AS@%     else if( _setvideomode( _MRES4COLOR ) );
  11442. %@AS@%     else
  11443. %@AS@%     {
  11444. %@AS@%        printf( "Error: No color graphics capability\n" );
  11445. %@AS@%        exit( 0 );
  11446. %@AS@%     }
  11447. %@AS@%  
  11448. %@AS@%     _getvideoconfig( &vc );
  11449. %@AS@%  
  11450. %@AS@%     printf( "%d available colors\n", vc.numcolors );
  11451. %@AS@%     printf( "%d horizontal pixels\n", vc.numxpixels );
  11452. %@AS@%     printf( "%d vertical pixels\n", vc.numypixels );
  11453. %@AS@%  
  11454. %@AS@%     getch();
  11455. %@AS@%     _clearscreen( _GCLEARSCREEN );
  11456. %@AS@%     _setvideomode( _DEFAULTMODE );
  11457. %@AS@%  }%@AE@%%@NL@%
  11458. %@NL@%
  11459. Although color graphics are an improvement over black and white, if you use
  11460. color you must make a compromise. When you request the maximum number of
  11461. colors, you sacrifice some resolution─a 320 x 200 screen instead of a higher
  11462. resolution. Thus, the COLORS.C program always creates a screen 320 pixels
  11463. wide and 200 pixels high. Note also the use of the function %@AB@%_clearscreen%@AE@%,
  11464. which clears the screen in any video mode (text or graphics).  %@NL@%
  11465. %@NL@%
  11466. To view every possible graphics mode, you can run the program GRAPHIC.C
  11467. shown below. Explanations of the various color graphics modes─CGA, EGA, and
  11468. VGA─follow.  %@NL@%
  11469. %@NL@%
  11470. %@AS@%  /* GRAPHIC.C: Display every graphics mode. */
  11471. %@AS@%  #include <stdio.h>
  11472. %@AS@%  #include <graph.h>
  11473. %@AS@%  #include <conio.h>
  11474. %@AS@%  
  11475. %@AS@%  struct videoconfig screen;
  11476. %@AS@%  int modes[12] =
  11477. %@AS@%  {
  11478. %@AS@%     _MRES4COLOR, _MRESNOCOLOR, _HRESBW, _HERCMONO,
  11479. %@AS@%     _MRES16COLOR, _HRES16COLOR, _ERESNOCOLOR, _ERESCOLOR,
  11480. %@AS@%     _VRES2COLOR, _VRES16COLOR, _MRES256COLOR, _ORESCOLOR
  11481. %@AS@%  };
  11482. %@AS@%  
  11483. %@AS@%  void print_menu( void );
  11484. %@AS@%  void show_mode( char );
  11485. %@AS@%  
  11486. %@AS@%  main()
  11487. %@AS@%  {
  11488. %@AS@%     char key;
  11489. %@AS@%     print_menu();
  11490. %@AS@%     while( (key = getch()) != 'x' )
  11491. %@AS@%        show_mode( key );
  11492. %@AS@%  }
  11493. %@AS@%  
  11494. %@AS@%  void print_menu( void )
  11495. %@AS@%  {
  11496. %@AS@%     _setvideomode( _DEFAULTMODE );
  11497. %@AS@%     _clearscreen( _GCLEARSCREEN );
  11498. %@AS@%     printf( "Please choose a graphics mode\nType 'x' to exit.\n\n" );
  11499. %@AS@%     printf( "0 _MRES4COLOR\n1 _MRESNOCOLOR\n2 _HRESBW\n" );
  11500. %@AS@%     printf( "3 _HERCMONO\n4 _MRES16COLOR\n5 _HRES16COLOR\n" );
  11501. %@AS@%     printf( "6 _ERESNOCOLOR\n7 _ERESCOLOR\n" );
  11502. %@AS@%     printf( "8 _VRES2COLOR\n9 _VRES16COLOR\na _MRES256COLOR\n" );
  11503. %@AS@%     printf( "b _ORESCOLOR\n" );
  11504. %@AS@%  }
  11505. %@AS@%  
  11506. %@AS@%  void show_mode( char which )
  11507. %@AS@%  {
  11508. %@AS@%     int nc, i;
  11509. %@AS@%     int height, width;
  11510. %@AS@%     int mode = which;
  11511. %@AS@%  
  11512. %@AS@%     if( mode < '0' || mode > '9' )
  11513. %@AS@%        if( mode == 'a' )
  11514. %@AS@%      mode = '9' + 1;
  11515. %@AS@%        else if( mode == 'b' )
  11516. %@AS@%      mode = '9' + 2;%@AE@%%@NL@%
  11517. %@NL@%
  11518. %@AS@%  else
  11519. %@AS@%      return;
  11520. %@AS@%  
  11521. %@AS@%     if( _setvideomode( modes[mode - '0'] ) )
  11522. %@AS@%     {
  11523. %@AS@%        _getvideoconfig( &screen );
  11524. %@AS@%        nc = screen.numcolors;
  11525. %@AS@%        width = screen.numxpixels/nc;
  11526. %@AS@%        height = screen.numypixels/2;
  11527. %@AS@%        for( i = 0; i < nc; i++ )
  11528. %@AS@%        {
  11529. %@AS@%      _setcolor( i );
  11530. %@AS@%      _rectangle( _GFILLINTERIOR, i * width, 0, (i + 1) * width, height );
  11531. %@AS@%        }
  11532. %@AS@%     }
  11533. %@AS@%     else
  11534. %@AS@%     {
  11535. %@AS@%        printf( " \nVideo mode %c is not available.\n", which );
  11536. %@AS@%        printf( "Please press a key.\n" );
  11537. %@AS@%     }
  11538. %@AS@%     getch();
  11539. %@AS@%     _setvideomode( _DEFAULTMODE );
  11540. %@AS@%     print_menu();
  11541. %@AS@%  }%@AE@%%@NL@%
  11542. %@NL@%
  11543. %@NL@%
  11544. %@4@%%@AB@%CGA Color Graphics Modes%@AE@%%@EH@%%@NL@%
  11545. %@NL@%
  11546. The CGA color graphics modes %@AB@%_MRES4COLOR%@AE@% and %@AB@%_MRESNOCOLOR%@AE@% display four
  11547. colors selected from one of several predefined palettes of colors. They
  11548. display these foreground colors against a background color which can be any
  11549. one of the 16 available colors. With the CGA hardware, the palette of
  11550. foreground colors is predefined and cannot be changed. Each palette number
  11551. is an integer as shown in Table 13.2.  %@NL@%
  11552. %@NL@%
  11553. %@AB@%Table 13.2  %@AB@%Available CGA Colors%@AE@%%@AE@%
  11554.  
  11555. %@TH:   8   529 03 18 14 16 28 @%
  11556. Palette Number    Color Index   
  11557.                   1             2               3
  11558. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11559. 0                 Green         Red             Brown
  11560. 1                 Cyan          Magenta         Light gray
  11561. 2                 Light green   Light red       Yellow
  11562. 3                 Light cyan    Light magenta   White
  11563. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11564. %@TE:   8   529 03 18 14 16 28 @%
  11565.  
  11566. The %@AB@%_MRESNOCOLOR%@AE@% graphics mode produces palettes containing various shades
  11567. of gray on black-and-white monitors. The %@AB@%_MRESNOCOLOR%@AE@% mode displays colors
  11568. when used with a color display. However, only two palettes  %@NL@%
  11569. %@NL@%
  11570. are available with a color display. You can use the %@AB@%_selectpalette%@AE@% function
  11571. to select one of these predefined palettes. Table 13.3 shows the
  11572. correspondence between the color indexes and the palettes.  %@NL@%
  11573. %@NL@%
  11574. %@AB@%Table 13.3  %@AB@%CGA Colors:  _MRESNOCOLOR Mode%@AE@%%@AE@%
  11575.  
  11576. %@TH:   6   404 03 18 13 12 33 @%
  11577. Palette Number    Color Index  
  11578.                   1            2           3
  11579. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11580. 0                 Blue         Red         Light gray
  11581. 1                 Light blue   Light red   White
  11582. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11583. %@TE:   6   404 03 18 13 12 33 @%
  11584.  
  11585. You may use the %@AB@%_selectpalette%@AE@% function only with the %@AB@%_MRES4COLOR%@AE@% and
  11586. %@AB@%_MRESNOCOLOR%@AE@% graphics modes. To change palettes in other graphics modes, use
  11587. the %@AB@%_remappalette%@AE@% or %@AB@%_remapallpalette%@AE@% functions.  %@NL@%
  11588. %@NL@%
  11589. The following program sets the video mode to %@AB@%_MRES4COLOR%@AE@% and then cycles
  11590. through background colors and palette combinations. It works on computers
  11591. equipped with CGA, EGA, MCGA, or VGA cards. A color monitor is required.  %@NL@%
  11592. %@NL@%
  11593. %@AS@%  /* CGA.C: Demonstrate CGA colors. */
  11594. %@AS@%  
  11595. %@AS@%  #include <stdio.h>
  11596. %@AS@%  #include <graph.h>
  11597. %@AS@%  #include <conio.h>
  11598. %@AS@%  
  11599. %@AS@%  long bkcolor[8] = 
  11600. %@AS@%  {
  11601. %@AS@%     _BLACK, _BLUE, _GREEN, _CYAN,
  11602. %@AS@%    _RED, _MAGENTA, _BROWN, _WHITE
  11603. %@AS@%  };
  11604. %@AS@%  
  11605. %@AS@%  char *bkcolor_name[] =
  11606. %@AS@%  {
  11607. %@AS@%     "_BLACK", "_BLUE", "_GREEN", "_CYAN",
  11608. %@AS@%     "_RED", "_MAGENTA", "_BROWN", "_WHITE"
  11609. %@AS@%  };%@AE@%%@NL@%
  11610. %@NL@%
  11611. %@AS@%  main()
  11612. %@AS@%  {
  11613. %@AS@%     int i, j, k;
  11614. %@AS@%     _setvideomode( _MRES4COLOR );
  11615. %@AS@%     for( i=0; i<= 3; i++ )
  11616. %@AS@%     {
  11617. %@AS@%        _selectpalette( i );
  11618. %@AS@%        for( k=0; k <= 7; k++ )
  11619. %@AS@%        {
  11620. %@AS@%           _setbkcolor( bkcolor[k] );
  11621. %@AS@%           for( j=0; j<=3; j++ )
  11622. %@AS@%           {
  11623. %@AS@%              _settextposition( 1, 1 );
  11624. %@AS@%              printf( "background color: %8s\n", bkcolor_name[k] );
  11625. %@AS@%              printf( "palette: %d\ncolor: %d\n", i, j );
  11626. %@AS@%              _setcolor( j );
  11627. %@AS@%              _rectangle( _GFILLINTERIOR, 160, 100, 320, 200 );
  11628. %@AS@%               getch();
  11629. %@AS@%           }
  11630. %@AS@%        }
  11631. %@AS@%     }
  11632. %@AS@%     _setvideomode( _DEFAULTMODE );
  11633. %@AS@%  }%@AE@%%@NL@%
  11634. %@NL@%
  11635. %@NL@%
  11636. %@4@%%@AB@%EGA, MCGA, and VGA Palettes%@AE@%%@EH@%%@NL@%
  11637. %@NL@%
  11638. At the beginning of this chapter, we mentioned the difference between color
  11639. indexes and color values. An analogy might make things clearer. Imagine a
  11640. painter who owns 64 tubes of paint and a painter's palette that has room for
  11641. only 16 globs of paint at any one time. A painting created under these
  11642. constraints could contain only 16 colors (selected from a total of 64). One
  11643. of the EGA graphics modes (%@AB@%_ERESCOLOR%@AE@%) is similar: 16 color indexes chosen
  11644. from a total of 64 color values. (Color indexes are sometimes called "color
  11645. attributes," or "pixel values." Color values are sometimes called "actual
  11646. colors.")  %@NL@%
  11647. %@NL@%
  11648. %@AB@%VGA Color Mixing%@AE@% - VGA offers the widest variety of color values: 262,144
  11649. (256K). Depending on the graphics mode, the VGA palette size may be 2, 16,
  11650. or 256. When you select a color value, you specify a level of intensity
  11651. ranging from 0-63 for each of the red, green, and blue color values. The
  11652. long integer that defines a color value consists of four bytes (32 bits):%@NL@%
  11653. %@NL@%
  11654. %@AS@%  MSB                             LSB
  11655. %@AS@%  zzzzzzzz zzBBBBBB zzGGGGGG zzRRRRRR%@AE@%%@NL@%
  11656. %@NL@%
  11657. The most-significant byte must contain all zeros. The two high bits in the
  11658. remaining three bytes must also be 0. To mix a light red (pink), turn red
  11659. all the way up, and mix in some green and blue:  %@NL@%
  11660. %@NL@%
  11661. %@AS@%  00000000 00100000 00100000 00111111%@AE@%%@NL@%
  11662. %@NL@%
  11663. To represent this value in hexadecimal, use the number %@AS@% 0x0020203FL%@AE@% (the %@AS@% L %@AE@%
  11664. marks it as a long value). You could also use the following macro:  %@NL@%
  11665. %@NL@%
  11666. %@AS@%  #define RGB ( r, g, b ) (0x3F3F3FL & ((long)(b) << 16 | (g) << 8 | (r)))%@AE@%%@NL@%
  11667. %@NL@%
  11668. To create pure yellow (100% red plus 100% green) and assign it to a variable
  11669. %@AS@% y1%@AE@%, use this line:  %@NL@%
  11670. %@NL@%
  11671. %@AS@%  y1 = RGB( 63, 63, 0 );%@AE@%%@NL@%
  11672. %@NL@%
  11673. For white, turn all the colors on: %@AS@% RGB( 63, 63, 63 )%@AE@%. For black, set all
  11674. colors to 0: %@AS@% RGB( 0, 0, 0 )%@AE@%.  %@NL@%
  11675. %@NL@%
  11676. %@AB@%EGA Color Mixing%@AE@% - Mixing colors in EGA modes is similar to the mixing
  11677. described above, but there are fewer intensities for the red, green, and
  11678. blue components. In the modes that offer 64 colors, the R, G, and B values
  11679. cover 2 bits and can range from 0 to 3. The long integer that defines an RGB
  11680. color looks like this:%@NL@%
  11681. %@NL@%
  11682. %@AS@%  MSB                             LSB
  11683. %@AS@%  zzzzzzzz zzBB???? zzGG???? zzRR????%@AE@%%@NL@%
  11684. %@NL@%
  11685. The bits marked %@AS@% z %@AE@% must be zeros and the bits marked with question marks
  11686. can be any value. To form a pure red color value, you would use the constant
  11687. %@AS@% 0x00000030L%@AE@%. For cyan (blue plus green), use %@AS@% 0x00303000L%@AE@%. The RGB macro
  11688. defined above is easily modified for EGA monitors:  %@NL@%
  11689. %@NL@%
  11690. %@AS@%  #define EGARGB( r, g, b ) (0x3F3F3FL & ((long)(b) << 20 | (g) << 12 | (r
  11691. %@AS@%  << 4)))%@AE@%%@NL@%
  11692. %@NL@%
  11693. In this macro, you would pass values in the range 0-3 instead of 0-63.  %@NL@%
  11694. %@NL@%
  11695. %@NL@%
  11696. %@4@%%@AB@%EGA Color Graphics Modes%@AE@%%@EH@%%@NL@%
  11697. %@NL@%
  11698. The %@AB@%_MRES16COLOR%@AE@%, %@AB@%_HRES16COLOR%@AE@%, or %@AB@%_ERESCOLOR%@AE@% video modes display the best
  11699. color graphics with an EGA adapter. The CGA modes will also display on the
  11700. EGA but with the lower CGA resolution and decreased color options.  %@NL@%
  11701. %@NL@%
  11702. The %@AB@%_remappalette%@AE@% function assigns a new color value to a color index. For
  11703. example, when you first enter an EGA graphics mode, color index 1 equals the
  11704. color value blue. To reassign the pure red color value to color index 1, you
  11705. could use this line:  %@NL@%
  11706. %@NL@%
  11707. %@AS@%  _remappalette( 1, 0x000030L );%@AE@%%@NL@%
  11708. %@NL@%
  11709. Or, use the symbolic constant %@AB@%_RED%@AE@%, which is defined in the %@AS@% GRAPH.H %@AE@% file:
  11710. %@NL@%
  11711. %@NL@%
  11712. %@AS@%  _remappalette( 1, _RED );%@AE@%%@NL@%
  11713. %@NL@%
  11714. After this function call, any object currently drawn in color index 1 will
  11715. instantly switch from blue to red.  %@NL@%
  11716. %@NL@%
  11717. For EGA graphics, the first value is an integer in the range 0-15 and the
  11718. second value is a%@AB@% long int%@AE@% defined as a mixture of red, green, and blue (you
  11719. may also use the symbolic constants such as %@AB@%_RED%@AE@%).  %@NL@%
  11720. %@NL@%
  11721. The %@AB@%_remapallpalette%@AE@% function changes all of the color indexes
  11722. simultaneously. You pass it an array of color values. The first color value
  11723. in the list becomes the new color associated with the color index 0.  %@NL@%
  11724. %@NL@%
  11725. The number in a function call to set the color (such as %@AB@%_setcolor%@AE@%) is an
  11726. index into the palette of available colors. In the default text palette, an
  11727. index of 1 refers to blue but the palette could be remapped to change index
  11728. 1 to any other available color. As a result, the color produced by that
  11729. pixel value also changes. The number of color indexes depends on the number
  11730. of colors supported by the current video mode.  %@NL@%
  11731. %@NL@%
  11732. The %@AB@%_remappalette%@AE@% and %@AB@%_remapallpalette%@AE@% functions work in all modes but only
  11733. with the EGA, MCGA, or VGA hardware. The %@AB@%_remappalette%@AE@% and %@AB@%_remapallpalette%@AE@%
  11734. functions fail and return a value of -1 when you attempt to remap a palette
  11735. without the EGA, MCGA, or VGA hardware.  %@NL@%
  11736. %@NL@%
  11737. The following program draws a rectangle with a red interior. In the default
  11738. EGA palette, color index 4 is red. This color index is changed to %@AB@%_BLUE%@AE@% in
  11739. this program.  %@NL@%
  11740. %@NL@%
  11741. %@AS@%  /* EGA.C: EGA palettes. */
  11742. %@AS@%  
  11743. %@AS@%  #include <stdio.h>
  11744. %@AS@%  #include <conio.h>
  11745. %@AS@%  #include <graph.h>
  11746. %@AS@%  
  11747. %@AS@%  main()
  11748. %@AS@%  {
  11749. %@AS@%     _setvideomode( _ERESCOLOR );
  11750. %@AS@%     _setcolor( 4 );
  11751. %@AS@%     _rectangle( _GFILLINTERIOR, 50, 50, 200, 200 );
  11752. %@AS@%  
  11753. %@AS@%     _settextposition( 1, 1 );
  11754. %@AS@%     printf( "Normal palette\n" );
  11755. %@AS@%     printf( "Press a key" );
  11756. %@AS@%     getch();
  11757. %@AS@%  
  11758. %@AS@%     _remappalette( 4, _BLUE );
  11759. %@AS@%  
  11760. %@AS@%     _settextposition( 1, 1 );
  11761. %@AS@%     printf( "Remapped palette\n" );
  11762. %@AS@%     printf( "Press a key" );
  11763. %@AS@%     getch();
  11764. %@AS@%  
  11765. %@AS@%     _remappalette( 4, _RED );
  11766. %@AS@%  
  11767. %@AS@%     _settextposition( 1, 1 );
  11768. %@AS@%     printf( "Restored palette\n" );
  11769. %@AS@%     printf( "Press a key to clear the screen" );
  11770. %@AS@%     getch();
  11771. %@AS@%  
  11772. %@AS@%     _clearscreen( _GCLEARSCREEN );
  11773. %@AS@%     _setvideomode( _DEFAULTMODE );
  11774. %@AS@%  }%@AE@%%@NL@%
  11775. %@NL@%
  11776. %@NL@%
  11777. %@4@%%@AB@%VGA Color Graphics Modes%@AE@%%@EH@%%@NL@%
  11778. %@NL@%
  11779. The VGA card adds graphics modes %@AB@%_VRES2COLOR%@AE@%, %@AB@%_VRES16COLOR%@AE@%, and
  11780. %@AB@%_MRES256COLOR%@AE@% to your repertoire. EGA and CGA modes can also be used with
  11781. the VGA hardware, but with either lower resolution or fewer color choices.  %@NL@%
  11782. %@NL@%
  11783. The VGA color graphics modes operate with a range of 262,144 (256K)  color
  11784. values. The %@AB@%_VRES2COLOR%@AE@% graphics mode displays two colors, the %@AB@%_VRES16COLOR%@AE@%
  11785. graphics mode displays 16, and the %@AB@%_MRES256COLOR%@AE@% graphics mode displays 256
  11786. colors from the available VGA colors.  %@NL@%
  11787. %@NL@%
  11788. %@AB@%Changing the Palette%@AE@% - The %@AB@%_remappalette%@AE@% function changes a color index to a
  11789. specified color value. The function below remaps the color index 1 to the
  11790. color value given by the symbolic constant %@AB@%_RED%@AE@% (which represents red).
  11791. After this statement is executed, whatever was displayed as blue will now
  11792. appear as red:%@NL@%
  11793. %@NL@%
  11794. %@AS@%  _remappalette( 1, _RED );  /*reassign color index 1
  11795. %@AS@%                               to VGA red */%@AE@%%@NL@%
  11796. %@NL@%
  11797. Use the %@AB@%_remapallpalette%@AE@% function to remap all of the available color
  11798. indexes simultaneously. The function's argument references an array of color
  11799. values that reflects the remapping. The first color number in the list
  11800. becomes the new color associated with color index 0.  %@NL@%
  11801. %@NL@%
  11802. Symbolic constants for the default color numbers are supplied so that the
  11803. remapping of VGA colors is compatible with EGA practice. The names of these
  11804. constants are self-explanatory. For example, the color numbers for black,
  11805. red, and light yellow are represented by the symbolic constants %@AB@%_BLACK%@AE@%,
  11806. %@AB@%_RED%@AE@%, and %@AB@%_LIGHTYELLOW%@AE@%.  %@NL@%
  11807. %@NL@%
  11808. All of the VGA display modes operate with any VGA video monitor. Colors are
  11809. displayed as shades of gray when the monochrome analog display is connected.
  11810. %@NL@%
  11811. %@NL@%
  11812. If you have a VGA card, the HORIZON.C program illustrates what can be done
  11813. with the range of 256 colors:  %@NL@%
  11814. %@NL@%
  11815. %@AS@%  /* HORIZON.C: VGA graphics with cycling of 256 colors. */
  11816. %@AS@%  
  11817. %@AS@%  #include <stdio.h>
  11818. %@AS@%  #include <stdlib.h>
  11819. %@AS@%  #include <conio.h>
  11820. %@AS@%  #include <graph.h>
  11821. %@AS@%  
  11822. %@AS@%  #define RED 0x0000003FL
  11823. %@AS@%  #define GRN 0x00003F00L
  11824. %@AS@%  #define BLU 0x003F0000L
  11825. %@AS@%  #define WHT 0x003F3F3FL
  11826. %@AS@%  #define STEP 21
  11827. %@AS@%  
  11828. %@AS@%  struct videoconfig screen;
  11829. %@AS@%  long int rainbow[512];
  11830. %@AS@%  
  11831. %@AS@%  main()
  11832. %@AS@%  {
  11833. %@AS@%     int i;
  11834. %@AS@%     long int col, gray;
  11835. %@AS@%  
  11836. %@AS@%     if( _setvideomode( _MRES256COLOR ) == 0 )
  11837. %@AS@%     {
  11838. %@AS@%        printf( "This program requires a VGA card.\n" );
  11839. %@AS@%        exit( 0 );
  11840. %@AS@%     }
  11841. %@AS@%     for( col = 0; col < 64; col++ )
  11842. %@AS@%     {
  11843. %@AS@%        gray = col | (col << 8) | (col << 16);
  11844. %@AS@%        rainbow[col] = rainbow[col + 256] = BLU & gray;
  11845. %@AS@%        rainbow[col + 64] = rainbow[col + 64 + 256] = BLU | gray;
  11846. %@AS@%        rainbow[col + 128] = rainbow[col + 128 + 256] = RED | (WHT & ~gray);
  11847. %@AS@%        rainbow[col + 192] = rainbow[col + 192 + 256] = RED & ~gray;
  11848. %@AS@%     }
  11849. %@AS@%     _setvieworg( 160, 85 );
  11850. %@AS@%  
  11851. %@AS@%     for( i = 0; i < 255; i++ )
  11852. %@AS@%     {
  11853. %@AS@%        _setcolor( 255 - i );
  11854. %@AS@%        _moveto( i, i - 255 );
  11855. %@AS@%        _lineto( -i, 255 - i );
  11856. %@AS@%        _moveto( -i, i - 255 );
  11857. %@AS@%        _lineto( i, 255 - i );
  11858. %@AS@%        _ellipse( _GBORDER, -i, -i / 2, i, i / 2 );
  11859. %@AS@%     }
  11860. %@AS@%     for( i = 0; !kbhit(); i += STEP, i %= 256 )
  11861. %@AS@%        _remapallpalette( &(rainbow[i]) );
  11862. %@AS@%  
  11863. %@AS@%     _setvideomode( _DEFAULTMODE );
  11864. %@AS@%  }%@AE@%%@NL@%
  11865. %@NL@%
  11866. %@NL@%
  11867. %@3@%%@CR:C6A00130007 @%%@AB@%Using the Color Video Text Modes%@AE@%%@EH@%%@NL@%
  11868. %@NL@%
  11869. Two color video text modes, %@AB@%_TEXTC40%@AE@% and %@AB@%_TEXTC80%@AE@%, can be used with the CGA,
  11870. EGA, and VGA displays. These modes display steady or blinking text in any of
  11871. 16 foreground colors with any one of 8 background colors.  %@NL@%
  11872. %@NL@%
  11873. %@NL@%
  11874. %@4@%%@AB@%Basics of Text Color Selection%@AE@%%@EH@%%@NL@%
  11875. %@NL@%
  11876. In a video text mode, each displayed character requires two bytes of video
  11877. memory. The first byte contains the ASCII code representing the character
  11878. and the second byte contains the display attribute. In the CGA color video
  11879. text modes, the attribute byte determines the color and whether it will
  11880. blink. Sixteen colors are available: the CGA pixel values, and the default
  11881. EGA and VGA pixel values. Since the EGA and VGA palette can be remapped,
  11882. these values can be made to correspond to any set of 16 colors with the
  11883. appropriate palette mapping.  %@NL@%
  11884. %@NL@%
  11885. %@NL@%
  11886. %@4@%%@AB@%Using Text Colors%@AE@%%@EH@%%@NL@%
  11887. %@NL@%
  11888. Use the %@AB@%_gettextcolor%@AE@% and %@AB@%_getbkcolor%@AE@% functions to find the current text
  11889. foreground and background colors.  %@NL@%
  11890. %@NL@%
  11891. Values in the range 0-15 are interpreted as normal color. Values in the
  11892. range 16-31 are the same colors as those in the range 0-15 but with blinking
  11893. text.  %@NL@%
  11894. %@NL@%
  11895. Use the %@AB@%_settextcolor%@AE@% and %@AB@%_setbkcolor%@AE@% functions to set foreground and
  11896. background colors in video text mode. These functions use a single argument
  11897. that specifies the pixel value to be used for text displayed with the
  11898. %@AB@%_outtext%@AE@% function. The color indexes for color video text modes are defined
  11899. in Table 13.4.  %@NL@%
  11900. %@NL@%
  11901. %@AB@%Table 13.4  %@AB@%Text Colors%@AE@%%@AE@%
  11902.  
  11903. %@TH:  11   556 02 08 10 08 50 @%
  11904. Number  Color     Number  Color
  11905. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11906. 0       Black     8       Dark gray
  11907. 1       Blue      9       Light blue
  11908. 2       Green     10      Light green
  11909. 3       Cyan      11      Light cyan
  11910. 4       Red       12      Light red
  11911. 5       Magenta   13      Light magenta
  11912. 6       Brown     14      Light brown
  11913. 7       White     15      Light white
  11914. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  11915. %@TE:  11   556 02 08 10 08 50 @%
  11916.  
  11917. %@NL@%
  11918. %@4@%%@AB@%Displaying Color Text%@AE@%%@EH@%%@NL@%
  11919. %@NL@%
  11920. The %@AB@%_settextposition%@AE@% function moves the cursor to a row and column for
  11921. displaying color text. The %@AB@%_outtext%@AE@% function displays the text.  %@NL@%
  11922. %@NL@%
  11923. %@NL@%
  11924. %@4@%%@AB@%Example: Viewing Text Colors%@AE@%%@EH@%%@NL@%
  11925. %@NL@%
  11926. The following program displays a chart showing all possible combinations of
  11927. text and background colors:  %@NL@%
  11928. %@NL@%
  11929. %@AS@%  /* COLTEXT.C: Display text in color. */
  11930. %@AS@%  
  11931. %@AS@%  #include <stdio.h>
  11932. %@AS@%  #include <conio.h>
  11933. %@AS@%  #include <graph.h>
  11934. %@AS@%  
  11935. %@AS@%  char buffer [80];
  11936. %@AS@%  
  11937. %@AS@%  main()
  11938. %@AS@%  {
  11939. %@AS@%     int blink,fgd;
  11940. %@AS@%     long bgd;
  11941. %@AS@%  
  11942. %@AS@%     _clearscreen( _GCLEARSCREEN );
  11943. %@AS@%     printf( "Text color attributes:\n" );
  11944. %@AS@%  
  11945. %@AS@%     for( blink=0; blink<=16; blink+=16 )
  11946. %@AS@%     {
  11947. %@AS@%        for( bgd=0; bgd<8; bgd++ )
  11948. %@AS@%        {
  11949. %@AS@%           _setbkcolor( bgd );
  11950. %@AS@%           _settextposition( bgd + ((blink / 16) * 9) + 3, 1 );
  11951. %@AS@%           _settextcolor( 7 );
  11952. %@AS@%           sprintf( buffer, "Bgd: %d Fgd:", bgd );
  11953. %@AS@%           _outtext( buffer );
  11954. %@AS@%   
  11955. %@AS@%           for( fgd=0; fgd<16; fgd++ )
  11956. %@AS@%           {
  11957. %@AS@%              _settextcolor( fgd+blink );
  11958. %@AS@%              sprintf( buffer, " %2d ", fgd+blink );
  11959. %@AS@%              _outtext( buffer );
  11960. %@AS@%           }
  11961. %@AS@%        }
  11962. %@AS@%     }
  11963. %@AS@%     getch();
  11964. %@AS@%     _setvideomode( _DEFAULTMODE );
  11965. %@AS@%  }%@AE@%%@NL@%
  11966. %@NL@%
  11967. %@NL@%
  11968. %@2@%%@CR:C6A00130008 @%%@AB@%Text Coordinates%@AE@%%@EH@%%@NL@%
  11969. %@NL@%
  11970. Before you can write a program to print a word %@AI@%over there%@AE@% on the screen, you
  11971. need a system that describes to the compiler where %@AI@%there%@AE@% really is. QuickC
  11972. divides the text screen into rows and columns. See Figure 13.2.  %@NL@%
  11973. %@NL@%
  11974. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  11975. %@NL@%
  11976. Two important conventions to keep in mind about video text mode are:  %@NL@%
  11977. %@NL@%
  11978. %@NL@%
  11979.   1.  Numbering starts at 1, not 0. An 80-column screen contains columns
  11980.       1-80.%@NL@%
  11981. %@NL@%
  11982.   2.  The row is always listed before the column.%@NL@%
  11983. %@NL@%
  11984. %@NL@%
  11985. If the screen is in a video text mode that displays 25 rows and 80 columns
  11986. (as in Figure 13.2), the rows are numbered 1-25 and the columns are numbered
  11987. 1-80. In functions such as %@AB@%_settextposition%@AE@%, which is called in the next
  11988. example program, the parameters you pass are row and column (in that order).
  11989. %@NL@%
  11990. %@NL@%
  11991. %@NL@%
  11992. %@2@%%@CR:C6A00130009 @%%@AB@%Graphics Coordinates%@AE@%%@EH@%%@NL@%
  11993. %@NL@%
  11994. A similar (but slightly different) system is used for locating pixels on a
  11995. graphics screen. There are three ways of describing the location of pixels
  11996. on the screen:  %@NL@%
  11997. %@NL@%
  11998. %@NL@%
  11999.   1.  The physical screen coordinates%@NL@%
  12000. %@NL@%
  12001.   2.  The viewport coordinates%@NL@%
  12002. %@NL@%
  12003.   3.  The window coordinates%@NL@%
  12004. %@NL@%
  12005. %@NL@%
  12006. Each method is explained in the following sections.  %@NL@%
  12007. %@NL@%
  12008. %@NL@%
  12009. %@3@%%@CR:C6A00130010 @%%@AB@%The Physical Screen%@AE@%%@EH@%%@NL@%
  12010. %@NL@%
  12011. Suppose you write a program that calls %@AB@%_setvideomode%@AE@% and puts the screen
  12012. into the VGA graphics mode %@AB@%_VRES16COLOR%@AE@%. This gives you a screen containing
  12013. 640 horizontal pixels and 480 vertical pixels. The individual pixels are
  12014. named by their location relative to the %@AI@%x%@AE@% axis and %@AI@%y%@AE@% axis, as shown in
  12015. Figure 13.3.  %@NL@%
  12016. %@NL@%
  12017. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12018. %@NL@%
  12019. Two important differences between text coordinates and pixel coordinates
  12020. are:  %@NL@%
  12021. %@NL@%
  12022. %@NL@%
  12023.   1.  Numbering starts at 0, not 1. If there are 640 pixels, they're
  12024.       numbered 0-639.%@NL@%
  12025. %@NL@%
  12026.   2.  The %@AI@%x%@AE@% coordinate (equivalent to a text column) is listed before the %@AI@%y%@AE@%
  12027.       coordinate.%@NL@%
  12028. %@NL@%
  12029. %@NL@%
  12030. The upper left corner is called the "origin." The %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinates for
  12031. the origin are always (0, 0). If you use variables to refer to pixel
  12032. locations, declare them as integers.  %@NL@%
  12033. %@NL@%
  12034. %@NL@%
  12035. %@4@%%@AB@%Changing the Origin with _setvieworg%@AE@%%@EH@%%@NL@%
  12036. %@NL@%
  12037. The %@AB@%_setvieworg%@AE@% function changes the current location of the viewport's
  12038. origin. When you first enter graphics mode, the "viewport" is equivalent to
  12039. the physical  %@NL@%
  12040. %@NL@%
  12041. screen. You pass two integers, which represent the %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinates of a
  12042. physical screen location. For example, the following line would move the
  12043. origin to the physical screen location (50, 100):  %@NL@%
  12044. %@NL@%
  12045. %@AS@%  _setvieworg( 50, 100 );%@AE@%%@NL@%
  12046. %@NL@%
  12047. The effect on the screen is illustrated in Figure 13.4.  %@NL@%
  12048. %@NL@%
  12049. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12050. %@NL@%
  12051. The number of pixels hasn't changed, but the names given to the points have
  12052. changed. The %@AI@%x%@AE@% axis now ranges from -50 to +589 instead of 0 to 639. The %@AI@%y%@AE@%
  12053. axis now covers the values -100 to +379. (If you own an adapter other than
  12054. the VGA, the numbers are different but the effect is the same.)  %@NL@%
  12055. %@NL@%
  12056. All standard graphics functions are affected by the new origin, including
  12057. %@AB@%_arc%@AE@%, %@AB@%_ellipse%@AE@%, %@AB@%_lineto%@AE@%, %@AB@%_moveto%@AE@%, %@AB@%_pie%@AE@%, and %@AB@%_rectangle%@AE@%.  %@NL@%
  12058. %@NL@%
  12059. For example, if you call the %@AB@%_rectangle%@AE@% function after relocating the
  12060. viewport origin, and pass it the values (0, 0) and (40, 40), the rectangle
  12061. would be drawn 50 pixels from the left edge of the screen and 100 pixels
  12062. from the top. It would not appear in the upper left corner.  %@NL@%
  12063. %@NL@%
  12064. The values passed to %@AB@%_setvieworg%@AE@% are always physical screen locations.
  12065. Suppose you called the same function twice:  %@NL@%
  12066. %@NL@%
  12067. %@AS@%  _setvieworg( 50, 100 );
  12068. %@AS@%  _setvieworg( 50, 100 );%@AE@%%@NL@%
  12069. %@NL@%
  12070. The viewport origin would not move to (100, 200). It would remain at the
  12071. phys-ical screen location (50, 100).  %@NL@%
  12072. %@NL@%
  12073. %@NL@%
  12074. %@4@%%@AB@%Defining a Clipping Region with _setcliprgn%@AE@%%@EH@%%@NL@%
  12075. %@NL@%
  12076. The %@AB@%_setcliprgn%@AE@% function creates an invisible rectangular area on the screen
  12077. called a "clipping region." Attempts to draw inside the clipping region are
  12078. successful, while attempts to draw outside the region are not.  %@NL@%
  12079. %@NL@%
  12080. When you first enter a graphics mode, the default clipping region occupies
  12081. the entire screen. QuickC ignores any attempts to draw outside the screen.  %@NL@%
  12082. %@NL@%
  12083. Changing the clipping region requires one call to %@AB@%_setcliprgn%@AE@%. Suppose
  12084. you've entered the CGA graphics mode %@AB@% _MRES4COLOR%@AE@%, which has a screen
  12085. resolution of 320 x 200. If you draw a diagonal line from (0, 0) to (319,
  12086. 199), from the top left to the bottom right corner, the screen looks like
  12087. Figure 13.5.  %@NL@%
  12088. %@NL@%
  12089. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12090. %@NL@%
  12091. You could create a clipping region with this line:  %@NL@%
  12092. %@NL@%
  12093. %@AS@%  _setcliprgn( 10, 10, 309, 189 )%@AE@%%@NL@%
  12094. %@NL@%
  12095. With the clipping region in effect, the same %@AB@%_lineto%@AE@% command would put the
  12096. line shown in Figure 13.6 on the screen.  %@NL@%
  12097. %@NL@%
  12098. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12099. %@NL@%
  12100. The broken lines don't actually print on the screen. They indicate the outer
  12101. bounds of the clipping region.  %@NL@%
  12102. %@NL@%
  12103. %@NL@%
  12104. %@3@%%@CR:C6A00130011 @%%@AB@%Viewport Coordinates%@AE@%%@EH@%%@NL@%
  12105. %@NL@%
  12106. The %@AB@%_setviewport%@AE@% function establishes a new viewport within the boundaries
  12107. of the physical screen. A standard viewport has two distinguishing features:
  12108. %@NL@%
  12109. %@NL@%
  12110. %@NL@%
  12111.   1.  The origin of a viewport is in the upper left corner.%@NL@%
  12112. %@NL@%
  12113.   2.  The clipping region matches the outer boundaries of the viewport.%@NL@%
  12114. %@NL@%
  12115. %@NL@%
  12116. The %@AB@%_setviewport%@AE@% function does the same thing as calling the %@AB@%_setvieworg%@AE@% and
  12117. the %@AB@%_setcliprgn%@AE@% functions.  %@NL@%
  12118. %@NL@%
  12119. %@NL@%
  12120. %@3@%%@CR:C6A00130012 @%%@AB@%Real Coordinates in a Window%@AE@%%@EH@%%@NL@%
  12121. %@NL@%
  12122. Functions that refer to coordinates on the physical screen and within the
  12123. viewport require integer values. In real-life graphing applications, you
  12124. might wish to use floating-point values─stock prices, the price of wheat,
  12125. average rainfall, and so on. The %@AB@%_setwindow%@AE@% function allows you to scale the
  12126. screen to almost any size. In addition, the window-related functions take
  12127. double-precision, floating-point values instead of integers.  %@NL@%
  12128. %@NL@%
  12129. For example, say you want to graph 12 months of average temperatures that
  12130. range from -40 to +100. You could add the following line to your program:  %@NL@%
  12131. %@NL@%
  12132. %@AS@%  _setwindow( TRUE, 1.0, -40.0, 12.0, 100.0 );%@AE@%%@NL@%
  12133. %@NL@%
  12134. The first argument is the invert flag, which puts the lowest %@AI@%y%@AE@% value in the
  12135. bottom left corner. The minimum and maximum Cartesian coordinates follow
  12136. (the decimal point marks them as floating-point values). The new
  12137. organization of the screen is shown in Figure 13.7.  %@NL@%
  12138. %@NL@%
  12139. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12140. %@NL@%
  12141. Note that January and December are plotted on the left and right edges of
  12142. the screen. In an application like this, it might be better to number the %@AI@%x%@AE@%
  12143. axis from 0.0 to 13.0, to provide some extra space.  %@NL@%
  12144. %@NL@%
  12145. If you next plot a point with %@AB@%_setpixel_w%@AE@% or draw a line with %@AB@%_lineto_w%@AE@%, the
  12146. values are automatically scaled to the established window.  %@NL@%
  12147. %@NL@%
  12148. Follow these four steps to use real-coordinate graphics:  %@NL@%
  12149. %@NL@%
  12150. %@NL@%
  12151.   1.  Enter a graphics mode with %@AB@%_setvideomode%@AE@%.%@NL@%
  12152. %@NL@%
  12153.   2.  Use %@AB@%_setviewport%@AE@% to create a viewport area. (This step is optional if
  12154.       you plan to use the entire screen.)%@NL@%
  12155. %@NL@%
  12156.   3.  Create a real-coordinate window with %@AB@%_setwindow%@AE@%, passing an %@AB@%int%@AE@% invert
  12157.       flag and four %@AB@%double%@AE@% %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinates for the minimum and maximum
  12158.       values.%@NL@%
  12159. %@NL@%
  12160.   4.  Draw graphics shapes with %@AB@%_rectangle_w%@AE@% and other functions. Do not
  12161.       confuse %@AB@%_rectangle%@AE@% (the viewport function) with %@AB@%_rectangle_w%@AE@% (the
  12162.       window function for drawing rectangles). All window functions end with
  12163.       an underscore and a letter %@AB@%w%@AE@% or an underscore and %@AB@%wxy%@AE@%.%@NL@%
  12164. %@NL@%
  12165. %@NL@%
  12166. Real-coordinate graphics can give you a lot of flexibility. For example, you
  12167. can fit either axis into a small range (such as 151.25 to 151.45) or into a
  12168. large range (-50,000 to +80,000), depending on the type of data you're
  12169. graphing. In addition, by changing the window coordinates, you can create
  12170. the effects of zooming in or panning across a figure.  %@NL@%
  12171. %@NL@%
  12172. %@NL@%
  12173. %@4@%%@AB@%Example Program%@AE@%%@EH@%%@NL@%
  12174. %@NL@%
  12175. The program below illustrates some ways to use the real-coordinate windowing
  12176. functions.  %@NL@%
  12177. %@NL@%
  12178. %@AS@%  /* REALG.C: Real-coordinate graphics. */
  12179. %@AS@%  
  12180. %@AS@%  #include <stdio.h>
  12181. %@AS@%  #include <conio.h>
  12182. %@AS@%  #include <graph.h>
  12183. %@AS@%  
  12184. %@AS@%  #define TRUE 1
  12185. %@AS@%  #define FALSE 0
  12186. %@AS@%  
  12187. %@AS@%  int four_colors( void );
  12188. %@AS@%  void three_graphs( void );
  12189. %@AS@%  void grid_shape( void );
  12190. %@AS@%  
  12191. %@AS@%  int halfx, halfy;
  12192. %@AS@%  struct videoconfig screen;
  12193. %@AS@%  double bananas[] =
  12194. %@AS@%    {
  12195. %@AS@%      -0.3, -0.2, -0.224, -0.1, -0.5, +0.21, +2.9,
  12196. %@AS@%      +0.3, +0.2, 0.0, -0.885, -1.1, -0.3, -0.2,
  12197. %@AS@%      +.001, +.005, +0.14, 0.0, -0.9, -0.13, +0.3
  12198. %@AS@%    };
  12199. %@AS@%  
  12200. %@AS@%  main()
  12201. %@AS@%  {
  12202. %@AS@%    if( four_colors() )
  12203. %@AS@%       three_graphs();
  12204. %@AS@%    else
  12205. %@AS@%       printf( "This program requires a CGA, EGA,\
  12206. %@AS@%               or VGA graphics card.\n" );
  12207. %@AS@%  }
  12208. %@AS@%  /*
  12209. %@AS@%  . Additional functions defined below
  12210. %@AS@%  .
  12211. %@AS@%  .
  12212. %@AS@%  */%@AE@%%@NL@%
  12213. %@NL@%
  12214. The %@AB@%main%@AE@% function is very short. It calls the %@AS@% four_colors %@AE@% function
  12215. (defined below), which attempts to enter a graphics mode where at least four
  12216. colors are available. If it succeeds, the %@AS@% three_graphs %@AE@% function is called,
  12217. which uses the numbers in the %@AS@% bananas %@AE@% array to draw three graphs. The
  12218. REALG.C screen output is shown in Figure 13.8.  %@NL@%
  12219. %@NL@%
  12220. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12221. %@NL@%
  12222. It's worth noting that the %@AS@% grid_shape %@AE@% function (defined below) that draws
  12223. the graphs is using the same numbers in each case. However, the program uses
  12224. three different real-coordinate windows. The two windows in the top half are
  12225. the same size in physical coordinates, but they have different window sizes.
  12226. In all three cases, the grid is 2 units wide. In the upper left corner, the
  12227. window is 4 units wide; in the upper right, the window is 6 units wide,
  12228. which makes the graph appear smaller.  %@NL@%
  12229. %@NL@%
  12230. In two of the three graphs, one of the lines goes off the edge, outside the
  12231. clipping region. The lines do not intrude into the other windows, since
  12232. defining a window creates a clipping region.  %@NL@%
  12233. %@NL@%
  12234. Finally, note that the graph on the bottom of the screen seems to be upside
  12235. down with respect to the two graphs above it.  %@NL@%
  12236. %@NL@%
  12237. %@NL@%
  12238. %@4@%%@AB@%Checking the Adapter%@AE@%%@EH@%%@NL@%
  12239. %@NL@%
  12240. The first step in any graphics program is to enter a graphics mode. The %@AS@%
  12241. %@AS@%four_colors %@AE@% function performs this step:  %@NL@%
  12242. %@NL@%
  12243. %@AS@%  /* four_colors function from REALG.C. */
  12244. %@AS@%  
  12245. %@AS@%  int four_colors( void )
  12246. %@AS@%  {
  12247. %@AS@%     _getvideoconfig( &screen );
  12248. %@AS@%     switch( screen.adapter )
  12249. %@AS@%     {
  12250. %@AS@%        case _CGA:
  12251. %@AS@%        case _OCGA:
  12252. %@AS@%           _setvideomode( _MRES4COLOR );
  12253. %@AS@%           break;
  12254. %@AS@%        case _EGA:
  12255. %@AS@%        case _OEGA:
  12256. %@AS@%           _setvideomode( _ERESCOLOR );
  12257. %@AS@%           break;
  12258. %@AS@%        case _VGA:
  12259. %@AS@%        case _OVGA:
  12260. %@AS@%           _setvideomode( _VRES16COLOR );
  12261. %@AS@%           break;
  12262. %@AS@%        default:
  12263. %@AS@%           return( FALSE );
  12264. %@AS@%     }
  12265. %@AS@%     _getvideoconfig( &screen );
  12266. %@AS@%     return( TRUE );
  12267. %@AS@%  }%@AE@%%@NL@%
  12268. %@NL@%
  12269. The %@AB@%_getvideoconfig%@AE@% function places some information into the %@AB@%videoconfig%@AE@%
  12270. structure called %@AS@% screen%@AE@%. Then we use the member %@AS@% screen.adapter %@AE@% in a
  12271. %@AB@%switch%@AE@% statement construct to turn on the matching graphics mode. The
  12272. symbolic constants %@AB@%_CGA%@AE@% and the rest are defined in the GRAPH.H file. The
  12273. modes that begin with the letter %@AB@%O%@AE@% are Olivetti modes.  %@NL@%
  12274. %@NL@%
  12275. If the computer is equipped with a color card, %@AB@%_getvideoconfig%@AE@% returns a
  12276. %@AB@%TRUE%@AE@%. If it is not, it returns a %@AB@%FALSE%@AE@%, which causes %@AB@%main%@AE@% to skip the %@AS@%
  12277. %@AS@%three_graphs %@AE@% function.  %@NL@%
  12278. %@NL@%
  12279. %@NL@%
  12280. %@4@%%@AB@%Three Windows, Three Graphs%@AE@%%@EH@%%@NL@%
  12281. %@NL@%
  12282. If the %@AS@% four_colors %@AE@% function works properly, %@AB@%main%@AE@% calls the function below,
  12283. which prints the three graphs.  %@NL@%
  12284. %@NL@%
  12285. %@AS@%  /* three_graphs function from REALG.C. */
  12286. %@AS@%  
  12287. %@AS@%  void three_graphs( void )
  12288. %@AS@%  {
  12289. %@AS@%     int xwidth, yheight, cols, rows;
  12290. %@AS@%     struct _wxycoord upleft, botright;
  12291. %@AS@%  
  12292. %@AS@%     _clearscreen( _GCLEARSCREEN );
  12293. %@AS@%     xwidth = screen.numxpixels;
  12294. %@AS@%     yheight = screen.numypixels;
  12295. %@AS@%     halfx = xwidth/2;
  12296. %@AS@%     halfy = yheight/2;
  12297. %@AS@%     cols = screen.numtextcols;
  12298. %@AS@%     rows = screen.numtextrows;
  12299. %@AS@%   
  12300. %@AS@%     /* first window */
  12301. %@AS@%     _setviewport( 0, 0, halfx-1, halfy-1 );
  12302. %@AS@%     _settextwindow( 1, 1, rows/2, cols/2 );
  12303. %@AS@%     _setwindow( FALSE, -2.0, -2.0, 2.0, 2.0 );
  12304. %@AS@%     grid_shape();
  12305. %@AS@%     _rectangle( _GBORDER, 0, 0, halfx-1, halfy-1 );
  12306. %@AS@%   
  12307. %@AS@%     /* second window */
  12308. %@AS@%     _setviewport( halfx, 0, xwidth-1, halfy-1 );
  12309. %@AS@%     _settextwindow( 1, cols/2+1, rows/2, cols );
  12310. %@AS@%     _setwindow( FALSE, -3.0, -3.0, 3.0, 3.0 );
  12311. %@AS@%     grid_shape();
  12312. %@AS@%     _rectangle_w( _GBORDER, -3.0, -3.0, 3.0, 3.0 );
  12313. %@AS@%   
  12314. %@AS@%     /* third window */
  12315. %@AS@%     _setviewport( 0, halfy, xwidth-1, yheight-1 );
  12316. %@AS@%     _settextwindow( rows/2+1, 1, rows, cols );
  12317. %@AS@%     _setwindow( TRUE, -3.0, -1.5, 1.5, 1.5 );
  12318. %@AS@%     grid_shape();
  12319. %@AS@%     upleft.wx = -3.0;
  12320. %@AS@%     upleft.wy = -1.5;
  12321. %@AS@%     botright.wx = 1.5;
  12322. %@AS@%     botright.wy = 1.5;
  12323. %@AS@%     _rectangle_wxy( _GBORDER, &upleft, &botright );
  12324. %@AS@%   
  12325. %@AS@%     getch();
  12326. %@AS@%     _setvideomode( _DEFAULTMODE );
  12327. %@AS@%  }%@AE@%%@NL@%
  12328. %@NL@%
  12329. %@AB@%Clearing the Screen%@AE@% - Although entering a graphics mode automatically clears
  12330. the screen, it doesn't hurt to be sure, so %@AS@% three_graphs %@AE@% calls the
  12331. %@AB@%_clearscreen%@AE@% function:%@NL@%
  12332. %@NL@%
  12333. %@AS@%  _clearscreen( _GCLEARSCREEN );%@AE@%%@NL@%
  12334. %@NL@%
  12335. The %@AB@%_GCLEARSCREEN%@AE@% constant causes the entire physical screen to clear. Other
  12336. options include %@AB@%_GVIEWPORT%@AE@% and %@AB@%_GWINDOW%@AE@%, which clear the current viewport
  12337. and the current text window, respectively.  %@NL@%
  12338. %@NL@%
  12339. %@AB@%The First Window%@AE@% - After assigning values to some variables, the %@AS@%
  12340. %@AS@%three_graphs %@AE@% function creates the first window:%@NL@%
  12341. %@NL@%
  12342. %@AS@%  _setviewport( 0, 0, halfx - 1, halfy - 1 );
  12343. %@AS@%  _settextwindow( 1, 1, rows / 2, cols / 2 );
  12344. %@AS@%  _setwindow( FALSE, -2.0, -2.0, 2.0, 2.0 );%@AE@%%@NL@%
  12345. %@NL@%
  12346. First a viewport is defined to cover the upper left quarter of the screen.
  12347. Next, a text window is defined within the boundaries of that border. (Note
  12348. the numbering starts at 1 and the row location precedes the column.)
  12349. Finally, a window is defined. The %@AB@%FALSE%@AE@% constant forces the %@AI@%y%@AE@% axis to
  12350. increase from top to bottom. The corners of the window are (-2.0, -2.0) in
  12351. the upper left and (2.0, 2.0) in the bottom right corner.  %@NL@%
  12352. %@NL@%
  12353. Next, the function %@AS@% grid_shape %@AE@% is called, and a border is added to the
  12354. window:  %@NL@%
  12355. %@NL@%
  12356. %@AS@%  grid_shape();
  12357. %@AS@%  _rectangle( _GBORDER, 0, 0, halfx-1, halfy-1 );%@AE@%%@NL@%
  12358. %@NL@%
  12359. Note that this is the standard %@AB@%_rectangle%@AE@% function, which takes coordinates
  12360. relative to the viewport (not window coordinates).  %@NL@%
  12361. %@NL@%
  12362. %@AB@%Two More Windows%@AE@% - The two other windows are similar to the first. All three
  12363. call %@AS@% grid_shape %@AE@% (defined below), which draws a grid from location (-1.0,
  12364. -1.0) to (+1.0, +1.0). The grid appears in different sizes because the
  12365. coordinates in the windows vary. The second window ranges from (-3.0, -3.0)
  12366. to (+3.0, +3.0), so the width of the grid is one-third the width of the
  12367. second window, while it is one-half the width of the first.%@NL@%
  12368. %@NL@%
  12369. Note also that the third window contains a %@AB@%TRUE%@AE@% as the first argument. This
  12370. causes the%@AI@% y %@AE@%axis to increase from bottom to top, instead of top to bottom.
  12371. As a result, this graph appears to be upside down in relation to the other
  12372. two.  %@NL@%
  12373. %@NL@%
  12374. After calling %@AS@% grid_shape%@AE@%, the program frames each window with one of the
  12375. following functions:  %@NL@%
  12376. %@NL@%
  12377. %@AS@%  _rectangle( _GBORDER, 0, 0, halfx -1, halfy -1 );%@AE@%%@NL@%
  12378. %@NL@%
  12379. %@AS@%  _rectangle_w( _GBORDER, -3.0, -3.0, 3.0, 3.0 ); %@AE@%%@NL@%
  12380. %@NL@%
  12381. %@AS@%  _rectangle_wxy( _GBORDER, &upleft, &botright );%@AE@%%@NL@%
  12382. %@NL@%
  12383. All three functions contain a fill flag as the first argument. The
  12384. %@AB@%_rectangle%@AE@% function takes integer arguments that refer to the viewport
  12385. screen coordinates. The function %@AB@%_rectangle_w%@AE@% takes four double-precision,
  12386. floating-point values referring to window coordinates: upper left %@AI@%x%@AE@%, upper
  12387. left %@AI@%y%@AE@%, lower right %@AI@%x%@AE@%, and lower right %@AI@%y%@AE@%. The function %@AB@%_rectangle_wxy%@AE@% takes
  12388. two arguments: the addresses of two structures of type %@AB@%_wxycoord%@AE@%, which
  12389. contains two %@AB@%double%@AE@% types named %@AB@%wx%@AE@% and %@AB@%wy%@AE@%. The structure is defined in
  12390. GRAPH.H. The values are assigned just before %@AB@%_rectangle_wxy%@AE@% is called.  %@NL@%
  12391. %@NL@%
  12392. %@AB@%Text, Colors, and Lines%@AE@% - The %@AS@% grid_shape %@AE@% function is shown below:%@NL@%
  12393. %@NL@%
  12394. %@AS@%  /* grid_shape from the REALG.C program. */
  12395. %@AS@%  
  12396. %@AS@%  void grid_shape( void )
  12397. %@AS@%  {
  12398. %@AS@%     int i, numc, x1, y1, x2, y2;
  12399. %@AS@%     double x, y;
  12400. %@AS@%     char txt[80];%@AE@%%@NL@%
  12401. %@NL@%
  12402. %@AS@%  numc = screen.numcolors;
  12403. %@AS@%     for( i = 1; i <numc; i++ )
  12404. %@AS@%     {
  12405. %@AS@%        _settextposition( i, 2 );
  12406. %@AS@%        _settextcolor( i );
  12407. %@AS@%        sprintf( txt, "Color %d", i );
  12408. %@AS@%        _outtext( txt );
  12409. %@AS@%     }
  12410. %@AS@%     _setcolor( 1 );
  12411. %@AS@%     _rectangle_w( _GBORDER, -1.0, -1.0, 1.0, 1.0 );
  12412. %@AS@%     _rectangle_w( _GBORDER, -1.02, -1.02, 1.02, 1.02 );%@AE@%%@NL@%
  12413. %@NL@%
  12414. %@AS@%  for( x = -0.9, i = 0; x <0.9; x += 0.1 )
  12415. %@AS@%     {
  12416. %@AS@%        _setcolor( 2 );
  12417. %@AS@%        _moveto_w( x, -1.0 );
  12418. %@AS@%        _lineto_w( x, 1.0 );
  12419. %@AS@%        _moveto_w( -1.0, x );
  12420. %@AS@%        _lineto_w( 1.0, x );
  12421. %@AS@%  
  12422. %@AS@%        _setcolor( 3 );
  12423. %@AS@%        _moveto_w( x - 0.1, bananas[i++] );
  12424. %@AS@%        _lineto_w( x, bananas[i] );
  12425. %@AS@%     }
  12426. %@AS@%     _moveto_w( 0.9, bananas[i++] );
  12427. %@AS@%     _lineto_w( 1.0, bananas[i] );
  12428. %@AS@%  }%@AE@%%@NL@%
  12429. %@NL@%
  12430. First, the number of available color indexes is assigned to the %@AS@% numc %@AE@%
  12431. variable and a %@AB@%for%@AE@% loop displays all of the available colors:  %@NL@%
  12432. %@NL@%
  12433. %@AS@%  numc = screen.numcolors;
  12434. %@AS@%  for( i = 1; i < numc; i++ )
  12435. %@AS@%  {
  12436. %@AS@%     _settextposition( i, 2 );
  12437. %@AS@%     _settextcolor( i );
  12438. %@AS@%     sprintf( txt, "Color %d", i );
  12439. %@AS@%     _outtext( txt );
  12440. %@AS@%  }%@AE@%%@NL@%
  12441. %@NL@%
  12442. The names of the functions are self-explanatory. The advantage of using
  12443. %@AB@%_outtext%@AE@% in graphics mode is that, unlike %@AB@%printf%@AE@%, you can control the text
  12444. color.  %@NL@%
  12445. %@NL@%
  12446. The function names that end with %@AB@%_w%@AE@% work the same as their viewport
  12447. equivalents, except you pass double-precision, floating-point values instead
  12448. of integers. For example, you pass integers to %@AB@%_lineto%@AE@% but floating-point
  12449. values to %@AB@%_lineto_w.%@AE@%  %@NL@%
  12450. %@NL@%
  12451. If you're interested in further explorations of graphics, Chapters 14 and 15
  12452. introduce Presentation Graphics and fonts, both of which offer even more
  12453. graphics options.  %@NL@%
  12454. %@NL@%
  12455. %@NL@%
  12456. %@NL@%
  12457. %@NL@%
  12458. %@NL@%
  12459. %@NL@%
  12460. %@CR:C6A00140001 @%%@1@%%@AB@%Chapter 14  Presentation Graphics%@AE@%%@EH@%%@NL@%
  12461. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12462. %@NL@%
  12463. Presentation Graphics is the name given to a library of chart-generating
  12464. functions included with the QuickC package. With these functions your QuickC
  12465. programs can display data as a variety of graphs such as pie charts, bar and
  12466. column charts, line graphs, and scatter diagrams. Whole columns of
  12467. unintelligible numbers can be reduced to a single expressive picture with
  12468. Presentation Graphics.  %@NL@%
  12469. %@NL@%
  12470. This chapter shows you how to use the Presentation Graphics library in your
  12471. QuickC programs. The first section is an introduction to Presentation
  12472. Graphics. It explains terminology and describes some of the library's many
  12473. capabilities. The middle sections of this chapter list the steps involved in
  12474. writing a charting program and illustrate them with short examples.  %@NL@%
  12475. %@NL@%
  12476. The concluding portions of the chapter delve more deeply into Presentation
  12477. Graphics. Here you'll learn about the Presentation Graphics default data
  12478. structures and how to manipulate them. The final section presents a short
  12479. reference list of all the functions that comprise the Presentation Graphics
  12480. library.  %@NL@%
  12481. %@NL@%
  12482. To use Presentation Graphics you need a graphics adapter and a monitor
  12483. capable of bit-mapped display─the same equipment mentioned in Chapter 13,
  12484. "Graphics." Support is provided for CGA, EGA, VGA, MCGA, Hercules monochrome
  12485. graphics, and Olivetti Color Board.  %@NL@%
  12486. %@NL@%
  12487. %@NL@%
  12488. %@2@%%@CR:C6A00140002 @%%@AB@%Terminology%@AE@%%@EH@%%@NL@%
  12489. %@NL@%
  12490. Certain terms and phrases pertaining to Presentation Graphics and its
  12491. functions are used throughout this chapter. The following description of
  12492. Presentation Graphics terminology will help you better understand this
  12493. chapter.  %@NL@%
  12494. %@NL@%
  12495. %@NL@%
  12496. %@4@%%@AB@%Data Series%@AE@%%@EH@%%@NL@%
  12497. %@NL@%
  12498. %@AU@% Groups or series of data can be graphed on the same chart.%@AE@%  %@NL@%
  12499. %@NL@%
  12500. Data that are related by a common idea or purpose constitutes a "series."
  12501. For example, the prices of a futures commodity over the course of a year
  12502. form a single series of data. The commodity's volume and open interest form
  12503. two more series for the same period of time. Presentation Graphics allows
  12504. you to plot multiple series on the same graph. In theory only your system's
  12505. memory capacity restricts the number of data series that can appear on a
  12506. graph. However, there are practical considerations.  %@NL@%
  12507. %@NL@%
  12508. Characteristics such as color and pattern help distinguish one series from
  12509. an-other. You can more readily differentiate series on a color monitor than
  12510. you can on a monochrome monitor. The number of series that can comfortably
  12511. appear on the same chart depends on the chart type and the number of
  12512. available colors. Only experimentation can tell you what is best for your
  12513. system.  %@NL@%
  12514. %@NL@%
  12515. %@NL@%
  12516. %@4@%%@AB@%Categories%@AE@%%@EH@%%@NL@%
  12517. %@NL@%
  12518. Categories are non-numeric data. A set of categories forms a frame of
  12519. reference for the comparisons of numeric data. For example, the months of
  12520. the year are categories against which numeric data such as rainfall can be
  12521. plotted.  %@NL@%
  12522. %@NL@%
  12523. Regional sales provide another example. A chart can show comparisons of a
  12524. company's sales in different parts of the country. Each region forms a
  12525. category. The sales within each region are numeric data that have meaning
  12526. only within the context of a particular category.  %@NL@%
  12527. %@NL@%
  12528. %@NL@%
  12529. %@4@%%@AB@%Values%@AE@%%@EH@%%@NL@%
  12530. %@NL@%
  12531. Values are numeric data. Sales, stock prices, air temperatures,
  12532. populations─all are series of values that can be plotted against categories
  12533. or against other values.  %@NL@%
  12534. %@NL@%
  12535. Presentation Graphics allows you to overlay different series of value data
  12536. on a single graph. For example, average monthly temperatures or monthly
  12537. sales of heating oil during different years─or a combination of temperatures
  12538. and sales─can be plotted together on the same graph.  %@NL@%
  12539. %@NL@%
  12540. %@NL@%
  12541. %@4@%%@AB@%Pie Charts%@AE@%%@EH@%%@NL@%
  12542. %@NL@%
  12543. %@AU@%(Please refer to the printed book.)%@AE@%%@NL@%
  12544. %@NL@%
  12545. "Pie charts" are used to represent data by showing the relationship of each
  12546. part to the whole. A good example is a company's monthly sales figures. The
  12547. sales to the company's various accounts can be represented as slices of the
  12548. pie.  %@NL@%
  12549. %@NL@%
  12550. Presentation Graphics can display either a standard or an "exploded" pie
  12551. chart. The exploded view shows the pie with one or more pieces separated for
  12552. emphasis. Presentation Graphics optionally labels each slice of a pie chart
  12553. with a percentage figure.  %@NL@%
  12554. %@NL@%
  12555. %@NL@%
  12556. %@4@%%@AB@%Bar and Column Charts%@AE@%%@EH@%%@NL@%
  12557. %@NL@%
  12558. %@AU@%(Please refer to the printed book.)%@AE@%%@NL@%
  12559. %@NL@%
  12560. As the name implies, a "bar chart" shows data as horizontal bars. Bar charts
  12561. show comparisons among items rather than absolute value.  %@NL@%
  12562. %@NL@%
  12563. "Column charts"%@NL@%
  12564. %@NL@%
  12565. %@AU@%(Please refer to the printed book.)%@AE@%%@NL@%
  12566. %@NL@%
  12567. are vertical bar charts. Column charts are frequently used to show
  12568. variations over a period of time, since they suggest time flow better than a
  12569. bar chart  %@NL@%
  12570. %@4@%%@AB@%Line Graphs%@AE@%%@EH@%%@NL@%
  12571. %@NL@%
  12572. %@AU@%(Please refer to the printed book.)%@AE@%%@NL@%
  12573. %@NL@%
  12574. "Line graphs" illustrate trends or changes in data. They show how a series
  12575. of values varies against some category─for example, average temperatures
  12576. throughout a particular year.  %@NL@%
  12577. %@NL@%
  12578. Traditionally, line graphs show a collection of data points connected by
  12579. lines; hence the name. However, Presentation Graphics can also plot points
  12580. that are not connected by lines.  %@NL@%
  12581. %@NL@%
  12582. %@NL@%
  12583. %@4@%%@AB@%Scatter Diagrams%@AE@%%@EH@%%@NL@%
  12584. %@NL@%
  12585. %@AU@%(Please refer to the printed book.)%@AE@%%@NL@%
  12586. %@NL@%
  12587. A "scatter diagram" is the only type of graph available in Presentation
  12588. Graphics that compares values with values. A scatter diagram simply plots
  12589. points. One value may correspond to several other values.  %@NL@%
  12590. %@NL@%
  12591. Scatter diagrams illustrate the relationship between numeric values in
  12592. different groups of data. They graphically show trends and correlations not
  12593. easily detected from rows and columns of raw numbers. This explains why
  12594. scatter diagrams are a favorite tool of statisticians and forecasters.  %@NL@%
  12595. %@NL@%
  12596. They are most useful with relatively large populations of data. Consider,
  12597. for example, the relationship between personal income and family size. If
  12598. you poll one thousand wage earners for their income and family size, you
  12599. have a scatter diagram with one thousand points. If you combine your results
  12600. so that you're left with one average income for each family size, you have a
  12601. line graph.  %@NL@%
  12602. %@NL@%
  12603. %@NL@%
  12604. %@4@%%@AB@%Axes%@AE@%%@EH@%%@NL@%
  12605. %@NL@%
  12606. All Presentation Graphics charts except pie charts are displayed with two
  12607. perpendicular reference lines called "axes." The vertical or %@AI@%y%@AE@% axis runs
  12608. from top to bottom of the chart and is placed against the left side of the
  12609. screen. The horizontal or %@AI@%x%@AE@% axis runs from left to right across the bottom
  12610. of the screen.  %@NL@%
  12611. %@NL@%
  12612. %@AU@% The chart type determines which axes are used for category and value data.%@AE@%
  12613. %@NL@%
  12614. %@NL@%
  12615. The %@AI@%x%@AE@% axis is the category axis for column and line charts and the value
  12616. axis for bar charts. The %@AI@%y%@AE@% axis is the value axis for column and line charts
  12617. and the category axis for bar charts.  %@NL@%
  12618. %@NL@%
  12619. %@NL@%
  12620. %@4@%%@AB@%Chart Windows%@AE@%%@EH@%%@NL@%
  12621. %@NL@%
  12622. The "chart window" defines that part of the screen on which the chart is
  12623. drawn. Normally the window fills the entire screen, but Presentation
  12624. Graphics allows you to resize the window for smaller graphs. By redefining
  12625. the chart window to different screen locations, you can view separate graphs
  12626. together on the same screen.  %@NL@%
  12627. %@NL@%
  12628. %@NL@%
  12629. %@4@%%@AB@%Data Windows%@AE@%%@EH@%%@NL@%
  12630. %@NL@%
  12631. While the chart window defines the entire graph including axes and labels,
  12632. the "data window" defines only the actual plotting area. This is the portion
  12633. of the graph to the right of the %@AI@%y%@AE@% axis and above the %@AI@%x%@AE@% axis. You cannot
  12634. directly specify the size of the data window. Presentation Graphics
  12635. automatically determines its size based on the dimensions of the chart
  12636. window.  %@NL@%
  12637. %@NL@%
  12638. %@NL@%
  12639. %@4@%%@AB@%Chart Styles%@AE@%%@EH@%%@NL@%
  12640. %@NL@%
  12641. Each of the five types of Presentation Graphics charts can appear in two
  12642. different chart styles, as described in Table 14.1.  %@NL@%
  12643. %@NL@%
  12644. %@AB@%Table 14.1  %@AB@%Presentation Graphics Chart Styles%@AE@%%@AE@%
  12645.  
  12646. %@TH:   8   488 02 12 20 44 @%
  12647. Chart Type  Chart Style #1      Chart Style #2
  12648. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12649. Pie         With percentages    Without percentages
  12650. Bar         Side-by-side        Stacked
  12651. Column      Side-by-side        Stacked
  12652. Line        Points with lines   Points only
  12653. Scatter     Points with lines   Points only
  12654. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12655. %@TE:   8   488 02 12 20 44 @%
  12656.  
  12657. Bar and column charts have only one style when displaying a single series of
  12658. data. The styles "side-by-side" and "stacked" are applicable when more than
  12659. one series appear on the same chart. The first style arranges the bars or
  12660. columns for the different series side by side, showing relative heights or
  12661. lengths. The stacked style, illustrated in Figure 14.1 for a column chart,
  12662. emphasizes relative sizes between bars or columns.  %@NL@%
  12663. %@NL@%
  12664. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12665. %@NL@%
  12666. %@NL@%
  12667. %@4@%%@AB@%Legends%@AE@%%@EH@%%@NL@%
  12668. %@NL@%
  12669. %@AU@% Legends help identify  individual data series.%@AE@%  %@NL@%
  12670. %@NL@%
  12671. When displaying more than one data series on a chart, Presentation Graphics
  12672. uses different colors, line styles, or patterns to differentiate the series.
  12673. Presentation Graphics also can display a "legend" that labels the different
  12674. series of a chart. For a pie chart, the legend labels individual slices of
  12675. the pie.  %@NL@%
  12676. %@NL@%
  12677. The format is similar to the legends found on printed graphs and maps. A
  12678. sample of the color and pattern used to graph the series appears next to the
  12679. series label. This identifies which set of data the labels belong to. The
  12680. "Palettes" section later in this chapter explains how different data series
  12681. are identified by color and pattern.  %@NL@%
  12682. %@NL@%
  12683. %@NL@%
  12684. %@2@%%@CR:C6A00140003 @%%@AB@%Presentation Graphics Program Structure%@AE@%%@EH@%%@NL@%
  12685. %@NL@%
  12686. QuickC programs that use Presentation Graphics typically follow seven steps:
  12687. %@NL@%
  12688. %@NL@%
  12689. %@AB@%Step%@AE@%                              %@AB@%Comments%@AE@%
  12690. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12691. Include required header files.    Along with other header files your 
  12692.                                   program may need, you must include the 
  12693.                                   files GRAPH.H and PGCHART.H.
  12694.  
  12695. Set video mode to graphics.       Refer to Chapter 13, "Graphics," for a 
  12696.                                   discussion 
  12697.                                   of video modes supported by QuickC. This
  12698.                                   chapter explains how to change modes 
  12699.                                   within a QuickC program.
  12700.  
  12701. Initialize Presentation Graphics  Presentation Graphics places charting 
  12702. chart                             parameters in a data structure. These 
  12703. environment.                      parameters determine how a graph will 
  12704.                                   appear on the screen. Collectively they 
  12705.                                   make up the "chart environment," 
  12706.                                   described in the section "Customizing 
  12707.                                   Presentation Graphics."  Presentation 
  12708.                                   Graphics sets the environment parameters
  12709.                                   to default values. The amount of 
  12710.                                   initialization that must be done by your
  12711.                                   program depends on how extensively it 
  12712.                                   relies on defaults.
  12713.  
  12714. Assemble plot data.               Data can be collected in a variety of 
  12715.                                   ways:  by calculating it elsewhere in 
  12716.                                   the program, reading it from files, or 
  12717.                                   entering it from the keyboard. All plot 
  12718.                                   data
  12719.                                   must be assembled in arrays because the 
  12720.                                   Presentation Graphics functions locate 
  12721.                                   them through
  12722.                                   pointers.
  12723.  
  12724. Call Presentation Graphics        Display your chart.
  12725. functions.                        
  12726.  
  12727. Pause while chart is on the       Your program should pause after a chart 
  12728. screen.                           is displayed. This step allows 
  12729.                                   sufficient time to read the chart. A 
  12730.                                   common method is to wait for a keyboard 
  12731.                                   entry before resuming.
  12732.  
  12733. Reset video mode.                 When your program detects the signal to 
  12734.                                   continue,
  12735.                                   it should normally reset the video to 
  12736.                                   its original
  12737.                                   mode.
  12738.  
  12739. Once your program successfully compiles, you must link it to the library
  12740. modules PGCHART.LIB and GRAPHICS.LIB. Use the Microsoft Overlay Linker  %@NL@%
  12741. %@NL@%
  12742. QLINK.EXE or the QCL command-line interface to link programs outside the
  12743. QuickC environment. For descriptions of QLINK and QCL, see the %@AI@%Microsoft
  12744. %@AI@%QuickC Tool Kit%@AE@%, Chapter 1, "Creating Executable Programs."  %@NL@%
  12745. %@NL@%
  12746. %@NL@%
  12747. %@2@%%@CR:C6A00140004 @%%@AB@%Five Example Chart Programs%@AE@%%@EH@%%@NL@%
  12748. %@NL@%
  12749. You'll have a better idea of Presentation Graphics capabilities once you've
  12750. seen what it can do. To that end some simple examples are presented in this
  12751. section. The sample programs that follow use only five of the 22
  12752. Presentation Graphics functions: %@AB@%_pg_initchart%@AE@%, %@AB@%_pg_defaultchart%@AE@%,
  12753. %@AB@%_pg_chartpie%@AE@%, %@AB@%_pg_chart%@AE@%, and %@AB@%_pg_chartscatter%@AE@%. Appendix B, "C Library
  12754. Guide," and online help document these functions and their arguments. But
  12755. the example code is straightforward, and you should be able to follow easily
  12756. for now. Each program is commented so that you can recognize the seven steps
  12757. given above.  %@NL@%
  12758. %@NL@%
  12759. %@NL@%
  12760. %@4@%%@AB@%A Sample Data Set%@AE@%%@EH@%%@NL@%
  12761. %@NL@%
  12762. Suppose a grocer wants to graph the sales of orange juice over the course of
  12763. a single year. Sales figures are on a monthly basis, so the grocer selects
  12764. as category data the months of the year from January through December. The
  12765. sales figures are shown below.  %@NL@%
  12766. %@NL@%
  12767. %@TH:  15   614 02 26 50 @%
  12768. Month                     Quantity (cases)
  12769. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12770. January                   33
  12771. February                  27
  12772. March                     42
  12773. April                     64
  12774. May                       106
  12775. June                      157
  12776. July                      182
  12777. August                    217
  12778. September                 128
  12779. October                   62
  12780. November                  43
  12781. December                  36
  12782. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12783. %@TE:  15   614 02 26 50 @%
  12784.  
  12785. %@NL@%
  12786. %@4@%%@AB@%Example: Pie Chart%@AE@%%@EH@%%@NL@%
  12787. %@NL@%
  12788. The following program uses Presentation Graphics to display a pie chart for
  12789. the grocer's data. The chart, which is shown in Figure 14.2, remains on the
  12790. screen until a key is pressed.  %@NL@%
  12791. %@NL@%
  12792. The Presentation Graphics functions return values that identify error
  12793. conditions. A return value of 0 indicates that the function has completed
  12794. its work without error. Refer to the header file PGCHART.H and online help
  12795. for descriptions of the nonzero error codes.  %@NL@%
  12796. %@NL@%
  12797. %@AS@%  /* PIE.C:  Create sample pie chart.  */
  12798. %@AS@%  
  12799. %@AS@%  #include <conio.h>
  12800. %@AS@%  #include <string.h>
  12801. %@AS@%  #include <graph.h>
  12802. %@AS@%  #include <pgchart.h>%@AE@%%@NL@%
  12803. %@NL@%
  12804. %@AS@%  #define MONTHS 12
  12805. %@AS@%  
  12806. %@AS@%  typedef enum {FALSE, TRUE} boolean;
  12807. %@AS@%  
  12808. %@AS@%  float far value[MONTHS] = 
  12809. %@AS@%  {
  12810. %@AS@%     33.0, 27.0, 42.0, 64.0,106.0,157.0,
  12811. %@AS@%    182.0,217.0,128.0, 62.0, 43.0, 36.0
  12812. %@AS@%  };
  12813. %@AS@%  char far *category[MONTHS] = 
  12814. %@AS@%  {
  12815. %@AS@%    "Jan", "Feb", "Mar", "Apr",
  12816. %@AS@%    "May", "Jun", "Jly", "Aug",
  12817. %@AS@%    "Sep", "Oct", "Nov", "Dec"
  12818. %@AS@%  };
  12819. %@AS@%  short far explode[MONTHS] = {0};
  12820. %@AS@%  
  12821. %@AS@%  main()
  12822. %@AS@%  {
  12823. %@AS@%    chartenv env;
  12824. %@AS@%    int mode = _VRES16COLOR;
  12825. %@AS@%  
  12826. %@AS@%    /* Set highest video mode available */
  12827. %@AS@%    while(!_setvideomode( mode ))
  12828. %@AS@%       mode--;
  12829. %@AS@%    if(mode == _TEXTMONO)
  12830. %@AS@%       return( 0 );
  12831. %@AS@%  
  12832. %@AS@%    /* Initialize chart library and a default pie chart */
  12833. %@AS@%    _pg_initchart();
  12834. %@AS@%    _pg_defaultchart( &env, _PG_PIECHART, _PG_PERCENT );
  12835. %@AS@%  
  12836. %@AS@%    /* Add titles and some chart options */
  12837. %@AS@%    strcpy( env.maintitle.title, "Good Neighbor Grocery" );
  12838. %@AS@%    env.maintitle.titlecolor = 6;
  12839. %@AS@%    env.maintitle.justify = _PG_RIGHT;
  12840. %@AS@%    strcpy( env.subtitle.title, "Orange Juice Sales" ); 
  12841. %@AS@%    env.subtitle.titlecolor = 6;
  12842. %@AS@%    env.subtitle.justify = _PG_RIGHT;
  12843. %@AS@%    env.chartwindow.border = FALSE;%@AE@%%@NL@%
  12844. %@NL@%
  12845. %@AS@%    /* Parameters for call to _pg_chartpie are:
  12846. %@AS@%     *  
  12847. %@AS@%     *    env        - Environment variable
  12848. %@AS@%     *    category   - Category labels
  12849. %@AS@%     *    value      - Data to chart
  12850. %@AS@%     *    explode    - Separated pieces
  12851. %@AS@%     *    MONTHS     - Number of data values
  12852. %@AS@%     */
  12853. %@AS@%    if(_pg_chartpie( &env, category, value,
  12854. %@AS@%                      explode, MONTHS ))
  12855. %@AS@%    {
  12856. %@AS@%       _setvideomode( _DEFAULTMODE );
  12857. %@AS@%       _outtext( "Error:  can't draw chart" );
  12858. %@AS@%    }
  12859. %@AS@%    else
  12860. %@AS@%    {
  12861. %@AS@%       getch(); 
  12862. %@AS@%       _setvideomode( _DEFAULTMODE );
  12863. %@AS@%    }
  12864. %@AS@%    return( 0 );
  12865. %@AS@%  } %@AE@%%@NL@%
  12866. %@NL@%
  12867. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12868. %@NL@%
  12869. %@NL@%
  12870. %@4@%%@AB@%Example: Bar Chart%@AE@%%@EH@%%@NL@%
  12871. %@NL@%
  12872. The code for the PIE.C program needs only minor alterations to produce bar,
  12873. column, and line charts for the same data:  %@NL@%
  12874. %@NL@%
  12875. %@NL@%
  12876.   ■   Replace the call to %@AB@%_pg_chartpie%@AE@% with %@AB@%_pg_chart%@AE@%. This function
  12877.       produces bar, column, and line charts depending on the value of the
  12878.       second argument for %@AB@%_pg_defaultchart%@AE@%.%@NL@%
  12879. %@NL@%
  12880.   ■   Give new arguments to %@AB@%_pg_defaultchart%@AE@% that specify chart type and
  12881.       style.%@NL@%
  12882. %@NL@%
  12883.   ■   Assign titles for the %@AI@%x%@AE@% axis and %@AI@%y%@AE@% axis in the structure %@AS@% env %@AE@%.%@NL@%
  12884. %@NL@%
  12885.   ■   Remove references to array %@AS@% explode %@AE@%(applicable only to pie charts).%@NL@%
  12886. %@NL@%
  12887. %@NL@%
  12888. The following example produces the bar chart shown in Figure 14.3.  %@NL@%
  12889. %@NL@%
  12890. %@AS@%  /* BAR.C:  Create sample bar chart. */
  12891. %@AS@%  #include <conio.h>
  12892. %@AS@%  #include <string.h>
  12893. %@AS@%  #include <graph.h>
  12894. %@AS@%  #include <pgchart.h>
  12895. %@AS@%  #define MONTHS 12
  12896. %@AS@%  typedef enum {FALSE, TRUE} boolean;
  12897. %@AS@%  float far value[MONTHS] = 
  12898. %@AS@%  { 
  12899. %@AS@%     33.0, 27.0, 42.0, 64.0,106.0,157.0,
  12900. %@AS@%    182.0,217.0,128.0, 62.0, 43.0, 36.0
  12901. %@AS@%  };
  12902. %@AS@%  char far *category[MONTHS] =
  12903. %@AS@%  {
  12904. %@AS@%    "Jan", "Feb", "Mar", "Apr",
  12905. %@AS@%    "May", "Jun", "Jly", "Aug",
  12906. %@AS@%    "Sep", "Oct", "Nov", "Dec"
  12907. %@AS@%  };
  12908. %@AS@%  
  12909. %@AS@%  main()
  12910. %@AS@%  {
  12911. %@AS@%    chartenv env;
  12912. %@AS@%    int mode = _VRES16COLOR;
  12913. %@AS@%    /* Set highest video mode available */
  12914. %@AS@%    while(!_setvideomode( mode ))
  12915. %@AS@%       mode--;
  12916. %@AS@%    if(mode == _TEXTMONO)
  12917. %@AS@%       return(0);
  12918. %@AS@%  
  12919. %@AS@%    /* Initialize chart library and a default bar chart */       
  12920. %@AS@%    _pg_initchart();
  12921. %@AS@%    _pg_defaultchart( &env, _PG_BARCHART, _PG_PLAINBARS );
  12922. %@AS@%  
  12923. %@AS@%    /* Add titles and some chart options */
  12924. %@AS@%    strcpy( env.maintitle.title, "Good Neighbor Grocery" );
  12925. %@AS@%    env.maintitle.titlecolor = 6;
  12926. %@AS@%    env.maintitle.justify = _PG_RIGHT;
  12927. %@AS@%    strcpy( env.subtitle.title, "Orange Juice Sales" );
  12928. %@AS@%    env.subtitle.titlecolor = 6;
  12929. %@AS@%    env.subtitle.justify = _PG_RIGHT;
  12930. %@AS@%    strcpy( env.yaxis.axistitle.title, "Months" );
  12931. %@AS@%    strcpy( env.xaxis.axistitle.title, "Quantity (cases)" );
  12932. %@AS@%    env.chartwindow.border = FALSE;
  12933. %@AS@%  
  12934. %@AS@%    /* Parameters for call to _pg_chart are:
  12935. %@AS@%     *    env        - Environment variable
  12936. %@AS@%     *    category   - Category labels
  12937. %@AS@%     *    value      - Data to chart
  12938. %@AS@%     *    MONTHS     - Number of data values */
  12939. %@AS@%    if(_pg_chart( &env, category, value, MONTHS ))
  12940. %@AS@%    {
  12941. %@AS@%       _setvideomode( _DEFAULTMODE );
  12942. %@AS@%       _outtext( "Error:  can't draw chart" );
  12943. %@AS@%    }
  12944. %@AS@%    else
  12945. %@AS@%    {
  12946. %@AS@%        getch(); 
  12947. %@AS@%        _setvideomode( _DEFAULTMODE );
  12948. %@AS@%     }
  12949. %@AS@%     return(0);
  12950. %@AS@%  }%@AE@%%@NL@%
  12951. %@NL@%
  12952. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12953. %@NL@%
  12954. %@NL@%
  12955. %@4@%%@AB@%Example: Column Chart%@AE@%%@EH@%%@NL@%
  12956. %@NL@%
  12957. The grocer's bar chart becomes a column chart in two easy steps. Simply
  12958. specify the new chart type when calling %@AB@%_pg_defaultchart%@AE@% and switch the axis
  12959. titles. To produce a column chart for the data, replace the call to%@AB@%
  12960. %@AB@%_pg_defaultchart%@AE@% with:  %@NL@%
  12961. %@NL@%
  12962. %@AS@%  _pg_defaultchart( &env, _PG_COLUMNCHART, _PG_PLAINBARS );%@AE@%%@NL@%
  12963. %@NL@%
  12964. and replace the last two calls to %@AB@%strcpy%@AE@% with:  %@NL@%
  12965. %@NL@%
  12966. %@AS@%  strcpy( env.xaxis.axistitle.title, "Months" );
  12967. %@AS@%  strcpy( env.yaxis.axistitle.title, "Quantity (cases)" );%@AE@%%@NL@%
  12968. %@NL@%
  12969. Notice that now the %@AI@%x%@AE@% axis is labeled "Months" and the %@AI@%y %@AE@%axis is labeled
  12970. "Quantity (cases)." Figure 14.4 shows the resulting column chart.  %@NL@%
  12971. %@NL@%
  12972. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12973. %@NL@%
  12974. %@NL@%
  12975. %@4@%%@AB@%Example: Line Chart%@AE@%%@EH@%%@NL@%
  12976. %@NL@%
  12977. Creating an equivalent line chart requires only one change. Use the same
  12978. code as for the column chart and replace the call to %@AB@%_pg_defaultchart%@AE@% with:
  12979. %@NL@%
  12980. %@NL@%
  12981. %@AS@%  _pg_defaultchart( &env, _PG_LINECHART, _PG_POINTANDLINE );%@AE@%%@NL@%
  12982. %@NL@%
  12983. Figure 14.5 shows the line chart for the grocer's data.  %@NL@%
  12984. %@NL@%
  12985. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  12986. %@NL@%
  12987. %@NL@%
  12988. %@4@%%@AB@%Example: Scatter Diagram%@AE@%%@EH@%%@NL@%
  12989. %@NL@%
  12990. Now suppose that the store owner wants to compare the sales of orange juice
  12991. to the sales of another product, say hot chocolate. Possible monthly sales
  12992. are shown below.  %@NL@%
  12993. %@NL@%
  12994. %@TH:  15   729 02 12 22 42 @%
  12995. Months      Orange Juice (cases)  Hot Chocolate (cases)
  12996. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  12997. January     33                    37
  12998. February    27                    37
  12999. March       42                    30
  13000. April       64                    19
  13001. May         106                   10
  13002. June        157                   5
  13003. July        182                   2
  13004. August      217                   1
  13005. September   128                   7%@AB@%%@AE@%
  13006. October     62                    15
  13007. November    43                    28
  13008. December    36                    39
  13009. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13010. %@TE:  15   729 02 12 22 42 @%
  13011.  
  13012. The program SCATTER.C displays a scatter diagram that illustrates the
  13013. relationship between the sales of orange juice and hot chocolate throughout
  13014. a 12-month period.  %@NL@%
  13015. %@NL@%
  13016. %@AS@%  /* SCATTER.C:  Create sample scatter diagram. */
  13017. %@AS@%  
  13018. %@AS@%  #include <conio.h>
  13019. %@AS@%  #include <string.h>
  13020. %@AS@%  #include <graph.h>
  13021. %@AS@%  #include <pgchart.h>
  13022. %@AS@%  
  13023. %@AS@%  #define MONTHS 12
  13024. %@AS@%  typedef enum {FALSE, TRUE} boolean;
  13025. %@AS@%  
  13026. %@AS@%  /* Orange juice sales */
  13027. %@AS@%  
  13028. %@AS@%  float far xvalue[MONTHS] = 
  13029. %@AS@%  { 
  13030. %@AS@%     33.0, 27.0, 42.0, 64.0,106.0,157.0,
  13031. %@AS@%    182.0,217.0,128.0, 62.0, 43.0, 36.0
  13032. %@AS@%  };
  13033. %@AS@%  /* Hot chocolate sales */
  13034. %@AS@%  
  13035. %@AS@%  float far yvalue[MONTHS] = 
  13036. %@AS@%  { 
  13037. %@AS@%    37.0, 37.0, 30.0, 19.0, 10.0,  5.0,
  13038. %@AS@%     2.0,  1.0,  7.0, 15.0, 28.0, 39.0
  13039. %@AS@%  };
  13040. %@AS@%  
  13041. %@AS@%  main()
  13042. %@AS@%  {
  13043. %@AS@%    chartenv env;
  13044. %@AS@%    int mode = _VRES16COLOR;
  13045. %@AS@%  
  13046. %@AS@%    /* Set highest video mode available */
  13047. %@AS@%  
  13048. %@AS@%    while(!_setvideomode( mode ))
  13049. %@AS@%       mode--;
  13050. %@AS@%    if(mode == _TEXTMONO)
  13051. %@AS@%       return(0);%@AE@%%@NL@%
  13052. %@NL@%
  13053. %@AS@%    /* Initialize chart library and default
  13054. %@AS@%     * scatter diagram
  13055. %@AS@%     */
  13056. %@AS@%    _pg_initchart();
  13057. %@AS@%    _pg_defaultchart( &env, _PG_SCATTERCHART,
  13058. %@AS@%                      _PG_POINTONLY );
  13059. %@AS@%  
  13060. %@AS@%    /* Add titles and some chart options */
  13061. %@AS@%  
  13062. %@AS@%    strcpy( env.maintitle.title, "Good Neighbor Grocery" );
  13063. %@AS@%    env.maintitle.titlecolor = 6;
  13064. %@AS@%    env.maintitle.justify = _PG_RIGHT;
  13065. %@AS@%    strcpy( env.subtitle.title,
  13066. %@AS@%            "Orange Juice vs Hot Chocolate" );
  13067. %@AS@%    env.subtitle.titlecolor = 6;
  13068. %@AS@%    env.subtitle.justify = _PG_RIGHT;
  13069. %@AS@%    env.yaxis.grid = TRUE;
  13070. %@AS@%    strcpy( env.xaxis.axistitle.title,
  13071. %@AS@%            "Orange Juice Sales" );
  13072. %@AS@%    strcpy( env.yaxis.axistitle.title,
  13073. %@AS@%            "Hot Chocolate Sales" );
  13074. %@AS@%    env.chartwindow.border = FALSE;
  13075. %@AS@%  
  13076. %@AS@%    /* Parameters for call to _pg_chartscatter are:
  13077. %@AS@%     *    env        - Environment variable
  13078. %@AS@%     *    xvalue     - X-axis data
  13079. %@AS@%     *    yvalue     - Y-axis data
  13080. %@AS@%     *    MONTHS     - Number of data values
  13081. %@AS@%     */%@AE@%%@NL@%
  13082. %@NL@%
  13083. %@AS@%    if(_pg_chartscatter( &env, xvalue,
  13084. %@AS@%                          yvalue, MONTHS ))
  13085. %@AS@%    {
  13086. %@AS@%       _setvideomode( _DEFAULTMODE );
  13087. %@AS@%       _outtext( "Error:  can't draw chart" );
  13088. %@AS@%    }
  13089. %@AS@%    else
  13090. %@AS@%    {
  13091. %@AS@%       getch(); 
  13092. %@AS@%       _setvideomode( _DEFAULTMODE );
  13093. %@AS@%    }
  13094. %@AS@%    return(0);
  13095. %@AS@%  } %@AE@%%@NL@%
  13096. %@NL@%
  13097. Figure 14.6 shows the results of SCATTER.C. Notice that the scatter points
  13098. form a slightly curved line, indicating a correlation exists between the
  13099. sales of the two products. The store owner can conclude from the scatter
  13100. diagram that the demand for orange juice is roughly inverse to the demand
  13101. for hot chocolate.  %@NL@%
  13102. %@NL@%
  13103. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  13104. %@NL@%
  13105. %@NL@%
  13106. %@2@%%@CR:C6A00140005 @%%@AB@%Palettes%@AE@%%@EH@%%@NL@%
  13107. %@NL@%
  13108. Presentation Graphics displays each data series in a way that makes it
  13109. discernible from other series. It does this by defining a separate "palette"
  13110. for every data series in a chart. Palettes consist of entries that determine
  13111. color, line style, fill pattern, and plot character used to graph the
  13112. series.  %@NL@%
  13113. %@NL@%
  13114. Presentation Graphics maintains its palettes as an array of structures. The
  13115. header file PGCHART.H defines the palette structures as:  %@NL@%
  13116. %@NL@%
  13117. %@AS@%  /* Typedef for pattern bitmap */
  13118. %@AS@%  typedef unsigned char fillmap[8];
  13119. %@AS@%  
  13120. %@AS@%  /* Typedef for palette entry definition */
  13121. %@AS@%  typedef struct 
  13122. %@AS@%  {
  13123. %@AS@%    unsigned short color;
  13124. %@AS@%    unsigned short style;
  13125. %@AS@%    fillmap        fill;
  13126. %@AS@%    char           plotchar;
  13127. %@AS@%  } paletteentry;
  13128. %@AS@%  
  13129. %@AS@%  /* Typedef for palette definition */
  13130. %@AS@%  typedef paletteentry palettetype[_PG_PALETTELEN];%@AE@%%@NL@%
  13131. %@NL@%
  13132. It's important not to confuse the Presentation Graphics palettes with the
  13133. adapter display palettes, which are register values kept by the video
  13134. controller. The function %@AB@%_selectpalette%@AE@% described in Chapter 13, "Graphics,"
  13135. sets the display palette. It does not define the data series palettes used
  13136. by Presentation Graphics.  %@NL@%
  13137. %@NL@%
  13138. %@NL@%
  13139. %@3@%%@CR:C6A00140006 @%%@AB@%Color Pool%@AE@%%@EH@%%@NL@%
  13140. %@NL@%
  13141. Presentation Graphics organizes all chart colors into a "color pool." The
  13142. color pool consists of pixel values valid for the current graphics mode.
  13143. (Refer to Chapter 13, "Graphics," or the Glossary for a definition of pixel
  13144. values.) Palette structures contain color codes that refer to the color
  13145. pool. A palette's color code determines the color used to graph the data
  13146. series associated with the palette. Colors of labels, titles, legends, and
  13147. axes are also determined by the contents of the color pool.  %@NL@%
  13148. %@NL@%
  13149. The first element of the color pool is always 0, which is the pixel value
  13150. for the screen background color. The second element is always the highest
  13151. pixel value available for the graphics mode. The remaining elements are
  13152. repeating sequences of available pixel values, beginning with 1.  %@NL@%
  13153. %@NL@%
  13154. As shown above, the first member of a palette data structure is:  %@NL@%
  13155. %@NL@%
  13156. %@AS@%  unsigned short color;%@AE@%%@NL@%
  13157. %@NL@%
  13158. This variable defines the color code for the data series associated with the
  13159. palette. The color code is neither a display attribute nor a pixel value. It
  13160. is an index number of the color pool.  %@NL@%
  13161. %@NL@%
  13162. An example should make this clearer. A graphics mode of %@AB@%_MRES4COLOR%@AE@%  (320 x
  13163. 200 graphics) provides four colors for display. Pixel values from 0 to 3
  13164. determine the possible pixel colors─say, black, green, red, and brown
  13165. respectively. In this case the first 8 elements of the color pool would be
  13166. the following:  %@NL@%
  13167. %@NL@%
  13168. %@TH:  11   550 02 18 13 45 @%
  13169. Color Pool Index  Pixel Value  Color
  13170. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13171. 0                 0            Black
  13172. 1                 3            Brown
  13173. 2                 1            Green
  13174. 3                 2            Red
  13175. 4                 3            Brown
  13176. 5                 1            Green
  13177. 6                 2            Red
  13178. 7                 3            Brown
  13179. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13180. %@TE:  11   550 02 18 13 45 @%
  13181.  
  13182. Notice that the sequence of available foreground colors repeats from the
  13183. third element. The first data series in this case would be plotted in brown,
  13184. the second series in green, the third series in red, the fourth series again
  13185. in brown, and so forth.  %@NL@%
  13186. %@NL@%
  13187. Video adapters such as the EGA or the Hercules InColor(tm) Card allow 16
  13188. on-screen colors. This allows Presentation Graphics to graph more series
  13189. without duplicating colors.  %@NL@%
  13190. %@NL@%
  13191. %@NL@%
  13192. %@3@%%@CR:C6A00140007 @%%@AB@%Style Pool%@AE@%%@EH@%%@NL@%
  13193. %@NL@%
  13194. Presentation Graphics matches the color pool with a collection of different
  13195. line styles called the "style pool." Entries in the style pool define the
  13196. appearance of lines such as axes and grids. Lines can be solid, dotted,
  13197. dashed, or of some combination.  %@NL@%
  13198. %@NL@%
  13199. The second member of a palette structure defines a style code as:  %@NL@%
  13200. %@NL@%
  13201. %@AS@%  unsigned short style;%@AE@%%@NL@%
  13202. %@NL@%
  13203. Each palette contains a style code that refers to an entry in the style pool
  13204. in the same way that it contains a color code that refers to an entry in the
  13205. color pool. The style code value in a palette is applicable only to line
  13206. graphs and lined scatter diagrams. The style code determines the appearance
  13207. of the lines drawn between points.  %@NL@%
  13208. %@NL@%
  13209. The palette's style code adds further variety to the lines of a multiseries
  13210. graph. It is most useful when the number of lines in a chart exceeds the
  13211. number of available colors. For example, a graph of nine different data
  13212. series must repeat colors if only three foreground colors are available for
  13213. display. However, the style code for each color repetition will be
  13214. different, ensuring that none of the lines looks the same.  %@NL@%
  13215. %@NL@%
  13216. %@NL@%
  13217. %@3@%%@CR:C6A00140008 @%%@AB@%Pattern Pool%@AE@%%@EH@%%@NL@%
  13218. %@NL@%
  13219. Presentation Graphics also maintains a pool of "fill patterns." Patterns
  13220. determine the fill design for column, bar, and pie charts. The third member
  13221. of a palette structure holds the palette's fill pattern. The pattern member
  13222. is an array:  %@NL@%
  13223. %@NL@%
  13224. %@AS@%  fillmap fill;%@AE@%%@NL@%
  13225. %@NL@%
  13226. where %@AS@% fillmap %@AE@% is type-defined as:  %@NL@%
  13227. %@NL@%
  13228. %@AS@%  typedef unsigned char fillmap[8];%@AE@%%@NL@%
  13229. %@NL@%
  13230. Each fill pattern array holds an 8 x 8 bit map that defines the fill pattern
  13231. for the data series associated with the palette. Table 14.2 shows how a fill
  13232. pattern of diagonal stripes is created with the %@AS@% fill %@AE@% pattern array.  %@NL@%
  13233. %@NL@%
  13234. The bit map below corresponds to screen pixels. Each of the 8 layers of the
  13235. map are binary numbers, where a solid circle signifies 1 and an open circle
  13236. signifies 0. Thus the first layer of the map─that is, the first
  13237. byte─represents the binary number 10011001, which is the decimal number 153.
  13238. %@NL@%
  13239. %@NL@%
  13240. %@AB@%Table 14.2  %@AB@%Fill Patterns%@AE@%%@AE@%
  13241.  
  13242. %@TH:  11   765 02 35 41 @%
  13243. Bit Map                            Value in fill
  13244. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13245.   ∙  ∙      ∙  ∙               %@AS@% fill[0]%@AE@% = 153
  13246.     ∙  ∙      ∙  ∙             %@AS@% fill[1]%@AE@% = 204
  13247. ∙      ∙  ∙      ∙             %@AS@% fill[2]%@AE@% = 102
  13248. ∙  ∙      ∙  ∙                 %@AS@% fill[3]%@AE@% =   51
  13249.   ∙  ∙      ∙  ∙               %@AS@% fill[4]%@AE@% = 153
  13250.     ∙  ∙      ∙  ∙             %@AS@% fill[5]%@AE@% = 204
  13251. ∙      ∙  ∙      ∙             %@AS@% fill[6]%@AE@% = 102
  13252. ∙  ∙      ∙  ∙                 %@AS@% fill[7]%@AE@% =   51
  13253. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13254. %@TE:  11   765 02 35 41 @%
  13255.  
  13256. If you wish to create the above pattern for your chart's first data series,
  13257. you must reset the %@AS@% fill %@AE@% array for the first palette structure. You can do
  13258. this in five steps:  %@NL@%
  13259. %@NL@%
  13260. %@NL@%
  13261.   1.  Declare a structure of type %@AB@%palettetype%@AE@% to hold the palette
  13262.       parameters.%@NL@%
  13263. %@NL@%
  13264.   2.  Call %@AB@%_pg_initchart%@AE@% to initialize the palettes with default values.%@NL@%
  13265. %@NL@%
  13266.   3.  Call the Presentation Graphics function %@AB@%_pg_getpalette%@AE@% to retrieve a
  13267.       copy of the current palette data.%@NL@%
  13268. %@NL@%
  13269.   4.  Assign the values given in Table 14.2 to the array %@AS@% fill %@AE@% for the
  13270.       first palette. %@NL@%
  13271. %@NL@%
  13272.   5.  Call the Presentation Graphics function %@AB@%_pg_setpalette%@AE@% to load the
  13273.       modified palette values.%@NL@%
  13274. %@NL@%
  13275. %@NL@%
  13276. The following lines of code demonstrate these five steps:  %@NL@%
  13277. %@NL@%
  13278. %@AS@%  /* Declare a structure array for palette data. */
  13279. %@AS@%  
  13280. %@AS@%  palettetype palette_struct;
  13281. %@AS@%  .
  13282. %@AS@%  .
  13283. %@AS@%  .
  13284. %@AS@%  /* Initialize chart library */
  13285. %@AS@%  
  13286. %@AS@%  _pg_initchart();
  13287. %@AS@%  .
  13288. %@AS@%  .
  13289. %@AS@%  .
  13290. %@AS@%  /* Copy current palette data into palette_struct */
  13291. %@AS@%  
  13292. %@AS@%  _pg_getpalette( palette_struct );
  13293. %@AS@%  
  13294. %@AS@%  /* Reinitialize fill pattern for first palette using
  13295. %@AS@%     values in Table 14.2 */
  13296. %@AS@%  
  13297. %@AS@%  palette_struct[1].fill[0] = 153;
  13298. %@AS@%  palette_struct[1].fill[1] = 204;
  13299. %@AS@%  palette_struct[1].fill[2] = 102;
  13300. %@AS@%  palette_struct[1].fill[3] =  51;
  13301. %@AS@%  palette_struct[1].fill[4] = 153;
  13302. %@AS@%  palette_struct[1].fill[5] = 204;
  13303. %@AS@%  palette_struct[1].fill[6] = 102;
  13304. %@AS@%  palette_struct[1].fill[7] =  51;
  13305. %@AS@%  
  13306. %@AS@%  /* Load new palette data */
  13307. %@AS@%  
  13308. %@AS@%  _pg_setpalette( palette_struct );%@AE@%%@NL@%
  13309. %@NL@%
  13310. Now when you display your bar or column chart the first series appears
  13311. filled with the striped pattern shown in Table 14.2.  %@NL@%
  13312. %@NL@%
  13313. Pie charts are a bit different. The idea of multiple series does not really
  13314. apply to them. Instead, palette structures correspond to individual slices.
  13315. If the number of slices exceeds the constant %@AB@%_PG_PALETTELEN%@AE@%, palettes are
  13316. recycled. Thus the first palette dictates not only the appearance of the
  13317. first slice, but of slice number %@AB@%_PG_PALETTELEN%@AE@% as well. The second palette
  13318. determines the appearance of both the second slice and of slice number
  13319. %@AB@%_PG_PALETTELEN%@AE@% + 1, and so forth.  %@NL@%
  13320. %@NL@%
  13321. %@NL@%
  13322. %@3@%%@CR:C6A00140009 @%%@AB@%Character Pool%@AE@%%@EH@%%@NL@%
  13323. %@NL@%
  13324. The last member of a palette structure is an index number in a pool of ASCII
  13325. characters:  %@NL@%
  13326. %@NL@%
  13327. %@AS@%  char plotchar;%@AE@%%@NL@%
  13328. %@NL@%
  13329. The member %@AS@%plotchar %@AE@% represents plot points on line graphs and scatter
  13330. diagrams. Each palette uses a different character to distinguish plot points
  13331. between data series.  %@NL@%
  13332. %@NL@%
  13333. %@NL@%
  13334. %@2@%%@CR:C6A00140010 @%%@AB@%Customizing Presentation Graphics%@AE@%%@EH@%%@NL@%
  13335. %@NL@%
  13336. Presentation Graphics is built for flexibility. You can use its system of
  13337. default values to produce professional-looking charts with a minimum of
  13338. programming effort. Or you can fine-tune the appearance of your charts by
  13339. overriding default values and initializing variables explicitly in your
  13340. program. The following section shows you how.  %@NL@%
  13341. %@NL@%
  13342. %@NL@%
  13343. %@3@%%@CR:C6A00140011 @%%@AB@%Chart Environment%@AE@%%@EH@%%@NL@%
  13344. %@NL@%
  13345. The header file PGCHART.H defines a structure type %@AB@%chartenv%@AE@%. This structure
  13346. type organizes the set of variables known as the "chart environment." The
  13347. chart environment describes everything about a chart except the plots
  13348. themselves. It's the blank page, in other words, ready for plotting data.
  13349. The environment determines the appearance of text, axes, grid lines, and
  13350. legends.  %@NL@%
  13351. %@NL@%
  13352. Calling the %@AB@%_pg_defaultchart%@AE@% function fills the chart environment with
  13353. default values. Presentation Graphics allows you to reset any variable in
  13354. the environment before displaying a chart. Except for adjusting the palette
  13355. values, all initialization of data is done through a %@AB@%chartenv%@AE@% type
  13356. structure.  %@NL@%
  13357. %@NL@%
  13358. The sample chart programs provided earlier illustrate how to adjust
  13359. variables in the chart environment. These programs create a structure %@AS@% env %@AE@%
  13360. of the type %@AB@%chartenv%@AE@%. The structure %@AS@% env %@AE@% contains the chart environment
  13361. variables, initialized by the call to %@AB@%_pg_defaultchart%@AE@%. Environment
  13362. variables such as the chart title are then given specific values, as in:  %@NL@%
  13363. %@NL@%
  13364. %@AS@%  strcpy( env.maintitle.title, "Good Neighbor Grocery" );%@AE@%%@NL@%
  13365. %@NL@%
  13366. Environment variables that determine colors and line styles deserve special
  13367. mention. The chart environment holds several such variables, which can be
  13368. recognized by their names. For example, the variable %@AI@%titlecolor%@AE@% specifies
  13369. the color of title text. Similarly, the variable %@AI@%gridstyle%@AE@% specifies the
  13370. line style used to draw the chart grid.  %@NL@%
  13371. %@NL@%
  13372. %@AU@% Colors and line styles in the chart environment are taken from palettes.%@AE@%  %@NL@%
  13373. %@NL@%
  13374. These variables are index numbers, but do not refer directly to the color
  13375. pool or line pool. They correspond instead to palette numbers. If you set
  13376. %@AI@%titlecolor%@AE@% to 2, Presentation Graphics uses the color code in the second
  13377. palette to determine the title's color. Thus the title in this case would be
  13378. the same color as the chart's second data series. If you change the color
  13379. code in the palette, you'll also change the title's color.  %@NL@%
  13380. %@NL@%
  13381. A structure of type %@AB@%chartenv%@AE@% consists of four secondary structures. The file
  13382. PGCHART.H type-defines the secondary structures as:  %@NL@%
  13383. %@NL@%
  13384. %@AS@%  titletype
  13385. %@AS@%  axistype
  13386. %@AS@%  windowtype
  13387. %@AS@%  legendtype%@AE@%%@NL@%
  13388. %@NL@%
  13389. The remainder of this section describes the chart environment of
  13390. Presentation Graphics. It first examines structures of the four secondary
  13391. types that make up the chart environment structure. The section concludes
  13392. with a description of the %@AB@%chartenv%@AE@% structure type. Each discussion begins
  13393. with a brief explanation of the structure's purpose, followed by a listing
  13394. of the structure type definition as it appears in the PGCHART.H file. All
  13395. symbolic constants are defined in the file PGCHART.H.  %@NL@%
  13396. %@NL@%
  13397. %@NL@%
  13398. %@3@%%@CR:C6A00140012 @%%@AB@%titletype%@AE@%%@EH@%%@NL@%
  13399. %@NL@%
  13400. Structures of type %@AB@%titletype%@AE@% determine text, color, and placement of titles
  13401. appearing in the graph. The PGCHART.H file defines the structure type as:  %@NL@%
  13402. %@NL@%
  13403. %@AS@%  typedef struct
  13404. %@AS@%  {
  13405. %@AS@%    char     title[_PG_TITLELEN];  /* Title text */
  13406. %@AS@%    short    titlecolor;           /* Palette color
  13407. %@AS@%                                      for title text */
  13408. %@AS@%    short    justify;              /* _PG_LEFT, _PG_CENTER,
  13409. %@AS@%                                      _PG_RIGHT */
  13410. %@AS@%  } titletype;%@AE@%%@NL@%
  13411. %@NL@%
  13412. The following list describes %@AB@%titletype%@AE@% members:  %@NL@%
  13413. %@NL@%
  13414. %@AB@%Member Variable%@AE@%                   %@AB@%Description%@AE@%
  13415. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13416. %@AI@%justify%@AE@%                           An integer specifying how the title is 
  13417.                                   justified
  13418.                                   within the chart window. The symbolic 
  13419.                                   constants
  13420.                                   defined in the PGCHART.H file for this 
  13421.                                   variable are %@AB@%_PG_LEFT%@AE@%, %@AB@%_PG_CENTER%@AE@%, and %@AB@%%@AE@%
  13422.                                   %@AB@%_PG_RIGHT%@AE@%.
  13423.  
  13424. %@AI@%titlecolor%@AE@%                        An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@%
  13425.                                   that specifies a title's color. The 
  13426.                                   default value for %@AI@%titlecolor%@AE@% is 1.
  13427.  
  13428. %@AI@%title%@AE@%%@AB@%[_PG_TITLELEN]%@AE@%               A character array containing title text.
  13429.                                   For example, if %@AS@% env %@AE@% is a structure of 
  13430.                                   type%@AB@% chartenv%@AE@%, then %@AS@% env.maintitle.title%@AE@%
  13431.                                   holds the character string used for the 
  13432.                                   main title of the chart. Similarly, %@AS@%%@AE@%
  13433.                                   %@AS@%env.xaxis.axistitle.title%@AE@%  contains the 
  13434.                                   axis title. The number of characters in 
  13435.                                   a title must be one less than %@AB@%%@AE@%
  13436.                                   %@AB@%_PG_TITLELEN%@AE@% to allow room for a null 
  13437.                                   terminator. 
  13438.  
  13439. %@NL@%
  13440. %@3@%%@CR:C6A00140013 @%%@AB@%axistype%@AE@%%@EH@%%@NL@%
  13441. %@NL@%
  13442. Structures of type %@AB@%axistype%@AE@% contain variables for the axes such as color,
  13443. scale, grid style, and tick marks. The PGCHART.H file defines the structure
  13444. type as:  %@NL@%
  13445. %@NL@%
  13446. %@AS@%  typedef struct
  13447. %@AS@%  {
  13448. %@AS@%    short       grid;          /* TRUE=grid lines drawn;
  13449. %@AS@%                                  FALSE=no lines */
  13450. %@AS@%    short       gridstyle;     /* Style bytes for grid */
  13451. %@AS@%    titletype   axistitle;     /* Title definition
  13452. %@AS@%                                  for axis */
  13453. %@AS@%    short       axiscolor;     /* Color for axis */
  13454. %@AS@%    short       labeled;       /* TRUE=ticks marks and titles
  13455. %@AS@%                                  drawn */
  13456. %@AS@%    short       rangetype;     /* _PG_LINEARAXIS,
  13457. %@AS@%                                  _PG_LOGAXIS */
  13458. %@AS@%    float       logbase;       /* Base used if log axis */
  13459. %@AS@%    short       autoscale;     /* TRUE=next 7 values
  13460. %@AS@%                                  calculated by system */
  13461. %@AS@%    float       scalemin;      /* Minimum value of scale */
  13462. %@AS@%    float       scalemax;      /* Maximum value of scale */
  13463. %@AS@%    float       scalefactor;   /* Scale factor for data on
  13464. %@AS@%                                  this axis */
  13465. %@AS@%    titletype   scaletitle;    /* Title definition for
  13466. %@AS@%                                  scaling factor */
  13467. %@AS@%    float       ticinterval;   /* Distance between tick marks
  13468. %@AS@%                                  (world coord.) */
  13469. %@AS@%    short       ticformat;     /* _PG_EXPFORMAT or
  13470. %@AS@%                                  _PG_DECFORMAT */
  13471. %@AS@%    short       ticdecimals;   /* Number of decimals for tick
  13472. %@AS@%                                  labels (max=9) */
  13473. %@AS@%  } axistype;%@AE@%%@NL@%
  13474. %@NL@%
  13475. The following list describes %@AB@%axistype%@AE@% member variables:  %@NL@%
  13476. %@NL@%
  13477. %@AB@%Member Variable%@AE@%                   %@AB@%Description%@AE@%
  13478. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13479. %@AI@%autoscale%@AE@%                         A boolean variable. If %@AI@%autoscale%@AE@% is %@AB@%TRUE%@AE@%,
  13480.                                   Presentation Graphics automatically 
  13481.                                   determines values
  13482.                                   for %@AI@% scalefactor%@AE@%, %@AI@%scalemax%@AE@%, %@AI@%scalemin%@AE@%, %@AI@%%@AE@%
  13483.                                   %@AI@%scaletitle%@AE@%, %@AI@%ticdecimals%@AE@%, %@AI@%ticformat%@AE@%, and %@AI@%%@AE@%
  13484.                                   %@AI@%ticinterval%@AE@% (see below).
  13485.                                   If %@AI@%autoscale%@AE@% equals %@AB@%FALSE%@AE@%, these seven 
  13486.                                   variables must be specified in your 
  13487.                                   program.
  13488.  
  13489. %@AI@%axiscolor%@AE@%                         An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@% 
  13490.                                   that specifies the color used for the 
  13491.                                   axis and parallel grid lines. (See 
  13492.                                   description for %@AI@%gridstyle%@AE@% above.) Note 
  13493.                                   that this member does not determine the 
  13494.                                   color of the axis title. That selection 
  13495.                                   is made through the structure %@AI@%%@AE@%
  13496.                                   %@AI@%axistitle%@AE@%.
  13497.  
  13498. %@AI@%axistitle%@AE@%                         A%@AB@% titletype%@AE@% structure that defines the 
  13499.                                   title of the associated axis. The title 
  13500.                                   of the %@AI@%y%@AE@% axis displays vertically to the
  13501.                                   left of the %@AI@%y%@AE@% axis, and the title of the
  13502.                                   %@AI@%x%@AE@% axis displays horizontally below the %@AI@%x%@AE@%
  13503.                                   axis.
  13504.  
  13505. %@AI@%grid%@AE@%                              A boolean true/false value that 
  13506.                                   determines whether grid lines are drawn 
  13507.                                   for the associated axis. Grid lines span
  13508.                                   the data window perpendicular to the 
  13509.                                   axis.
  13510.  
  13511. %@AI@%gridstyle%@AE@%                         An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@% 
  13512.                                   that specifies the grid's line style. 
  13513.                                   Lines can be solid, dashed, dotted, or 
  13514.                                   some combination. The default value for %@AI@%%@AE@%
  13515.                                   %@AI@%gridstyle%@AE@% is 1. Note that the color of 
  13516.                                   the parallel axis determines the color 
  13517.                                   of the grid lines. Thus the %@AI@%x%@AE@% axis grid 
  13518.                                   is the same color as the %@AI@%y%@AE@% axis, and the
  13519.                                   %@AI@%y%@AE@% axis grid is the same color as the %@AI@%x%@AE@% 
  13520.                                   axis.
  13521.  
  13522. %@AI@%labeled%@AE@%                           A boolean value that determines whether 
  13523.                                   tick marks and labels are drawn on the 
  13524.                                   axis. Axis labels should not be confused
  13525.                                   with axis titles. Axis labels are 
  13526.                                   numbers or descriptions such as "23.2" 
  13527.                                   or "January" attached to each tick mark.
  13528.  
  13529. %@AI@%logbase%@AE@%                           If %@AI@%rangetype%@AE@% is logarithmic, the %@AI@%logbase%@AE@%
  13530.                                   variable determines the log base used to
  13531.                                   scale the axis. Default value is 10.
  13532.  
  13533. %@AI@%rangetype%@AE@%                         An integer that determines whether the 
  13534.                                   scale of the axis is linear or 
  13535.                                   logarithmic. The %@AI@%rangetype%@AE@% variable 
  13536.                                   applies only to value data.
  13537.  
  13538.                                   Specify a linear scale with the %@AB@%%@AE@%
  13539.                                   %@AB@%_PG_LINEARAXIS%@AE@% constant. A linear scale 
  13540.                                   is best when the difference between axis
  13541.                                   minimum and maximum is relatively small.
  13542.                                   For example, a linear axis range 0-10 
  13543.                                   results in 10 tick marks evenly spaced 
  13544.                                   along the axis.
  13545.  
  13546.                                   Use %@AB@%_PG_LOGAXIS%@AE@% to specify a logarithmic
  13547.                                   %@AI@%rangetype%@AE@%. Logarithmic scales are useful
  13548.                                   when the range is very large or when the
  13549.                                   data varies exponentially. Line graphs 
  13550.                                   of exponentially varying data can be 
  13551.                                   made straight with a logarithmic %@AI@%%@AE@%
  13552.                                   %@AI@%rangetype%@AE@%.
  13553.  
  13554. %@AI@%scalefactor%@AE@%                       All numeric data are scaled by dividing 
  13555.                                   each value by %@AI@%scalefactor%@AE@%. For 
  13556.                                   relatively small values, the variable %@AI@%%@AE@%
  13557.                                   %@AI@%scalefactor%@AE@% should be 1, which is the 
  13558.                                   default.
  13559.                                   But data with large values should be 
  13560.                                   scaled by an
  13561.                                   appropriate factor. For example, data in
  13562.                                   the range
  13563.                                   2 million-20 million should be plotted 
  13564.                                   with %@AI@%scale-min%@AE@% set to 2, %@AI@%scalemax%@AE@% set to
  13565.                                   20, and %@AI@%scalefactor%@AE@% set to 1 million.
  13566.  
  13567.                                   If %@AI@%autoscale%@AE@% is set to %@AB@%TRUE%@AE@%, 
  13568.                                   Presentation Graphics automatically 
  13569.                                   determines a suitable value for %@AI@%%@AE@%
  13570.                                   %@AI@%scalefactor%@AE@% based on the range of data 
  13571.                                   to be plotted. Presentation Graphics 
  13572.                                   selects only values that are
  13573.                                   a factor of 1 thousand─that is, values 
  13574.                                   such as 1
  13575.                                   thousand, 1 million, or 1 billion. It 
  13576.                                   then labels the %@AI@%scaletitle%@AE@% appropriately
  13577.                                   (see below). If you desire some other 
  13578.                                   value for scaling, you must set %@AI@%%@AE@%
  13579.                                   %@AI@%autoscale%@AE@% to %@AB@%FALSE%@AE@% and set %@AI@%scalefactor%@AE@% 
  13580.                                   to the desired scaling value.
  13581.  
  13582. %@AI@%scalemax%@AE@%                          Highest value represented by the axis. 
  13583.  
  13584. %@AI@%scalemin%@AE@%                          Lowest value represented by the axis.
  13585.  
  13586. %@AI@%scaletitle%@AE@%                        A %@AB@%titletype%@AE@% structure defining a string 
  13587.                                   of text that 
  13588.                                   describes the value of %@AI@%scalefactor%@AE@%. If %@AI@%%@AE@%
  13589.                                   %@AI@%autoscale%@AE@% is %@AB@%TRUE%@AE@%, Presentation Graphics
  13590.                                   automatically writes
  13591.                                   a scale description to %@AI@%scaletitle%@AE@%. If%@AI@% %@AE@%
  13592.                                   %@AI@%autoscale%@AE@% equals %@AB@%FALSE%@AE@% and %@AI@%scalefactor%@AE@% 
  13593.                                   is 1, %@AI@%scaletitle.title%@AE@% should be blank. 
  13594.                                   Otherwise your program should copy an 
  13595.                                   appropriate scale description to %@AI@%%@AE@%
  13596.                                   %@AI@%scaletitle.title%@AE@%, such as "( x 1000)," 
  13597.                                   "(in millions of units)," "times 10 
  13598.                                   thousand dollars," etc.
  13599.  
  13600.                                   For the %@AI@%y%@AE@% axis, the %@AI@%scaletitle%@AE@% text 
  13601.                                   displays vertically between the axis 
  13602.                                   title and the %@AI@%y%@AE@% axis. For the %@AI@%x %@AE@%axis,%@AI@% %@AE@%
  13603.                                   the scale title appears below the%@AI@% x%@AE@% axis
  13604.                                   title.
  13605.  
  13606. %@AI@%ticdecimals%@AE@%                       Number of digits to display after the 
  13607.                                   decimal point in tick labels. Maximum 
  13608.                                   value is 9. Note that this variable 
  13609.                                   applies only to axes with value data. It
  13610.                                   is
  13611.                                   ignored for the category axis.
  13612.  
  13613. %@AI@%ticformat%@AE@%                         An integer that determines the format of
  13614.                                   the labels assigned to each tick mark. 
  13615.                                   Set %@AI@%ticformat%@AE@% to %@AB@%_PG_EXPFORMAT%@AE@% for 
  13616.                                   exponential format or set it to  %@AB@%%@AE@%
  13617.                                   %@AB@%_PG_DECFORMAT%@AE@% for decimal. The default 
  13618.                                   is %@AB@%_PG_DECFORMAT%@AE@%. Note that this 
  13619.                                   variable applies only to axes with value
  13620.                                   data. It is ignored for the category 
  13621.                                   axis.
  13622.  
  13623. %@AI@%ticinterval%@AE@%                       Sets interval between tick marks on the 
  13624.                                   axis. The tick interval is measured in 
  13625.                                   the same units as the numeric data 
  13626.                                   associated with the axis. For example, 
  13627.                                   if 2 sequential tick marks correspond to
  13628.                                   the values 20 and 25, the tick interval 
  13629.                                   between them is 5. Note that this 
  13630.                                   variable applies only to axes with value
  13631.                                   data. It is ignored for the category 
  13632.                                   axis.
  13633.  
  13634. %@NL@%
  13635. %@3@%%@CR:C6A00140014 @%%@AB@%windowtype%@AE@%%@EH@%%@NL@%
  13636. %@NL@%
  13637. Structures of type %@AB@%windowtype%@AE@% contain sizes, locations, and color codes for
  13638. the three windows produced by Presentation Graphics: the chart window, the
  13639. data window, and the legend. Refer to the "Terminology" section at the
  13640. beginning of this chapter for definitions of these terms. Windows are
  13641. located on the screen relative to the screen's logical origin. By changing
  13642. the logical origin, you can display charts that are partly or completely off
  13643. the screen. The PGCHART.H file defines %@AB@%windowtype%@AE@% as:  %@NL@%
  13644. %@NL@%
  13645. %@AS@%  typedef struct
  13646. %@AS@%  {
  13647. %@AS@%    short  x1;            /* Left edge of window in
  13648. %@AS@%                             pixels */
  13649. %@AS@%    short  y1;            /* Top edge of window in
  13650. %@AS@%                             pixels */
  13651. %@AS@%    short  x2;            /* Right edge of window in
  13652. %@AS@%                             pixels */
  13653. %@AS@%    short  y2;            /* Bottom edge of window in
  13654. %@AS@%                             pixels */
  13655. %@AS@%    short  border;        /* TRUE for border, FALSE
  13656. %@AS@%                             otherwise */
  13657. %@AS@%    short  background;    /* Internal palette color for
  13658. %@AS@%                             window background */
  13659. %@AS@%    short  borderstyle;   /* Style bytes for window
  13660. %@AS@%                             border */
  13661. %@AS@%    short  bordercolor;   /* Internal palette color for
  13662. %@AS@%                             window border */
  13663. %@AS@%  } windowtype;%@AE@%%@NL@%
  13664. %@NL@%
  13665. The following list describes %@AB@%windowtype%@AE@% member variables:  %@NL@%
  13666. %@NL@%
  13667. %@AB@%Member Variable%@AE@%                   %@AB@%Description%@AE@%
  13668. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13669. %@AI@%x1%@AE@%, %@AI@%y1%@AE@%, %@AI@%x2%@AE@%, %@AI@%y2%@AE@%                    Window coordinates in pixels. The 
  13670.                                   ordered pair (%@AI@%x1%@AE@%, %@AI@%y1%@AE@%) specifies the 
  13671.                                   coordinate of the upper left corner of 
  13672.                                   the window. The ordered pair (%@AI@%x2%@AE@%, %@AI@%y2%@AE@%) 
  13673.                                   specifies the coordinate of the lower 
  13674.                                   right corner.
  13675.  
  13676.                                   The reference point for the coordinates 
  13677.                                   depends on the type of window. The chart
  13678.                                   window is located relative to the 
  13679.                                   logical origin, usually the upper left 
  13680.                                   corner of the screen. The data and 
  13681.                                   legend windows are located relative to 
  13682.                                   the upper left corner of the chart 
  13683.                                   window. This allows you to change the 
  13684.                                   position of the chart window without 
  13685.                                   having to redefine coordinates for the 
  13686.                                   other two windows.
  13687.  
  13688. %@AI@%background%@AE@%                        An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@% 
  13689.                                   that specifies the window's background 
  13690.                                   color. The default value for %@AI@%background%@AE@% 
  13691.                                   is 1.
  13692.  
  13693. %@AI@%border%@AE@%                            A boolean variable that determines 
  13694.                                   whether a border frame is drawn around a
  13695.                                   window. 
  13696.  
  13697. %@AI@%bordercolor%@AE@%                       An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@% 
  13698.                                   that specifies the color of the window's
  13699.                                   border frame. The default value is 1.
  13700.  
  13701. %@AI@%borderstyle%@AE@%                       An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@%
  13702.                                   that specifies the line style of the 
  13703.                                   window's border frame. The default value
  13704.                                   is 1.
  13705.  
  13706. %@NL@%
  13707. %@3@%%@CR:C6A00140015 @%%@AB@%legendtype%@AE@%%@EH@%%@NL@%
  13708. %@NL@%
  13709. Structures of type %@AB@%legendtype%@AE@% contain size, location, and colors of the
  13710. chart legend. The PGCHART.H file defines the structure type as:  %@NL@%
  13711. %@NL@%
  13712. %@AS@%  typedef struct
  13713. %@AS@%  {
  13714. %@AS@%    short      legend;        /* TRUE=draw legend;
  13715. %@AS@%                                 FALSE=no legend */
  13716. %@AS@%    short      place;         /* _PG_RIGHT, _PG_BOTTOM,
  13717. %@AS@%                                 _PG_OVERLAY */
  13718. %@AS@%    short      textcolor;     /* Palette color for text*/
  13719. %@AS@%    short      autosize;      /* TRUE=system calculates
  13720. %@AS@%                                 legend size */
  13721. %@AS@%    windowtypelegendwindow;  /* Window definition for
  13722. %@AS@%                                 legend */
  13723. %@AS@%  } legendtype;%@AE@%%@NL@%
  13724. %@NL@%
  13725. The following list describes %@AB@%legendtype%@AE@% member variables:  %@NL@%
  13726. %@NL@%
  13727. %@AB@%Member Variable%@AE@%                   %@AB@%Description%@AE@%
  13728. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13729. %@AI@%autosize%@AE@%                          A boolean true/false variable that 
  13730.                                   determines whether Presentation Graphics
  13731.                                   is to automatically calculate the size 
  13732.                                   of the legend. If %@AI@%autosize%@AE@% equals %@AB@%FALSE%@AE@%,
  13733.                                   the legend window must be specified in 
  13734.                                   the %@AI@%legendwindow%@AE@% structure (see below).
  13735.  
  13736. %@AI@%legend%@AE@%                            A boolean true/false variable that 
  13737.                                   determines whether a legend is to appear
  13738.                                   on the chart. The %@AI@%legend%@AE@% variable is 
  13739.                                   ignored by functions that graph 
  13740.                                   single-series charts.
  13741.  
  13742. %@AI@%legendwindow%@AE@%                      A %@AB@%windowtype%@AE@% structure that defines 
  13743.                                   coordinates, background color, and 
  13744.                                   border frame for the legend. Coordinates
  13745.                                   given in %@AI@%legendwindow%@AE@% are ignored if %@AI@%%@AE@%
  13746.                                   %@AI@%autosize%@AE@% is %@AB@%TRUE%@AE@%.
  13747.  
  13748. %@AI@%place%@AE@%                             An integer that specifies the location 
  13749.                                   of the legend relative to the data 
  13750.                                   window. Setting the variable %@AI@%place%@AE@% equal
  13751.                                   to the constant %@AB@%_PG_RIGHT%@AE@% positions the 
  13752.                                   legend to the right of the data window. 
  13753.                                   Setting %@AI@%place%@AE@% to %@AB@%_PG_BOTTOM%@AE@% positions 
  13754.                                   the legend below the data window. 
  13755.                                   Setting %@AI@%place%@AE@% to %@AB@%_PG_OVERLAY%@AE@% positions 
  13756.                                   the legend within the data window.
  13757.  
  13758.                                   These settings influence the size of the
  13759.                                   data
  13760.                                   window. If %@AI@%place%@AE@% is equal to %@AB@%_PG_BOTTOM%@AE@% 
  13761.                                   or %@AB@%_PG_RIGHT%@AE@%, Presentation Graphics 
  13762.                                   automatically sizes the data window to 
  13763.                                   accommodate the legend.
  13764.                                   If %@AI@%place%@AE@% equals %@AB@%_PG_OVERLAY%@AE@% the data 
  13765.                                   window is sized without regard to the 
  13766.                                   legend.
  13767.  
  13768. %@AI@%textcolor%@AE@%                         An integer between 1 and %@AB@%_PG_PALETTELEN%@AE@% 
  13769.                                   that specifies the color of text within 
  13770.                                   the legend window.
  13771.  
  13772. %@NL@%
  13773. %@3@%%@CR:C6A00140016 @%%@AB@%chartenv%@AE@%%@EH@%%@NL@%
  13774. %@NL@%
  13775. A structure of type%@AB@% chartenv%@AE@% defines the chart environment. The following
  13776. code shows that a %@AB@%chartenv%@AE@% type structure consists almost entirely of
  13777. structures of the four types discussed above.  %@NL@%
  13778. %@NL@%
  13779. The PGCHART.H file defines the %@AB@%chartenv%@AE@% structure type as:  %@NL@%
  13780. %@NL@%
  13781. %@AS@%  typedef struct
  13782. %@AS@%  {
  13783. %@AS@%    short       charttype;     /* Chart type */
  13784. %@AS@%    short       chartstyle;    /* Chart style */
  13785. %@AS@%    windowtype  chartwindow;   /* Window definition for
  13786. %@AS@%                                  overall chart */
  13787. %@AS@%    windowtype  datawindow;    /* Window definition for data
  13788. %@AS@%                                  part of chart */
  13789. %@AS@%    titletype   maintitle;     /* Main chart title */
  13790. %@AS@%    titletype   subtitle;      /* Chart subtitle */
  13791. %@AS@%    axistype    xaxis;         /* Definition for x axis */
  13792. %@AS@%    axistype    yaxis;         /* Definition for y axis */
  13793. %@AS@%    legendtype  legend;        /* Definition for legend */
  13794. %@AS@%  } chartenv;%@AE@%%@NL@%
  13795. %@NL@%
  13796. %@AU@% Initialize the chart  environment with the _pg_defaultchart function.%@AE@%  %@NL@%
  13797. %@NL@%
  13798. Note that all the data in a %@AB@%chartenv%@AE@% type structure is initialized by
  13799. calling the %@AB@%_pg_defaultchart%@AE@% function. If your program does not call
  13800. %@AB@%_pg_defaultchart%@AE@%, it must explicitly define every variable in the chart
  13801. environment─a tedious and unnecessary procedure. The recommended method for
  13802. adjusting the appearance of your chart is to initialize variables for the
  13803. proper chart type by calling the %@AB@%_pg_defaultchart%@AE@% function, and then
  13804. reassign selected environment variables such as titles.  %@NL@%
  13805. %@NL@%
  13806. The following list describes %@AB@%chartenv%@AE@% member variables:  %@NL@%
  13807. %@NL@%
  13808. %@AB@%Member Variable%@AE@%                   %@AB@%Description%@AE@%
  13809. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13810. %@AI@%chartstyle%@AE@%                        An integer that determines the style of 
  13811.                                   the chart
  13812.                                   (see Table 14.1). Legal values for %@AI@%%@AE@%
  13813.                                   %@AI@%chartstyle%@AE@%
  13814.                                   are %@AB@%_PG_PERCENT%@AE@% and %@AB@%_PG_NOPERCENT%@AE@%
  13815.                                   for pie charts; %@AB@%_PG_STACKEDBARS%@AE@% and %@AB@%%@AE@%
  13816.                                   %@AB@%_PG_PLAINBARS%@AE@% for bar and column charts;
  13817.                                   and %@AB@%_PG_POINTANDLINE%@AE@% and %@AB@%_PG_POINTONLY%@AE@% 
  13818.                                   for line graphs and scatter diagrams. 
  13819.                                   This variable corresponds to the third 
  13820.                                   argument for the %@AB@%_pg_defaultchart%@AE@% 
  13821.                                   function.
  13822.  
  13823. %@AI@%charttype%@AE@%                         An integer that determines the type of 
  13824.                                   chart displayed. The value of the 
  13825.                                   variable %@AI@%charttype%@AE@% is  %@AB@%_PG_BARCHART%@AE@%, %@AB@%%@AE@%
  13826.                                   %@AB@%_PG_COLUMNCHART%@AE@%, %@AB@%_PG_LINECHART%@AE@%, %@AB@%%@AE@%
  13827.                                   %@AB@%_PG_SCATTERCHART%@AE@%, or %@AB@%_PG_PIECHART%@AE@%. This 
  13828.                                   variable corresponds to the second 
  13829.                                   argument for the %@AB@%_pg_defaultchart%@AE@% 
  13830.                                   function.
  13831.  
  13832. %@AI@%chartwindow%@AE@%                       A %@AB@%windowtype%@AE@% structure that defines the 
  13833.                                   appearance of the chart window.
  13834.  
  13835. %@AI@%datawindow%@AE@%                        A %@AB@%windowtype%@AE@% structure that defines the 
  13836.                                   appearance of the data window.
  13837.  
  13838. %@AI@%legend%@AE@%                            A %@AB@%legendtype%@AE@% structure that defines the 
  13839.                                   appearance of the legend window.
  13840.  
  13841. %@AI@%maintitle%@AE@%                         A %@AB@%titletype%@AE@% structure that defines the 
  13842.                                   appearance of the main title of the 
  13843.                                   chart.
  13844.  
  13845. %@AI@%subtitle%@AE@%                          A %@AB@%titletype%@AE@% structure that defines the 
  13846.                                   appearance of the chart's subtitle.
  13847.  
  13848. %@AI@%xaxis%@AE@%                             An %@AB@%axistype%@AE@% structure that defines the 
  13849.                                   appearance of the %@AI@%x%@AE@% axis. (This variable
  13850.                                   is not applicable for pie charts.)
  13851.  
  13852. %@AI@%yaxis%@AE@%                             An %@AB@%axistype%@AE@% structure that defines the 
  13853.                                   appearance of the %@AI@%y%@AE@% axis. (This variable
  13854.                                   is not applicable for pie charts.)
  13855.  
  13856. %@NL@%
  13857. %@2@%%@CR:C6A00140017 @%%@AB@%An Overview of the Presentation Graphics Functions%@AE@%%@EH@%%@NL@%
  13858. %@NL@%
  13859. The chapter concludes with a few words about the 22 functions that make up
  13860. the Presentation Graphics library. They are listed in Table 14.3 for
  13861. convenient reference. Refer to Appendix B, "C Library Guide," or online help
  13862. for a description of the functions and their arguments.  %@NL@%
  13863. %@NL@%
  13864. %@AB@%Table 14.3  %@AB@%Presentation Graphics Functions%@AE@%%@AE@%
  13865.  
  13866. %@TH:  11   975 02 21 22 33 @%
  13867. Primary Functions    Secondary Functions
  13868. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13869. %@AB@%_pg_initchart%@AE@%        %@AB@%_pg_hlabelchart%@AE@%       %@AB@%_pg_setpalette%@AE@%
  13870. %@AB@%_pg_defaultchart%@AE@%     %@AB@%_pg_vlabelchart%@AE@%       %@AB@%_pg_resetpalette%@AE@%
  13871. %@AB@%_pg_chart%@AE@%            %@AB@%_pg_analyzechart%@AE@%      %@AB@%_pg_getstyleset%@AE@%
  13872. %@AB@%_pg_chartms%@AE@%          %@AB@%_pg_analyzechartms%@AE@%    %@AB@%_pg_setstyleset%@AE@%
  13873. %@AB@%_pg_chartscatter%@AE@%     %@AB@%_pg_analyzescatter%@AE@%    %@AB@%_pg_resetstyleset%@AE@%
  13874. %@AB@%_pg_chartscatterms%@AE@%   %@AB@%_pg_analyzescatterms%@AE@%  %@AB@%_pg_getchardef%@AE@%
  13875. %@AB@%_pg_chartpie%@AE@%         %@AB@%_pg_analyzepie%@AE@%        %@AB@%_pg_setchardef%@AE@%
  13876.                      %@AB@%_pg_getpalette%@AE@%
  13877. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13878. %@TE:  11   975 02 21 22 33 @%
  13879.  
  13880. In most cases you need only be concerned with seven of the routines, called
  13881. the "primary functions." These functions initialize variables and display
  13882. the selected chart types. As demonstrated in example programs earlier in
  13883. this chapter, you can create very acceptable charts with programs that call
  13884. only three of the Presentation Graphics primary functions.  %@NL@%
  13885. %@NL@%
  13886. The 15 secondary functions of Presentation Graphics do not directly display
  13887. charts. Most of them retrieve or set data in the Presentation Graphics chart
  13888. environment.  %@NL@%
  13889. %@NL@%
  13890. Of special interest among the secondary functions are the "analysis
  13891. functions," identified by the prefix %@AB@%_pg_analyze%@AE@% in their function names.
  13892. These five functions calculate default values that pertain to a given chart
  13893. type and data set. Calling an analysis function has the same effect as
  13894. calling a corresponding primary function, except that the chart is not
  13895. displayed. This allows you to pass on to the library the burden of
  13896. calculating values. You can then make modifications  to the resulting values
  13897. and call a primary routine to display the chart.  %@NL@%
  13898. %@NL@%
  13899. Use the %@AB@%_pg_hlabelchart%@AE@% and %@AB@%_pg_vlabelchart%@AE@% functions to display text on
  13900. your chart that is not part of a title or axis label. These functions enable
  13901. you to attach notes or other messages to your chart. You may also find them
  13902. useful for labeling separate lines of a multiseries line graph.  %@NL@%
  13903. %@NL@%
  13904. %@NL@%
  13905. %@NL@%
  13906. %@NL@%
  13907. %@NL@%
  13908. %@NL@%
  13909. %@CR:C6A00150001 @%%@1@%%@AB@%Chapter 15  Fonts%@AE@%%@EH@%%@NL@%
  13910. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13911. %@NL@%
  13912. Preceding chapters have discussed how to write QuickC programs that generate
  13913. graphics and display charts. QuickC has yet another capability when it comes
  13914. to graphics: fonted text. Your programs can display various styles and sizes
  13915. of text in any graphics image or chart.  %@NL@%
  13916. %@NL@%
  13917. This chapter tells how. It assumes you have already read Chapter 13,
  13918. "Graphics." You should understand such terms as "graphics mode" and "text
  13919. mode," and be familiar with the functions %@AB@%_setvideomode%@AE@% and %@AB@%_moveto%@AE@%. Other
  13920. than that, there's very little to it. Fonts are simple to learn and even
  13921. simpler to use, yet they can add to your graphics a final touch of polish.  %@NL@%
  13922. %@NL@%
  13923. %@NL@%
  13924. %@2@%%@CR:C6A00150002 @%%@AB@%QuickC Fonts%@AE@%%@EH@%%@NL@%
  13925. %@NL@%
  13926. A "font" is a collection of stylized text characters. Each font consists of
  13927. several type sizes and a typeface.  %@NL@%
  13928. %@NL@%
  13929. "Typeface" is a printer's term that refers to the style of the displayed
  13930. text─ Courier, for example, or Roman. The list on the following page shows
  13931. six of the typefaces available with QuickC's font library.  %@NL@%
  13932. %@NL@%
  13933. "Type size" measures the screen area occupied by individual characters. This
  13934. term is also borrowed from the printer's lexicon, but for our purposes is
  13935. specified in units of screen pixels. For example, "Courier 16 x 9" denotes
  13936. text of Courier typeface, with each character occupying a screen area of 16
  13937. vertical pixels by 9 horizontal pixels.  %@NL@%
  13938. %@NL@%
  13939. QuickC's font functions use two methods to create fonts. The first technique
  13940. generates Courier, Helv, and Tms Rmn fonts through a "bit-mapping" (or
  13941. "raster-mapping") technique. Bit-mapping defines character images with
  13942. binary data. Each bit in the map corresponds to a screen pixel. If a bit is
  13943. 1, its associated pixel is set to the current screen color. A bit value of 0
  13944. clears the pixel. Video adapters use this same technique to display text in
  13945. graphics mode.  %@NL@%
  13946. %@NL@%
  13947. The second method creates the remaining three type styles─Modern, Script,
  13948. and Roman─as "vector-mapped" fonts. Vector-mapping represents each character
  13949. in terms of lines and arcs. In a literal sense vector-mapped characters are
  13950. drawn on the screen. You might think of bit-mapped characters as being
  13951. stenciled.  %@NL@%
  13952. %@NL@%
  13953. Each method has advantages and disadvantages. Bit-mapped characters are more
  13954. completely formed since the pixel mapping is predetermined. However, they
  13955. cannot be scaled. Vector-mapped text can be scaled to any size, but the
  13956. characters tend to lack the solid appearance of the bit-mapped characters.  %@NL@%
  13957. %@NL@%
  13958. %@AU@%(This figure may be found in the printed book.)%@AE@%%@NL@%
  13959. %@NL@%
  13960. Table 15.1 lists available sizes for each font. Notice that the bit-mapped
  13961. fonts come in preset sizes as measured in pixels. The exact size of any
  13962. fonted character depends on screen resolution and display type.  %@NL@%
  13963. %@NL@%
  13964. %@AB@%Table 15.1  %@AB@%Typefaces and Type Sizes in the QuickC Library%@AE@%%@AE@%
  13965.  
  13966. %@TH:  19   749 02 10 09 26 31 @%
  13967. Typeface  Mapping  Size (in pixels)          Spacing
  13968. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13969. Courier   Bit      13 x 8, 16 x 9,           Fixed
  13970.                    20 x 12                   
  13971.  
  13972. Helv      Bit      13 x 5, 16 x 7, 20 x 8,   Fixed
  13973.                    13 x 15, 16 x 6, 19 x 8   
  13974.  
  13975. Tms Rmn   Bit      10 x 5, 12 x 6, 15 x 8,   Fixed
  13976.                    16 x 9, 20 x 12, 26 x 16  
  13977.  
  13978. Modern    Vector   Scaled                    Proportional
  13979.  
  13980. Script    Vector   Scaled                    Proportional
  13981.  
  13982. Roman     Vector   Scaled                    Proportional
  13983.  
  13984. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  13985.  
  13986. %@TE:  19   749 02 10 09 26 31 @%
  13987.  
  13988. QuickC's font routines can display characters 32-255, including most
  13989. extended characters (ASCII 128-255). A few extended characters cannot be
  13990. displayed; these are represented as either an underscore (_) or period (.)
  13991. character.  %@NL@%
  13992. %@NL@%
  13993. %@NL@%
  13994. %@2@%%@CR:C6A00150003 @%%@AB@%Using QuickC's Font Library%@AE@%%@EH@%%@NL@%
  13995. %@NL@%
  13996. Data for both bit-mapped and vector-mapped fonts reside in files on disk. A
  13997. .FON extension identifies the files. The names of the .FON files indicate
  13998. their content. For example, the files MODERN.FON, ROMAN.FON, and SCRIPT.FON
  13999. hold data for the three vector-mapped fonts.  %@NL@%
  14000. %@NL@%
  14001. %@AU@% You can use Microsoft Windows .FON files.%@AE@%  %@NL@%
  14002. %@NL@%
  14003. QuickC .FON files are identical to the .FON files used in the Microsoft
  14004. Windows operating environment. If you have access to Windows you can use any
  14005. of its .FON files with QuickC's font functions. Windows .FON files are also
  14006. available for purchase separately. In addition, several vendors offer
  14007. software that can create or modify .FON files, allowing you to design your
  14008. own fonts.  %@NL@%
  14009. %@NL@%
  14010. Your programs should follow these three steps to display fonted text:  %@NL@%
  14011. %@NL@%
  14012. %@NL@%
  14013.   1.  Register fonts%@NL@%
  14014. %@NL@%
  14015.   2.  Set the current font from the register%@NL@%
  14016. %@NL@%
  14017.   3.  Display text using the current font%@NL@%
  14018. %@NL@%
  14019. %@NL@%
  14020. The following sections describe each of the three steps in detail. An
  14021. example program later in the chapter demonstrates the steps.  %@NL@%
  14022. %@NL@%
  14023. %@NL@%
  14024. %@3@%%@CR:C6A00150004 @%%@AB@%Register Fonts%@AE@%%@EH@%%@NL@%
  14025. %@NL@%
  14026. The fonts you plan to use must first be organized into a list in memory, a
  14027. process called "registering." The register list contains information about
  14028. the available .FON files. Register fonts by calling the function
  14029. %@AB@%_registerfonts%@AE@%. This function reads header information from specified .FON
  14030. files. It builds a list of file information but does not read mapping data
  14031. from the files.  %@NL@%
  14032. %@NL@%
  14033. The GRAPH.H file prototypes the %@AB@%_registerfonts%@AE@% function as:  %@NL@%
  14034. %@NL@%
  14035. %@AS@%  short far _registerfonts( unsigned char far * );%@AE@%%@NL@%
  14036. %@NL@%
  14037. The argument points to a string containing a file name. The file name is the
  14038. name of the .FON file for the desired font. The file name can include wild
  14039. cards, allowing you to register several fonts with one call to
  14040. %@AB@%_registerfonts%@AE@%.  %@NL@%
  14041. %@NL@%
  14042. If it successfully reads one or more .FON files, %@AB@%_registerfonts%@AE@% returns the
  14043. number of fonts registered. If the function fails, it returns a negative
  14044. error code. Refer to Appendix B, "C Library Guide," or to online help for a
  14045. description of error codes.  %@NL@%
  14046. %@NL@%
  14047. %@NL@%
  14048. %@3@%%@CR:C6A00150005 @%%@AB@%Set Current Font%@AE@%%@EH@%%@NL@%
  14049. %@NL@%
  14050. Call the function %@AB@%_setfont%@AE@% to select a current font. This function checks to
  14051. see if the requested font is registered, then reads the mapping data from
  14052. the appropriate .FON file. A font must be registered and marked current
  14053. before your program can display text of that font.  %@NL@%
  14054. %@NL@%
  14055. The GRAPH.H file prototypes %@AB@%_setfonts%@AE@% as  %@NL@%
  14056. %@NL@%
  14057. %@AS@%  short far _setfont( unsigned char far * );%@AE@%%@NL@%
  14058. %@NL@%
  14059. The function's argument is a pointer to a character string. The string
  14060. consists of letter codes that describe the desired font, as outlined below:
  14061. %@NL@%
  14062. %@NL@%
  14063. %@AB@%Option Code%@AE@%                       %@AB@%Meaning%@AE@%
  14064. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14065. %@AB@%b%@AE@%                                 Select the best fit from the registered 
  14066.                                   fonts. This option instructs %@AB@%_setfont%@AE@% to
  14067.                                   accept the closest-fitting font if a 
  14068.                                   font of the specified size is not 
  14069.                                   registered.
  14070.  
  14071.                                   If at least one font is registered, the %@AB@%%@AE@%
  14072.                                   %@AB@%b%@AE@% option always sets a current font. If 
  14073.                                   you do not specify the %@AB@%b%@AE@% option and an 
  14074.                                   exact matching font is not registered, %@AB@%%@AE@%
  14075.                                   %@AB@%_setfont%@AE@% will fail. In this case, any 
  14076.                                   existing current font remains current. 
  14077.                                   Refer to online help for a description 
  14078.                                   of error codes returned by %@AB@%_setfont%@AE@%.
  14079.  
  14080.                                   The %@AB@%_setfont%@AE@% function uses four criteria
  14081.                                   for selecting the best fit. In 
  14082.                                   descending order of precedence the four 
  14083.                                   criteria are pixel height, typeface, 
  14084.                                   pixel width, and spacing (fixed or 
  14085.                                   proportional). If you request a 
  14086.                                   vector-mapped font,%@AB@%_setfont%@AE@% sizes the 
  14087.                                   font to correspond with the specified 
  14088.                                   pixel height and width. If you request a
  14089.                                   raster-mapped (bit-mapped) font, %@AB@%%@AE@%
  14090.                                   %@AB@%_setfont%@AE@% chooses the closest available 
  14091.                                   size. If the requested type size for a 
  14092.                                   raster-mapped font fits exactly between 
  14093.                                   two registered fonts, the smaller size 
  14094.                                   takes precedence.
  14095.  
  14096. %@AB@%f%@AE@%                                 Select only a fixed-spaced font.
  14097.  
  14098. %@AB@%h%@AE@%%@AI@%y%@AE@%                                Character height, where %@AI@%y%@AE@% is the height 
  14099.                                   in pixels.
  14100.  
  14101. %@AB@%n%@AE@%%@AI@%x%@AE@%                                Select font number %@AI@%x%@AE@%, where %@AI@%x%@AE@% is less 
  14102.                                   than or equal to the value returned by %@AB@%%@AE@%
  14103.                                   %@AB@%_registerfonts%@AE@%. For example, the option %@AB@%%@AE@%
  14104.                                   %@AB@%n3%@AE@% makes the third registered font 
  14105.                                   current, assuming that three or more 
  14106.                                   fonts are registered.
  14107.  
  14108. %@AB@%p%@AE@%                                 Select only a proportional-spaced font.
  14109.  
  14110. %@AB@%r%@AE@%                                 Select only a raster-mapped (bit-mapped)
  14111.                                   font.
  14112.  
  14113. %@AB@%t`%@AE@%%@AI@%fontname%@AE@%%@AB@%'%@AE@%                       Typeface of the font in single quotes. 
  14114.                                   The %@AI@%fontname%@AE@% string is one of the 
  14115.                                   following:
  14116.  
  14117.                                   courier     modern
  14118.  
  14119.                                   helv        script
  14120.  
  14121.                                   tms rmn     roman
  14122.  
  14123.                                   Notice the space in "tms rmn."  
  14124.                                   Additional font files use other names 
  14125.                                   for %@AI@%fontname%@AE@%. Refer to the vendor's 
  14126.                                   documentation for these names.
  14127.  
  14128. %@AB@%v%@AE@%                                 Select only a vector-mapped font.
  14129.  
  14130. %@AB@%w%@AE@%%@AI@%x%@AE@%                                Character width, where %@AI@%x%@AE@% is the width in
  14131.                                   pixels.
  14132.  
  14133. Option codes are not case-sensitive and can be listed in any order. You can
  14134. separate codes with spaces or any other character that is not a valid option
  14135. code. The %@AB@%_setfont%@AE@% function ignores all invalid codes.  %@NL@%
  14136. %@NL@%
  14137. The %@AB@%_setfont%@AE@% function updates a data area with parameters of the current
  14138. font. The data area is in the form of a structure, defined in the GRAPH.H
  14139. file as  %@NL@%
  14140. %@NL@%
  14141. %@AS@%  struct _fontinfo 
  14142. %@AS@%  {
  14143. %@AS@%     int     type;          /* set = vector,clear = bit map */
  14144. %@AS@%     int     ascent;        /* pix dist from top to base */
  14145. %@AS@%     int     pixwidth;      /* character width in pixels */
  14146. %@AS@%     int     pixheight;     /* character height in pixels */
  14147. %@AS@%     int     avgwidth;      /* average character width */
  14148. %@AS@%     char    filename[81];  /* file name including path */
  14149. %@AS@%     char    faceName[32];  /* font name */
  14150. %@AS@%  };%@AE@%%@NL@%
  14151. %@NL@%
  14152. If you wish to retrieve the parameters of the current font, call the
  14153. function %@AB@%_getfontinfo%@AE@%. Refer to Appendix B, "C Library Guide," or online
  14154. help for a description of this function.  %@NL@%
  14155. %@NL@%
  14156. %@NL@%
  14157. %@3@%%@CR:C6A00150006 @%%@AB@%Display Text%@AE@%%@EH@%%@NL@%
  14158. %@NL@%
  14159. The last step consists of two parts. First, select a screen position for the
  14160. text with the graphics function %@AB@%_moveto%@AE@%. Then display fonted text at that
  14161. position with the function %@AB@%_outgtext%@AE@%. The %@AB@%_moveto%@AE@% function takes pixel
  14162. coordinates as arguments. The coordinates locate the top left of the first
  14163. character in the text string.  %@NL@%
  14164. %@NL@%
  14165. %@NL@%
  14166. %@2@%%@CR:C6A00150007 @%%@AB@%An Example Program%@AE@%%@EH@%%@NL@%
  14167. %@NL@%
  14168. QuickC's font functions shine when used in conjunction with your other
  14169. graphics functions. They allow you to dress up any image on the screen. Yet
  14170. they can make a visual impression when used by themselves, as an example
  14171. will show.  %@NL@%
  14172. %@NL@%
  14173. The program SAMPLER.C displays sample text in all the available fonts, then
  14174. exits when a key is pressed. Make sure the .FON files are in the current
  14175. directory before running the program.  %@NL@%
  14176. %@NL@%
  14177. %@AS@%  /* SAMPLER.C: Display sample text in various fonts. */
  14178. %@AS@%  
  14179. %@AS@%  #include <stdio.h>
  14180. %@AS@%  #include <conio.h>
  14181. %@AS@%  #include <stdlib.h>
  14182. %@AS@%  #include <graph.h>
  14183. %@AS@%  #include <string.h>%@AE@%%@NL@%
  14184. %@NL@%
  14185. %@AS@%  #define NFONTS 6
  14186. %@AS@%  
  14187. %@AS@%  main()
  14188. %@AS@%  
  14189. %@AS@%  {
  14190. %@AS@%    static unsigned char *text[2*NFONTS] =
  14191. %@AS@%    {
  14192. %@AS@%        "COURIER",        "courier",
  14193. %@AS@%        "HELV",           "helv",
  14194. %@AS@%        "TMS RMN",        "tms rmn",
  14195. %@AS@%        "MODERN",         "modern",
  14196. %@AS@%        "SCRIPT",         "script",
  14197. %@AS@%        "ROMAN",          "roman"
  14198. %@AS@%    };
  14199. %@AS@%    static unsigned char *face[NFONTS] =
  14200. %@AS@%    {
  14201. %@AS@%        "t'courier'",
  14202. %@AS@%        "t'helv'",
  14203. %@AS@%        "t'tms rmn'",
  14204. %@AS@%        "t'modern'",
  14205. %@AS@%        "t'script'",
  14206. %@AS@%        "t'roman'"
  14207. %@AS@%    };
  14208. %@AS@%    static unsigned char list[20];
  14209. %@AS@%    struct videoconfig vc;
  14210. %@AS@%    int mode = _VRES16COLOR;
  14211. %@AS@%    register i;
  14212. %@AS@%  
  14213. %@AS@%    /*  Read header info from all .FON files in
  14214. %@AS@%     *  current directory   */
  14215. %@AS@%  
  14216. %@AS@%    if(_registerfonts( "*.FON" )<0 )
  14217. %@AS@%    {
  14218. %@AS@%       _outtext("Error:  can't register fonts");
  14219. %@AS@%       exit( 0 );
  14220. %@AS@%    }
  14221. %@AS@%  
  14222. %@AS@%    /*   Set highest available video mode */
  14223. %@AS@%  
  14224. %@AS@%    while( !_setvideomode( mode ) )
  14225. %@AS@%       mode--;
  14226. %@AS@%    if( mode == _TEXTMONO )
  14227. %@AS@%       exit ( 0 );
  14228. %@AS@%  
  14229. %@AS@%    /*   Copy video configuration into structure vc */
  14230. %@AS@%  
  14231. %@AS@%    _getvideoconfig( &vc );%@AE@%%@NL@%
  14232. %@NL@%
  14233. %@AS@%    /*   Display six lines of sample text */
  14234. %@AS@%  
  14235. %@AS@%    for( i = 0; i<NFONTS; i++ )
  14236. %@AS@%    {
  14237. %@AS@%       strcpy( list, face[i] );
  14238. %@AS@%       strcat( list, "h30w24b" );
  14239. %@AS@%  
  14240. %@AS@%       if( !_setfont( list ) )
  14241. %@AS@%       {
  14242. %@AS@%           _setcolor( i + 1 );
  14243. %@AS@%           _moveto( 0, (i * vc.numypixels) / NFONTS );
  14244. %@AS@%           _outgtext( text[i * 2] );
  14245. %@AS@%           _moveto( vc.numxpixels / 2,
  14246. %@AS@%                       (i * vc.numypixels) / NFONTS );
  14247. %@AS@%           _outgtext( text[(i * 2) + 1] );
  14248. %@AS@%       }
  14249. %@AS@%       else
  14250. %@AS@%       {
  14251. %@AS@%           _setvideomode( _DEFAULTMODE );
  14252. %@AS@%           _outtext( "Error:  can't set font" );
  14253. %@AS@%           exit( 0 );
  14254. %@AS@%       }
  14255. %@AS@%    }
  14256. %@AS@%    getch();
  14257. %@AS@%    _setvideomode( _DEFAULTMODE );
  14258. %@AS@%  
  14259. %@AS@%    /* Return memory when finished with fonts */
  14260. %@AS@%  
  14261. %@AS@%    _unregisterfonts();
  14262. %@AS@%    exit ( 0 );
  14263. %@AS@%  }%@AE@%%@NL@%
  14264. %@NL@%
  14265. Notice that SAMPLER.C calls the graphics function %@AB@%_moveto%@AE@% to establish the
  14266. starting position for each text string. Chapter 13, "Graphics," describes
  14267. the %@AB@%_moveto%@AE@% function in the section "Graphics Coordinates." The function
  14268. %@AB@%_setfont%@AE@% takes a character string as an argument. The string is a list of
  14269. options that specifies typeface and the best fit for a character height of
  14270. 30 pixels, and a width of 24 pixels. See Appendix B, "C Library Guide," and
  14271. online help for complete descriptions of the QuickC font functions.  %@NL@%
  14272. %@NL@%
  14273. %@NL@%
  14274. %@2@%%@CR:C6A00150008 @%%@AB@%A Few Hints%@AE@%%@EH@%%@NL@%
  14275. %@NL@%
  14276. Fonted text is simply another form of graphics, and using fonts effectively
  14277. requires little programming effort. Still, there are a few things to watch:
  14278. %@NL@%
  14279. %@NL@%
  14280. %@NL@%
  14281.   ■   Remember the video should be set only once to establish a graphics
  14282.       mode. If you generate an image─say, with Presentation Graphics─and
  14283.       wish to incorporate fonted text into it, don't reset the video mode
  14284.       prior to calling the font routines. Doing so will blank the screen,
  14285.       destroying the original image.%@NL@%
  14286. %@NL@%
  14287.   ■   The %@AB@%_setfont%@AE@% function reads specified .FON files to obtain mapping
  14288.       data for the current font. Each call to %@AB@%_setfont%@AE@% causes a disk access
  14289.       and overwrites the old font data in memory. If you wish to show text
  14290.       of different styles on the same screen, display all text of one font
  14291.       before moving on to the others. By minimizing the number of calls to
  14292.       %@AB@%_setfont%@AE@% you'll save time spent in disk I/O and memory reloads. %@NL@%
  14293. %@NL@%
  14294.   ■   When your program finishes with the fonts library, you might wish to
  14295.       free the memory occupied by the register list. Call the function
  14296.       %@AB@%_unregisterfonts%@AE@% to do this. As its name implies, this function frees
  14297.       the memory allocated by %@AB@%_registerfonts%@AE@%. The register information for
  14298.       each type size of each font takes up approximately 140 bytes of
  14299.       memory. Thus the amount of memory returned by %@AB@%_unregisterfonts%@AE@% is
  14300.       significant only if you have many fonts registered.%@NL@%
  14301. %@NL@%
  14302.   ■   As for aesthetics, the same suggestions for the printed page apply to
  14303.       fonted screen text. Typefaces are more effective when they are not
  14304.       competing with each other for attention. Restricting the number of
  14305.       styles per screen to one or two generally results in a more pleasing,
  14306.       less cluttered image.%@NL@%
  14307. %@NL@%
  14308. %@NL@%
  14309. %@NL@%
  14310. %@NL@%
  14311. %@NL@%
  14312. %@NL@%
  14313. %@NL@%
  14314. %@CR:C6A00160001 @%%@1@%%@AB@%Chapter 16  In-Line Assembly%@AE@%%@EH@%%@NL@%
  14315. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14316. %@NL@%
  14317. QuickC has the ability to handle assembly-language instructions right in
  14318. your C programs. This powerful feature is called "in-line assembly."  %@NL@%
  14319. %@NL@%
  14320. Assembly language serves many purposes, such as improving program speed,
  14321. reducing memory needs, and controlling hardware. The in-line assembler lets
  14322. you embed assembly-language instructions directly in your C source programs
  14323. without extra assembly and link steps. And the assembler is built into the
  14324. compiler─you don't need a separate assembler such as the Microsoft Macro
  14325. Assembler (MASM).  %@NL@%
  14326. %@NL@%
  14327. This chapter assumes that you are familiar with assembly-language terms and
  14328. concepts. If you have never programmed in assembly language, refer to the
  14329. section "References and Books on Assembly Language," at the end of this
  14330. chapter.  %@NL@%
  14331. %@NL@%
  14332. %@NL@%
  14333. %@2@%%@CR:C6A00160002 @%%@AB@%Advantages of In-Line Assembly%@AE@%%@EH@%%@NL@%
  14334. %@NL@%
  14335. Because QuickC's in-line assembler doesn't require separate assembly and
  14336. link steps, it is more convenient than a separate assembler. In-line
  14337. assembly code can use any C variable or function name that is visible (in
  14338. scope), so it is easy to integrate it with your program's C code. And
  14339. because the assembly code can be mixed in-line with C statements, it can do
  14340. tasks that are cumbersome or impossible in C alone.  %@NL@%
  14341. %@NL@%
  14342. The uses of in-line assembly include  %@NL@%
  14343. %@NL@%
  14344. %@NL@%
  14345.   ■   Writing the body of a function in assembly language%@NL@%
  14346. %@NL@%
  14347.   ■   Spot-optimizing speed-critical sections of code%@NL@%
  14348. %@NL@%
  14349.   ■   Calling DOS and BIOS routines with the %@AB@%INT%@AE@% instruction%@NL@%
  14350. %@NL@%
  14351.   ■   Creating TSR (terminate-and-stay-resident) code or handler routines
  14352.       that require knowledge of processor states%@NL@%
  14353. %@NL@%
  14354. %@NL@%
  14355. In-line assembly is a special-purpose tool. If you plan to transport an
  14356. application, you'll probably want to place machine-specific code in a
  14357. separate module. And because the in-line assembler doesn't support all MASM
  14358. directives, you may find it more convenient to use MASM for such modules.  %@NL@%
  14359. %@NL@%
  14360. %@NL@%
  14361. %@2@%%@CR:C6A00160003 @%%@AB@%The _asm Keyword%@AE@%%@EH@%%@NL@%
  14362. %@NL@%
  14363. The %@AB@%_asm%@AE@% keyword invokes the in-line assembler and can appear wherever a C
  14364. statement is legal. It cannot appear by itself. It must be followed by an
  14365. assembly instruction, a group of instructions enclosed in braces, or, at the
  14366. very least, an empty pair of braces. The term "%@AB@%_asm%@AE@% block" here refers to
  14367. any instruction or group of instructions, whether or not in braces.  %@NL@%
  14368. %@NL@%
  14369. Below is a simple %@AB@%_asm%@AE@% block enclosed in braces. (The code prints the "beep"
  14370. character, ASCII 7.)  %@NL@%
  14371. %@NL@%
  14372. %@AS@%  _asm
  14373. %@AS@%  {
  14374. %@AS@%     mov ah, 2
  14375. %@AS@%     mov dl, 7
  14376. %@AS@%     int 21h
  14377. %@AS@%  }%@AE@%%@NL@%
  14378. %@NL@%
  14379. Alternatively, you can put %@AB@%_asm%@AE@% in front of each assembly instruction:  %@NL@%
  14380. %@NL@%
  14381. %@AS@%  _asm mov ah, 2
  14382. %@AS@%  _asm mov dl, 7
  14383. %@AS@%  _asm int 21h%@AE@%%@NL@%
  14384. %@NL@%
  14385. Since the %@AB@%_asm%@AE@% keyword is a statement separator, you can also put assembly
  14386. instructions on the same line:  %@NL@%
  14387. %@NL@%
  14388. %@AS@%  _asm mov ah, 2   _asm mov dl, 7   _asm int 21h%@AE@%%@NL@%
  14389. %@NL@%
  14390. %@AU@%  Braces can prevent ambiguity and needless repetition.%@AE@%  %@NL@%
  14391. %@NL@%
  14392. All three examples generate the same code, but the first style─enclosing the
  14393. %@AB@%_asm%@AE@% block in braces─has some advantages. The braces clearly separate
  14394. assembly code from C code and avoid needless repetition of the %@AB@%_asm%@AE@% keyword.
  14395. Braces can also prevent ambiguities. If you want to put a C statement on the
  14396. same line as an %@AB@%_asm%@AE@% block, you must enclose the block in braces. Without
  14397. the braces, the compiler cannot tell where assembly code stops and C
  14398. statements begin. Finally, since the text in braces has the same format as
  14399. ordinary MASM text, you can easily cut and paste text from existing MASM
  14400. source files.  %@NL@%
  14401. %@NL@%
  14402. The braces enclosing an %@AB@%_asm%@AE@% block don't affect variable visibility, as do
  14403. braces in C. You can also nest %@AB@%_asm%@AE@% blocks, but the nesting doesn't affect
  14404. variable visibility.  %@NL@%
  14405. %@NL@%
  14406. %@NL@%
  14407. %@2@%%@CR:C6A00160004 @%%@AB@%Using Assembly Language in _asm Blocks%@AE@%%@EH@%%@NL@%
  14408. %@NL@%
  14409. The in-line assembler has much in common with other assemblers. For example,
  14410. it accepts any expression that is legal in MASM, and it supports almost all
  14411. 80286 and 80287 instructions. This section describes the use of
  14412. assembly-language features in %@AB@%_asm%@AE@% blocks.  %@NL@%
  14413. %@NL@%
  14414. %@NL@%
  14415. %@3@%%@CR:C6A00160005 @%%@AB@%Instruction Set%@AE@%%@EH@%%@NL@%
  14416. %@NL@%
  14417. The in-line assembler supports the full instruction set of the Intel(R)
  14418. 80286 and 80287 processors, except for privileged instructions that control
  14419. the processor's protected mode (protected mode is available in the OS/2 and
  14420. XENIX(R) operating systems, but not in DOS). It does not recognize 80386-
  14421. and 80387-specific instructions. To use assembly instructions specific to
  14422. the 80286 and 80287 processors, you must compile your QuickC program with
  14423. the /G2 switch included in the command line. For a description of the
  14424. compiler /G command-line switch, refer to Chapter 4, "QCL Command
  14425. Reference," in the %@AI@%Microsoft QuickC Tool Kit%@AE@%.  %@NL@%
  14426. %@NL@%
  14427. %@NL@%
  14428. %@3@%%@CR:C6A00160006 @%%@AB@%Expressions%@AE@%%@EH@%%@NL@%
  14429. %@NL@%
  14430. In-line assembly code can use any MASM expression, that is, any combination
  14431. of operands and operators that evaluates to a single value or address.  %@NL@%
  14432. %@NL@%
  14433. %@NL@%
  14434. %@3@%%@CR:C6A00160007 @%%@AB@%Data Directives and Operators%@AE@%%@EH@%%@NL@%
  14435. %@NL@%
  14436. Although an %@AB@%_asm%@AE@% block can reference C data types and objects, it cannot
  14437. define data objects with MASM directives or operators. Specifically, you
  14438. cannot use the definition directives %@AB@%DB%@AE@%, %@AB@%DW%@AE@%, %@AB@%DD%@AE@%, %@AB@%DQ%@AE@%, %@AB@%DT%@AE@%, and %@AB@%DF%@AE@%, or the
  14439. operators %@AB@%DUP%@AE@% or %@AB@%THIS%@AE@%. Nor are MASM structures and records available. The
  14440. in-line assembler doesn't accept the directives %@AB@%STRUC%@AE@%, %@AB@%RECORD%@AE@%, %@AB@%WIDTH%@AE@%, or
  14441. %@AB@%MASK%@AE@%.  %@NL@%
  14442. %@NL@%
  14443. %@NL@%
  14444. %@3@%%@CR:C6A00160008 @%%@AB@%EVEN and ALIGN Directives%@AE@%%@EH@%%@NL@%
  14445. %@NL@%
  14446. While the in-line assembler doesn't support most MASM directives, it does
  14447. support %@AB@%EVEN%@AE@% and %@AB@%ALIGN%@AE@%. These directives put %@AB@%NOP%@AE@% (no operation) instructions
  14448. in the assembly code as needed to align labels to specific boundaries. This
  14449. makes instruction-fetch operations more efficient for some processors (not
  14450. including eight-bit processors such as the Intel 8088).  %@NL@%
  14451. %@NL@%
  14452. %@NL@%
  14453. %@3@%%@CR:C6A00160009 @%%@AB@%Macros%@AE@%%@EH@%%@NL@%
  14454. %@NL@%
  14455. The in-line assembler is not a macro assembler. You cannot use MASM macro
  14456. directives (%@AB@%MACRO%@AE@%, %@AB@%REPT%@AE@%, %@AB@%IRC%@AE@%, %@AB@%IRP%@AE@%, and %@AB@%ENDM%@AE@%) or macro operators ( %@AB@%<>%@AE@%, %@AB@%!%@AE@%, %@AB@%&%@AE@%,
  14457. %@AB@%%%@AE@%, and %@AB@%.TYPE%@AE@%). An %@AB@%_asm%@AE@% block can use C preprocessor directives, however. See
  14458. the section "Using C in %@AB@%_asm%@AE@% Blocks" for more information.  %@NL@%
  14459. %@NL@%
  14460. %@NL@%
  14461. %@3@%%@CR:C6A00160010 @%%@AB@%Segment References%@AE@%%@EH@%%@NL@%
  14462. %@NL@%
  14463. You must refer to segments by register rather than by name (the segment name
  14464. %@AB@%_TEXT%@AE@% is invalid, for instance). Segment overrides must use the register
  14465. explicitly, as in ES:[BX].  %@NL@%
  14466. %@NL@%
  14467. %@NL@%
  14468. %@3@%%@CR:C6A00160011 @%%@AB@%Type and Variable Sizes%@AE@%%@EH@%%@NL@%
  14469. %@NL@%
  14470. The %@AB@%LENGTH%@AE@%, %@AB@%SIZE%@AE@%, and %@AB@%TYPE%@AE@% operators have a limited meaning in in-line
  14471. assembly. They cannot be used at all with the %@AB@%DUP%@AE@% operator (because you
  14472. cannot define data with MASM directives or operators). But you can use them
  14473. to find the size of C variables or types:  %@NL@%
  14474. %@NL@%
  14475. %@NL@%
  14476.   ■   The %@AB@%LENGTH%@AE@% operator can return the number of elements in an array. It
  14477.       returns the value 1 for nonarray variables.%@NL@%
  14478. %@NL@%
  14479.   ■   The %@AB@%SIZE%@AE@% operator can return the size of a C variable. A variable's
  14480.       size is the product of its %@AB@%LENGTH%@AE@% and %@AB@%TYPE%@AE@%.%@NL@%
  14481. %@NL@%
  14482.   ■   The %@AB@%TYPE%@AE@% operator can return the size of a C type or variable. If the
  14483.       variable is an array, %@AB@%TYPE%@AE@% returns the size of a single element of the
  14484.       array.%@NL@%
  14485. %@NL@%
  14486. %@NL@%
  14487. For instance, if your program has an eight-element %@AB@%int%@AE@% array,  %@NL@%
  14488. %@NL@%
  14489. %@AS@%  int arr[8];%@AE@%%@NL@%
  14490. %@NL@%
  14491. the following C and assembly expressions yield the size of %@AS@% arr %@AE@% and its
  14492. elements:  %@NL@%
  14493. %@NL@%
  14494. %@TH:   6   465 02 12 28 36 @%
  14495. _asm        C                           Size
  14496. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14497. %@AS@%LENGTH arr%@AE@%  %@AS@%sizeof(arr)/sizeof(arr[0])%@AE@%  8
  14498. %@AS@%SIZE arr%@AE@%    %@AS@%sizeof(arr)%@AE@%                 16
  14499. %@AS@%TYPE arr%@AE@%    %@AS@%sizeof(arr[0])%@AE@%              2
  14500. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  14501. %@TE:   6   465 02 12 28 36 @%
  14502.  
  14503. %@NL@%
  14504. %@4@%%@AB@%Comments%@AE@%%@EH@%%@NL@%
  14505. %@NL@%
  14506. Instructions in an %@AB@%_asm%@AE@% block can use assembly-language comments:  %@NL@%
  14507. %@NL@%
  14508. %@AS@%  _asm mov ax, offset buff ; Load address of buff%@AE@%%@NL@%
  14509. %@NL@%
  14510. Because C macros expand into a single logical line, avoid using
  14511. assemblylanguage comments in macros (see the section "Defining %@AB@%_asm%@AE@% Blocks
  14512. as C Macros," below). An %@AB@%_asm%@AE@% block can also contain C-style comments, as
  14513. noted below.  %@NL@%
  14514. %@NL@%
  14515. %@NL@%
  14516. %@4@%%@AB@%Debugging with the CodeView(R) Debugger%@AE@%%@EH@%%@NL@%
  14517. %@NL@%
  14518. %@AU@% In-line assembly code can be debugged with CodeView.%@AE@%  %@NL@%
  14519. %@NL@%
  14520. Programs containing in-line assembly code can be debugged with the CodeView
  14521. debugger, assuming you compile with the /Zi option.  %@NL@%
  14522. %@NL@%
  14523. Note that putting multiple assembly instructions or C statements on one line
  14524. can hamper debugging with CodeView. In source mode, the CodeView debugger
  14525. lets you set breakpoints on a single line but not on individual statements
  14526. on the same line. The same principle applies to an %@AB@%_asm%@AE@% block defined as a C
  14527. macro, which expands to a single logical line.  %@NL@%
  14528. %@NL@%
  14529. %@NL@%
  14530. %@2@%%@CR:C6A00160012 @%%@AB@%Using C in _asm Blocks%@AE@%%@EH@%%@NL@%
  14531. %@NL@%
  14532. Because in-line assembly instructions can be mixed with C statements, they
  14533. can refer to C variables by name and use many other elements of C. An %@AB@%_asm%@AE@%
  14534. block can use the following C language elements:  %@NL@%
  14535. %@NL@%
  14536. %@NL@%
  14537.   ■   Symbols, including labels and variable and function names%@NL@%
  14538. %@NL@%
  14539.   ■   Constants, including symbolic constants and %@AB@%enum%@AE@% members%@NL@%
  14540. %@NL@%
  14541.   ■   Macros and preprocessor directives%@NL@%
  14542. %@NL@%
  14543.   ■   Comments (%@AS@% /* */ %@AE@%)%@NL@%
  14544. %@NL@%
  14545.   ■   Type names (wherever a MASM type would be legal)%@NL@%
  14546. %@NL@%
  14547.   ■   %@AB@%typedef%@AE@% names, generally used with operators such as %@AB@%PTR%@AE@% and %@AB@%TYPE%@AE@% or
  14548.       to specify structure or union members%@NL@%
  14549. %@NL@%
  14550. %@NL@%
  14551. Within an %@AB@%_asm%@AE@% block, you can specify integer constants with either C
  14552. notation or assembler radix notation (0x100 and 100h are equivalent, for
  14553. instance). This allows you to define (using %@AB@%#define%@AE@%) a constant in C, and
  14554. use it in both C and assembly portions of the program. You can also specify
  14555. constants in octal by preceding them with a 0. For example, 0777 specifies
  14556. an octal constant.  %@NL@%
  14557. %@NL@%
  14558. %@NL@%
  14559. %@3@%%@CR:C6A00160013 @%%@AB@%Using Operators%@AE@%%@EH@%%@NL@%
  14560. %@NL@%
  14561. An %@AB@%_asm%@AE@% block cannot use C-specific operators, such as the %@AB@%%@AE@% operator.
  14562. However, operators shared by QuickC and MASM, such as the %@AB@%*%@AE@% operator, are
  14563. interpreted as assembly-language operators. For instance, outside an %@AB@%_asm%@AE@%
  14564. block, square brackets (%@AB@% [] %@AE@%) are interpreted as enclosing array subscripts,
  14565. which C automatically scales to the size of an element in the array. Inside
  14566. an %@AB@%_asm%@AE@% block, they are seen as the MASM index operator, which yields an
  14567. unscaled byte offset from any data object or label (not just an array). The
  14568. following code illustrates the difference:  %@NL@%
  14569. %@NL@%
  14570. %@AS@%  int array[10];
  14571. %@AS@%  
  14572. %@AS@%  _asm mov array[6], bx ;  Store BX at array+6 (not scaled)
  14573. %@AS@%  
  14574. %@AS@%  array[6] = 0;         /* Store 0 at array+12 (scaled) */%@AE@%%@NL@%
  14575. %@NL@%
  14576. The first reference to %@AS@% array %@AE@% is not scaled, but the second is. Note that
  14577. you can use the %@AB@%TYPE%@AE@% operator to achieve scaling based on a constant. For
  14578. instance, the following statements are equivalent:  %@NL@%
  14579. %@NL@%
  14580. %@AS@%  _asm mov array[6 * TYPE int], 0 ; Store 0 at array + 12
  14581. %@AS@%  
  14582. %@AS@%  array[6] = 0;                   /* Store 0 at array + 12 */%@AE@%%@NL@%
  14583. %@NL@%
  14584. %@NL@%
  14585. %@3@%%@CR:C6A00160014 @%%@AB@%Using C Symbols%@AE@%%@EH@%%@NL@%
  14586. %@NL@%
  14587. An %@AB@%_asm%@AE@% block can refer to any C symbol that is visible (in scope) where the
  14588. block appears. (C symbols are variable names, function names, and labels─in
  14589. other words, names that aren't symbolic constants or %@AB@%enum%@AE@% members.)  %@NL@%
  14590. %@NL@%
  14591. A few restrictions apply to the use of C symbols:  %@NL@%
  14592. %@NL@%
  14593. %@NL@%
  14594.   ■   Each assembly-language statement can contain only one C symbol.
  14595.       Multiple symbols can appear in the same assembly instruction only with
  14596.       %@AB@%OFFSET%@AE@%,%@AB@% LENGTH%@AE@%,%@AB@% TYPE%@AE@%, and %@AB@%SIZE%@AE@% expressions.%@NL@%
  14597. %@NL@%
  14598.   ■   Functions referenced in an %@AB@%_asm%@AE@% block must be declared (prototyped)
  14599.       earlier in the program. Otherwise, the compiler cannot distinguish
  14600.       between function names and labels in the %@AB@%_asm%@AE@% block.%@NL@%
  14601. %@NL@%
  14602.   ■   An %@AB@%_asm%@AE@% block cannot use any C symbols with the same spelling as MASM
  14603.       reserved words (regardless of case). MASM reserved words include
  14604.       instruction names such as %@AB@%PUSH%@AE@% and register names such as SI.%@NL@%
  14605. %@NL@%
  14606.   ■   Structure and union tags are not recognized in %@AB@%_asm%@AE@% blocks.%@NL@%
  14607. %@NL@%
  14608. %@NL@%
  14609. %@NL@%
  14610. %@3@%%@CR:C6A00160015 @%%@AB@%Accessing C Data%@AE@%%@EH@%%@NL@%
  14611. %@NL@%
  14612. A great convenience of in-line assembly is the ability to refer to C
  14613. variables by name. An %@AB@%_asm%@AE@% block can refer to any symbols─including variable
  14614. names─that are visible where the block appears. For instance, if the C
  14615. variable %@AS@% var %@AE@% is visible, the instruction  %@NL@%
  14616. %@NL@%
  14617. %@AS@%  _asm mov ax, var%@AE@%%@NL@%
  14618. %@NL@%
  14619. stores the value of %@AS@% var %@AE@% in AX.  %@NL@%
  14620. %@NL@%
  14621. If a structure or union member has a unique name, an %@AB@%_asm%@AE@% block can refer to
  14622. it using only the member name, without specifying the C variable or %@AB@%typedef%@AE@%
  14623. name before the period (%@AB@%.%@AE@%) operator. If the member name is not unique,
  14624. however, you must place a variable or %@AB@%typedef%@AE@% name immediately before the
  14625. period (%@AB@%.%@AE@%) operator. For instance, the following structure types share %@AS@%
  14626. %@AS@%same_name %@AE@% as their member name:  %@NL@%
  14627. %@NL@%
  14628. %@AS@%  struct first_type
  14629. %@AS@%  {
  14630. %@AS@%     char *weasel;
  14631. %@AS@%     int same_name;
  14632. %@AS@%  };
  14633. %@AS@%  
  14634. %@AS@%  struct second_type
  14635. %@AS@%  {
  14636. %@AS@%     int wonton;
  14637. %@AS@%     long same_name;
  14638. %@AS@%  };%@AE@%%@NL@%
  14639. %@NL@%
  14640. If you declare variables with the types  %@NL@%
  14641. %@NL@%
  14642. %@AS@%  struct first_type hal;
  14643. %@AS@%  struct second_type oat;%@AE@%%@NL@%
  14644. %@NL@%
  14645. all references to the member %@AS@% same_name %@AE@% must use the variable name, because
  14646. %@AS@%same_name %@AE@% is not unique. But the member %@AS@% weasel %@AE@% has a unique name, so you
  14647. can refer to it using only its member name:  %@NL@%
  14648. %@NL@%
  14649. %@AS@%  _asm
  14650. %@AS@%  {
  14651. %@AS@%     mov bx, OFFSET hal
  14652. %@AS@%     mov cx, [bx]hal.same_name ; Must use 'hal'
  14653. %@AS@%     mov si, [bx].weasel       ; Can omit 'hal'
  14654. %@AS@%  }%@AE@%%@NL@%
  14655. %@NL@%
  14656. Note that omitting the variable name is merely a coding convenience. The
  14657. same assembly instructions are generated whether or not it is present.  %@NL@%
  14658. %@NL@%
  14659. %@NL@%
  14660. %@3@%%@CR:C6A00160016 @%%@AB@%Writing Functions%@AE@%%@EH@%%@NL@%
  14661. %@NL@%
  14662. If you write a function with in-line assembly code, it's a simple matter to
  14663. pass arguments to the function and return a value from it. The following
  14664. examples compare a function first written for a separate assembler and then
  14665. rewritten for the in-line assembler. The function, called %@AS@% power2%@AE@%, receives
  14666. two parameters, multiplying the first parameter by 2 to the power of the
  14667. second parameter. Written for a separate assembler, the function might look
  14668. like this:  %@NL@%
  14669. %@NL@%
  14670. %@AS@%  ; POWER.ASM
  14671. %@AS@%  ; Compute the power of an integer
  14672. %@AS@%  ;
  14673. %@AS@%         PUBLIC _power2
  14674. %@AS@%  _TEXT SEGMENT WORD PUBLIC 'CODE'
  14675. %@AS@%  _power2 PROC
  14676. %@AS@%  
  14677. %@AS@%          push bp         ; Save BP
  14678. %@AS@%          mov bp, sp      ; Move SP into BP so we can refer
  14679. %@AS@%                          ;   to arguments on the stack
  14680. %@AS@%          mov ax, [bp+4]  ; Get first argument
  14681. %@AS@%          mov cx, [bp+6]  ; Get second argument
  14682. %@AS@%          shl ax, cl      ; AX = AX * ( 2 ^ CL )
  14683. %@AS@%          pop bp          ; Restore BP
  14684. %@AS@%          ret             ; Return with sum in AX
  14685. %@AS@%  
  14686. %@AS@%  _power2 ENDP
  14687. %@AS@%  _TEXT   ENDS
  14688. %@AS@%          END%@AE@%%@NL@%
  14689. %@NL@%
  14690. %@AU@% Function arguments are usually passed on the stack.%@AE@%  %@NL@%
  14691. %@NL@%
  14692. Since it's written for a separate assembler, the function requires a
  14693. separate source file and assembly and link steps. C function arguments
  14694. usually are passed on the stack, so this version of the %@AS@% power2 %@AE@% function
  14695. accesses its arguments by their positions on the stack. (Note that the %@AB@%MODEL%@AE@%
  14696. directive, available in MASM and some other assemblers, also allows you to
  14697. access stack arguments and local stack variables by name.)  %@NL@%
  14698. %@NL@%
  14699. The POWER2.C program below writes the %@AS@% power2 %@AE@% function with in-line
  14700. assembly code:  %@NL@%
  14701. %@NL@%
  14702. %@AS@%  /* POWER2.C */
  14703. %@AS@%  #include <stdio.h>
  14704. %@AS@%  
  14705. %@AS@%  int power2( int num, int power );
  14706. %@AS@%  
  14707. %@AS@%  void main( void )
  14708. %@AS@%  {
  14709. %@AS@%     printf( "3 times 2 to the power of 5 is %d\n", \
  14710. %@AS@%             power2( 3, 5) );
  14711. %@AS@%  }
  14712. %@AS@%  
  14713. %@AS@%  int power2( int num, int power )
  14714. %@AS@%  {
  14715. %@AS@%     _asm
  14716. %@AS@%     {
  14717. %@AS@%        mov ax, num    ; Get first argument
  14718. %@AS@%        mov cx, power  ; Get second argument
  14719. %@AS@%        shl ax, cl     ; AX = AX * ( 2 to the power of CL )
  14720. %@AS@%     }
  14721. %@AS@%     /* Return with result in AX */
  14722. %@AS@%  }%@AE@%%@NL@%
  14723. %@NL@%
  14724. The in-line version of the %@AS@% power2 %@AE@% function refers to its arguments by name
  14725. and appears in the same source file as the rest of the program. This version
  14726. also requires fewer assembly instructions. Since C automatically preserves
  14727. BP, the %@AB@%_asm%@AE@% block doesn't need to do so. It can also dispense with the %@AB@%RET%@AE@%
  14728. instruction, since the C part of the function performs the return.  %@NL@%
  14729. %@NL@%
  14730. Because the in-line version of %@AS@% power2 %@AE@% doesn't execute a C %@AB@%return%@AE@%
  14731. statement, it causes a harmless warning if you compile at warning levels 2
  14732. or higher:  %@NL@%
  14733. %@NL@%
  14734. %@AS@%  warning C4035: 'power2' : no return value%@AE@%%@NL@%
  14735. %@NL@%
  14736. The function does return a value, but QuickC cannot tell that in the absence
  14737. of a %@AB@%return%@AE@% statement. Simply ignore the warning in this context.  %@NL@%
  14738. %@NL@%
  14739. %@NL@%
  14740. %@2@%%@CR:C6A00160017 @%%@AB@%Using and Preserving Registers%@AE@%%@EH@%%@NL@%
  14741. %@NL@%
  14742. In general, you should not assume that a register will have a given value
  14743. when an %@AB@%_asm%@AE@% block begins. An %@AB@%_asm%@AE@% block inherits whatever register values
  14744. happen to result from the normal flow of control.  %@NL@%
  14745. %@NL@%
  14746. As you may have noticed in the POWER2.C example in the previous section, the
  14747. %@AS@%power2 %@AE@% function doesn't preserve the value in the AX register. When you
  14748. write a function in assembly language, you don't need to preserve the AX,
  14749. BX, CX, DX, ES, and flags registers. However, you should preserve any other
  14750. registers you use (DI, SI, DS, SS, SP, and BP).  %@NL@%
  14751. %@NL@%
  14752. ────────────────────────────────────────────────────────────────────────────%@NL@%
  14753. %@AU@%WARNING%@AE@%%@NL@%
  14754. %@NL@%
  14755. If your in-line assembly code changes the direction flag using the STD or
  14756. CLD instructions, you must restore the flag to its original value.%@NL@%
  14757. ────────────────────────────────────────────────────────────────────────────%@NL@%
  14758. %@NL@%
  14759. The POWER2.C example in the previous section also shows that functions
  14760. return values in registers. This is true whether the function is written in
  14761. assembly language or in C.  %@NL@%
  14762. %@NL@%
  14763. %@AU@% Functions return values in the AX and DX registers.%@AE@%  %@NL@%
  14764. %@NL@%
  14765. If the return value is short (a %@AB@%char%@AE@%, %@AB@%int%@AE@%, or %@AB@%near%@AE@% pointer), it is stored in
  14766. AX. The POWER2.C example returned a value by terminating with the desired
  14767. value in AX.  %@NL@%
  14768. %@NL@%
  14769. If the return value is long, store the high word in DX and the low word in
  14770. AX. To return a longer value (such as a floating-point value), store the
  14771. value in memory and return a pointer to the value (in AX if %@AB@%near%@AE@% or in DX:AX
  14772. if %@AB@%far%@AE@%).  %@NL@%
  14773. %@NL@%
  14774. Assembly instructions that appear in-line with C statements are free to
  14775. alter the AX, BX, CX, and DX registers. C doesn't expect these registers to
  14776. be maintained between statements, so you don't need to preserve them. The
  14777. same is true of the SI and DI registers, with some exceptions (see the
  14778. section "Optimizing," below). You should preserve the SP and BP registers
  14779. unless you have some reason to change them─to switch stacks, for instance.  %@NL@%
  14780. %@NL@%
  14781. %@NL@%
  14782. %@2@%%@CR:C6A00160018 @%%@AB@%Jumping to Labels%@AE@%%@EH@%%@NL@%
  14783. %@NL@%
  14784. Like an ordinary C label, a label in an %@AB@%_asm%@AE@% block is visible (has scope)
  14785. throughout the function in which it is defined (not only in the block). Both
  14786. assembly instructions and C %@AB@%goto%@AE@% statements can jump to labels inside or
  14787. outside the %@AB@%_asm%@AE@% block.  %@NL@%
  14788. %@NL@%
  14789. %@AU@% Labels in _asm blocks have function scope and are not case sensitive.%@AE@%  %@NL@%
  14790. %@NL@%
  14791. Unlike C labels, labels defined in %@AB@%_asm%@AE@% blocks are not case sensitive, even
  14792. when used in C statements. C labels are not case sensitive in an %@AB@%_asm%@AE@% block,
  14793. either. (Outside an %@AB@%_asm%@AE@% block, a C label is case sensitive as usual.) The
  14794. following do-nothing code shows all the permutations.  %@NL@%
  14795. %@NL@%
  14796. %@AS@%  void func( void )
  14797. %@AS@%  {
  14798. %@AS@%     goto C_Dest;  /* legal */
  14799. %@AS@%     goto c_dest;  /* error */
  14800. %@AS@%  
  14801. %@AS@%     goto A_Dest;  /* legal */
  14802. %@AS@%     goto a_dest;  /* legal */
  14803. %@AS@%  
  14804. %@AS@%     _asm
  14805. %@AS@%     {
  14806. %@AS@%        jmp C_Dest ; legal
  14807. %@AS@%        jmp c_dest ; legal
  14808. %@AS@%  
  14809. %@AS@%        jmp A_Dest ; legal
  14810. %@AS@%        jmp a_dest ; legal
  14811. %@AS@%  
  14812. %@AS@%        a_dest:    ; _asm label
  14813. %@AS@%     }
  14814. %@AS@%  
  14815. %@AS@%     C_Dest:       /* C label */ 
  14816. %@AS@%     return;
  14817. %@AS@%  }%@AE@%%@NL@%
  14818. %@NL@%
  14819. Don't use C library function names as labels in %@AB@%_asm%@AE@% blocks. For instance,
  14820. you might be tempted to use %@AS@% exit %@AE@% as a label,  %@NL@%
  14821. %@NL@%
  14822. %@AS@%  jne exit
  14823. %@AS@%     .
  14824. %@AS@%     .
  14825. %@AS@%     .
  14826. %@AS@%  exit:
  14827. %@AS@%     ; More _asm code follows%@AE@%%@NL@%
  14828. %@NL@%
  14829. forgetting that %@AB@%exit%@AE@% is the name of a C library function. The code doesn't
  14830. cause a compiler error, but it might cause a jump to the %@AB@%exit%@AE@% function
  14831. instead of the desired location.  %@NL@%
  14832. %@NL@%
  14833. As in MASM programs, the dollar symbol (%@AB@%$%@AE@%) serves as the current location
  14834. counter─a label for the instruction currently being assembled. In %@AB@%_asm%@AE@%
  14835. blocks, its main use is to make long conditional jumps:  %@NL@%
  14836. %@NL@%
  14837. %@AS@%  jne $+5 ; next instruction is 5 bytes long
  14838. %@AS@%  jmp farlabel
  14839. %@AS@%  ; $+5
  14840. %@AS@%     .
  14841. %@AS@%     .
  14842. %@AS@%     .
  14843. %@AS@%  farlabel:%@AE@%%@NL@%
  14844. %@NL@%
  14845. %@NL@%
  14846. %@2@%%@CR:C6A00160019 @%%@AB@%Calling C Functions%@AE@%%@EH@%%@NL@%
  14847. %@NL@%
  14848. An %@AB@%_asm%@AE@% block can call C functions, including C library routines. The
  14849. following example calls the %@AB@%printf%@AE@% library routine:  %@NL@%
  14850. %@NL@%
  14851. %@AS@%  #include <stdio.h>
  14852. %@AS@%  
  14853. %@AS@%  char format[] = "%s %s\n";
  14854. %@AS@%  char hello[] = "Hello";
  14855. %@AS@%  char world[] = "world";
  14856. %@AS@%  
  14857. %@AS@%  void main( void )
  14858. %@AS@%  {
  14859. %@AS@%     _asm
  14860. %@AS@%     {
  14861. %@AS@%        mov  ax, offset world
  14862. %@AS@%        push ax
  14863. %@AS@%        mov  ax, offset hello
  14864. %@AS@%        push ax
  14865. %@AS@%        mov  ax, offset format
  14866. %@AS@%        push ax
  14867. %@AS@%        call printf
  14868. %@AS@%       add sp, 6
  14869. %@AS@%     }
  14870. %@AS@%  }%@AE@%%@NL@%
  14871. %@NL@%
  14872. Since function arguments are passed on the stack, you simply push the needed
  14873. arguments─string pointers, in the example above─before calling the function.
  14874. The arguments are pushed in reverse order, so they come off the stack in the
  14875. desired order. To emulate the C statement  %@NL@%
  14876. %@NL@%
  14877. %@AS@%  printf( format, hello, world );%@AE@%%@NL@%
  14878. %@NL@%
  14879. the example pushes pointers to %@AS@% world%@AE@%, %@AS@% hello%@AE@%, and %@AS@% format%@AE@%, in that order,
  14880. then calls %@AB@%printf%@AE@%. The last instruction in the %@AB@%_asm%@AE@% block adjusts the stack
  14881. to account for the arguments previously pushed onto it.  %@NL@%
  14882. %@NL@%
  14883. %@NL@%
  14884. %@2@%%@CR:C6A00160020 @%%@AB@%Defining _asm Blocks as C Macros%@AE@%%@EH@%%@NL@%
  14885. %@NL@%
  14886. C macros offer a convenient way to insert assembly code into C code, but
  14887. they demand extra care because a macro expands into a single logical line.
  14888. To create trouble-free macros, follow these rules:  %@NL@%
  14889. %@NL@%
  14890. %@NL@%
  14891.   ■   Enclose the %@AB@%_asm%@AE@% block in braces%@NL@%
  14892. %@NL@%
  14893.   ■   Put the %@AB@%_asm%@AE@% keyword in front of each assembly instruction%@NL@%
  14894. %@NL@%
  14895.   ■   Use old-style C comments (%@AS@% /* comment */ %@AE@%) instead of assembly-style
  14896.       comments (%@AS@% ; comment %@AE@%)%@NL@%
  14897. %@NL@%
  14898. %@NL@%
  14899. To illustrate, the following example defines a simple macro:  %@NL@%
  14900. %@NL@%
  14901. %@AS@%  #define BEEP _asm \
  14902. %@AS@%  /* Beep sound */       \
  14903. %@AS@%  {                       \
  14904. %@AS@%     _asm mov ah, 2       \
  14905. %@AS@%     _asm mov dl, 7       \
  14906. %@AS@%     _asm int 21h         \
  14907. %@AS@%  }%@AE@%%@NL@%
  14908. %@NL@%
  14909. At first glance, the last three %@AB@%_asm%@AE@% keywords seem superfluous. They are
  14910. needed, however, because the macro expands into a single line:  %@NL@%
  14911. %@NL@%
  14912. %@AS@%  _asm /* Beep sound */ { _asm mov ah, 2  _asm mov dl, 7 _asm int 21h }%@AE@%%@NL@%
  14913. %@NL@%
  14914. The third and fourth %@AB@%_asm%@AE@% keywords are needed as statement separators. The
  14915. only statement separators recognized in %@AB@%_asm%@AE@% blocks are the newline
  14916. character and %@AB@%_asm%@AE@% keyword. And since a block defined as a macro is one
  14917. logical line, you must separate each instruction with %@AB@%_asm%@AE@%.  %@NL@%
  14918. %@NL@%
  14919. The braces are essential as well. If you omit them, the compiler can be
  14920. confused by C statements on the same line to the right of the macro
  14921. invocation. Without the closing brace, QuickC cannot tell where assembly
  14922. code stops, and it sees C statements after the %@AB@%_asm%@AE@% block as assembly
  14923. instructions.  %@NL@%
  14924. %@NL@%
  14925. %@AU@%  Use C comments in _asm blocks written as macros.%@AE@%  %@NL@%
  14926. %@NL@%
  14927. Assembly-style comments that start with a semicolon (;) continue to the end
  14928. of the line. This causes problems in macros because QuickC ignores
  14929. everything after the comment, all the way to the end of the logical line. To
  14930. prevent errors, use C comments (%@AS@% /* comment */ %@AE@%) in %@AB@%_asm%@AE@% blocks defined as
  14931. macros.  %@NL@%
  14932. %@NL@%
  14933. An %@AB@%_asm%@AE@% block written as a C macro can take arguments. Unlike an ordinary C
  14934. macro, however, an %@AB@%_asm%@AE@% macro cannot return a value. So you cannot use such
  14935. macros in C expressions.  %@NL@%
  14936. %@NL@%
  14937. %@AU@% You can convert MASM macros to C macros.%@AE@%  %@NL@%
  14938. %@NL@%
  14939. Note that some MASM-style macros can be written as C macros. Below is a MASM
  14940. macro that sets the video page to the value specified in the %@AS@% page %@AE@%
  14941. argument:  %@NL@%
  14942. %@NL@%
  14943. %@AS@%  setpage   MACRO page
  14944. %@AS@%            mov ah, 5
  14945. %@AS@%            mov al, page
  14946. %@AS@%            int 10h
  14947. %@AS@%            ENDM%@AE@%%@NL@%
  14948. %@NL@%
  14949. The following code defines %@AS@% setpage %@AE@% as a C macro:  %@NL@%
  14950. %@NL@%
  14951. %@AS@%  #define setpage( page ) _asm  \
  14952. %@AS@%     {                                \
  14953. %@AS@%        _asm mov ah, 5                \
  14954. %@AS@%        _asm mov al, page             \
  14955. %@AS@%        _asm int 10h                  \
  14956. %@AS@%  }%@AE@%%@NL@%
  14957. %@NL@%
  14958. Both macros do the same job.  %@NL@%
  14959. %@NL@%
  14960. %@NL@%
  14961. %@2@%%@CR:C6A00160021 @%%@AB@%Optimizing%@AE@%%@EH@%%@NL@%
  14962. %@NL@%
  14963. The presence of an %@AB@%_asm%@AE@% block in a function affects optimization in a few
  14964. different ways. First, as you might expect, QuickC doesn't try to optimize
  14965. the %@AB@%_asm%@AE@% block itself. What you write in assembly language is exactly what
  14966. you get.  %@NL@%
  14967. %@NL@%
  14968. Second, the presence of an %@AB@%_asm%@AE@% block affects register variable storage.
  14969. (See the section "Register Variables" in Chapter 5, "Advanced Data Types,"
  14970. for a discussion of register variables.) Under normal circumstances, QuickC
  14971. automatically stores variables in registers. This is not done, however, in
  14972. any function that contains an %@AB@%_asm%@AE@% block. To get register variable storage
  14973. in such a function, you must request it with the %@AB@%register%@AE@% keyword.  %@NL@%
  14974. %@NL@%
  14975. Since the compiler stores register variables in the SI and DI registers,
  14976. these registers represent variables in functions that request register
  14977. storage. The first eligible variable is stored in SI and the second in DI.
  14978. Preserve SI and DI in such functions unless you want to change the register
  14979. variables.  %@NL@%
  14980. %@NL@%
  14981. Keep in mind that the name of a variable declared with %@AB@%register%@AE@% translates
  14982. directly into a register reference (assuming a register is available for
  14983. such use). For instance, if you declare  %@NL@%
  14984. %@NL@%
  14985. %@AS@%  register int sample;%@AE@%%@NL@%
  14986. %@NL@%
  14987. and the variable %@AS@% sample %@AE@% happens to be stored in SI, then the %@AB@%_asm%@AE@%
  14988. instruction  %@NL@%
  14989. %@NL@%
  14990. %@AS@%  _asm mov ax, sample%@AE@%%@NL@%
  14991. %@NL@%
  14992. is equivalent to  %@NL@%
  14993. %@NL@%
  14994. %@AS@%  _asm mov ax, si%@AE@%%@NL@%
  14995. %@NL@%
  14996. If you declare a variable with %@AB@%register%@AE@% and the compiler cannot store the
  14997. variable in a register, QuickC issues a compiler error if you reference the
  14998. variable in an %@AB@%_asm%@AE@% block. The solution is to remove the %@AB@%register%@AE@%
  14999. declaration from that variable.  %@NL@%
  15000. %@NL@%
  15001. Register variables form a slight exception to the general rule that an
  15002. assembly-language statement can contain no more than one C symbol. If one of
  15003. the symbols is a register variable, for example,  %@NL@%
  15004. %@NL@%
  15005. %@AS@%  register int v1;
  15006. %@AS@%  int v2;%@AE@%%@NL@%
  15007. %@NL@%
  15008. then an instruction can use two C symbols, as in  %@NL@%
  15009. %@NL@%
  15010. %@AS@%  mov v1, v2%@AE@%%@NL@%
  15011. %@NL@%
  15012. Finally, the presence of in-line assembly code inhibits loop optimization
  15013. for the entire function in which the code appears. (Loop optimization can be
  15014. selected with the /Ol command-line switch; see Chapter 4, "QCL Command
  15015. Reference," in %@AI@%Microsoft QuickC Tool Kit%@AE@%.) This optimization is suppressed
  15016. no matter which compiler options you use.  %@NL@%
  15017. %@NL@%
  15018. %@NL@%
  15019. %@2@%%@CR:C6A00160022 @%%@AB@%References and Books on Assembly Language%@AE@%%@EH@%%@NL@%
  15020. %@NL@%
  15021. Assembly language varies widely for different computer processors. In
  15022. selecting a reference on assembly language, make sure it describes assembly
  15023. for the Intel 8086 family of processors or compatibles. These are the
  15024. microprocessors used in the IBM and IBM-compatible computers able to run
  15025. QuickC.  %@NL@%
  15026. %@NL@%
  15027. The following books and articles may be useful in learning to program in
  15028. assembly language:  %@NL@%
  15029. %@NL@%
  15030. Chesley, Harry R. and Mitchell Waite. %@AI@%Supercharging C with Assembly
  15031. %@AI@%Language%@AE@%.
  15032.     Reading, Massachusetts: Addison-Wesley Publishing Company,  Inc., 1987.%@NL@%
  15033. %@NL@%
  15034. Duncan, Ray. %@AI@%Advanced MS-DOS Programming, %@AE@%2nd ed. Redmond,  Washington:
  15035. Microsoft Press, 1988.%@NL@%
  15036. %@NL@%
  15037. Lafore, Robert. %@AI@%Assembly Language Primer for the IBM PC & XT%@AE@%.
  15038.     New York, New York: Plume/Waite, 1984.%@NL@%
  15039. %@NL@%
  15040. Metcalf, Christopher D. and Marc B. Sugiyama. %@AI@%COMPUTE!'s Beginner's Guide to
  15041. %@AI@%Machine Language on the IBM PC & PCjr%@AE@%.
  15042.     Greensboro, North Carolina: COMPUTE! Publications, Inc., 1985.%@NL@%
  15043. %@NL@%
  15044. Microsoft. %@AI@%Microsoft Macro Assembler 5.1 Programmer's Guide%@AE@%.
  15045.     Redmond, Washington, 1987. (Included with Microsoft Macro Assembler.)%@NL@%
  15046. %@NL@%
  15047. Microsoft. %@AI@%Microsoft Macro Assembler 5.1 Reference%@AE@%.
  15048.     Redmond, Washington, 1987. (Included with Microsoft Macro Assembler.)%@NL@%
  15049. %@NL@%
  15050. Sargent, Murray and Richard L. Shoemaker. %@AI@%The IBM Personal Computer from the
  15051. %@AI@%Inside Out%@AE@%.
  15052.     Reading, Massachusetts: Addison-Wesley Publishing Company, Inc., 1986.%@NL@%
  15053. %@NL@%
  15054. The above references are listed for your convenience only. With the
  15055. exception of those published by Microsoft, Microsoft Corporation does not
  15056. endorse these books or recommend them over others on the same subject.  %@NL@%
  15057. %@NL@%
  15058. %@NL@%
  15059. %@NL@%
  15060. %@NL@%
  15061. %@NL@%
  15062. %@NL@%
  15063. %@CR:C6A-A0001   @%%@1@%%@AB@%Appendix A  C Language Guide%@AE@%%@EH@%%@NL@%
  15064. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15065. %@NL@%
  15066. This appendix provides a quick summary of C language fundamentals. It does
  15067. not attempt to teach you the C language (Part 1 of this book does that) or
  15068. document all the details of C. Use it as a refresher or ready reference
  15069. after you have read all the material in Chapters 1 through 10.  %@NL@%
  15070. %@NL@%
  15071. To simplify reference, this appendix has the same general organization as
  15072. the chapters in Part 1. Each major section lists the chapter(s) where you
  15073. may find more detailed information on a given topic.  %@NL@%
  15074. %@NL@%
  15075. You can also use QuickC's online help to get instant information on any
  15076. topic. The online help index and table of contents provide alternate ways to
  15077. access information.  %@NL@%
  15078. %@NL@%
  15079. %@NL@%
  15080. %@2@%%@CR:C6A-A0002   @%%@AB@%General Syntax%@AE@%%@EH@%%@NL@%
  15081. %@NL@%
  15082. Basic C-language syntax is explained in Chapter 1, "Anatomy of a C Program."
  15083. %@NL@%
  15084. %@NL@%
  15085. A C statement consists of keywords, expressions, and function calls. A
  15086. statement always ends with a semicolon. A statement block is a collection of
  15087. statements enclosed by braces (%@AB@%{%@AE@% %@AB@%}%@AE@%). A statement block can appear anywhere a
  15088. simple C statement appears. No semicolon occurs after the closing brace.  %@NL@%
  15089. %@NL@%
  15090. C is a free-format programming language. You can insert "whitespace"
  15091. characters (spaces, tabs, carriage returns, and form feeds) almost anywhere,
  15092. to indent statement blocks and otherwise make your code more readable.  %@NL@%
  15093. %@NL@%
  15094. Comments begin with the slash-asterisk sequence (%@AB@%/*%@AE@%) and end with the
  15095. asterisk-slash sequence (%@AB@%*/%@AE@%). Comments are legal anywhere a space is legal,
  15096. but they cannot be nested.  %@NL@%
  15097. %@NL@%
  15098. %@NL@%
  15099. %@3@%%@CR:C6A-A0003   @%%@AB@%User-Defined Names%@AE@%%@EH@%%@NL@%
  15100. %@NL@%
  15101. The rules governing user-defined names are explained in Chapter 1, "Anatomy
  15102. of a C Program," and Chapter 4, "Basic Data Types."  %@NL@%
  15103. %@NL@%
  15104. You can define your own names ("identifiers") for variables, functions, and
  15105. user-defined types. Identifiers are case sensitive. For instance, the
  15106. identifier %@AS@%myVariable %@AE@% is not the same as the identifier %@AS@% Myvariable%@AE@%. You
  15107. cannot use a C keyword (see the list below) as an identifier.  %@NL@%
  15108. %@NL@%
  15109. An identifier can contain only the following characters:  %@NL@%
  15110. %@NL@%
  15111. %@NL@%
  15112.   ■   abcdefghijklmnopqrstuvwxyz%@NL@%
  15113. %@NL@%
  15114.   ■   ABCDEFGHIJKLMNOPQRSTUVWXYZ%@NL@%
  15115. %@NL@%
  15116.   ■   0123456789%@NL@%
  15117. %@NL@%
  15118.   ■   _ (underscore)%@NL@%
  15119. %@NL@%
  15120. %@NL@%
  15121. The first character of an identifier must be a letter or the underscore
  15122. character. The first 31 characters of local identifiers are significant. The
  15123. name can contain more than 31 characters, but QuickC ignores everything
  15124. beyond the thirty-first character. Global identifiers are normally
  15125. significant to 30 characters.  %@NL@%
  15126. %@NL@%
  15127. %@NL@%
  15128. %@3@%%@CR:C6A-A0004   @%%@AB@%Keywords%@AE@%%@EH@%%@NL@%
  15129. %@NL@%
  15130. A keyword has a special meaning in the C language. You must spell keywords
  15131. as shown in the following list, and you cannot use them as user-defined
  15132. names (see above).  %@NL@%
  15133. %@NL@%
  15134. %@AB@%_asm            _emit           _interrupt       signed%@AE@%
  15135. %@AB@% auto            enum           _loadds          sizeof%@AE@%
  15136. %@AB@%_based          _export          long            static%@AE@%
  15137. %@AB@%  break          extern         _near            struct%@AE@%
  15138. %@AB@% case           _far            _pascal          switch%@AE@%
  15139. %@AB@%_cdecl          _fastcall        register        typedef%@AE@%
  15140. %@AB@% char            float           return          union%@AE@%
  15141. %@AB@% const           for            _saveregs        unsigned%@AE@%
  15142. %@AB@% continue       _fortran        _segname         void%@AE@%
  15143. %@AB@% default         goto           _segment         volatile%@AE@%
  15144. %@AB@% do             _huge           _self            while%@AE@%
  15145. %@AB@% double          if              short          %@AE@%
  15146. %@AB@% else            int            
  15147.  
  15148. A few other words, such as %@AB@%main%@AE@%, have a special meaning but are not keywords
  15149. in the strict sense. Use online help to get details on all such words.  %@NL@%
  15150. %@NL@%
  15151. %@NL@%
  15152. %@2@%%@CR:C6A-A0005   @%%@AB@%Functions%@AE@%%@EH@%%@NL@%
  15153. %@NL@%
  15154. The rules governing C functions are explained in Chapter 2, "Functions."  %@NL@%
  15155. %@NL@%
  15156. Every C program must have at least one function, named %@AB@%main%@AE@%, which marks the
  15157. beginning and end of the program's execution. Every executable statement in
  15158. a C program must occur within a function.  %@NL@%
  15159. %@NL@%
  15160. Variables can be declared inside or outside functions. Variables declared
  15161. inside a function are "local" and can only be accessed in that function.
  15162. Variables declared outside all functions are "global" and can be accessed
  15163. from any function in your program.  %@NL@%
  15164. %@NL@%
  15165. You call a C function by stating its name. If the function requires
  15166. "arguments" (data), you list the arguments in the parentheses that follow
  15167. the function name. Arguments that you pass to a function become local
  15168. variables in the function.  %@NL@%
  15169. %@NL@%
  15170. A function can return a value (using the %@AB@%return%@AE@% keyword) or return nothing.
  15171. If the function contains no %@AB@%return%@AE@% statement, it ends automatically when
  15172. execution reaches the closing brace of the function definition.  %@NL@%
  15173. %@NL@%
  15174. A function "prototype" (declaration) tells QuickC the function's name, the
  15175. type of value it returns, and the number and type of arguments it requires.
  15176. Function prototypes normally appear near the beginning of the program. They
  15177. allow QuickC to check the accuracy of every reference to the function.  %@NL@%
  15178. %@NL@%
  15179. %@NL@%
  15180. %@2@%%@CR:C6A-A0006   @%%@AB@%Flow Control%@AE@%%@EH@%%@NL@%
  15181. %@NL@%
  15182. Flow-control statements are explained in Chapter 3, "Flow Control."  %@NL@%
  15183. %@NL@%
  15184. The C language provides several kinds of flow-control statements. The %@AB@%for%@AE@%,
  15185. %@AB@%while%@AE@%, and %@AB@%do%@AE@% statements create loops. The %@AB@%if%@AE@% and %@AB@%switch%@AE@% statements perform
  15186. a branch. The %@AB@%break%@AE@%, %@AB@%continue%@AE@%, %@AB@%return%@AE@%, and %@AB@%goto%@AE@% statements perform an
  15187. unconditional "jump" to another location in your program.  %@NL@%
  15188. %@NL@%
  15189. The following sections describe the C flow-control statements in
  15190. alphabetical order.  %@NL@%
  15191. %@NL@%
  15192. %@NL@%
  15193. %@3@%%@CR:C6A-A0007   @%%@AB@%The break Statement%@AE@%%@EH@%%@NL@%
  15194. %@NL@%
  15195. The %@AB@%break%@AE@% statement terminates the smallest enclosing %@AB@%do%@AE@%, %@AB@%for%@AE@%, %@AB@%switch%@AE@%, or
  15196. %@AB@%while%@AE@% statement in which it appears. It passes control to the statement
  15197. following the terminated statement.  %@NL@%
  15198. %@NL@%
  15199. This statement is often used to exit from a loop or %@AB@%switch%@AE@% statement (see
  15200. below). The following example illustrates %@AB@%break%@AE@%:  %@NL@%
  15201. %@NL@%
  15202. %@AS@%  while( c != 'Q' )
  15203. %@AS@%  {
  15204. %@AS@%    /* Some C statements here */
  15205. %@AS@%    if( number_of_characters > 80 )
  15206. %@AS@%        break;  /* Break out of while loop */
  15207. %@AS@%    /* More C statements here */
  15208. %@AS@%  }
  15209. %@AS@%  /* Execution continues here after break statement */%@AE@%%@NL@%
  15210. %@NL@%
  15211. %@NL@%
  15212. %@3@%%@CR:C6A-A0008   @%%@AB@%The continue Statement%@AE@%%@EH@%%@NL@%
  15213. %@NL@%
  15214. The %@AB@%continue%@AE@% statement is the opposite of the %@AB@%break%@AE@% statement. It passes
  15215. control to the next iteration of the smallest enclosing %@AB@%do%@AE@%, %@AB@%for%@AE@%, or %@AB@%while%@AE@%
  15216. statement in which it appears.  %@NL@%
  15217. %@NL@%
  15218. This statement is often used to return to the start of a loop from within a
  15219. deeply nested loop.  %@NL@%
  15220. %@NL@%
  15221. The following example illustrates %@AB@%continue%@AE@%:  %@NL@%
  15222. %@NL@%
  15223. %@AS@%  while( c != 'Q' )
  15224. %@AS@%  {
  15225. %@AS@%    /* Some C statements here*/
  15226. %@AS@%    if( c == 0x20 )
  15227. %@AS@%       continue;    /* Skip rest of loop */
  15228. %@AS@%    /* More C statements here */
  15229. %@AS@%  }%@AE@%%@NL@%
  15230. %@NL@%
  15231. In the example, the %@AB@%continue%@AE@% statement skips to the next iteration of the
  15232. loop whenever %@AS@% c %@AE@% equals 0x20, the ASCII value for a space character.  %@NL@%
  15233. %@NL@%
  15234. %@NL@%
  15235. %@3@%%@CR:C6A-A0009   @%%@AB@%The do Statement%@AE@%%@EH@%%@NL@%
  15236. %@NL@%
  15237. The %@AB@%do%@AE@% statement repeats a statement until a specified expression becomes
  15238. false. The test expression in the loop is evaluated after the body of the
  15239. loop executes. Thus, the body of a %@AB@%do%@AE@% loop always executes at least once.  %@NL@%
  15240. %@NL@%
  15241. Use a %@AB@%break%@AE@%, %@AB@%goto%@AE@%, or %@AB@%return%@AE@% statement when you need to exit a %@AB@%do%@AE@% loop
  15242. early. Use the %@AB@%continue%@AE@% statement to terminate an iteration without exiting
  15243. the loop. The %@AB@%continue%@AE@% statement passes control to the next iteration of the
  15244. loop.  %@NL@%
  15245. %@NL@%
  15246. The following example illustrates %@AB@%do%@AE@%:  %@NL@%
  15247. %@NL@%
  15248. %@AS@%  sample = 1;
  15249. %@AS@%  do
  15250. %@AS@%    printf( "%d\t%d\n", sample, sample * sample );
  15251. %@AS@%  while( ++x <= 7 );%@AE@%%@NL@%
  15252. %@NL@%
  15253. The %@AB@%printf%@AE@% statement in the example always executes at least once, no matter
  15254. what value %@AS@% x %@AE@% has when the loop begins.  %@NL@%
  15255. %@NL@%
  15256. %@NL@%
  15257. %@3@%%@CR:C6A-A0010   @%%@AB@%The for Statement%@AE@%%@EH@%%@NL@%
  15258. %@NL@%
  15259. The %@AB@%for%@AE@% statement lets you repeat a statement a specified number of times.
  15260. It consists of three expressions:  %@NL@%
  15261. %@NL@%
  15262. %@NL@%
  15263.   ■   An initializing expression, which is evaluated when the loop begins%@NL@%
  15264. %@NL@%
  15265.   ■   A test expression, which is evaluated before each iteration of the
  15266.       loop%@NL@%
  15267. %@NL@%
  15268.   ■   A modifying expression, which is evaluated at the end of each
  15269.       iteration of the loop%@NL@%
  15270. %@NL@%
  15271. %@NL@%
  15272. These expressions are enclosed in parentheses and followed by the loop
  15273. body─the statement the loop is to execute. Each expression in the
  15274. parentheses can be any legal C statement.  %@NL@%
  15275. %@NL@%
  15276. The %@AB@%for%@AE@% statement works as follows:  %@NL@%
  15277. %@NL@%
  15278. %@NL@%
  15279.   1.  The initializing expression is evaluated.%@NL@%
  15280. %@NL@%
  15281.   2.  As long as the test expression evaluates to a nonzero value, the loop
  15282.       body is executed. When the test expression becomes 0, control passes
  15283.       to the statement following the loop body.%@NL@%
  15284. %@NL@%
  15285.   3.  At the end of each iteration of the loop, the modifying expression is
  15286.       evaluated.%@NL@%
  15287. %@NL@%
  15288. %@NL@%
  15289. You can use a %@AB@%break%@AE@%, %@AB@%goto%@AE@%, or %@AB@%return%@AE@% statement to exit a %@AB@%for%@AE@% loop early. Use
  15290. the %@AB@%continue%@AE@% statement to terminate an iteration without exiting the %@AB@%for%@AE@%
  15291. loop. The %@AB@%continue%@AE@% statement passes control to the next iteration of the
  15292. loop.  %@NL@%
  15293. %@NL@%
  15294. The following example illustrates %@AB@%for%@AE@%:  %@NL@%
  15295. %@NL@%
  15296. %@AS@%  for( counter = 0; counter < 100; counter++ )
  15297. %@AS@%  {
  15298. %@AS@%    x[counter] = 0; /* Set every array element to zero */
  15299. %@AS@%  }%@AE@%%@NL@%
  15300. %@NL@%
  15301. %@NL@%
  15302. %@3@%%@CR:C6A-A0011   @%%@AB@%The goto Statement%@AE@%%@EH@%%@NL@%
  15303. %@NL@%
  15304. The %@AB@%goto%@AE@% statement performs a jump to the statement following the specified
  15305. label. A %@AB@%goto%@AE@% statement can jump anywhere within the current function.  %@NL@%
  15306. %@NL@%
  15307. A common use of %@AB@%goto%@AE@% is to exit immediately from a deeply nested loop. For
  15308. instance:  %@NL@%
  15309. %@NL@%
  15310. %@AS@%  for( ... ) 
  15311. %@AS@%  {
  15312. %@AS@%     for( ... ) 
  15313. %@AS@%     {
  15314. %@AS@%        /* Do something here */
  15315. %@AS@%        if(c == CTRL_C)
  15316. %@AS@%           goto myplace;
  15317. %@AS@%     }
  15318. %@AS@%     /* Do something else here */
  15319. %@AS@%  }
  15320. %@AS@%  
  15321. %@AS@%  /* The goto label is named myplace */
  15322. %@AS@%  myplace:
  15323. %@AS@%  /* The goto statement transfers control here */%@AE@%%@NL@%
  15324. %@NL@%
  15325. %@NL@%
  15326. %@3@%%@CR:C6A-A0012   @%%@AB@%The if Statement%@AE@%%@EH@%%@NL@%
  15327. %@NL@%
  15328. The %@AB@%if%@AE@% statement performs a branch based on the outcome of a conditional
  15329. test. If the test expression is true, the body of the %@AB@%if%@AE@% statement executes.
  15330. If it is false, the statement body is skipped.  %@NL@%
  15331. %@NL@%
  15332. The %@AB@%else%@AE@% keyword is used with %@AB@%if%@AE@% to form an either-or construct that
  15333. executes one statement when the test expression is true and another when
  15334. it's false. C does not offer an "else-if" keyword. You can combine %@AB@%if%@AE@% and
  15335. %@AB@%else%@AE@% statements to achieve the same effect. C pairs each %@AB@%else%@AE@% with the most
  15336. recent %@AB@%if%@AE@% that lacks an %@AB@%else%@AE@%.  %@NL@%
  15337. %@NL@%
  15338. Below is a simple %@AB@%if%@AE@% statement:  %@NL@%
  15339. %@NL@%
  15340. %@AS@%  if( score < 70 )
  15341. %@AS@%    grade = 'F';
  15342. %@AS@%  else
  15343. %@AS@%    grade = 'P';%@AE@%%@NL@%
  15344. %@NL@%
  15345. If the value of the variable %@AS@% score %@AE@% is less than 70, the variable %@AS@% grade %@AE@%
  15346. is set to the constant %@AS@% F%@AE@%. Otherwise, %@AS@% score %@AE@% is set to %@AS@% P%@AE@%.  %@NL@%
  15347. %@NL@%
  15348. %@NL@%
  15349. %@3@%%@CR:C6A-A0013   @%%@AB@%The return Statement%@AE@%%@EH@%%@NL@%
  15350. %@NL@%
  15351. The %@AB@%return%@AE@% statement ends the execution of the function in which it appears.
  15352. It can also return a value to the calling function. For example:  %@NL@%
  15353. %@NL@%
  15354. %@AS@%  return;      /* End function and return no value */
  15355. %@AS@%  
  15356. %@AS@%  return myvariable; /* End function and return value of myvariable */%@AE@%%@NL@%
  15357. %@NL@%
  15358. %@NL@%
  15359. %@3@%%@CR:C6A-A0014   @%%@AB@%The switch Statement%@AE@%%@EH@%%@NL@%
  15360. %@NL@%
  15361. The %@AB@%switch%@AE@% statement allows you to branch to various sections of code based
  15362. on the value of a single variable. This variable must evaluate to a %@AB@%char%@AE@%,
  15363. %@AB@%int%@AE@%, or %@AB@%long%@AE@% constant.  %@NL@%
  15364. %@NL@%
  15365. Each section of code in the %@AB@%switch%@AE@% statement is marked with a case label─the
  15366. keyword %@AB@%case%@AE@% followed by a constant or constant expression. The value of the
  15367. %@AB@%switch%@AE@% test expression is compared to the constant in each case label. If a
  15368. match is found, control transfers to the statement after the matching label
  15369. and continues until you reach a %@AB@%break%@AE@% statement or the end of the %@AB@%switch%@AE@%
  15370. statement.  %@NL@%
  15371. %@NL@%
  15372. For example:  %@NL@%
  15373. %@NL@%
  15374. %@AS@%  switch( answer )
  15375. %@AS@%  {
  15376. %@AS@%    case 'y': /* First case */
  15377. %@AS@%       printf( "lowercase y\n" );
  15378. %@AS@%       break;
  15379. %@AS@%  
  15380. %@AS@%    case 'n': /* Another case */
  15381. %@AS@%       printf( "lowercase n\n" );
  15382. %@AS@%       break;
  15383. %@AS@%  
  15384. %@AS@%    default:  /* Default case */
  15385. %@AS@%       printf( "not a lowercase y or n\n" );
  15386. %@AS@%       break;
  15387. %@AS@%  }%@AE@%%@NL@%
  15388. %@NL@%
  15389. The example tests the value of the variable %@AS@% answer%@AE@%. If %@AS@% answer %@AE@% evaluates
  15390. to the constant %@AS@% 'y'%@AE@%, control transfers to the first case in the %@AB@%switch%@AE@%
  15391. statement. If it equals %@AS@% 'n'%@AE@%, control transfers to the second case.  %@NL@%
  15392. %@NL@%
  15393. A case labelled with the %@AB@%default%@AE@% keyword executes when none of the other
  15394. case constants matches the value of the %@AB@%switch%@AE@% test expression. In the
  15395. example, the %@AB@%default%@AE@% case executes when %@AS@% answer %@AE@% equals any value other than
  15396. %@AS@% 'y' %@AE@% or %@AS@% 'n'%@AE@%.  %@NL@%
  15397. %@NL@%
  15398. If you omit the %@AB@%break%@AE@% statement at the end of a case, execution falls
  15399. through to the next case.  %@NL@%
  15400. %@NL@%
  15401. If you omit the %@AB@%default%@AE@% case and no matching case is found, nothing in the
  15402. %@AB@%switch%@AE@% statement executes.  %@NL@%
  15403. %@NL@%
  15404. No two %@AB@%case%@AE@% constants in the same %@AB@%switch%@AE@% statement can have the same value.
  15405. %@NL@%
  15406. %@NL@%
  15407. %@NL@%
  15408. %@3@%%@CR:C6A-A0015   @%%@AB@%The while Statement%@AE@%%@EH@%%@NL@%
  15409. %@NL@%
  15410. The %@AB@%while%@AE@% statement repeats a statement until its test expression becomes
  15411. false. A %@AB@%while%@AE@% loop evaluates its test expression before executing its loop
  15412. body. If the test expression is false when the loop begins, the loop body
  15413. never executes. (Contrast this behavior with the %@AB@%do%@AE@% loop, which always
  15414. executes its loop body at least once.)  %@NL@%
  15415. %@NL@%
  15416. For example:  %@NL@%
  15417. %@NL@%
  15418. %@AS@%  while( !sample )  /* Repeat until sample equals 1 */
  15419. %@AS@%  {
  15420. %@AS@%    printf( "%d\t%d\n", x, x*x );
  15421. %@AS@%    x += 6;
  15422. %@AS@%    if( x > 20 )
  15423. %@AS@%       sample = 1;
  15424. %@AS@%  }%@AE@%%@NL@%
  15425. %@NL@%
  15426. You can exit a %@AB@%while%@AE@% loop early with a %@AB@%break%@AE@% or %@AB@%goto%@AE@% statement. The %@AB@%continue%@AE@%
  15427. statement skips to the next iteration of the loop.  %@NL@%
  15428. %@NL@%
  15429. %@NL@%
  15430. %@2@%%@CR:C6A-A0016   @%%@AB@%Data Types%@AE@%%@EH@%%@NL@%
  15431. %@NL@%
  15432. Data types are explained in Chapter 4, "Data Types," and Chapter 5,
  15433. "Advanced Data Types." A brief description is given here.  %@NL@%
  15434. %@NL@%
  15435. %@NL@%
  15436. %@3@%%@CR:C6A-A0017   @%%@AB@%Basic Data Types%@AE@%%@EH@%%@NL@%
  15437. %@NL@%
  15438. The basic data types in C are character (%@AB@%char%@AE@%), integer (%@AB@%int%@AE@%), and floating
  15439. point (%@AB@%float%@AE@% and %@AB@%double%@AE@%). All other data types are derived from these basic
  15440. types. For example, a string is an array of %@AB@%char%@AE@% values.  %@NL@%
  15441. %@NL@%
  15442. Table A.1 lists the range of values for each data type.  %@NL@%
  15443. %@NL@%
  15444. %@AB@%Table A.1  %@AB@%Basic Data Types%@AE@%%@AE@%
  15445.  
  15446. %@TH:  38  1806 02 17 29 30 @%
  15447. Type Name        Other Names                  Range of Values
  15448. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15449. %@AB@%char%@AE@%             %@AB@%signed char%@AE@%                  -128 to 127
  15450.  
  15451. %@AB@%unsigned char%@AE@%    none                         0 to 255
  15452.  
  15453. %@AB@%int%@AE@%              %@AB@%signed%@AE@%, %@AB@%signed int%@AE@%           -32,768 to 32,767
  15454.  
  15455. %@AB@%unsigned%@AE@%         %@AB@%unsigned int%@AE@%                 0 to 65,535
  15456.  
  15457. %@AB@%unsigned short%@AE@%   %@AB@%unsigned short int%@AE@%           0 to 65,535
  15458.  
  15459. %@AB@%short%@AE@%            %@AB@%short int%@AE@%, %@AB@%signed short%@AE@%      -32,768 to
  15460.  
  15461.                  %@AB@%signed short int%@AE@%             32,767
  15462.  
  15463. %@AB@%long%@AE@%             %@AB@%long int%@AE@%, %@AB@%signed long%@AE@%        -2,147,483,647 to
  15464.  
  15465.                  %@AB@%signed long int%@AE@%              2,147,483,648
  15466.  
  15467. %@AB@%unsigned long%@AE@%    %@AB@%unsigned long int%@AE@%            0 to 4,294,967,295
  15468.  
  15469. %@AB@%_segment%@AE@%         none                         0 to 65,535
  15470.  
  15471. %@AB@%enum%@AE@%             none                         -32,768 to 32,767
  15472.  
  15473. %@AB@%float%@AE@%            none                         Approximately 1.2E-38 to 
  15474.                                               3.4E+38 (7-digit precision)
  15475.  
  15476. %@AB@%double%@AE@%           none                         Approximately 2.2E-308 to 
  15477.                                               1.8E+308 (15-digit precision)
  15478.  
  15479. %@AB@%long double%@AE@%      none                         Approximately 3.4E-4932 to 
  15480.                                               1.2E+4932 (19-digit 
  15481.                                               precision)
  15482.  
  15483. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15484.  
  15485. %@TE:  38  1806 02 17 29 30 @%
  15486.  
  15487. %@NL@%
  15488. %@4@%%@AB@%Character Type%@AE@%%@EH@%%@NL@%
  15489. %@NL@%
  15490. The character type (%@AB@%char%@AE@%) occupies one byte of storage and can express a
  15491. whole number in the range of -128 to 127. Unsigned characters have a range
  15492. of 0 to 255. You can represent any ASCII character as an %@AB@%unsigned char%@AE@%
  15493. value.  %@NL@%
  15494. %@NL@%
  15495. Typical declarations of character types are shown below:  %@NL@%
  15496. %@NL@%
  15497. %@AS@%  char answer; /* Declare a character variable answer */
  15498. %@AS@%  
  15499. %@AS@%  char alpha = 'a'; /* Declare character variable alpha
  15500. %@AS@%                       and initialize it */%@AE@%%@NL@%
  15501. %@NL@%
  15502. A character constant represents a single ASCII character. Typical character
  15503. constants are shown below:  %@NL@%
  15504. %@NL@%
  15505. %@AS@%  char alpha = 'a'; /* Declare and initialize */
  15506. %@AS@%  
  15507. %@AS@%  char c2 = 0x61; /* Declare and initialize with
  15508. %@AS@%                     hexadecimal value for 'a' */%@AE@%%@NL@%
  15509. %@NL@%
  15510. %@AB@%Escape Sequences%@AE@% - Escape sequences represent special characters, such as
  15511. the carriage return. An escape sequence consists of a backslash character
  15512. plus a letter or punctuation mark. Table A.2 lists the C escape sequences;
  15513. they are also listed in online help.%@NL@%
  15514. %@NL@%
  15515. %@AB@%Table A.2  %@AB@%C Escape Sequences%@AE@%%@AE@%
  15516.  
  15517. %@TH:  14   834 02 11 22 43 @%
  15518. Character  Meaning               Hexadecimal Value
  15519. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15520. %@AB@%\a%@AE@%         Alert (bell)          0x07
  15521. %@AB@%\n%@AE@%         New line (linefeed)   0x0A
  15522. %@AB@%\b%@AE@%         Backspace             0x08
  15523. %@AB@%\r%@AE@%         Carriage return       0x0D
  15524. %@AB@%\f%@AE@%         Formfeed              0x0C
  15525. %@AB@%\t%@AE@%         Tab                   0x09
  15526. %@AB@%\v%@AE@%         Vertical tab          0x0B
  15527. %@AB@%\\%@AE@%         Backslash             0x5C
  15528. %@AB@%\%@AS@%'%@AE@%%@AE@%         Single quote          0x27
  15529. %@AB@%\"%@AE@%         Double quote          0x22
  15530. %@AB@%\0%@AE@%         Null                  0x00
  15531. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15532. %@TE:  14   834 02 11 22 43 @%
  15533.  
  15534. %@NL@%
  15535. %@4@%%@AB@%Integer Type%@AE@%%@EH@%%@NL@%
  15536. %@NL@%
  15537. The integer (%@AB@%int%@AE@%) type occupies two bytes of storage and can express a whole
  15538. number in the range -32,768 to 32,767. Unsigned integers (%@AB@%unsigned%@AE@% or
  15539. %@AB@%unsigned int%@AE@%) have a range of 0 to 65,535.  %@NL@%
  15540. %@NL@%
  15541. In QuickC, short integers (%@AB@%short%@AE@% or %@AB@%short int%@AE@%) are the same as integers
  15542. (%@AB@%int%@AE@%). Note that the %@AB@%short%@AE@% and %@AB@%int%@AE@% types are not the same in some operating
  15543. systems other than DOS.  %@NL@%
  15544. %@NL@%
  15545. Signed long integers (%@AB@%long%@AE@%) occupy four bytes and have a range of
  15546. -2,147,483,648 to 2,147,483,647. Unsigned long integers have a range of 0 to
  15547. 4,294,967,295.  %@NL@%
  15548. %@NL@%
  15549. Integer variables are declared with the keywords %@AB@%int%@AE@%, %@AB@%short%@AE@%, %@AB@%unsigned%@AE@%, or
  15550. %@AB@%long%@AE@%. Typical declarations of integer types are shown below:  %@NL@%
  15551. %@NL@%
  15552. %@AS@%  int z; /* Declare an int variable z */
  15553. %@AS@%  
  15554. %@AS@%  int ten = 10; /* Declare int variable and
  15555. %@AS@%                   assign it the value 10 */
  15556. %@AS@%  
  15557. %@AS@%  unsigned int a; /* Declare unsigned int variable */
  15558. %@AS@%  
  15559. %@AS@%  unsigned long BigInt = 2000000001UL; /* Declare and
  15560. %@AS@%                                          initialize */%@AE@%%@NL@%
  15561. %@NL@%
  15562. Integer constants are used to represent decimal, octal, and hexadecimal
  15563. numbers. There are three types of integer constants:  %@NL@%
  15564. %@NL@%
  15565. %@NL@%
  15566.   1.  Decimal constants can only contain the digits 0-9. The first digit
  15567.       must not be 0.%@NL@%
  15568. %@NL@%
  15569.   2.  Octal constants can only contain the digits 0-7. The first digit must
  15570.       be 0.%@NL@%
  15571. %@NL@%
  15572.   3.  Hexadecimal constants can only contain the digits 0-9, plus the
  15573.       letters a-f or A-F. The constant must begin with either 0x or 0X.%@NL@%
  15574. %@NL@%
  15575. %@NL@%
  15576. You can specify that an integer constant is long by adding the suffix %@AB@%l%@AE@% or
  15577. %@AB@%L%@AE@%. The suffix can be used with decimal, hexadecimal, or octal notation.  %@NL@%
  15578. %@NL@%
  15579. To specify that an integer constant is short, add the suffix %@AB@%u%@AE@% or %@AB@%U%@AE@%. This
  15580. suffix can also be used with decimal, hexadecimal, or octal notation.  %@NL@%
  15581. %@NL@%
  15582. Typical integer constants are shown below:  %@NL@%
  15583. %@NL@%
  15584. %@AS@%  42    /* Decimal constant */
  15585. %@AS@%  
  15586. %@AS@%  0x34  /* Hexadecimal constant */
  15587. %@AS@%  
  15588. %@AS@%  0x3cL /* Long hexadecimal constant */%@AE@%%@NL@%
  15589. %@NL@%
  15590. %@AS@%  052   /* Octal constant */%@AE@%%@NL@%
  15591. %@NL@%
  15592. %@NL@%
  15593. %@4@%%@AB@%Floating-Point Types%@AE@%%@EH@%%@NL@%
  15594. %@NL@%
  15595. You can declare floating-point variables using the keywords %@AB@%float%@AE@% or %@AB@%double%@AE@%.
  15596. The %@AB@%float%@AE@% type occupies four bytes of storage and can express a
  15597. floating-point value in the range 1.2E-38 to 3.4E+38. This type has
  15598. seven-digit precision.  %@NL@%
  15599. %@NL@%
  15600. The %@AB@%double%@AE@% type occupies eight bytes of storage and can express a
  15601. floating-point value in the range 2.2E-308 to 1.8E+308. This type has
  15602. fifteen-digit precision.  %@NL@%
  15603. %@NL@%
  15604. The %@AB@%long double%@AE@% type occupies ten bytes of storage and can express a
  15605. floating-point value in the range 3.4E-4932 to 1.2E+4932. This type has
  15606. nineteen-digit precision.  %@NL@%
  15607. %@NL@%
  15608. Typical declarations of floating-point types are shown below:  %@NL@%
  15609. %@NL@%
  15610. %@AS@%  float SmallPi = 3.14;  /* Declare floating-point variable */
  15611. %@AS@%  
  15612. %@AS@%  double AccuratePi = 3.141592653596  /* Declare
  15613. %@AS@%                                        double-precision */%@AE@%%@NL@%
  15614. %@NL@%
  15615. Floating-point constants can represent decimal numbers in either single or
  15616. double precision. A floating-point constant must either contain a decimal
  15617. point or end with the suffix %@AB@%e%@AE@% or %@AB@%E%@AE@%. Typical floating-point constants are
  15618. shown below:  %@NL@%
  15619. %@NL@%
  15620. %@AS@%  2.78   /* Floating-point constant */
  15621. %@AS@%  
  15622. %@AS@%  3E     /* Floating-point constant */%@AE@%%@NL@%
  15623. %@NL@%
  15624. %@NL@%
  15625. %@3@%%@CR:C6A-A0018   @%%@AB@%Aggregate Data Types%@AE@%%@EH@%%@NL@%
  15626. %@NL@%
  15627. Aggregate data types are built from one or more of the basic data types.
  15628. These include the following:  %@NL@%
  15629. %@NL@%
  15630. %@NL@%
  15631.   ■   Arrays (including strings)%@NL@%
  15632. %@NL@%
  15633.   ■   Structures%@NL@%
  15634. %@NL@%
  15635.   ■   Unions%@NL@%
  15636. %@NL@%
  15637. %@NL@%
  15638. %@NL@%
  15639. %@4@%%@AB@%Arrays and Strings%@AE@%%@EH@%%@NL@%
  15640. %@NL@%
  15641. An "array" is a collection of data elements of a single type. An array can
  15642. contain any data type. You can access an element of an array by using the
  15643. array name and a numeric subscript.  %@NL@%
  15644. %@NL@%
  15645. A "string" is an array of characters that terminates with the null character
  15646. (%@AB@%\0%@AE@%). Arrays that contain strings must allow space for the final null
  15647. character.  %@NL@%
  15648. %@NL@%
  15649. Typical arrays and strings are shown below:  %@NL@%
  15650. %@NL@%
  15651. %@AS@%  int id_number[10]; /* One-dimensional; 
  15652. %@AS@%                        10 elements; integer */
  15653. %@AS@%  
  15654. %@AS@%  char name[30]; /* String */
  15655. %@AS@%  
  15656. %@AS@%  float matrix[5][3]; /* Two-dimensional array, 
  15657. %@AS@%                         5 rows, 3 columns */
  15658. %@AS@%  
  15659. %@AS@%  char baby[30] = "Peter Roddy"; /* String initialization */%@AE@%%@NL@%
  15660. %@NL@%
  15661. %@NL@%
  15662. %@4@%%@AB@%Structures%@AE@%%@EH@%%@NL@%
  15663. %@NL@%
  15664. A "structure" is a collection of data items of different types. Once you
  15665. have defined a structure type, you can declare a structure variable using
  15666. that type.  %@NL@%
  15667. %@NL@%
  15668. The following example illustrates a simple structure:  %@NL@%
  15669. %@NL@%
  15670. %@AS@%  struct date
  15671. %@AS@%  {
  15672. %@AS@%    int month;
  15673. %@AS@%    int day;
  15674. %@AS@%    int year;
  15675. %@AS@%  }
  15676. %@AS@%  
  15677. %@AS@%  struct date today;%@AE@%%@NL@%
  15678. %@NL@%
  15679. The example defines a structure type named %@AS@% date %@AE@% and declares a structure
  15680. variable %@AS@% today %@AE@% to be of type %@AS@% date%@AE@%.  %@NL@%
  15681. %@NL@%
  15682. Use the structure-member operator ( . ) to access the "elements" (members)
  15683. of a structure. The name  %@NL@%
  15684. %@NL@%
  15685. %@AS@%  today.month%@AE@%%@NL@%
  15686. %@NL@%
  15687. refers to the %@AS@% month %@AE@% member of the %@AS@% today %@AE@% structure in the example.  %@NL@%
  15688. %@NL@%
  15689. %@NL@%
  15690. %@4@%%@AB@%Unions%@AE@%%@EH@%%@NL@%
  15691. %@NL@%
  15692. A "union" is a set of data items of different types sharing the same storage
  15693. space in memory. One use of unions is accessing the computer's DOS
  15694. registers. For instance, QuickC defines the union %@AB@%REGS%@AE@% as the following:  %@NL@%
  15695. %@NL@%
  15696. %@AS@%  union REGS 
  15697. %@AS@%  {
  15698. %@AS@%    struct WORDREGS x;
  15699. %@AS@%    struct BYTEREGS h;
  15700. %@AS@%  };%@AE@%%@NL@%
  15701. %@NL@%
  15702. %@NL@%
  15703. %@2@%%@CR:C6A-A0019   @%%@AB@%Advanced Data Types%@AE@%%@EH@%%@NL@%
  15704. %@NL@%
  15705. Advanced data topics are explained in Chapter 5, "Advanced Data Types." A
  15706. brief description of each topic is given here.  %@NL@%
  15707. %@NL@%
  15708. %@NL@%
  15709. %@3@%%@CR:C6A-A0020   @%%@AB@%Visibility%@AE@%%@EH@%%@NL@%
  15710. %@NL@%
  15711. Variables declared outside all functions are global and can be accessed
  15712. anywhere in the current source file. Variables declared inside a function
  15713. are local and can be accessed only in that function. Use the %@AB@%extern%@AE@% keyword
  15714. to make a variable declared in another source file visible in the current
  15715. source file.  %@NL@%
  15716. %@NL@%
  15717. %@NL@%
  15718. %@3@%%@CR:C6A-A0021   @%%@AB@%Lifetime%@AE@%%@EH@%%@NL@%
  15719. %@NL@%
  15720. Global variables, and local variables declared with the %@AB@%static%@AE@% keyword,
  15721. exist for the lifetime of the program. Other local variables are
  15722. "automatic;" they come into being when the function starts and evaporate
  15723. when it ends.  %@NL@%
  15724. %@NL@%
  15725. %@NL@%
  15726. %@3@%%@CR:C6A-A0022   @%%@AB@%Type Conversions%@AE@%%@EH@%%@NL@%
  15727. %@NL@%
  15728. A type conversion occurs automatically when an expression mixes two
  15729. different data types. QuickC converts the lower-ranking type to the
  15730. higher-ranking type before it performs the specified operation.  %@NL@%
  15731. %@NL@%
  15732. You can also "cast" (manually convert) a value to any type by placing the
  15733. desired type name in parentheses in front of the value. The example below
  15734. casts the value of %@AS@% sample %@AE@% to type %@AB@%float%@AE@% and assigns the value to %@AS@% x%@AE@%:  %@NL@%
  15735. %@NL@%
  15736. %@AS@%  int sample; 
  15737. %@AS@%  float x; 
  15738. %@AS@%  x = (float)sample;%@AE@%%@NL@%
  15739. %@NL@%
  15740. %@NL@%
  15741. %@3@%%@CR:C6A-A0023   @%%@AB@%User-Defined Types%@AE@%%@EH@%%@NL@%
  15742. %@NL@%
  15743. The %@AB@%typedef%@AE@% keyword allows you to create user-defined types, which are
  15744. synonyms for existing data types. User-defined types can make your program
  15745. more readable. For example, a type called %@AS@% string %@AE@% may be easier to
  15746. understand than a type called %@AB@%char *%@AE@%.  %@NL@%
  15747. %@NL@%
  15748. A simple %@AB@%typedef%@AE@% declaration is shown below. The name of an existing type
  15749. (%@AB@%long int%@AE@%) is followed by the synonym %@AS@% income%@AE@%.  %@NL@%
  15750. %@NL@%
  15751. %@AS@%  typedef long int income;%@AE@%%@NL@%
  15752. %@NL@%
  15753. Once you have created a new type name, you can use it wherever the original
  15754. type name could be used:  %@NL@%
  15755. %@NL@%
  15756. %@AS@%  income net_income, gross_income;%@AE@%%@NL@%
  15757. %@NL@%
  15758. In the example above, the variables %@AS@% net_income %@AE@% and %@AS@% gross_income %@AE@% are of
  15759. type %@AS@% income%@AE@%, which is the same as %@AB@%long int%@AE@%.  %@NL@%
  15760. %@NL@%
  15761. %@NL@%
  15762. %@3@%%@CR:C6A-A0024   @%%@AB@%Enumerated Types%@AE@%%@EH@%%@NL@%
  15763. %@NL@%
  15764. An enumerated type (declared with %@AB@%enum%@AE@%) has values limited to a specified
  15765. set. If the %@AB@%enum%@AE@% declaration does not specify any values, QuickC assigns
  15766. sequential integers to the enumeration identifiers beginning at zero.  %@NL@%
  15767. %@NL@%
  15768. The example below assigns the values of 0, 1, and 2 to the enumeration
  15769. identifiers %@AS@% zero%@AE@%, %@AS@% one%@AE@%, and %@AS@% two%@AE@%, respectively. It also creates an
  15770. enumerated type %@AS@% small_numbers %@AE@% that can be used to declare other variables.
  15771. %@NL@%
  15772. %@NL@%
  15773. %@AS@%  /* Enumerated data type */
  15774. %@AS@%  enum small_numbers {zero, one, two};
  15775. %@AS@%  
  15776. %@AS@%  /* Variable my_numbers is of type small_numbers */
  15777. %@AS@%  enum small_numbers  my_numbers;%@AE@%%@NL@%
  15778. %@NL@%
  15779. The following example explicitly assigns values to the enumeration
  15780. identifiers:  %@NL@%
  15781. %@NL@%
  15782. %@AS@%  /* Enumerated data type */
  15783. %@AS@%  enum even_numbers { two = 2, four = 4, six = 6 };%@AE@%%@NL@%
  15784. %@NL@%
  15785. %@NL@%
  15786. %@2@%%@CR:C6A-A0025   @%%@AB@%Operators%@AE@%%@EH@%%@NL@%
  15787. %@NL@%
  15788. C-language operators are explained in Chapter 6, "Operators."  %@NL@%
  15789. %@NL@%
  15790. An "operand" is a constant or variable manipulated by an operator in an
  15791. expression. An "operator" specifies how the operands in an expression are to
  15792. be evaluated. Operators also produce a result that can be nested within a
  15793. larger expression.  %@NL@%
  15794. %@NL@%
  15795. C provides a rich set of operators covering everything from basic arithmetic
  15796. operations to logical and bitwise operations. You can also combine the
  15797. assignment operator (%@AB@%=%@AE@%) with any arithmetic or bitwise operator to form a
  15798. combined assignment operator.  %@NL@%
  15799. %@NL@%
  15800. C operators have two properties, precedence and associativity. You can
  15801. change the normal order of evaluation by enclosing expressions in
  15802. parentheses.  %@NL@%
  15803. %@NL@%
  15804. Table A.3 lists the C operators and their precedence and associativity
  15805. values. The lines in the table separate precedence levels. The highest
  15806. precedence level is at the top of the table.  %@NL@%
  15807. %@NL@%
  15808. %@AB@%Table A.3  %@AB@%C Operators%@AE@%%@AE@%
  15809.  
  15810. %@TH: 114  4500 02 24 37 15 @%
  15811. Symbol                  Name or Meaning                      Associativity
  15812. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15813. ( )                     Function call                        Left to right
  15814.  
  15815. [ ]                     Array element 
  15816.  
  15817. %@AB@%.%@AE@%                       Structure or union 
  15818.                         member 
  15819.  
  15820. %@AB@%->%@AE@%                      Pointer to structure 
  15821.                         member 
  15822.  
  15823. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15824.  
  15825. %@AB@%- -%@AE@%                     Decrement                            Right to left
  15826.  
  15827. %@AB@%++%@AE@%                      Increment 
  15828.  
  15829. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15830.  
  15831. :>                      Base operator                        Left to right
  15832.  
  15833. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15834.  
  15835. %@AB@%!%@AE@%                       Logical NOT                          Right to left
  15836.  
  15837. %@AB@%~ %@AE@%                      One's complement%@AB@% %@AE@%
  15838.  
  15839. %@AB@%-%@AE@%                       Unary minus 
  15840.  
  15841. %@AB@%+%@AE@%                       Unary plus 
  15842.  
  15843. %@AB@%&%@AE@%                       Address 
  15844.  
  15845. %@AB@%*%@AE@%                       Indirection 
  15846.  
  15847. %@AB@%sizeof%@AE@%                  Size in bytes 
  15848.  
  15849. %@AB@%(%@AE@%type%@AB@%)%@AE@%                  Type cast [for example, (%@AB@%float%@AE@%) i] 
  15850.  
  15851. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15852.  
  15853. %@AB@%*%@AE@%                       Multiply                             Left to right
  15854.  
  15855. %@AB@%/%@AE@%                       Divide 
  15856.  
  15857. %@AB@%%%@AE@%                       Modulus (remainder)
  15858.  
  15859. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15860.  
  15861. %@AB@%+%@AE@%                       Add                                  Left to right
  15862.  
  15863. %@AB@%-%@AE@%                       Subtract 
  15864.  
  15865. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15866.  
  15867. %@AB@%<<%@AE@%                      Left shift                           Left to right
  15868.  
  15869. %@AB@%>>%@AE@%                      Right shift 
  15870.  
  15871. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15872.  
  15873. %@AB@%<%@AE@%                       Less than                            Left to right
  15874.  
  15875. %@AB@%<=%@AE@%                      Less than or equal to 
  15876.  
  15877. %@AB@%>%@AE@%                       Greater than 
  15878.  
  15879. %@AB@%>=%@AE@%                      Greater than or equal to 
  15880.  
  15881. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15882.  
  15883. %@AB@%==%@AE@%                      Equal                                Left to right
  15884.  
  15885. %@AB@%!=%@AE@%                      Not equal 
  15886.  
  15887. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15888.  
  15889. %@AB@%&%@AE@%                       Bitwise AND                          Left to right
  15890.  
  15891. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15892.  
  15893. %@AB@%^%@AE@%                       Bitwise exclusive OR                 Left to right
  15894.  
  15895. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15896.  
  15897. %@AB@%|%@AE@%                       Bitwise OR                           Left to right
  15898.  
  15899. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15900.  
  15901. %@AB@%&&%@AE@%                      Logical AND                          Left to right
  15902.  
  15903. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15904.  
  15905. %@AB@%||%@AE@%                      Logical OR                           Left to right
  15906.  
  15907. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15908.  
  15909. %@AB@%? : %@AE@%                    Conditional                          Right to left
  15910.  
  15911. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15912.  
  15913. %@AB@%=%@AE@%                       Assignment                           Right to left
  15914.  
  15915. %@AB@%*=, /=, %=, +=, -=%@AE@%      Compound assignment
  15916.  
  15917. %@AB@%<<=, >>=,  &=, ^=, |=%@AE@%   
  15918.  
  15919. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15920.  
  15921. %@AB@%,%@AE@%                       Comma                                Left to right
  15922.  
  15923. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15924.  
  15925. %@TE: 114  4500 02 24 37 15 @%
  15926.  
  15927. %@NL@%
  15928. %@2@%%@CR:C6A-A0026   @%%@AB@%Preprocessor Directives%@AE@%%@EH@%%@NL@%
  15929. %@NL@%
  15930. Preprocessor directives are explained in Chapter 7, "Preprocessor
  15931. Directives."  %@NL@%
  15932. %@NL@%
  15933. A "preprocessor directive" is a command to the QuickC compiler, which
  15934. processes all such commands before it compiles your source program. A
  15935. preprocessor directive begins with the %@AB@%#%@AE@% symbol, followed by the directive
  15936. and any arguments the directive needs. Since a preprocessor directive is not
  15937. a C language statement, it doesn't end in a semicolon.  %@NL@%
  15938. %@NL@%
  15939. The two most commonly used directives are %@AB@%#define%@AE@% and %@AB@%#include%@AE@%. Use the
  15940. %@AB@%#define%@AE@% directive to give a meaningful name to some constant in your
  15941. program. The following directive tells QuickC to replace %@AS@% PI %@AE@% with %@AS@% 3.14159 %@AE@%
  15942. everywhere in the source program:  %@NL@%
  15943. %@NL@%
  15944. %@AS@%  #define PI  3.14159%@AE@%%@NL@%
  15945. %@NL@%
  15946. The %@AB@%#include%@AE@% directive below tells QuickC to insert the contents of a
  15947. specified file at the current location in your source program.  %@NL@%
  15948. %@NL@%
  15949. %@AS@%  #include <stdio.h> /* Standard header file */%@AE@%%@NL@%
  15950. %@NL@%
  15951. Such files are called "include files" or "header files." Standard header
  15952. files, such as STDIO.H, end with the .H extension and contain function
  15953. prototypes and other definitions needed for QuickC library routines.  %@NL@%
  15954. %@NL@%
  15955. Table A.4 lists and describes the QuickC standard header files. Consult
  15956. online help for information on the header files needed by individual library
  15957. functions.  %@NL@%
  15958. %@NL@%
  15959. %@AB@%Table A.4  %@AB@%QuickC Header Files%@AE@%%@AE@%
  15960.  
  15961. %@TH:  73  2606 02 34 42 @%
  15962. File Name                         Major Contents
  15963. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  15964. ASSERT.H                          %@AB@%assert%@AE@% debugging macro
  15965.  
  15966. BIOS.H                            BIOS service functions
  15967.  
  15968. CONIO.H                           Console and port I/O routines
  15969.  
  15970. CTYPE.H                           Character classification
  15971.  
  15972. DIRECT.H                          Directory control
  15973.  
  15974. DOS.H                             MS-DOS interface functions
  15975.  
  15976. ERRNO.H                           System-wide error numbers
  15977.  
  15978. FCNTL.H                           Flags used in %@AB@%open%@AE@% and %@AB@%sopen%@AE@% functions
  15979.  
  15980. FLOAT.H                           Constants needed by math functions
  15981.  
  15982. GRAPH.H                           Low-level graphics and font routines
  15983.  
  15984. IO.H                              File-handling and low-level I/O
  15985.  
  15986. LIMITS.H                          Ranges of integers and character types
  15987.  
  15988. LOCALE.H                          Internationalization functions
  15989.  
  15990. MALLOC.H                          Memory-allocation functions
  15991.  
  15992. MATH.H                            Floating-point math routines
  15993.  
  15994. MEMORY.H                          Buffer-manipulation routines
  15995.  
  15996. PGCHART.H                         Presentation graphics
  15997.  
  15998. PROCESS.H                         Process-control routines
  15999.  
  16000. SEARCH.H                          Searching and sorting functions
  16001.  
  16002. SETJMP.H                          %@AB@%setjmp%@AE@% and %@AB@%longjmp%@AE@% functions
  16003.  
  16004. SHARE.H                           Flags used in %@AB@%sopen%@AE@%
  16005.  
  16006. SIGNAL.H                          Constants used by signal function
  16007.  
  16008. STDARG.H                          Macros used to access variable-length 
  16009.                                   argument-list functions
  16010.  
  16011. STDDEF.H                          Commonly used data types and values
  16012.  
  16013. STDIO.H                           Standard I/O header file
  16014.  
  16015. STDLIB.H                          Commonly used library functions
  16016.  
  16017. STRING.H                          String-manipulation functions
  16018.  
  16019. TIME.H                            General time functions
  16020.  
  16021. VARARGS.H                         Variable-length argument-list functions
  16022.  
  16023. SYS\LOCKING.H                     Flags used by %@AB@%locking%@AE@% function
  16024.  
  16025. SYS\STAT.H                        File-status structures and functions
  16026.  
  16027. SYS\TIMEB.H                       %@AB@%time%@AE@% function
  16028.  
  16029. SYS\TYPES.H                       File-status and time types
  16030.  
  16031. SYS\UTIME.H                       %@AB@%utime%@AE@% function
  16032.  
  16033. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16034.  
  16035. %@TE:  73  2606 02 34 42 @%
  16036.  
  16037. %@NL@%
  16038. %@2@%%@CR:C6A-A0027   @%%@AB@%Pointers%@AE@%%@EH@%%@NL@%
  16039. %@NL@%
  16040. Pointers are described in Chapter 8, "Pointers," and Chapter 9, "Advanced
  16041. Pointers."  %@NL@%
  16042. %@NL@%
  16043. A "pointer" is a variable that contains the memory address of an item rather
  16044. than its value. A pointer can point to any type of data item or to a
  16045. function. The following code illustrates pointer declarations:  %@NL@%
  16046. %@NL@%
  16047. %@AS@%  int *intptr; /* Pointer to an integer */
  16048. %@AS@%  char *name; /* Pointer to char */%@AE@%%@NL@%
  16049. %@NL@%
  16050. The following operators are used with pointers:  %@NL@%
  16051. %@NL@%
  16052. %@NL@%
  16053.   ■   The indirection operator (%@AB@%*%@AE@%) has two uses. In a declaration, it means
  16054.       that the declared item is a pointer. In an expression, it denotes the
  16055.       data being pointed to.%@NL@%
  16056. %@NL@%
  16057.   ■   The address-of operator (%@AB@%&%@AE@%) yields the memory address at which an item
  16058.       is stored.%@NL@%
  16059. %@NL@%
  16060. %@NL@%
  16061. You can perform four arithmetic operations on pointers:  %@NL@%
  16062. %@NL@%
  16063. %@NL@%
  16064.   1.  Adding a pointer and an integer%@NL@%
  16065. %@NL@%
  16066.   2.  Subtracting an integer from a pointer%@NL@%
  16067. %@NL@%
  16068.   3.  Subtracting two pointers%@NL@%
  16069. %@NL@%
  16070.   4.  Comparing two pointers%@NL@%
  16071. %@NL@%
  16072. %@NL@%
  16073. Pointer arithmetic operations are automatically scaled by the size of the
  16074. object pointed to. For instance, adding 1 to a pointer to a %@AB@%float%@AE@% item
  16075. causes the address stored in the pointer to be incremented four bytes, the
  16076. size of one %@AB@%float%@AE@% item.  %@NL@%
  16077. %@NL@%
  16078. QuickC 2.5 also supports based pointers, a highly advanced feature, that are
  16079. compatible with Microsoft C version 6.0. Please refer to your C 6.0
  16080. documentation for more information about based pointers and objects.  %@NL@%
  16081. %@NL@%
  16082. %@NL@%
  16083. %@NL@%
  16084. %@NL@%
  16085. %@NL@%
  16086. %@NL@%
  16087. %@CR:C6A-B0001   @%%@1@%%@AB@%Appendix B  C Library Guide%@AE@%%@EH@%%@NL@%
  16088. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16089. %@NL@%
  16090. This appendix outlines the features of the C run-time library provided with
  16091. QuickC. It does not intend to be a complete presentation of the complete C
  16092. run-time library. Instead, this appendix presents the most fundamental
  16093. routines, grouped by category so you can begin experimenting with C and with
  16094. QuickC.  %@NL@%
  16095. %@NL@%
  16096. Remember, use online help to get instant help on any topic of interest. The
  16097. online help system provided with QuickC provides complete reference
  16098. information for all C library functions, keywords, and preprocessor
  16099. directives.  %@NL@%
  16100. %@NL@%
  16101. %@NL@%
  16102. %@2@%%@CR:C6A-B0002   @%%@AB@%Overview of the C Run-Time Library%@AE@%%@EH@%%@NL@%
  16103. %@NL@%
  16104. At last count, the C run-time library contained over 400 functions to use in
  16105. C programs. This appendix describes the major categories of functions
  16106. included in the library and, within those categories, the fundamental
  16107. routines every C programmer should know.  %@NL@%
  16108. %@NL@%
  16109. The discussions of these categories give only a brief overview of the
  16110. capabilities of the run-time library. You can find a complete description of
  16111. the syntax and use of each routine in online help.  %@NL@%
  16112. %@NL@%
  16113. The routines in the C run-time library are divided into the following
  16114. categories:  %@NL@%
  16115. %@NL@%
  16116. %@AB@%Table B.1  %@AB@%C Run-Time Library Routines%@AE@%%@AE@%
  16117.  
  16118. %@TH: 131  7080 02 32 35 09 @%
  16119. Category                        Function Routines                  Page
  16120. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16121. %@AB@%Buffer Manipulation%@AE@%             memchr, memcmp, memcpy, memmove,   345
  16122.                                 memset                             
  16123.  
  16124. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16125.  
  16126. %@AB@%Character Classification%@AE@%        isalnum, isalpha, isascii,         346
  16127. %@AB@%and Conversion%@AE@%                  iscntrl, isdigit, isgraph,         
  16128.                                 islower, isprint, ispunct,         
  16129.                                 isspace, isupper, isxdigit,        
  16130.                                 tolower, toupper                   
  16131.  
  16132. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16133.  
  16134. %@AB@%Data Conversion%@AE@%                 atof, atoi, atol, itoa, ltoa,      348
  16135.                                 ultoa, strtod, strtol, strtoul     
  16136.  
  16137. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16138.  
  16139. %@AB@%Error Message%@AE@%                   assert, perror, strerror,          349
  16140.                                 _strerror                          
  16141.  
  16142. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16143.  
  16144. %@AB@%Graphics 1: Low-Level%@AE@%                                              350
  16145. %@AB@%                     Graphics%@AE@%                                      
  16146.  
  16147. Configure Mode and              _displaycursor, _getvideoconfig,   351
  16148.    Environment                  _setvideomode                      
  16149.  
  16150. Set Coordinates                 _getcurrentposition,               352
  16151.                                 _getphyscoord,_getviewcoord,       
  16152.                                 _getwindowcoord,                   
  16153.                                 _setcliprgn,_setvieworg,           
  16154.                                 _setviewport, _setwindow           
  16155.  
  16156. Set Palette                     _remapallpalette, remappallette,   354
  16157.                                 _selectpalette                     
  16158.  
  16159. Set Attributes                  _getbkcolor, _getcolor,            355
  16160.                                 _setbkcolor, _setcolor             
  16161.  
  16162. Output Images                   _arc, _clearscreen, _ellipse,      356
  16163.                                 _floodfill, _getpixel,             
  16164.                                 _lineto, _moveto, _pie,            
  16165.                                 _rectangle, _setpixel              
  16166.  
  16167. Output Text                     _displaycursor, _gettextcolor,     359
  16168.                                 _gettextcursor,                    
  16169.                                 _gettextposition, _outtext,        
  16170.                                 _settextposition,                  
  16171.                                 _settextcolor, _settextwindow      
  16172.  
  16173. Transfer Images                 _getimage, _imagesize, _putimage   361
  16174.  
  16175. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16176.  
  16177. %@AB@%Graphics 2: Presentation%@AE@%        _pg_chart, _pg_chartms,            362
  16178. %@AB@%                     Graphics%@AE@%   _pg_chartpie, _pg_chartscatter,    
  16179.                                 _pg_chartscatterms,                
  16180.                                 _pg_defaultchart, _pg_initchart    
  16181.  
  16182. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16183.  
  16184. %@AB@%Graphics 3: Font Display%@AE@%        _getfontinfo, _getgtextextent,     365
  16185.                                 _outgtext, _registerfonts,         
  16186.                                 _setfont, _unregisterfonts         
  16187.  
  16188. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16189.  
  16190. %@AB@%Input and Output%@AE@%                                                   367
  16191.  
  16192. Stream Routines                 clearerr, fclose, feof, ferror,    367
  16193.                                 fflush, fgetc, fgetpos, fgets,     
  16194.                                 fopen, fprintf, fputc, fputs,      
  16195.                                 fread, freopen, fscanf, fseek,     
  16196.                                 fsetpos, ftell, fwrite, getc,      
  16197.                                 getchar, gets, printf, putc,       
  16198.                                 putchar, puts, rewind, scanf,      
  16199.                                 sprintf, sscanf, tmpfile, tmpnam,  
  16200.                                 ungetc                             
  16201.  
  16202. Low-Level Routines              close, creat, eof, lseek, open,    373
  16203.                                 read, tell, write                  
  16204.  
  16205. Console and Port                cgets, cprintf, cputs, cscanf,     375
  16206.    I/O Routines                 getch, getche, kbhit,              
  16207.                                 putch, ungetch                     
  16208.  
  16209. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16210.  
  16211. %@AB@%Math%@AE@%                            abs, fabs, labs, acos, asin, atan,  377
  16212.                                 atan2, ceil, cos, cosh,            
  16213.                                 exp, floor, fmod, frexp, ldexp,    
  16214.                                 log, log10, modf, pow, rand,       
  16215.                                 srand, sin, sinh, sqrt, tan, tanh  
  16216.  
  16217. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16218.  
  16219. %@AB@%Memory Allocation%@AE@%               calloc, free, _ffree, hfree,       381
  16220.                                 _nfree, malloc, _fmalloc,          
  16221.                                 _nmalloc, realloc                  
  16222.  
  16223. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16224.  
  16225. %@AB@%Process Control%@AE@%                 abort, atexit, exit, _exit,        383
  16226.                                 system                             
  16227.  
  16228. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16229.  
  16230. %@AB@%Searching and Sorting%@AE@%           bsearch, lfind, lsearch, qsort     384
  16231.  
  16232. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16233.  
  16234. %@AB@%String Manipulation%@AE@%             strcat, strcpy, strdup, strncat,   385
  16235.                                 strncpy, strchr,                   
  16236.                                 strcspn, strpbrk, strrchr, strspn,  
  16237.                                 strstr, strcmp,                    
  16238.                                 strcmpi, stricmp, strncmp,         
  16239.                                 strnicmp, strlen, strlwr,          
  16240.                                 strupr, strnset, strset, strtok    
  16241.  
  16242. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16243.  
  16244. %@AB@%Time%@AE@%                            asctime, clock, ctime, difftime,   389
  16245.                                 ftime, gmtime,                     
  16246.                                 mktime, time                       
  16247.  
  16248. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16249.  
  16250. %@TE: 131  7080 02 32 35 09 @%
  16251.  
  16252. %@NL@%
  16253. %@2@%%@CR:C6A-B0003   @%%@AB@%Buffer-Manipulation Routines%@AE@%%@EH@%%@NL@%
  16254. %@NL@%
  16255. Buffer manipulation routines are used with areas of memory on a
  16256. character-by-character basis. Buffers are arrays of characters (bytes).
  16257. Unlike strings, however, they are not usually terminated with a null
  16258. character (%@AB@%\0%@AE@%).  %@NL@%
  16259. %@NL@%
  16260. %@AB@%memchr%@AE@% - Returns a pointer to the first occurrence, within a specified
  16261. number of characters, of a given character in the buffer.%@NL@%
  16262. %@NL@%
  16263. %@AB@%Include%@AE@%                           STRING.H
  16264.  
  16265. %@AB@%Prototype%@AE@%                         %@AB@%void *memchr( const void *%@AE@%%@AI@%buf%@AE@%%@AB@%,  int%@AE@% %@AI@%c%@AE@%%@AB@%, %@AE@%
  16266.                                   %@AB@%size_t%@AE@% %@AI@%count %@AE@%%@AB@%);%@AE@%
  16267.  
  16268. %@AB@%Arguments%@AE@%                         %@AI@%buf%@AE@%         Pointer to buffer
  16269.  
  16270.                                   %@AI@%c%@AE@%           Character to copy
  16271.  
  16272.                                   %@AI@%count%@AE@%       Number of characters
  16273.  
  16274. %@AB@%Returns%@AE@%                           A pointer to the location of %@AI@%c%@AE@% in %@AI@%buf%@AE@%  
  16275.                                   if successful;
  16276.  
  16277.                                   %@AB@%NULL%@AE@% if %@AI@%c%@AE@% is not within first %@AI@%count%@AE@% 
  16278.                                   bytes  of %@AI@%buf%@AE@%
  16279.  
  16280. ────────────────────────────────────────────────────────────────────────────
  16281. %@AB@%memcmp%@AE@% - Compares a specified number of characters from two buffers.%@NL@%
  16282. %@NL@%
  16283. %@AB@%Include%@AE@%                           STRING.H
  16284.  
  16285. %@AB@%Prototype%@AE@%                         %@AB@%int memcmp( const void *%@AE@%%@AI@%buf1%@AE@%%@AB@%,%@AE@%  %@AB@%const %@AE@%
  16286.                                   %@AB@%void%@AE@% *%@AI@%buf2%@AE@%%@AB@%, size_t %@AE@%%@AI@%count %@AE@%%@AB@%);%@AE@%
  16287.  
  16288. %@AB@%Arguments%@AE@%                         %@AI@%buf1%@AE@%        First buffer
  16289.  
  16290.                                   %@AI@%buf2%@AE@%        Second buffer
  16291.  
  16292.                                   %@AI@%count%@AE@%       Number of characters
  16293.  
  16294. %@AB@%Returns%@AE@%                           A negative value if %@AI@%buf1%@AE@% < %@AI@%buf2%@AE@%,  0 if %@AI@%%@AE@%
  16295.                                   %@AI@%buf1%@AE@% = %@AI@%buf2%@AE@%,
  16296.  
  16297.                                   a positive value if %@AI@%buf1%@AE@% > %@AI@%buf2%@AE@%
  16298.  
  16299. ────────────────────────────────────────────────────────────────────────────
  16300. %@AB@%memcpy%@AE@% - Copies a specified number of characters from one buffer to another.%@NL@%
  16301. %@NL@%
  16302. %@AB@%Include%@AE@%                           STRING.H
  16303.  
  16304. %@AB@%Prototype%@AE@%                         %@AB@%void%@AE@% %@AB@%*memcpy( void *%@AE@%%@AI@%dest%@AE@%%@AB@%,  const void *%@AE@%%@AI@%%@AE@%
  16305.                                   %@AI@%src%@AE@%%@AB@%, size_t %@AE@%%@AI@%count %@AE@%%@AB@%);%@AE@%
  16306.  
  16307. %@AB@%Arguments%@AE@%                         %@AI@%dest%@AE@%        New buffer
  16308.  
  16309.                                   %@AI@%src%@AE@%         Buffer to copy from
  16310.  
  16311.                                   %@AI@%count%@AE@%       Number of characters to copy
  16312.  
  16313. %@AB@%Returns%@AE@%                           A pointer to %@AI@%dest%@AE@%
  16314.  
  16315. ────────────────────────────────────────────────────────────────────────────
  16316. %@AB@%memmove%@AE@% - Copies a specified number of characters from one buffer to
  16317. another. When the source and target areas overlap, the %@AB@%memmove%@AE@% function is
  16318. guaranteed to properly copy the full source. %@NL@%
  16319. %@NL@%
  16320. %@AB@%Include%@AE@%                           STRING.H
  16321.  
  16322. %@AB@%Prototype%@AE@%                         %@AB@%void *memmove( void *%@AE@%%@AI@%dest%@AE@%%@AB@%,  const void *%@AE@%
  16323.                                   %@AI@%src%@AE@%%@AB@%, size_t %@AE@%%@AI@%count %@AE@%%@AB@%);%@AE@%
  16324.  
  16325. %@AB@%Arguments%@AE@%                         %@AI@%dest%@AE@%        Target object
  16326.  
  16327.                                   %@AI@%src%@AE@%         Source object
  16328.  
  16329.                                   %@AI@%count%@AE@%       Number of characters to copy
  16330.  
  16331. %@AB@%Returns%@AE@%                           The value of %@AI@%dest%@AE@%
  16332.  
  16333. ────────────────────────────────────────────────────────────────────────────
  16334. %@AB@%memset%@AE@% - Uses a given character to initialize a specified number of bytes in
  16335. the buffer.%@NL@%
  16336. %@NL@%
  16337. %@AB@%Include%@AE@%                           STRING.H
  16338.  
  16339. %@AB@%Prototype%@AE@%                         %@AB@%void *memset( void *%@AE@%%@AI@%dest%@AE@%%@AB@%,  int %@AE@%%@AI@%c%@AE@%%@AB@%, size_t%@AE@%
  16340.                                   %@AB@%%@AE@%%@AI@%count %@AE@%%@AB@%);%@AE@%
  16341.  
  16342. %@AB@%Arguments%@AE@%                         %@AI@%dest%@AE@%        Pointer to destination
  16343.  
  16344.                                   %@AI@%c%@AE@%           Character to set
  16345.  
  16346.                                   %@AI@%count%@AE@%       Number of characters
  16347.  
  16348. %@AB@%Returns%@AE@%                           A pointer to%@AI@% dest%@AE@%
  16349.  
  16350. %@NL@%
  16351. %@2@%%@CR:C6A-B0004   @%%@AB@%Character Classification and Conversion Routines%@AE@%%@EH@%%@NL@%
  16352. %@NL@%
  16353. The classification routines (%@AB@%is...%@AE@%) test a character and return a one (1) if
  16354. the character is in the set that the routine is testing for. The conversion
  16355. routines (%@AB@%to...%@AE@%) convert characters between uppercase and lowercase. These
  16356. routines are generally faster than writing a test expression such as the
  16357. following:  %@NL@%
  16358. %@NL@%
  16359. %@AS@%  if ((c >= 0) || c <= 0x7f))%@AE@%%@NL@%
  16360. %@NL@%
  16361. ────────────────────────────────────────────────────────────────────────────
  16362. %@AB@%isalnum, isalpha, isascii, iscntrl, isdigit, isgraph, islower, isprint,
  16363. %@AB@%ispunct, isspace, isupper, isxdigit%@AE@% These routines test a character for a
  16364. specified condition and return a nonzero value if the condition is true. - %@NL@%
  16365. %@NL@%
  16366. %@AB@%Include%@AE@%                           CTYPE.H
  16367.  
  16368. %@AB@%Prototypes%@AE@%                        %@AB@%int isalnum( int %@AE@%%@AI@%c %@AE@%%@AB@%);%@AE@%  (alphanumeric  
  16369.                                   character: A-Z, a-z, 0-9)
  16370.  
  16371.  
  16372.  
  16373. %@AB@%%@AE@%                                  int isalpha( int %@AI@%c %@AE@%%@AB@%);%@AE@%   (alphabetic 
  16374.                                   character: A-Z%@AB@%,%@AE@%  a-z)%@AB@%%@AE@%
  16375.  
  16376.  
  16377.  
  16378.                                   int isascii( int %@AI@%c %@AE@%%@AB@%);%@AE@%     (ASCII 
  16379.                                   character: 0x00-0x7F)%@AB@%%@AE@%
  16380.  
  16381.  
  16382.  
  16383.                                   int iscntrl( int %@AI@%c%@AE@%%@AB@% );%@AE@%    (control 
  16384.                                   character: 0x00-0x1F,  0x7F)%@AB@%%@AE@%
  16385.  
  16386.  
  16387.  
  16388.                                   int isdigit( int %@AI@%c %@AE@%%@AB@%);    %@AE@% (decimal 
  16389.                                   digit: 0-9)
  16390.  
  16391. %@AB@%%@AE@%
  16392.  
  16393.                                   int isgraph( int %@AI@%c%@AE@%%@AB@% );%@AE@%   (printable 
  16394.                                   character, not space:  0x21-0x7E)
  16395.  
  16396. %@AB@%%@AE@%
  16397.  
  16398.                                   int islower( int %@AI@%c %@AE@%%@AB@%); %@AE@%  (lowercase 
  16399.                                   letter: a-z)%@AB@%%@AE@%
  16400.  
  16401.  
  16402.  
  16403.                                   int isprint( int %@AI@%c %@AE@%%@AB@%);%@AE@%    (printable 
  16404.                                   character: 0x20-0x7E)%@AB@%%@AE@%
  16405.  
  16406.  
  16407.  
  16408.                                   int ispunct( int %@AI@%c %@AE@%%@AB@%);%@AE@%   (punctuation 
  16409.                                   character)%@AB@%%@AE@%
  16410.  
  16411.  
  16412.  
  16413.                                   int isspace( int %@AI@%c %@AE@%%@AB@%);%@AE@%    (white-space 
  16414.                                   character:  0x09-0x0D, 0x20)
  16415.  
  16416.  
  16417.  
  16418.                                   %@AB@%int isupper( int %@AE@%%@AI@%c %@AE@%%@AB@%);%@AE@%   (uppercase 
  16419.                                   letter: A-Z)%@AB@%%@AE@%
  16420.  
  16421.  
  16422.  
  16423.                                   int isxdigit( int %@AI@%c %@AE@%%@AB@%);%@AE@%   (hexadecimal 
  16424.                                   digit: A-F,  a-f, 0-9)
  16425.  
  16426. %@AB@%Argument%@AE@%                          %@AI@%c%@AE@%           Character to be tested
  16427.  
  16428. %@AB@%Returns%@AE@%                           A nonzero value if the condition is true
  16429.  
  16430. ────────────────────────────────────────────────────────────────────────────
  16431. %@AB@%tolower, toupper%@AE@% - These routines accept a character argument and return a
  16432. converted character. The %@AB@%tolower%@AE@% and %@AB@%toupper%@AE@% routines are also implemented
  16433. as functions. To use the function versions, you must do the following:%@NL@%
  16434. %@NL@%
  16435. %@NL@%
  16436.   ■   Include CTYPE.H if necessary for other macro definitions%@NL@%
  16437. %@NL@%
  16438.   ■   If CTYPE.H is included, give %@AB@%#undef%@AE@% directives for %@AB@%tolower%@AE@% and %@AB@%toupper%@AE@%%@NL@%
  16439. %@NL@%
  16440.   ■   Include STDLIB.H (which contains the function prototypes)%@NL@%
  16441. %@NL@%
  16442. %@NL@%
  16443. %@AB@%Include%@AE@%                           CTYPE.H
  16444.  
  16445. %@AB@%Prototypes%@AE@%                        %@AB@%int tolower( int %@AE@%%@AI@%c %@AE@%%@AB@%);%@AE@%
  16446.  
  16447.  
  16448.  
  16449.                                   int toupper( int %@AI@%c %@AE@%%@AB@%);%@AE@%
  16450.  
  16451. %@AB@%Argument%@AE@%                          %@AI@%c%@AE@%           Character to be converted
  16452.  
  16453. %@AB@%Returns%@AE@%                           tolower: the lowercase equivalent of %@AI@%c%@AE@%  
  16454.                                   only if %@AI@%c%@AE@% is an uppercase letter
  16455.  
  16456.                                   %@AB@%toupper%@AE@%: the uppercase equivalent of %@AI@%c%@AE@% 
  16457.                                   only if %@AI@%c%@AE@%  is a lowercase letter
  16458.  
  16459. %@NL@%
  16460. %@2@%%@CR:C6A-B0005   @%%@AB@%Data Conversion Routines%@AE@%%@EH@%%@NL@%
  16461. %@NL@%
  16462. The data conversion routines convert numbers to strings of ASCII characters
  16463. and vice versa.  %@NL@%
  16464. %@NL@%
  16465. ────────────────────────────────────────────────────────────────────────────
  16466. %@AB@%atof, atoi, atol%@AE@% - These ASCII-to-number routines convert an ASCII string to
  16467. a %@AB@%float%@AE@%, an %@AB@%integer%@AE@%, and a %@AB@%long%@AE@%, respectively.%@NL@%
  16468. %@NL@%
  16469. %@AB@%Include%@AE@%                           STDLIB.H or MATH.H (%@AB@%atof%@AE@%)
  16470.  
  16471.                                   STDLIB.H (%@AB@%atoi%@AE@%, %@AB@%atol%@AE@%)
  16472.  
  16473. %@AB@%Prototypes%@AE@%                        %@AB@%double atof( const char *%@AE@%%@AI@%string%@AE@%%@AB@%  );%@AE@%
  16474.  
  16475.  
  16476.  
  16477.                                   %@AB@%int atoi( const char%@AE@% %@AB@%*%@AE@%%@AI@%string %@AE@%%@AB@%);%@AE@%
  16478.  
  16479.  
  16480.  
  16481.                                   long atol( const char *%@AI@%string %@AE@%%@AB@%);%@AE@%
  16482.  
  16483. %@AB@%Argument%@AE@%                          %@AI@%string%@AE@%      String to be converted
  16484.  
  16485. %@AB@%Returns%@AE@%                           The converted string, or 0 if %@AI@%string%@AE@% 
  16486.                                   cannot  be converted
  16487.  
  16488. ────────────────────────────────────────────────────────────────────────────
  16489. %@AB@%itoa, ltoa, ultoa%@AE@% - These number-to-ASCII routines convert an integer, a
  16490. long value, or an unsigned long value to an ASCII string.%@NL@%
  16491. %@NL@%
  16492. %@AB@%Include%@AE@%                           STDLIB.H
  16493.  
  16494. %@AB@%Prototypes%@AE@%                        %@AB@%char * itoa( int %@AE@%%@AI@%value%@AE@%%@AB@%, char  *%@AE@%%@AI@%string%@AE@%%@AB@%, %@AE@%
  16495.                                   %@AB@%int %@AE@%%@AI@%radix %@AE@%%@AB@%);%@AE@%
  16496.  
  16497.  
  16498.  
  16499.                                   char * ltoa( long %@AI@%value%@AE@%%@AB@%, char *%@AE@%%@AI@%string%@AE@%%@AB@%,  %@AE@%
  16500.                                   %@AB@%int %@AE@%%@AI@%radix %@AE@%%@AB@%);%@AE@%
  16501.  
  16502.  
  16503.  
  16504.                                   char * ultoa( unsigned long %@AI@%value%@AE@%%@AB@%, char %@AE@%
  16505.                                   %@AB@%*%@AE@%%@AI@%string%@AE@%%@AB@%,  int %@AE@%%@AI@%radix%@AE@%%@AB@% );%@AE@%
  16506.  
  16507. %@AB@%Arguments%@AE@%                         %@AI@%value%@AE@%       Number to be converted
  16508.  
  16509.                                   %@AI@%string%@AE@%      String result
  16510.  
  16511.                                   %@AI@%radix%@AE@%       Number base of value
  16512.  
  16513. %@AB@%Returns%@AE@%                           A pointer to %@AI@%string%@AE@%; there is no error  
  16514.                                   return
  16515.  
  16516. ────────────────────────────────────────────────────────────────────────────
  16517. %@AB@%strtod, strtol, strtoul%@AE@% - These routines convert a string to a %@AB@%double%@AE@%, a
  16518. %@AB@%long%@AE@%, and an %@AB@%unsigned long%@AE@%, respectively.%@NL@%
  16519. %@NL@%
  16520. %@AB@%Include%@AE@%                           STDLIB.H
  16521.  
  16522. %@AB@%Prototypes%@AE@%                        %@AB@%double strtod( const char *%@AE@%%@AI@%nptr%@AE@%%@AB@%,  char %@AE@%
  16523.                                   %@AB@%**%@AE@%%@AI@%endptr %@AE@%%@AB@%);%@AE@%
  16524.  
  16525.  
  16526.  
  16527.                                   long strtol( const char *%@AI@%nptr%@AE@%%@AB@%, char **%@AE@%%@AI@%%@AE@%
  16528.                                   %@AI@%endptr%@AE@%%@AB@%,  int %@AE@%%@AI@%base%@AE@%%@AB@% );%@AE@%
  16529.  
  16530.  
  16531.  
  16532.                                   unsigned long strtoul( const char *%@AI@%nptr%@AE@%%@AB@%,%@AE@%
  16533.                                   %@AB@%char **%@AE@%%@AI@%endptr%@AE@%%@AB@%,  int %@AE@%%@AI@%base%@AE@%%@AB@% );%@AE@%
  16534.  
  16535. %@AB@%Arguments%@AE@%                         %@AI@%nptr%@AE@%        String to convert
  16536.  
  16537.                                   %@AI@%endptr%@AE@%      End of scan
  16538.  
  16539.                                   %@AI@%base%@AE@%        Number base to use
  16540.  
  16541. %@AB@%Returns%@AE@%                           %@AB@%strtod%@AE@%: the converted value; overflow 
  16542.                                   returns  %@AB@%HUGE_VAL%@AE@%,
  16543.  
  16544.                                   underflow returns 0
  16545.  
  16546.                                   %@AB@%strtol%@AE@%: the converted value; overflow 
  16547.                                   returns %@AB@%LONG_MAX%@AE@%  
  16548.  
  16549. %@AB@%%@AE@%                                  or%@AB@% LONG_MIN%@AE@%, depending on sign of 
  16550.                                   converted  value
  16551.  
  16552.                                   %@AB@%strtoul%@AE@%: the converted value if 
  16553.                                   successful, 0 if not, and
  16554.  
  16555.                                   %@AB@%ULONG_MAX%@AE@% on overflow
  16556.  
  16557. %@NL@%
  16558. %@2@%%@CR:C6A-B0006   @%%@AB@%Error Message Routines%@AE@%%@EH@%%@NL@%
  16559. %@NL@%
  16560. The routines in this category handle the display of error messages.  %@NL@%
  16561. %@NL@%
  16562. The %@AB@%assert%@AE@% macro is typically used to test for program logic errors; it
  16563. prints a message when a given "assertion" fails to hold true. Defining the
  16564. identifier %@AB@%NDEBUG%@AE@% to any value causes occurrences of %@AB@%assert%@AE@% to be disabled
  16565. in the source file, thus allowing you to turn off assertion checking without
  16566. modifying the source file.  %@NL@%
  16567. %@NL@%
  16568. The %@AB@%perror%@AE@% routine prints the system-error message, along with a
  16569. user-supplied message, for the last system-level call that produced an
  16570. error. The %@AB@%perror%@AE@% routine is declared in the include files STDLIB.H and
  16571. STDIO.H. The error number is obtained from the %@AB@%errno%@AE@% variable. The system
  16572. message is taken from the %@AB@%sys_errlist%@AE@% array.  %@NL@%
  16573. %@NL@%
  16574. The %@AB@%strerror%@AE@% and %@AB@%_strerror%@AE@% routines store error messages in a string.  %@NL@%
  16575. %@NL@%
  16576. ────────────────────────────────────────────────────────────────────────────
  16577. %@AB@%assert%@AE@% - Tests for logic error.%@NL@%
  16578. %@NL@%
  16579. %@AB@%Include%@AE@%                           ASSERT.H, STDIO.H
  16580.  
  16581. %@AB@%Prototype%@AE@%                         %@AB@%void assert(%@AE@%%@AI@% expression %@AE@%%@AB@%);%@AE@%
  16582.  
  16583. %@AB@%Argument%@AE@%                          %@AI@%expression%@AE@%  Expression to test
  16584.  
  16585. %@AB@%Returns%@AE@%                           Void
  16586.  
  16587. ────────────────────────────────────────────────────────────────────────────
  16588. %@AB@%perror%@AE@% - Prints error message.%@NL@%
  16589. %@NL@%
  16590. %@AB@%Include%@AE@%                           STDIO.H
  16591.  
  16592. %@AB@%Prototypes%@AE@%                        %@AB@%void perror( const char *%@AE@%%@AI@%string%@AE@%%@AB@%  );%@AE@%
  16593.  
  16594.                                   int %@AI@%errno%@AE@%%@AB@%;%@AE@%
  16595.  
  16596.                                   int %@AI@%sys_nerr%@AE@%%@AB@%;%@AE@%
  16597.  
  16598.                                   char *%@AI@%sys_errlist %@AE@%%@AB@%[%@AE@%%@AI@%sys_nerr%@AE@%%@AB@%];%@AE@%
  16599.  
  16600. %@AB@%Arguments%@AE@%                         %@AI@%string%@AE@%      User-supplied message
  16601.  
  16602.                                   %@AI@%errno%@AE@%       Error number
  16603.  
  16604.                                   %@AI@%sys_nerr%@AE@%    Number of system-error 
  16605.                                               messages
  16606.  
  16607.                                   %@AI@%sys_errlis%@AE@%  Array of error messages
  16608.                                   %@AI@%t%@AE@%           
  16609.  
  16610. %@AB@%Returns%@AE@%                           Void
  16611.  
  16612. ────────────────────────────────────────────────────────────────────────────
  16613. %@AB@%strerror, _strerror %@AE@% - Saves system-error message and optional user-error
  16614. message in string. The routine %@AB@%strerror%@AE@% is the ANSI-compatible version.%@NL@%
  16615. %@NL@%
  16616. %@AB@%Include%@AE@%                           STRING.H
  16617.  
  16618. %@AB@%Prototypes%@AE@%                        %@AB@%char *strerror( int %@AE@%%@AI@%errnum%@AE@%%@AB@%  );%@AE@%
  16619.  
  16620.                                   %@AB@%char *_strerror( char *%@AE@%%@AI@%string%@AE@%%@AB@% );%@AE@%
  16621.  
  16622.                                   %@AB@%int%@AE@% %@AI@%errno%@AE@%%@AB@%;%@AE@%
  16623.  
  16624.                                   %@AB@%int%@AE@% %@AI@%sys_nerr%@AE@%%@AB@%;%@AE@%
  16625.  
  16626.                                   %@AB@%char *%@AE@%%@AI@%sys_errlist %@AE@%%@AB@%[%@AE@%%@AI@%sys_nerr%@AE@%%@AB@%];%@AE@%
  16627.  
  16628. %@AB@%Arguments%@AE@%                         %@AI@%errnum%@AE@%      Error number
  16629.  
  16630.                                   %@AI@%string%@AE@%      User-supplied message
  16631.  
  16632.                                   %@AI@%errno%@AE@%       Error number
  16633.  
  16634.                                   %@AI@%sys_nerr%@AE@%    Number of system-error 
  16635.                                               messages
  16636.  
  16637.                                   %@AI@%sys_errlis%@AE@%  Array of error messages
  16638.                                   %@AI@%t%@AE@%           
  16639.  
  16640. %@AB@%Returns%@AE@%                           A pointer to the error-message string
  16641.  
  16642. %@NL@%
  16643. %@2@%%@CR:C6A-B0007   @%%@AB@%Graphics 1: Low-Level Graphics Routines%@AE@%%@EH@%%@NL@%
  16644. %@NL@%
  16645. The low-level graphics routines provide line, figure, and pixel manipulation
  16646. capabilities. The routines for presentation graphics are described in the
  16647. next section. The routines for displaying fonts follow the presentation
  16648. graphics section.  %@NL@%
  16649. %@NL@%
  16650. The graphics package supports the IBM(R) (and compatible) Enhanced Graphics
  16651. Adapter (EGA), Color Graphics Adapter (CGA), certain operating modes of the
  16652. Video Graphics Array (VGA) hardware configurations, and the MCGA (Multicolor
  16653. Graphics Array). The graphics package also supports the Hercules Graphics
  16654. Card, Graphics Card Plus, InColor Card, and 100 percent compatible cards, as
  16655. well as the special Olivetti(R) modes available on AT&T(R) computers.  %@NL@%
  16656. %@NL@%
  16657. The low-level graphics routines can be divided into the seven categories
  16658. listed below, corresponding to the different tasks involved with creating
  16659. and manipulating graphic objects:  %@NL@%
  16660. %@NL@%
  16661. %@AB@%Category%@AE@%                          %@AB@%Task%@AE@%
  16662. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  16663. Configure mode and environment    Selects the proper display mode for the 
  16664.                                   hardware and establishes memory areas 
  16665.                                   for writing and displaying images
  16666.  
  16667. Set coordinates                   Specifies the logical origin and the 
  16668.                                   active display area within the screen
  16669.  
  16670. Set palette                       Specifies a palette mapping
  16671.  
  16672. Set attributes                    Specifies background and foreground 
  16673.                                   colors and mask and line styles
  16674.  
  16675. Output images                     Draws and fills figures on the screen
  16676.  
  16677. Output text                       Writes text to the screen
  16678.  
  16679. Transfer images                   Stores images in memory and retrieves 
  16680.                                   them
  16681.  
  16682. %@NL@%
  16683. %@4@%%@AB@%Configure Mode and Environment%@AE@%%@EH@%%@NL@%
  16684. %@NL@%
  16685. The configure category of functions sets the status of the cursor, sets
  16686. active and visual pages, and determines and sets video display modes.  %@NL@%
  16687. %@NL@%
  16688. The %@AB@%_setvideomode%@AE@% and %@AB@%_getvideoconfig%@AE@% functions are generally used at the
  16689. very beginning of a graphics program.  %@NL@%
  16690. %@NL@%
  16691. ────────────────────────────────────────────────────────────────────────────
  16692. %@AB@%_displaycursor%@AE@% - Determines whether the cursor will be left on or turned off
  16693. on exit from graphics routines.%@NL@%
  16694. %@NL@%
  16695. %@AB@%Include%@AE@%                           GRAPH.H
  16696.  
  16697. %@AB@%Prototype%@AE@%                         %@AB@%short _far _displaycursor( short %@AE@%%@AI@%toggle %@AE@%
  16698.                                   %@AI@%%@AE@%%@AB@%);%@AE@%
  16699.  
  16700. %@AB@%Argument%@AE@%                          %@AI@%toggle%@AE@%      Cursor state (%@AB@%_GCURSORON%@AE@%,%@AB@%  %@AE@%
  16701.                                               %@AB@%_GCURSOROFF%@AE@%  )
  16702.  
  16703. %@AB@%Returns%@AE@%                           The previous value of toggle
  16704.  
  16705. ────────────────────────────────────────────────────────────────────────────
  16706. %@AB@%_getvideoconfig%@AE@% - Obtains status of current graphics environment.%@NL@%
  16707. %@NL@%
  16708. %@AB@%Include%@AE@%                           GRAPH.H
  16709.  
  16710. %@AB@%Prototype%@AE@%                         %@AB@%struct videoconfig _far * _far %@AE@%
  16711.                                   %@AB@%_getvideoconfig%@AE@%
  16712.  
  16713.                                   ( struct videoconfig _far *%@AI@%config %@AE@%%@AB@%);%@AE@%
  16714.  
  16715. %@AB@%Argument%@AE@%                          %@AI@%config%@AE@%      Configuration information
  16716.  
  16717. %@AB@%Returns%@AE@%                           The configuration information as a %@AB@%%@AE@%
  16718.                                   %@AB@%videoconfig%@AE@%  structure
  16719.  
  16720. ────────────────────────────────────────────────────────────────────────────
  16721. %@AB@%_setvideomode%@AE@% - Selects screen display mode.%@NL@%
  16722. %@NL@%
  16723. %@AB@%Include%@AE@%                           GRAPH.H
  16724.  
  16725. %@AB@%Prototype%@AE@%                         %@AB@%short _far _setvideomode( short %@AE@%%@AI@%mode%@AE@%%@AB@% );%@AE@%
  16726.  
  16727. %@AB@%Argument%@AE@%                          %@AI@%mode%@AE@%        Desired mode (%@AB@%_DEFAULTMODE%@AE@%,%@AB@% %@AE@%
  16728.                                               %@AB@%_TEXTBW40%@AE@%,%@AB@%%@AE@%
  16729.  
  16730.                                   _TEXTC40,%@AB@% _TEXTBW80%@AE@%,%@AB@% _TEXTC80%@AE@%,%@AB@% %@AE@%
  16731.                                   %@AB@%_MRES4COLOR%@AE@%,
  16732.  
  16733.                                   %@AB@%_MRESNOCOLOR%@AE@%,%@AB@% _HRESBW%@AE@%,%@AB@% _TEXTMONO%@AE@%,%@AB@%%@AE@%
  16734.  
  16735.                                   _HERCMONO, %@AB@%_MRES16COLOR%@AE@%,%@AB@% _HRES16COLOR%@AE@%,%@AB@%%@AE@%
  16736.  
  16737.                                   _ERESNOCOLOR,%@AB@% _ERESCOLOR%@AE@%,%@AB@% _VRES2COLOR%@AE@%,%@AB@%%@AE@%
  16738.  
  16739.                                   _VRES16COLOR,%@AB@% _MRES256COLOR%@AE@%,%@AB@% _ORESCOLOR%@AE@%%@AI@%,%@AE@%
  16740.  
  16741.                                   %@AB@%_MAXRESMODE%@AE@%, %@AB@%_MAXCOLORMODE%@AE@%)
  16742.  
  16743. %@AB@%Returns%@AE@%                           A nonzero value if successful, 0 if not
  16744.  
  16745. %@NL@%
  16746. %@4@%%@AB@%Set Coordinates%@AE@%%@EH@%%@NL@%
  16747. %@NL@%
  16748. The Microsoft C graphics routines recognize three sets of coordinates:  %@NL@%
  16749. %@NL@%
  16750. %@NL@%
  16751.   1.  Window coordinates defined with real-number values that are mapped to
  16752.       a specified viewport%@NL@%
  16753. %@NL@%
  16754.   2.  Viewport coordinates defined by the application (viewport coordinates)%@NL@%
  16755. %@NL@%
  16756.   3.  Fixed physical coordinates determined by the hardware and display
  16757.       configuration of the user's environment (physical coordinates)%@NL@%
  16758. %@NL@%
  16759. %@NL@%
  16760. The functions in this category alter the coordinate systems and provide a
  16761. means to translate coordinates between the various systems.  %@NL@%
  16762. %@NL@%
  16763. Most of these routines have two or three forms. The functions are listed by
  16764. the "base" name, without a suffix. Note, though, that function names that
  16765. end with a %@AB@%_w%@AE@%, such as %@AB@%_getcurrentposition_w%@AE@%, use the window-coordinate
  16766. system. Those that end with a %@AB@%_wxy%@AE@%, such as %@AB@%_getviewcoord_wxy%@AE@%, use the
  16767. window-coordinate system and a %@AB@%_wxycoord%@AE@% structure to define the
  16768. coordinates.  %@NL@%
  16769. %@NL@%
  16770. The default viewport-coordinate system is identical to the physical one. The
  16771. physical origin (0, 0) is always in the upper left corner of the display.
  16772. The %@AI@%x%@AE@% axis extends in the positive direction left to right, and the %@AI@%y%@AE@% axis
  16773. extends in the positive direction top to bottom.  %@NL@%
  16774. %@NL@%
  16775. The dimensions of the %@AI@%x%@AE@% and %@AI@%y%@AE@% axes depend upon the hardware display
  16776. configuration and the selected mode. These values are accessible at run time
  16777. by examining the %@AB@%numxpixels%@AE@% and %@AB@%numypixels%@AE@% fields of the %@AB@%videoconfig%@AE@%
  16778. structure returned by %@AB@%_getvideoconfig%@AE@%.  %@NL@%
  16779. %@NL@%
  16780. ────────────────────────────────────────────────────────────────────────────
  16781. %@AB@%_getcurrentposition%@AE@% - Obtains the coordinates of the current graphic-output
  16782. position. The %@AB@%_getcurrentposition%@AE@% function returns the position as an
  16783. %@AB@%xycoord%@AE@% structure and the %@AB@%_getcurrentposition_w%@AE@% function returns the
  16784. position as a %@AB@% _wxycoord%@AE@% structure.%@NL@%
  16785. %@NL@%
  16786. %@AB@%Include%@AE@%                           GRAPH.H
  16787.  
  16788. %@AB@%Prototypes%@AE@%                        %@AB@%struct xycoord _far _getcurrentposition(%@AE@%
  16789.                                   %@AB@%void );%@AE@%
  16790.  
  16791.  
  16792.  
  16793.                                   struct _wxycoord _far 
  16794.                                   _getcurrentposition_w( void );
  16795.  
  16796. %@AB@%Arguments%@AE@%                         None
  16797.  
  16798. %@AB@%Returns%@AE@%                           %@AB@%_getcurrentposition%@AE@%: the coordinates of 
  16799.                                   the current position as
  16800.  
  16801.                                   an %@AB@%xycoord%@AE@% structure
  16802.  
  16803.                                   %@AB@%_getcurrentposition_w%@AE@%: the coordinates 
  16804.                                   of the current position
  16805.  
  16806.                                   as a %@AB@%_wxycoord%@AE@% structure
  16807.  
  16808. ────────────────────────────────────────────────────────────────────────────
  16809. %@AB@%_getphyscoord%@AE@% - Converts viewport coordinates to physical coordinates.%@NL@%
  16810. %@NL@%
  16811. %@AB@%Include%@AE@%                           GRAPH.H
  16812.  
  16813. %@AB@%Prototype%@AE@%                         %@AB@%struct xycoord _far _getphyscoord( short%@AE@%
  16814.                                   %@AB@%%@AE@%%@AI@%x%@AE@%%@AB@%, short %@AE@%%@AI@%y%@AE@%%@AB@% );%@AE@%
  16815.  
  16816. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%, %@AI@%y%@AE@%        View point to translate
  16817.  
  16818. %@AB@%Returns%@AE@%                           A pair of physical coordinates as an %@AB@%%@AE@%
  16819.                                   %@AB@%xycoord%@AE@%  structure
  16820.  
  16821. ────────────────────────────────────────────────────────────────────────────
  16822. %@AB@%_getviewcoord %@AE@% - Converts specified coordinates to viewport coordinates.%@NL@%
  16823. %@NL@%
  16824. %@AB@%Include%@AE@%                           GRAPH.H
  16825.  
  16826. %@AB@%Prototypes%@AE@%                        %@AB@%struct xycoord _far _getviewcoord( short%@AE@%
  16827.                                   %@AB@%%@AE@%%@AI@%x%@AE@%%@AB@%, short  );%@AE@%
  16828.  
  16829.  
  16830.  
  16831.                                   struct xycoord _far _getviewcoord_w( 
  16832.                                   double %@AI@%wx%@AE@%%@AB@%, double %@AE@%%@AI@%wy  %@AE@%%@AB@%);%@AE@%
  16833.  
  16834.  
  16835.  
  16836.                                   struct xycoord _far _getviewcoord_wxy( 
  16837.                                   struct _wxycoord _far
  16838.  
  16839.                                   *%@AI@%pwxy1%@AE@%%@AB@% );%@AE@%
  16840.  
  16841. %@AB@%Arguments%@AE@%                         %@AI@%x%@AE@%, %@AI@%y%@AE@%        Physical point to translate
  16842.  
  16843.                                   %@AI@%wx%@AE@%, %@AI@%wy%@AE@%      Window-coordinate point to 
  16844.                                               translate
  16845.  
  16846.                                   %@AI@%pwxy1%@AE@%       Window-coordinate point to 
  16847.                                               translate
  16848.  
  16849. %@AB@%Returns%@AE@%                           A pair of logical coordinates as an %@AB@%%@AE@%
  16850.                                   %@AB@%xycoord%@AE@%  structure
  16851.  
  16852. ────────────────────────────────────────────────────────────────────────────
  16853. %@AB@%_getwindowcoord%@AE@% - Converts physical coordinates to window coordinates.%@NL@%
  16854. %@NL@%
  16855. %@AB@%Include%@AE@%                           GRAPH.H
  16856.  
  16857. %@AB@%Prototype%@AE@%                         %@AB@%struct _wxycoord _far _getwindowcoord( %@AE@%
  16858.                                   %@AB@%short  %@AE@%%@AI@%x%@AE@%%@AB@%, short %@AE@%%@AI@%y%@AE@%%@AB@% );%@AE@%
  16859.  
  16860. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%, %@AI@%y%@AE@%        Physical point to translate
  16861.  
  16862. %@AB@%Returns%@AE@%                           A pair of window coordinates as a %@AB@%%@AE@%
  16863.                                   %@AB@%_wxycoord%@AE@%  structure
  16864.  
  16865. ────────────────────────────────────────────────────────────────────────────
  16866. %@AB@%_setcliprgn%@AE@% - Limits graphic output to part of the screen.%@NL@%
  16867. %@NL@%
  16868. %@AB@%Include%@AE@%                           GRAPH.H
  16869.  
  16870. %@AB@%Prototype%@AE@%                         %@AB@%void _far _setcliprgn( short %@AE@%%@AI@%x1%@AE@%%@AB@%, short  %@AE@%
  16871.                                   %@AI@%y1%@AE@%%@AB@%, short %@AE@%%@AI@%x2%@AE@%%@AB@%, short %@AE@%%@AI@%y2 %@AE@%%@AB@%);%@AE@%
  16872.  
  16873. %@AB@%Arguments%@AE@%                         %@AI@%x1%@AE@%,%@AI@% y1%@AE@%      Upper left corner of clip  
  16874.                                               region
  16875.  
  16876.                                   %@AI@%x2, y2%@AE@%      Lower right corner of clip 
  16877.                                               region
  16878.  
  16879. %@AB@%Returns%@AE@%                           Void
  16880.  
  16881. ────────────────────────────────────────────────────────────────────────────
  16882. %@AB@%_setvieworg%@AE@% - Positions the logical origin.%@NL@%
  16883. %@NL@%
  16884. %@AB@%Include%@AE@%                           GRAPH.H
  16885.  
  16886. %@AB@%Prototype%@AE@%                         %@AB@%struct xycoord _far _setvieworg( short %@AE@%%@AI@%x%@AE@%
  16887.                                   %@AB@%,  short %@AE@%%@AI@%y %@AE@%%@AB@%);%@AE@%
  16888.  
  16889. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%, %@AI@%y%@AE@%        New origin point
  16890.  
  16891. %@AB@%Returns%@AE@%                           The physical coordinates of the previous
  16892.                                   viewport  origin in an
  16893.  
  16894.                                   %@AB@%xycoord%@AE@% structure
  16895.  
  16896. ────────────────────────────────────────────────────────────────────────────
  16897. %@AB@%_setviewport%@AE@% - Limits graphic output and positions the logical origin within
  16898. a limited area.%@NL@%
  16899. %@NL@%
  16900. %@AB@%Include%@AE@%                           GRAPH.H
  16901.  
  16902. %@AB@%Prototype%@AE@%                         %@AB@%void _far _setviewport( short %@AE@%%@AI@%x1%@AE@%%@AB@%,  short%@AE@%
  16903.                                   %@AB@%%@AE@%%@AI@%y1%@AE@%%@AB@%, short %@AE@%%@AI@%x2%@AE@%%@AB@%, short %@AE@%%@AI@%y2%@AE@%%@AB@% );%@AE@%
  16904.  
  16905. %@AB@%Arguments%@AE@%                         %@AI@%x1%@AE@%, %@AI@%y1%@AE@%      Upper left corner of window
  16906.  
  16907.                                   %@AI@%x2%@AE@%, %@AI@%y2%@AE@%      Lower right corner of window
  16908.  
  16909. %@AB@%Returns%@AE@%                           Void
  16910.  
  16911. ────────────────────────────────────────────────────────────────────────────
  16912. %@AB@%_setwindow%@AE@% - Defines a window-coordinate system.%@NL@%
  16913. %@NL@%
  16914. %@AB@%Include%@AE@%                           GRAPH.H
  16915.  
  16916. %@AB@%Prototype%@AE@%                         %@AB@%void _far _setwindow( short %@AE@%%@AI@%finvert%@AE@%%@AB@%,  %@AE@%
  16917.                                   %@AB@%double %@AE@%%@AI@%wx1%@AE@%%@AB@%, double %@AE@%%@AI@%wy1%@AE@%%@AB@%,%@AE@%
  16918.  
  16919.                                   double %@AI@%wx2%@AE@%%@AB@%, double %@AE@%%@AI@%wy2%@AE@%%@AB@% );%@AE@%
  16920.  
  16921. %@AB@%Arguments%@AE@%                         %@AI@%wx1%@AE@%,%@AI@% wy1%@AE@%    Upper left corner of  window
  16922.  
  16923.                                   %@AI@%wx2%@AE@%,%@AI@% wy2%@AE@%    Lower right corner of window
  16924.  
  16925.                                   %@AI@%finvert%@AE@%     Invert flag  (TRUE, FALSE)
  16926.  
  16927. %@AB@%Returns%@AE@%                           Void
  16928.  
  16929. %@NL@%
  16930. %@4@%%@AB@%Set Palette%@AE@%%@EH@%%@NL@%
  16931. %@NL@%
  16932. A screen pixel can be represented as a one-, two-, or four-bit value,
  16933. depending on the particular mode. The byte representation is called the
  16934. "color value."  %@NL@%
  16935. %@NL@%
  16936. Each color that can be displayed is represented by a unique ordinal value
  16937. called a "color index." A palette is simply a mapping of the actual display
  16938. colors to the legal values.  %@NL@%
  16939. %@NL@%
  16940. ────────────────────────────────────────────────────────────────────────────
  16941. %@AB@%_remapallpalette, _remappalette%@AE@% - The %@AB@%_remapallpalette%@AE@% routine assigns
  16942. colors to all color values. The %@AB@%_remappalette%@AE@% routine assigns color indexes
  16943. to selected color values.%@NL@%
  16944. %@NL@%
  16945. %@AB@%Include%@AE@%                           GRAPH.H
  16946.  
  16947. %@AB@%Prototypes%@AE@%                        %@AB@%short _far _remapallpalette( long _far *%@AE@%
  16948.                                   %@AI@%colors%@AE@%%@AB@%  );%@AE@%
  16949.  
  16950.  
  16951.  
  16952.                                   long _far _remappalette( short %@AI@%index%@AE@%%@AB@%, %@AE@%
  16953.                                   %@AB@%long %@AE@%%@AI@%color%@AE@%%@AB@% );%@AE@%
  16954.  
  16955.  
  16956.  
  16957. Arguments                         %@AI@%colors%@AE@%      Color value array: %@AB@%(_BLACK%@AE@%, 
  16958.                                               %@AB@%_BLUE%@AE@%, %@AB@%_GREEN,%@AE@%
  16959.  
  16960.                                   _CYAN, _RED,%@AB@% _MAGENTA%@AE@%,%@AB@% _BROWN%@AE@%,%@AB@%  _WHITE%@AE@%,
  16961.  
  16962. %@AB@%%@AE@%                                  _GRAY, %@AB@%_LIGHTBLUE, ,_LIGHTGREEN,%@AE@%
  16963.  
  16964.                                   _LIGHTCYAN, %@AB@%_LIGHTRED, _LIGHTMAGENTA,%@AE@%
  16965.  
  16966.                                   _LIGHTYELL  %@AB@%_BRIGHTWHITE)%@AE@%
  16967.                                   OW,         
  16968.  
  16969.                                   %@AI@%index%@AE@%       Color index to reassign
  16970.  
  16971.                                   %@AI@%color%@AE@%       Color value to assign color 
  16972.                                               index
  16973.  
  16974. %@AB@%Returns%@AE@%                           %@AB@%_remapallpalette:%@AE@%  0 if successful, -1  
  16975.                                   if not
  16976.  
  16977.                                   %@AB@%_remappalette:%@AE@%  the previous color value
  16978.                                   of the index argument
  16979.  
  16980.                                   if successful, -1 if not
  16981.  
  16982. ────────────────────────────────────────────────────────────────────────────
  16983. %@AB@%_selectpalette%@AE@% - Selects a predefined palette.%@NL@%
  16984. %@NL@%
  16985. %@AB@%Include%@AE@%                           GRAPH.H
  16986.  
  16987. %@AB@%Prototype%@AE@%                         %@AB@%short _far _selectpalette( short %@AE@%%@AI@%number %@AE@%
  16988.                                   %@AI@%%@AE@%%@AB@%);%@AE@%
  16989.  
  16990. %@AB@%Argument%@AE@%                          %@AI@%number%@AE@%      Palette number
  16991.  
  16992. %@AB@%Returns%@AE@%                           The value of the previous palette
  16993.  
  16994. %@NL@%
  16995. %@4@%%@AB@%Set Attributes%@AE@%%@EH@%%@NL@%
  16996. %@NL@%
  16997. Attributes are characteristics (color, fill pattern, or line style) that can
  16998. be specified for low-level graphics routines.  %@NL@%
  16999. %@NL@%
  17000. A fill mask is an 8-by-8-bit template array, with each bit representing a
  17001. pixel. If a bit is 0, the pixel in memory is left untouched: the mask is
  17002. transparent to that pixel. If a bit is 1, the pixel is assigned the current
  17003. color value. The template is repeated over the entire fill area.  %@NL@%
  17004. %@NL@%
  17005. A line style is a 16-bit template buffer, with each bit corresponding to a
  17006. pixel. If a bit is 0, the pixel is set to the current background color. If a
  17007. bit is 1, the pixel is set to the current color. The template is repeated
  17008. for the length of the line.  %@NL@%
  17009. %@NL@%
  17010. ────────────────────────────────────────────────────────────────────────────
  17011. %@AB@%_getbkcolor%@AE@% - Reports the current background color.%@NL@%
  17012. %@NL@%
  17013. %@AB@%Include%@AE@%                           GRAPH.H
  17014.  
  17015. %@AB@%Prototype%@AE@%                         %@AB@%long _far _getbkcolor( void );%@AE@%
  17016.  
  17017. %@AB@%Arguments%@AE@%                         None
  17018.  
  17019. %@AB@%Returns%@AE@%                           The current background color
  17020.  
  17021. ────────────────────────────────────────────────────────────────────────────
  17022. %@AB@%_getcolor%@AE@% - Obtains the current color.%@NL@%
  17023. %@NL@%
  17024. %@AB@%Include%@AE@%                           GRAPH.H
  17025.  
  17026. %@AB@%Prototype%@AE@%                         %@AB@%short _far _getcolor( void );%@AE@%
  17027.  
  17028. %@AB@%Arguments%@AE@%                         None
  17029.  
  17030. %@AB@%Returns%@AE@%                           The current color
  17031.  
  17032. ────────────────────────────────────────────────────────────────────────────
  17033. %@AB@%_setbkcolor%@AE@% - Sets the current background color.%@NL@%
  17034. %@NL@%
  17035. %@AB@%Include%@AE@%                           GRAPH.H
  17036.  
  17037. %@AB@%Prototype%@AE@%                         %@AB@%long _far _setbkcolor( long %@AE@%%@AI@%color %@AE@%%@AB@%);%@AE@%
  17038.  
  17039. %@AB@%Argument%@AE@%                          %@AI@%color%@AE@%       Desired color value
  17040.  
  17041. %@AB@%Returns%@AE@%                           The color value of the previous 
  17042.                                   background color
  17043.  
  17044. ────────────────────────────────────────────────────────────────────────────
  17045. %@AB@%_setcolor%@AE@% - Sets the current color.%@NL@%
  17046. %@NL@%
  17047. %@AB@%Include%@AE@%                           GRAPH.H
  17048.  
  17049. %@AB@%Prototype%@AE@%                         %@AB@%short _far _setcolor( short %@AE@%%@AI@%color %@AE@%%@AB@%);%@AE@%
  17050.  
  17051. %@AB@%Argument%@AE@%                          %@AI@%color%@AE@%       Desired color index
  17052.  
  17053. %@AB@%Returns%@AE@%                           The previous color
  17054.  
  17055. %@NL@%
  17056. %@4@%%@AB@%Output Images%@AE@%%@EH@%%@NL@%
  17057. %@NL@%
  17058. These routines display graphic elements (arcs, lines, pixels, etc.) on the
  17059. screen.  %@NL@%
  17060. %@NL@%
  17061. Circular figures such as arcs and ellipses are centered within a "bounding
  17062. rectangle," specified by two points that define the diagonally opposed
  17063. corners of the rectangle. The center of the rectangle becomes the center of
  17064. the figure, and the rectangle's borders determine the size of the figure.  %@NL@%
  17065. %@NL@%
  17066. Most of these routines have two or three forms. The functions are listed by
  17067. the "base" name, without a suffix. Note, though, that function names that
  17068. end with a %@AB@%_w%@AE@%, such as %@AB@%_arc_w%@AE@%, use the window coordinate system. Those that
  17069. end with a %@AB@%_wxy%@AE@%, such as %@AB@%_ellipse_wxy%@AE@%, use the window coordinate system and
  17070. a %@AB@% _wxycoord%@AE@% structure to define the coordinates.  %@NL@%
  17071. %@NL@%
  17072. ────────────────────────────────────────────────────────────────────────────
  17073. %@AB@%_arc %@AE@% - Draws an arc.%@NL@%
  17074. %@NL@%
  17075. %@AB@%Include%@AE@%                           GRAPH.H
  17076.  
  17077. %@AB@%Prototypes%@AE@%                        %@AB@%short _far _arc( short %@AE@%%@AI@%x1%@AE@%%@AB@%, short  %@AE@%%@AI@%y1%@AE@%%@AB@%, %@AE@%
  17078.                                   %@AB@%short %@AE@%%@AI@%x2%@AE@%%@AB@%, short %@AE@%%@AI@%y2%@AE@%%@AB@%,%@AE@%
  17079.  
  17080.                                   short %@AI@%x3%@AE@%%@AB@%, short %@AE@%%@AI@%y3%@AE@%%@AB@%, short %@AE@%%@AI@%x4%@AE@%%@AB@%, short %@AE@%%@AI@%y4  %@AE@%
  17081.                                   %@AB@%);%@AE@%
  17082.  
  17083.  
  17084.  
  17085.                                   short _far _arc_wxy( struct _wxycoord %@AI@%%@AE@%
  17086.                                   %@AI@%pwxy1%@AE@%%@AB@%,%@AE@%
  17087.  
  17088.                                   struct _wxycoord*%@AI@%pwxy2%@AE@%%@AB@%, struct %@AE@%
  17089.                                   %@AB@%_wxycoord*%@AE@%%@AI@%pwxy3%@AE@%%@AB@%,  %@AE@%
  17090.  
  17091.                                   struct _wxycoord*%@AI@%pwxy4 %@AE@%%@AB@%);%@AE@%
  17092.  
  17093. %@AB@%Arguments%@AE@%                         %@AI@%x1%@AE@%, %@AI@%y1%@AE@%      Upper left corner of 
  17094.                                               bounding  rectangle
  17095.  
  17096.                                   %@AI@%x2%@AE@%,%@AI@% y2%@AE@%      Lower right corner of 
  17097.                                               bounding rectangle
  17098.  
  17099.                                   %@AI@%x%@AE@%3,%@AI@% y3%@AE@%      Start vector
  17100.  
  17101.                                   %@AI@%x4%@AE@%,%@AI@% y4%@AE@%      End vector
  17102.  
  17103.                                   %@AI@%pwxy1%@AE@%       Upper left corner of 
  17104.                                               bounding rectangle
  17105.  
  17106.                                   %@AI@%pwxy2%@AE@%       Lower right corner of 
  17107.                                               bounding rectangle
  17108.  
  17109.                                   %@AI@%pwxy3%@AE@%       Start vector
  17110.  
  17111.                                   %@AI@%pwxy4%@AE@%       End vector
  17112.  
  17113. %@AB@%Returns%@AE@%                           A nonzero value if the arc is drawn 
  17114.                                   successfully,  0 if not
  17115.  
  17116. ────────────────────────────────────────────────────────────────────────────
  17117. %@AB@%_clearscreen%@AE@% - Erases the screen and fills it with the current background
  17118. color.%@NL@%
  17119. %@NL@%
  17120. %@AB@%Include%@AE@%                           GRAPH.H
  17121.  
  17122. %@AB@%Prototype%@AE@%                         %@AB@%void _far _clearscreen( short %@AE@%%@AI@%area %@AE@%%@AB@%);%@AE@%
  17123.  
  17124. %@AB@%Argument%@AE@%                          %@AI@%area%@AE@%        Target area (%@AB@%_GCLEARSCREEN%@AE@%,%@AB@% %@AE@%
  17125.                                               %@AB@%_GVIEWPORT%@AE@%,
  17126.  
  17127.                                   %@AB@% _GWINDOW%@AE@%)
  17128.  
  17129. %@AB@%Returns%@AE@%                           Void
  17130.  
  17131. ────────────────────────────────────────────────────────────────────────────
  17132. %@AB@%_ellipse %@AE@% - Draws an ellipse.%@NL@%
  17133. %@NL@%
  17134. %@AB@%Include%@AE@%                           GRAPH.H
  17135.  
  17136. %@AB@%Prototypes%@AE@%                        %@AB@%short _far _ellipse( short %@AE@%%@AI@%control%@AE@%%@AB@%,  %@AE@%
  17137.                                   %@AB@%short %@AE@%%@AI@%x1%@AE@%%@AB@%, short %@AE@%%@AI@%y1%@AE@%%@AB@%,%@AE@%
  17138.  
  17139.                                   short %@AI@%x2%@AE@%%@AB@%, short %@AE@%%@AI@%y2 %@AE@%%@AB@%);%@AE@%
  17140.  
  17141.  
  17142.  
  17143.                                   short _far _ellipse_w( short %@AI@%control%@AE@%%@AB@%, %@AE@%
  17144.                                   %@AB@%double %@AE@%%@AI@%wx1%@AE@%%@AB@%,  double %@AE@%%@AI@%wy1%@AE@%%@AB@%,%@AE@%
  17145.  
  17146.                                   double %@AI@%wx2%@AE@%%@AB@%, double %@AE@%%@AI@%wy2 %@AE@%%@AB@%);%@AE@%
  17147.  
  17148.  
  17149.  
  17150.                                   short _far _ellipse_wxy( short %@AI@%control%@AE@%%@AB@%, %@AE@%
  17151.                                   %@AB@%struct _wxycoord*  %@AE@%%@AI@%pwxy1%@AE@%%@AB@%,%@AE@%
  17152.  
  17153.                                   struct _wxycoord*%@AI@%pwxy2%@AE@%%@AB@% );%@AE@%
  17154.  
  17155. %@AB@%Arguments%@AE@%                         %@AI@%control%@AE@%     Fill flag (%@AB@% _GFILLINTERIOR%@AE@%, 
  17156.                                               %@AB@% _GBORDER%@AE@%)
  17157.  
  17158.                                   %@AI@%x1%@AE@%, %@AI@%y1%@AE@%      Upper left corner of 
  17159.                                               bounding rectangle (view  
  17160.  
  17161.                                   coordinates)
  17162.  
  17163.                                   %@AI@%x2%@AE@%, %@AI@%y2%@AE@%      Lower right corner of 
  17164.                                               bounding rectangle (view  
  17165.  
  17166.                                   coordinates)
  17167.  
  17168.                                   %@AI@%wx1, wy1%@AE@%    Upper left corner of 
  17169.                                               bounding rectangle (window  
  17170.  
  17171.                                   coordinates)
  17172.  
  17173.                                   %@AI@%wx%@AE@%2,%@AI@% wy2%@AE@%    Lower right corner of 
  17174.                                               bounding rectangle  (window
  17175.  
  17176.                                   coordinates)
  17177.  
  17178.                                   %@AI@%pwxy1%@AE@%       Upper left corner of 
  17179.                                               bounding rectangle (window
  17180.  
  17181.                                   coordinates)
  17182.  
  17183.                                   %@AI@%pwxy2%@AE@%       Lower right corner of 
  17184.                                               bounding rectangle (window
  17185.  
  17186.                                   coordinates)
  17187.  
  17188. %@AB@%Returns%@AE@%                           A nonzero value if the ellipse is drawn 
  17189.                                   successfully,  0 if not
  17190.  
  17191. ────────────────────────────────────────────────────────────────────────────
  17192. %@AB@%_floodfill %@AE@% - Fills an area of the screen with the current color.%@NL@%
  17193. %@NL@%
  17194. %@AB@%Include%@AE@%                           GRAPH.H
  17195.  
  17196. %@AB@%Prototypes%@AE@%                        %@AB@%short _far _floodfill( short %@AE@%%@AI@%x%@AE@%%@AB@%, short  %@AE@%%@AI@%y%@AE@%
  17197.                                   %@AB@%, short %@AE@%%@AI@%boundary %@AE@%%@AB@%);%@AE@%
  17198.  
  17199.  
  17200.  
  17201.                                   short _far _floodfill_w( double %@AI@%wx%@AE@%%@AB@%, %@AE@%
  17202.                                   %@AB@%double %@AE@%%@AI@%wy%@AE@%%@AB@%, short  %@AE@%%@AI@%boundary %@AE@%%@AB@%);%@AE@%
  17203.  
  17204. %@AB@%Arguments%@AE@%                         %@AI@%x, y%@AE@%        Start point (view 
  17205.                                               coordinates)%@AB@%%@AE@%
  17206.  
  17207.                                   %@AI@%wx%@AE@%, %@AI@%wy%@AE@%      Start point (window 
  17208.                                               coordinates)
  17209.  
  17210.                                   %@AI@%boundary%@AE@%    Boundary color
  17211.  
  17212. %@AB@%Returns%@AE@%                           A nonzero value if successful, 0 if not
  17213.  
  17214. ────────────────────────────────────────────────────────────────────────────
  17215. %@AB@%_getpixel %@AE@% - Obtains a pixel's color index. The coordinates can be specified
  17216. in either view coordinates (%@AB@%_getpixel%@AE@%) or in window coordinates
  17217. (%@AB@%_getpixel_w%@AE@%).%@NL@%
  17218. %@NL@%
  17219. %@AB@%Include%@AE@%                           GRAPH.H
  17220.  
  17221. %@AB@%Prototypes%@AE@%                        %@AB@%short _far _getpixel( short %@AE@%%@AI@%x%@AE@%%@AB@%, short  %@AE@%%@AI@%y %@AE@%
  17222.                                   %@AB@%);%@AE@%
  17223.  
  17224.  
  17225.  
  17226.                                   short _far _getpixel_w( double %@AI@%wx%@AE@%%@AB@%, %@AE@%
  17227.                                   %@AB@%double %@AE@%%@AI@%wy%@AE@%%@AB@% );%@AE@%
  17228.  
  17229. %@AB@%Arguments%@AE@%                         %@AI@%x%@AE@%,%@AI@% y%@AE@%        Pixel position (view 
  17230.                                               coordinates)
  17231.  
  17232.                                   %@AI@%wx, wy%@AE@%      Pixel position (window 
  17233.                                               coordinates)
  17234.  
  17235. %@AB@%Returns%@AE@%                           The color index if successful, -1 if not
  17236.  
  17237. ────────────────────────────────────────────────────────────────────────────
  17238. %@AB@%_lineto %@AE@% - Draws a line from the current graphic output position to a
  17239. specified point. The coordinate of the end point can be specified in either
  17240. view coordinates (%@AB@%_lineto%@AE@%) or in window coordinates (%@AB@%_lineto_w%@AE@%).%@NL@%
  17241. %@NL@%
  17242. %@AB@%Include%@AE@%                           GRAPH.H
  17243.  
  17244. %@AB@%Prototypes%@AE@%                        %@AB@%short _far _lineto( short %@AE@%%@AI@%x%@AE@%%@AB@%, short  %@AE@%%@AI@%y %@AE@%%@AB@%);%@AE@%
  17245.  
  17246.  
  17247.  
  17248.                                   short _far _lineto_w( double %@AI@%wx%@AE@%%@AB@%, double %@AE@%
  17249.                                   %@AI@%wy %@AE@%%@AB@%);%@AE@%
  17250.  
  17251. %@AB@%Arguments%@AE@%                         %@AI@%x%@AE@%, %@AI@%y%@AE@%        End point (view coordinates)
  17252.  
  17253.                                   %@AI@%wx%@AE@%,%@AI@% wy%@AE@%      End point (window 
  17254.                                               coordinates)
  17255.  
  17256. %@AB@%Returns%@AE@%                           A nonzero value if the line is drawn 
  17257.                                   successfully,  0 if not
  17258.  
  17259. ────────────────────────────────────────────────────────────────────────────
  17260. %@AB@%_moveto %@AE@% - Moves the current graphic-output position to a specified point.
  17261. The coordinates can be specified in either view coordinates (%@AB@%_moveto%@AE@%) or in
  17262. window coordinates (%@AB@%_moveto_w%@AE@%).%@NL@%
  17263. %@NL@%
  17264. %@AB@%Include%@AE@%                           GRAPH.H
  17265.  
  17266. %@AB@%Prototypes%@AE@%                        %@AB@%struct xycoord _far _moveto( short %@AE@%%@AI@%x%@AE@%%@AB@%,  %@AE@%
  17267.                                   %@AB@%short );%@AE@%
  17268.  
  17269.  
  17270.  
  17271.                                   struct _wxycoord _far _moveto_w( double %@AI@%%@AE@%
  17272.                                   %@AI@%wx%@AE@%%@AB@%, double %@AE@%%@AI@%wy  %@AE@%%@AB@%);%@AE@%
  17273.  
  17274. %@AB@%Arguments%@AE@%                         %@AI@%x%@AE@%, %@AI@%y%@AE@%        Target position (view 
  17275.                                               coordinates)
  17276.  
  17277.                                   %@AI@%wx%@AE@%, %@AI@%wy%@AE@%      Target position (window 
  17278.                                               coordinates)
  17279.  
  17280. %@AB@%Returns%@AE@%                           The logical coordinates of the previous 
  17281.                                   position  as an %@AB@%xycoord%@AE@%
  17282.  
  17283.                                   structure (%@AB@%_moveto%@AE@%) or as a %@AB@%_wxycoord%@AE@% 
  17284.                                   structure (%@AB@%_moveto_w%@AE@%)
  17285.  
  17286. ────────────────────────────────────────────────────────────────────────────
  17287. %@AB@%_pie %@AE@% - Draws a figure shaped like a pie wedge.%@NL@%
  17288. %@NL@%
  17289. %@AB@%Include%@AE@%                           GRAPH.H
  17290.  
  17291. %@AB@%Prototypes%@AE@%                        %@AB@%short _far _pie( short %@AE@%%@AI@%control%@AE@%%@AB@%, short  %@AE@%%@AI@%%@AE@%
  17292.                                   %@AI@%x1%@AE@%%@AB@%, short %@AE@%%@AI@%y1%@AE@%%@AB@%,%@AE@%
  17293.  
  17294.                                   short %@AI@%x2%@AE@%%@AB@%, short %@AE@%%@AI@%y2%@AE@%%@AB@%, short %@AE@%%@AI@%x3%@AE@%%@AB@%, short %@AE@%%@AI@%y3%@AE@%%@AB@%, %@AE@%
  17295.                                   %@AB@%short %@AE@%%@AI@%x4%@AE@%%@AB@%, short %@AE@%%@AI@%y%@AE@%%@AB@%4 );%@AE@%
  17296.  
  17297.  
  17298.  
  17299.                                   short _far _pie_wxy( short %@AI@%control%@AE@%%@AB@%, %@AE@%
  17300.                                   %@AB@%struct _wxycoord*  %@AE@%%@AI@%pwxy1%@AE@%%@AB@%,%@AE@%
  17301.  
  17302.                                   struct _wxycoord*%@AI@%pwxy2%@AE@%%@AB@%, struct %@AE@%
  17303.                                   %@AB@%_wxycoord* %@AE@%%@AI@%pwxy3%@AE@%%@AB@%,%@AE@%
  17304.  
  17305.                                   struct _wxycoord*%@AI@%pwxy4 %@AE@%%@AB@%);%@AE@%
  17306.  
  17307. %@AB@%Arguments%@AE@%                         %@AI@%control%@AE@%     Fill flag (%@AB@%_GFILLINTERIOR%@AE@%,  %@AB@%%@AE@%
  17308.                                               %@AB@%_GBORDER%@AE@%)
  17309.  
  17310.                                   %@AI@%x1, y1%@AE@%      Upper left corner of 
  17311.                                               bounding rectangle (view 
  17312.                                               coordinates)
  17313.  
  17314.                                   %@AI@%x2%@AE@%, %@AI@%y2%@AE@%      Lower right corner of 
  17315.                                               bounding rectangle (view  
  17316.                                               coordinates)
  17317.  
  17318.                                   %@AI@%x3%@AE@%, %@AI@%y3%@AE@%      Start vector(view 
  17319.                                               coordinates)
  17320.  
  17321.                                   %@AI@%x4%@AE@%,%@AI@% y4%@AE@%      End vector (view coordinates)
  17322.  
  17323.                                   %@AI@%pwxy1%@AE@%       Upper left corner of 
  17324.                                               bounding rectangle (window 
  17325.                                               coordinates)
  17326.  
  17327.                                   %@AI@%pwxy2%@AE@%       Lower right corner of 
  17328.                                               bounding rectangle (window 
  17329.                                               coordinates)
  17330.  
  17331.                                   %@AI@%pwxy3%@AE@%       Start vector (window 
  17332.                                               coordinates)
  17333.  
  17334.                                   %@AI@%pwxy4%@AE@%       End vector (window 
  17335.                                               coordinates)
  17336.  
  17337. %@AB@%Returns%@AE@%                           A nonzero value if the pie is drawn 
  17338.                                   successfully,  0 if not
  17339.  
  17340.  
  17341.  
  17342. ────────────────────────────────────────────────────────────────────────────
  17343. %@AB@%_rectangle %@AE@% - Draws a rectangle.%@NL@%
  17344. %@NL@%
  17345. %@AB@%Include%@AE@%                           GRAPH.H
  17346.  
  17347. %@AB@%Prototypes%@AE@%                        %@AB@%short _far _rectangle( short %@AE@%%@AI@%control%@AE@%%@AB@%,  %@AE@%
  17348.                                   %@AB@%short %@AE@%%@AI@%x1%@AE@%%@AB@%, short %@AE@%%@AI@%y1%@AE@%%@AB@%,%@AE@%
  17349.  
  17350.                                   short %@AI@%x2%@AE@%%@AB@%, short %@AE@%%@AI@%y2 %@AE@%%@AB@%);%@AE@%
  17351.  
  17352.  
  17353.  
  17354.                                   short _far _rectangle_w( short%@AI@% control%@AE@%%@AB@%, %@AE@%
  17355.                                   %@AB@%double %@AE@%%@AI@%wx1%@AE@%%@AB@%,  double %@AE@%%@AI@%wy1%@AE@%%@AB@%,%@AE@%
  17356.  
  17357.                                   double %@AI@%wx2%@AE@%%@AB@%, double %@AE@%%@AI@%wy2 %@AE@%%@AB@%);%@AE@%
  17358.  
  17359.  
  17360.  
  17361.                                   short _far _rectangle_wxy( short %@AI@%control%@AE@%
  17362.                                   %@AB@%, struct _wxycoord*%@AE@%%@AI@%pwxy1%@AE@%%@AB@%,%@AE@%
  17363.  
  17364.                                   struct _wxycoord*%@AI@%pwxy2%@AE@%%@AB@% );%@AE@%
  17365.  
  17366. %@AB@%Arguments%@AE@%                         %@AI@%control%@AE@%     Fill flag (%@AB@%_GFILLINTERIOR%@AE@%,  %@AB@%%@AE@%
  17367.                                               %@AB@%_GBORDER%@AE@%)
  17368.  
  17369.                                   %@AI@%x1%@AE@%,%@AI@% y1%@AE@%      Upper left corner (view 
  17370.                                               coordinates)
  17371.  
  17372.                                   %@AI@%x2%@AE@%,%@AI@% y2%@AE@%      Lower right corner (view 
  17373.                                               coordinates)
  17374.  
  17375.                                   %@AI@%wx1%@AE@%, %@AI@%wy1%@AE@%    Upper left corner (window 
  17376.                                               coordinates)
  17377.  
  17378.                                   %@AI@%wx2%@AE@%, %@AI@%wy2%@AE@%    Lower right corner (window 
  17379.                                               coordinates)
  17380.  
  17381.                                   %@AI@%pwxy1%@AE@%       Upper left corner (window 
  17382.                                               coordinates)
  17383.  
  17384.                                   %@AI@%pwxy2%@AE@%       Lower right corner (window 
  17385.                                               coordinates)
  17386.  
  17387. %@AB@%Returns%@AE@%                           A nonzero value if the rectangle is 
  17388.                                   drawn successfully,  0 if not
  17389.  
  17390. ────────────────────────────────────────────────────────────────────────────
  17391. %@AB@%_setpixel %@AE@% - Sets a pixel's color index.%@NL@%
  17392. %@NL@%
  17393. %@AB@%Include%@AE@%                           GRAPH.H
  17394.  
  17395. %@AB@%Prototypes%@AE@%                        %@AB@%short _far _setpixel( short %@AE@%%@AI@%x%@AE@%%@AB@%, short  %@AE@%%@AI@%y %@AE@%
  17396.                                   %@AB@%);%@AE@%
  17397.  
  17398.  
  17399.  
  17400.                                   short _far _setpixel_w( double %@AI@%wx%@AE@%%@AB@%, %@AE@%
  17401.                                   %@AB@%double%@AE@%%@AI@% wy%@AE@%%@AB@% );%@AE@%
  17402.  
  17403. %@AB@%Arguments%@AE@%                         %@AI@%x%@AE@%, %@AI@%y%@AE@%        Target pixel (view 
  17404.                                               coordinates)
  17405.  
  17406.                                   %@AI@%wx%@AE@%, %@AI@%wy%@AE@%      Target pixel (window 
  17407.                                               coordinates)
  17408.  
  17409. %@AB@%Returns%@AE@%                           The pixel's previous value if successful,
  17410.                                   -1  if not
  17411.  
  17412. %@NL@%
  17413. %@4@%%@AB@%Output Text%@AE@%%@EH@%%@NL@%
  17414. %@NL@%
  17415. These routines provide text output in both graphics and text modes.  %@NL@%
  17416. %@NL@%
  17417. These functions recognize text window boundaries and should be used in
  17418. applications using text windows.  %@NL@%
  17419. %@NL@%
  17420. No formatting capability is provided. If you want to output integer or
  17421. floating-point values, you must convert the values into a string variable
  17422. before calling these routines. All screen positions are specified as
  17423. character-row and character-column coordinates.  %@NL@%
  17424. %@NL@%
  17425. ────────────────────────────────────────────────────────────────────────────
  17426. %@AB@%_displaycursor%@AE@% - Sets the cursor "on" or "off" on exit from a graphics
  17427. routine.%@NL@%
  17428. %@NL@%
  17429. %@AB@%Include%@AE@%                           GRAPH.H
  17430.  
  17431. %@AB@%Prototype%@AE@%                         %@AB@%short _far _displaycursor( short %@AE@%%@AI@%toggle %@AE@%
  17432.                                   %@AI@%%@AE@%%@AB@%);%@AE@%
  17433.  
  17434. %@AB@%Argument%@AE@%                          %@AI@%toggle%@AE@%      Cursor state (%@AB@%_GCURSORON%@AE@%,%@AB@%  %@AE@%
  17435.                                               %@AB@%_GCURSOROFF%@AE@%)
  17436.  
  17437. %@AB@%Returns%@AE@%                           The previous value of %@AI@%toggle%@AE@%
  17438.  
  17439. ────────────────────────────────────────────────────────────────────────────
  17440. %@AB@%_gettextcolor%@AE@% - Obtains the current text color.%@NL@%
  17441. %@NL@%
  17442. %@AB@%Include%@AE@%                           GRAPH.H
  17443.  
  17444. %@AB@%Prototype%@AE@%                         %@AB@%short _far _gettextcolor( void );%@AE@%
  17445.  
  17446. %@AB@%Arguments%@AE@%                         None
  17447.  
  17448. %@AB@%Returns%@AE@%                           The color index of the current text 
  17449.                                   color
  17450.  
  17451. ────────────────────────────────────────────────────────────────────────────
  17452. %@AB@%_gettextcursor%@AE@% - Obtains the current cursor attribute.%@NL@%
  17453. %@NL@%
  17454. %@AB@%Include%@AE@%                           GRAPH.H
  17455.  
  17456. %@AB@%Prototype%@AE@%                         %@AB@%short _far _gettextcursor( void );%@AE@%
  17457.  
  17458. %@AB@%Arguments%@AE@%                         None
  17459.  
  17460. %@AB@%Returns%@AE@%                           The current cursor attribute
  17461.  
  17462. ────────────────────────────────────────────────────────────────────────────
  17463. %@AB@%_gettextposition%@AE@% - Obtains the current text-output position.%@NL@%
  17464. %@NL@%
  17465. %@AB@%Include%@AE@%                           GRAPH.H
  17466.  
  17467. %@AB@%Prototype%@AE@%                         %@AB@%struct rccoord _far _gettextposition( %@AE@%
  17468.                                   %@AB@%void  );%@AE@%
  17469.  
  17470. %@AB@%Arguments%@AE@%                         None
  17471.  
  17472. %@AB@%Returns%@AE@%                           The current text position as an %@AB@%rccoord%@AE@% 
  17473.                                   structure
  17474.  
  17475. ────────────────────────────────────────────────────────────────────────────
  17476. %@AB@%_outtext%@AE@% - Outputs text to the screen at the current position.%@NL@%
  17477. %@NL@%
  17478. %@AB@%Include%@AE@%                           GRAPH.H
  17479.  
  17480. %@AB@%Prototype%@AE@%                         %@AB@%void _far _outtext( unsigned char _far *%@AE@%
  17481.                                   %@AI@%text  %@AE@%%@AB@%);%@AE@%
  17482.  
  17483. %@AB@%Argument%@AE@%                          %@AI@%text%@AE@%        Text to be output
  17484.  
  17485. %@AB@%Returns%@AE@%                           Void
  17486.  
  17487. ────────────────────────────────────────────────────────────────────────────
  17488. %@AB@%_settextposition%@AE@% - Relocates the current text position.%@NL@%
  17489. %@NL@%
  17490. %@AB@%Include%@AE@%                           GRAPH.H
  17491.  
  17492. %@AB@%Prototype%@AE@%                         %@AB@%struct rccoord _far _settextposition( %@AE@%
  17493.                                   %@AB@%short  %@AE@%%@AI@%row%@AE@%%@AB@%, short %@AE@%%@AI@%col %@AE@%%@AB@%);%@AE@%
  17494.  
  17495. %@AB@%Arguments%@AE@%                         %@AI@%row%@AE@%         Row coordinate of new output
  17496.                                               position
  17497.  
  17498.                                   %@AI@%col%@AE@%         Column coordinate of new 
  17499.                                               output position
  17500.  
  17501. %@AB@%Returns%@AE@%                           The previous text position in an%@AB@% rccoord%@AE@%
  17502.                                   structure
  17503.  
  17504. ────────────────────────────────────────────────────────────────────────────
  17505. %@AB@%_settextcolor%@AE@% - Sets the current text color.%@NL@%
  17506. %@NL@%
  17507. %@AB@%Include%@AE@%                           GRAPH.H
  17508.  
  17509. %@AB@%Prototype%@AE@%                         %@AB@%short _far _settextcolor( short %@AE@%%@AI@%index  %@AE@%%@AB@%%@AE@%
  17510.                                   %@AB@%);%@AE@%
  17511.  
  17512. %@AB@%Argument%@AE@%                          %@AI@%index%@AE@%       Desired color index
  17513.  
  17514. %@AB@%Returns%@AE@%                           The value of the previous color
  17515.  
  17516. ────────────────────────────────────────────────────────────────────────────
  17517. %@AB@%_settextwindow%@AE@% - Sets the current text-display window.%@NL@%
  17518. %@NL@%
  17519. %@AB@%Include%@AE@%                           GRAPH.H
  17520.  
  17521. %@AB@%Prototype%@AE@%                         %@AB@%void _far _settextwindow( short %@AE@%%@AI@%r1%@AE@%%@AB@%,  %@AE@%
  17522.                                   %@AB@%short %@AE@%%@AI@%c1%@AE@%%@AB@%, short %@AE@%%@AI@%r2%@AE@%%@AB@%, short %@AE@%%@AI@%c2 %@AE@%%@AB@%);%@AE@%
  17523.  
  17524. %@AB@%Arguments%@AE@%                         %@AI@%r1%@AE@%,%@AI@% c1%@AE@%      Upper left corner of window
  17525.  
  17526.                                   %@AI@%r2%@AE@%, %@AI@%c2%@AE@%      Lower right corner of window
  17527.  
  17528. %@AB@%Returns%@AE@%                           Void
  17529.  
  17530. %@NL@%
  17531. %@4@%%@AB@%Transfer Images%@AE@%%@EH@%%@NL@%
  17532. %@NL@%
  17533. These functions transfer screen images between memory and the display, using
  17534. a buffer allocated by the application. You can use these functions to
  17535. animate graphics elements on the screen.  %@NL@%
  17536. %@NL@%
  17537. Most of these routines have two or three forms. The functions are listed by
  17538. the "base" name, without a suffix. Note, though, that function names that
  17539. end in a %@AB@%_w%@AE@%, such as %@AB@%_getimage_w%@AE@%, use the window-coordinate system. Those
  17540. that end with a %@AB@%_wxy%@AE@%, such as %@AB@%_imagesize_wxy%@AE@%, use the window-coordinate
  17541. system and a %@AB@%_wxycoord%@AE@% structure to define the coordinates.  %@NL@%
  17542. %@NL@%
  17543. The %@AB@%_imagesize%@AE@% function is used to find the size in bytes of the buffer
  17544. needed to store a given image.  %@NL@%
  17545. %@NL@%
  17546. ────────────────────────────────────────────────────────────────────────────
  17547. %@AB@%_getimage%@AE@% - Stores a screen image in memory.%@NL@%
  17548. %@NL@%
  17549. %@AB@%Include%@AE@%                           GRAPH.H
  17550.  
  17551. %@AB@%Prototypes%@AE@%                        %@AB@%void _far _getimage( short %@AE@%%@AI@%x1%@AE@%%@AB@%, short  %@AE@%%@AI@%y1%@AE@%
  17552.                                   %@AB@%,%@AE@%
  17553.  
  17554.                                   short %@AI@%x2%@AE@%%@AB@%, short %@AE@%%@AI@%y2%@AE@%%@AB@%, char _huge *%@AE@%%@AI@%image%@AE@%%@AB@%  %@AE@%
  17555.                                   %@AB@%);%@AE@%
  17556.  
  17557.  
  17558.  
  17559.                                   void _far _getimage_w( double %@AI@%wx1%@AE@%%@AB@%, %@AE@%
  17560.                                   %@AB@%double %@AE@%%@AI@%wy1%@AE@%%@AB@%,%@AE@%
  17561.  
  17562.                                   double %@AI@%wx2%@AE@%%@AB@%, double %@AE@%%@AI@%wy2%@AE@%%@AB@%, char _huge *%@AE@%%@AI@%%@AE@%
  17563.                                   %@AI@%image  %@AE@%%@AB@%);%@AE@%
  17564.  
  17565.  
  17566.  
  17567.                                   void _far _getimage_wxy( struct 
  17568.                                   _wxycoord*%@AI@%pwxy1%@AE@%%@AB@%,%@AE@%
  17569.  
  17570.                                   struct _wxycoord*%@AI@%pwxy2%@AE@%%@AB@%, char _huge *%@AE@%%@AI@%%@AE@%
  17571.                                   %@AI@%image  %@AE@%%@AB@%);%@AE@%
  17572.  
  17573. %@AB@%Arguments%@AE@%                         %@AI@%x1%@AE@%,%@AI@% y1%@AE@%      Upper left corner of 
  17574.                                               bounding  rectangle (view 
  17575.                                               coordinates)
  17576.  
  17577.                                   %@AI@%x2%@AE@%, %@AI@%y2%@AE@%      Lower right corner of 
  17578.                                               bounding rectangle (view  
  17579.                                               coordinates)
  17580.  
  17581.                                   %@AI@%wx1%@AE@%,%@AI@% wy1%@AE@%    Upper left corner of 
  17582.                                               bounding rectangle (window  
  17583.                                               coordinates)
  17584.  
  17585.                                   %@AI@%wx2%@AE@%, %@AI@%wy2%@AE@%    Lower right corner of 
  17586.                                               bounding rectangle  (window 
  17587.                                               coordinates)
  17588.  
  17589.                                   %@AI@%pwxy1%@AE@%       Upper left corner of 
  17590.                                               bounding rectangle (window 
  17591.                                               coordinates)
  17592.  
  17593.                                   %@AI@%pwxy2%@AE@%       Lower right corner of 
  17594.                                               bounding rectangle (window 
  17595.                                               coordinates)
  17596.  
  17597.                                   %@AI@%image%@AE@%       Storage buffer for screen 
  17598.                                               image
  17599.  
  17600. %@AB@%Returns%@AE@%                           Void
  17601.  
  17602. ────────────────────────────────────────────────────────────────────────────
  17603. %@AB@%_imagesize%@AE@% - Returns image size in bytes.%@NL@%
  17604. %@NL@%
  17605. %@AB@%Include%@AE@%                           GRAPH.H
  17606.  
  17607. %@AB@%Prototypes%@AE@%                        %@AB@%long _far _imagesize( short %@AE@%%@AI@%x1%@AE@%%@AB@%, short  %@AE@%%@AI@%%@AE@%
  17608.                                   %@AI@%y1%@AE@%%@AB@%, short %@AE@%%@AI@%x2%@AE@%%@AB@%, short %@AE@%%@AI@%y2 %@AE@%%@AB@%);%@AE@%
  17609.  
  17610.  
  17611.  
  17612.                                   long _far _imagesize_w( double %@AI@%wx1%@AE@%%@AB@%, %@AE@%
  17613.                                   %@AB@%double %@AE@%%@AI@%wy1%@AE@%%@AB@%, double  %@AE@%%@AI@%wx2%@AE@%%@AB@%,%@AE@%
  17614.  
  17615.                                   double %@AI@%wy2 %@AE@%%@AB@%);%@AE@%
  17616.  
  17617.  
  17618.  
  17619.                                   long _far _imagesize_wxy( struct 
  17620.                                   _wxycoord* %@AI@%pwxy1%@AE@%%@AB@%,%@AE@%
  17621.  
  17622.                                   struct _wxycoord* %@AI@%pwxy2 %@AE@%%@AB@%);%@AE@%
  17623.  
  17624. %@AB@%Arguments%@AE@%                         %@AI@%x1%@AE@%, %@AI@%y1%@AE@%      Upper left corner of 
  17625.                                               bounding  rectangle (view 
  17626.                                               coordinates)
  17627.  
  17628.                                   %@AI@%x2%@AE@%,%@AI@% y2%@AE@%      Lower right corner of 
  17629.                                               bounding rectangle (view  
  17630.                                               coordinates)
  17631.  
  17632.                                   %@AI@%wx1%@AE@%,%@AI@% wy1%@AE@%    Upper left corner of 
  17633.                                               bounding rectangle (window  
  17634.                                               coordinates)
  17635.  
  17636.                                   %@AI@%wx2%@AE@%,%@AI@% wy2%@AE@%    Lower right corner of 
  17637.                                               bounding rectangle  (window 
  17638.                                               coordinates)
  17639.  
  17640.                                   %@AI@%pwxy1%@AE@%       Upper left corner of 
  17641.                                               bounding rectangle (window 
  17642.                                               coordinates)
  17643.  
  17644.                                   %@AI@%pwxy2%@AE@%       Lower right corner of 
  17645.                                               bounding rectangle (window 
  17646.                                               coordinates)
  17647.  
  17648. %@AB@%Returns%@AE@%                           The storage size of the image in bytes
  17649.  
  17650. ────────────────────────────────────────────────────────────────────────────
  17651. %@AB@%_putimage%@AE@% - Retrieves an image from memory and displays it.%@NL@%
  17652. %@NL@%
  17653. %@AB@%Include%@AE@%                           GRAPH.H
  17654.  
  17655. %@AB@%Prototypes%@AE@%                        %@AB@%void _far _putimage( short %@AE@%%@AI@%x%@AE@%%@AB@%, short  %@AE@%%@AI@%y%@AE@%%@AB@%,%@AE@%
  17656.  
  17657.                                   char _huge *%@AI@%image%@AE@%%@AB@%, short %@AE@%%@AI@%action%@AE@%%@AB@% );%@AE@%
  17658.  
  17659.  
  17660.  
  17661.                                   void _far _putimage_w( double %@AI@%wx%@AE@%%@AB@%, double%@AE@%
  17662.                                   %@AB@%%@AE@%%@AI@%wy%@AE@%%@AB@%,%@AE@%
  17663.  
  17664.                                   char _huge *%@AI@%image%@AE@%%@AB@%, short %@AE@%%@AI@%action %@AE@%%@AB@%);%@AE@%
  17665.  
  17666. %@AB@%Arguments%@AE@%                         %@AI@%x, y%@AE@%        Position of upper left 
  17667.                                               corner of  image (view 
  17668.                                               coordinates)
  17669.  
  17670.                                   %@AI@%wx%@AE@%,%@AI@% wy%@AE@%      Position of upper left 
  17671.                                               corner of image (window  
  17672.                                               coordinates)
  17673.  
  17674.                                   %@AI@%image%@AE@%       Stored image buffer
  17675.  
  17676.                                   %@AI@%action%@AE@%      Interaction with existing 
  17677.                                               screen image (%@AB@%_GAND%@AE@%,  %@AB@% _GOR,%@AE@%
  17678.  
  17679.                                   _GXOR, %@AB@%_GPSET%@AE@%, %@AB@%_GPRESET%@AE@%)
  17680.  
  17681. %@AB@%Returns%@AE@%                           Void
  17682.  
  17683. %@NL@%
  17684. %@2@%%@CR:C6A-B0008   @%%@AB@%Graphics 2: Presentation Graphics Routines%@AE@%%@EH@%%@NL@%
  17685. %@NL@%
  17686. The presentation graphics routines provide complete charting capabilities
  17687. for line, bar, column, scatter, and pie charts.  %@NL@%
  17688. %@NL@%
  17689. Some charts plot both "categories," or non-numeric data such as time
  17690. periods, and "values," or specific numeric data, such as sales. Presentation
  17691. graphics routines support the following kinds of charts:  %@NL@%
  17692. %@NL@%
  17693. %@AB@%Chart Name%@AE@%                        %@AB@%Description%@AE@%
  17694. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  17695. Line                              Category/value chart, with styles for 
  17696.                                   lines between points and for no lines
  17697.  
  17698. Bar                               Category/value chart, horizontal bars, 
  17699.                                   styles for stacked and unstacked 
  17700.                                   multiple series charts
  17701.  
  17702. Column                            Category/value chart, vertical bars, 
  17703.                                   with styles for stacked and unstacked 
  17704.                                   multiple series charts
  17705.  
  17706. Scatter                           Value/value chart, with styles for lines
  17707.                                   connecting points or for no lines
  17708.  
  17709. Pie                               Pie chart, with optional percentages and
  17710.                                   exploded sections
  17711.  
  17712. The graphics package supports the IBM (and compatible) Enhanced Graphics
  17713. Adapter (EGA), Color Graphics Adapter (CGA), certain operating modes of the
  17714. Video Graphics Array (VGA) hardware configurations, and the Multicolor
  17715. Graphics Array (MCGA). The graphics package also supports the Hercules
  17716. Graphics Card, Graphics Card Plus, InColor Card, and 100-percent compatible
  17717. cards, as well as the special Olivetti modes available on AT&T computers.  %@NL@%
  17718. %@NL@%
  17719. The %@AB@%_pg_initchart%@AE@% and %@AB@%_pg_defaultchart%@AE@% functions are generally used at the
  17720. very beginning of a presentation graphics program.  %@NL@%
  17721. %@NL@%
  17722. The %@AB@%_pg_chart%@AE@% functions produce column charts, line charts, and bar charts.
  17723. The %@AB@%_pg_chartscatter%@AE@% functions produce a scatter plot of data. The
  17724. %@AB@%_pg_chartpie%@AE@% function generates a pie chart.  %@NL@%
  17725. %@NL@%
  17726. ────────────────────────────────────────────────────────────────────────────
  17727. %@AB@%_pg_chart%@AE@% - Generates a chart of the type specified in the %@AI@%env%@AE@% environment
  17728. variable. It produces a column, bar, or line chart for a single series of
  17729. data.%@NL@%
  17730. %@NL@%
  17731. %@AB@%Include%@AE@%                           PGCHART.H
  17732.  
  17733. %@AB@%Prototype%@AE@%                         %@AB@%short _far _pg_chart( chartenv _far*%@AE@%%@AI@%env%@AE@%%@AB@%,%@AE@%
  17734.                                   %@AB@%%@AE@%
  17735.  
  17736.                                   char _far*_far *%@AI@%categories%@AE@%%@AB@%, float _far*%@AE@%%@AI@%%@AE@%
  17737.                                   %@AI@%values%@AE@%%@AB@%,  short %@AE@%%@AI@%n %@AE@%%@AB@%);%@AE@%
  17738.  
  17739. %@AB@%Arguments%@AE@%                         %@AI@%env%@AE@%         Chart environment variable
  17740.  
  17741.                                   %@AI@%categories%@AE@%  Array of category variables
  17742.  
  17743.                                   %@AI@%values%@AE@%      Array of data values
  17744.  
  17745.                                   %@AI@%n%@AE@%           Number of data values to 
  17746.                                               chart
  17747.  
  17748. %@AB@%Returns%@AE@%                           0 if successful, nonzero if not
  17749.  
  17750. ────────────────────────────────────────────────────────────────────────────
  17751. %@AB@%_pg_chartms%@AE@% - Generates a multiple series of charts of the type specified in
  17752. the %@AI@%env%@AE@% environment variable. It produces a column, bar, or line chart for a
  17753. multiple series of data. All series must be the same length.%@NL@%
  17754. %@NL@%
  17755. %@AB@%Include%@AE@%                           PGCHART.H
  17756.  
  17757. %@AB@%Prototype%@AE@%                         %@AB@%short _far _pg_chartms( chartenv _far *%@AE@%%@AI@%%@AE@%
  17758.                                   %@AI@%env%@AE@%%@AB@%,  %@AE@%
  17759.  
  17760.                                   char _far * _far*%@AI@%categories%@AE@%%@AB@%, float _far*%@AE@%
  17761.                                   %@AI@%values%@AE@%%@AB@%,  short %@AE@%%@AI@%n%@AE@%%@AB@%, short %@AE@%%@AI@%nseries%@AE@%%@AB@%,%@AE@%
  17762.  
  17763.                                   short %@AI@%arraydim%@AE@%%@AB@%, char _far* _far*%@AE@%%@AI@%%@AE@%
  17764.                                   %@AI@%serieslabels  %@AE@%%@AB@%);%@AE@%
  17765.  
  17766. %@AB@%Arguments%@AE@%                         %@AI@%env%@AE@%         Chart environment variable
  17767.  
  17768.                                   %@AI@%categories%@AE@%  Array of category variables
  17769.  
  17770.                                   %@AI@%values%@AE@%      Two-dimensional array of 
  17771.                                               data values (series, data)
  17772.  
  17773.                                   %@AI@%n%@AE@%           Number of data values to 
  17774.                                               chart in a series
  17775.  
  17776.                                   %@AI@%nseries%@AE@%     Number of series to chart
  17777.  
  17778.                                   %@AI@%arraydim%@AE@%    Second (row) dimension of 
  17779.                                               data array
  17780.  
  17781.                                   %@AI@%serieslabe%@AE@%  Array of labels for series
  17782.                                   %@AI@%ls%@AE@%          
  17783.  
  17784. %@AB@%Returns%@AE@%                           0 if successful, nonzero if not
  17785.  
  17786. ────────────────────────────────────────────────────────────────────────────
  17787. %@AB@%_pg_chartpie%@AE@% - Generates a pie chart for a single series of data.%@NL@%
  17788. %@NL@%
  17789. %@AB@%Include%@AE@%                           PGCHART.H
  17790.  
  17791. %@AB@%Prototype%@AE@%                         %@AB@%short _far _pg_chartpie( chartenv _far*%@AE@%%@AI@%%@AE@%
  17792.                                   %@AI@%env%@AE@%%@AB@%,  %@AE@%
  17793.  
  17794.                                   char _far* _far*%@AI@%categories%@AE@%%@AB@%, float _far*%@AE@%%@AI@%%@AE@%
  17795.                                   %@AI@%values%@AE@%%@AB@%,  %@AE@%
  17796.  
  17797.                                   short _far*%@AI@%explode%@AE@%%@AB@%, short %@AE@%%@AI@%n %@AE@%%@AB@%);%@AE@%
  17798.  
  17799. %@AB@%Arguments%@AE@%                         %@AI@%env%@AE@%         Chart environment variable
  17800.  
  17801.                                   %@AI@%categories%@AE@%  Array of category names
  17802.  
  17803.                                   %@AI@%values%@AE@%      Array of data values
  17804.  
  17805.                                   %@AI@%explode %@AE@%    Array of explode flags; 
  17806.                                               1=explode, 0=do not explode
  17807.  
  17808.                                   %@AI@%n%@AE@%           Number of data values to 
  17809.                                               chart
  17810.  
  17811. %@AB@%Returns%@AE@%                           0 if successful, nonzero if not
  17812.  
  17813. ────────────────────────────────────────────────────────────────────────────
  17814. %@AB@%_pg_chartscatter%@AE@% - Generates a scatter chart for a single series of data. %@NL@%
  17815. %@NL@%
  17816. %@AB@%Include%@AE@%                           PGCHART.H
  17817.  
  17818. %@AB@%Prototype%@AE@%                         %@AB@%short _far _pg_chartscatter( chartenv %@AE@%
  17819.                                   %@AB@%_far  *%@AE@%%@AI@%env%@AE@%%@AB@%, float _far *%@AE@%%@AI@%xvalues%@AE@%%@AB@%,%@AE@%
  17820.  
  17821.                                   float _far *%@AI@%yvalues%@AE@%%@AB@%, short %@AE@%%@AI@%n %@AE@%%@AB@%);%@AE@%
  17822.  
  17823. %@AB@%Arguments%@AE@%                         %@AI@%env%@AE@%         Chart environment variable
  17824.  
  17825.                                   %@AI@%xvalues%@AE@%     Array of %@AI@%x-%@AE@%axis data values
  17826.  
  17827.                                   %@AI@%yvalues%@AE@%     Array of%@AI@% y%@AE@%-axis data values
  17828.  
  17829.                                   %@AI@%n%@AE@%           Number of data values to 
  17830.                                               chart
  17831.  
  17832. %@AB@%Returns%@AE@%                           0 if successful, nonzero if not
  17833.  
  17834. ────────────────────────────────────────────────────────────────────────────
  17835. %@AB@%_pg_chartscatterms%@AE@% - Generates a scatter chart for a multiple series of
  17836. data. %@NL@%
  17837. %@NL@%
  17838. %@AB@%Include%@AE@%                           PGCHART.H
  17839.  
  17840. %@AB@%Prototype%@AE@%                         %@AB@%short _far _pg_chartscatterms( chartenv %@AE@%
  17841.                                   %@AB@%_far  *%@AE@%%@AI@%env%@AE@%%@AB@%,%@AE@%
  17842.  
  17843.                                   float _far*%@AI@%xvalues%@AE@%%@AB@%, float _far*%@AE@%%@AI@%yvalues%@AE@%%@AB@%, %@AE@%
  17844.                                   %@AB@%short %@AE@%%@AI@%nseries%@AE@%%@AB@%, short %@AE@%%@AI@%n%@AE@%%@AB@%,%@AE@%
  17845.  
  17846.                                   short %@AI@%rowdim%@AE@%%@AB@%, char _far* _far *%@AE@%%@AI@%%@AE@%
  17847.                                   %@AI@%serieslabels  %@AE@%%@AB@%);%@AE@%
  17848.  
  17849. %@AB@%Arguments%@AE@%                         %@AI@%env%@AE@%         Chart environment variable
  17850.  
  17851.                                   %@AI@%xvalues%@AE@%     Two-dimensional array of %@AI@%x%@AE@%
  17852.                                               -axis values
  17853.  
  17854.                                   %@AI@%yvalues%@AE@%     Two-dimensional array of %@AI@%y%@AE@%
  17855.                                               -axis values
  17856.  
  17857.                                   %@AI@%n%@AE@%           Number of data values to 
  17858.                                               chart in a series
  17859.  
  17860.                                   %@AI@%nseries%@AE@%     Number of series to chart
  17861.  
  17862.                                   %@AI@%rowdim%@AE@%      Second (row) dimension of 
  17863.                                               data array
  17864.  
  17865.                                   %@AI@%serieslabe%@AE@%  Array of labels for series
  17866.                                   %@AI@%ls%@AE@%          
  17867.  
  17868. %@AB@%Returns%@AE@%                           0 if successful, nonzero if not
  17869.  
  17870. ────────────────────────────────────────────────────────────────────────────
  17871. %@AB@%_pg_defaultchart%@AE@% - Initializes all necessary variables in the chart
  17872. environment for the specified default chart and chart style.%@NL@%
  17873. %@NL@%
  17874. %@AB@%Include%@AE@%                           PGCHART.H
  17875.  
  17876. %@AB@%Prototype%@AE@%                         %@AB@%short _far _pg_defaultchart( chartenv %@AE@%
  17877.                                   %@AB@%_far  *%@AE@%%@AI@%env%@AE@%%@AB@%, short %@AE@%%@AI@%charttype%@AE@%%@AB@%,%@AE@%
  17878.  
  17879.                                   short %@AI@%chartstyle %@AE@%%@AB@%);%@AE@%
  17880.  
  17881. %@AB@%Arguments%@AE@%                         %@AI@%env%@AE@%         Chart environment variable
  17882.  
  17883.                                   %@AI@%charttype%@AE@%   Chart type (%@AB@%_PG_BARCHART%@AE@%,
  17884.  
  17885.                                   %@AB@%_PG_COLUMNCHART%@AE@%, %@AB@%_PG_LINECHART%@AE@%,
  17886.  
  17887.                                   %@AB@%_PG_SCATTERCHART%@AE@%, %@AB@%_PG_PIECHART)%@AE@%
  17888.  
  17889.                                   %@AI@%chartstyle%@AE@%  Chart style
  17890.  
  17891. %@AB@%Returns%@AE@%                           0 if successful, nonzero if not
  17892.  
  17893. ────────────────────────────────────────────────────────────────────────────
  17894. %@AB@%_pg_initchart%@AE@% - Initializes chart line-style set, default palettes, screen
  17895. modes, and character fonts. You must call this routine before any other
  17896. charting routine.%@NL@%
  17897. %@NL@%
  17898. %@AB@%Include%@AE@%                           PGCHART.H
  17899.  
  17900. %@AB@%Prototype%@AE@%                         %@AB@%short _far _pg_initchart( void );%@AE@%
  17901.  
  17902. %@AB@%Arguments%@AE@%                         None
  17903.  
  17904. %@AB@%Returns%@AE@%                           0 if successful, nonzero if not
  17905.  
  17906. %@NL@%
  17907. %@2@%%@CR:C6A-B0009   @%%@AB@%Graphics 3: Font Display Routines%@AE@%%@EH@%%@NL@%
  17908. %@NL@%
  17909. The font graphics routines display font-based characters on the screen.  %@NL@%
  17910. %@NL@%
  17911. The %@AB@%_registerfonts%@AE@% function initializes the fonts package with a set of
  17912. disk-based type fonts. This must be done at the very beginning of any fonts
  17913. program. The %@AB@%_unregisterfonts%@AE@% function frees fonts from memory when they are
  17914. no longer needed.  %@NL@%
  17915. %@NL@%
  17916. The %@AB@%_setfont%@AE@% function makes a specified font the current active font for
  17917. output. The %@AB@%_outgtext%@AE@% function displays text on the screen using the current
  17918. font.  %@NL@%
  17919. %@NL@%
  17920. ────────────────────────────────────────────────────────────────────────────
  17921. %@AB@%_getfontinfo%@AE@% - Obtains the current font characteristics.%@NL@%
  17922. %@NL@%
  17923. %@AB@%Include%@AE@%                           GRAPH.H
  17924.  
  17925. %@AB@%Prototype%@AE@%                         %@AB@%short _far _getfontinfo( struct %@AE@%
  17926.                                   %@AB@%_fontinfo  _far *%@AE@%%@AI@%fontbuffer%@AE@%%@AB@% );%@AE@%
  17927.  
  17928. %@AB@%Argument%@AE@%                          %@AI@%fontbuffer%@AE@%  Font information
  17929.  
  17930. %@AB@%Returns%@AE@%                           Font information as a %@AB@%_fontinfo%@AE@% 
  17931.                                   structure
  17932.  
  17933. ────────────────────────────────────────────────────────────────────────────
  17934. %@AB@%_getgtextextent%@AE@% - Determines the width of the specified text in the current
  17935. font.%@NL@%
  17936. %@NL@%
  17937. %@AB@%Include%@AE@%                           GRAPH.H
  17938.  
  17939. %@AB@%Prototype%@AE@%                         %@AB@%short _far _getgtextextent( unsigned %@AE@%
  17940.                                   %@AB@%char  _far * %@AE@%%@AI@%text %@AE@%%@AB@%);%@AE@%
  17941.  
  17942. %@AB@%Argument%@AE@%                          %@AI@%text%@AE@%        Text to be analyzed
  17943.  
  17944. %@AB@%Returns%@AE@%                           The width of the text in pixels
  17945.  
  17946. ────────────────────────────────────────────────────────────────────────────
  17947. %@AB@%_outgtext%@AE@% - Outputs text in the current font to the screen at the current
  17948. position.%@NL@%
  17949. %@NL@%
  17950. %@AB@%Include%@AE@%                           GRAPH.H
  17951.  
  17952. %@AB@%Prototype%@AE@%                         %@AB@%void _far _outgtext( unsigned char _far %@AE@%
  17953.                                   %@AB@%*%@AE@%%@AI@%text  %@AE@%%@AB@%);%@AE@%
  17954.  
  17955. %@AB@%Argument%@AE@%                          %@AI@%text%@AE@%        Text to be output
  17956.  
  17957. %@AB@%Returns%@AE@%                           Void
  17958.  
  17959. ────────────────────────────────────────────────────────────────────────────
  17960. %@AB@%_registerfonts%@AE@% - Initializes the font library.%@NL@%
  17961. %@NL@%
  17962. %@AB@%Include%@AE@%                           GRAPH.H
  17963.  
  17964. %@AB@%Prototype%@AE@%                         %@AB@%short _far _registerfonts( unsigned char%@AE@%
  17965.                                   %@AB@%_far *%@AE@%%@AI@%filename %@AE@%%@AB@%);%@AE@%
  17966.  
  17967. %@AB@%Argument%@AE@%                          %@AI@%file name%@AE@%   File name of .FON files to 
  17968.                                               register
  17969.  
  17970. %@AB@%Returns%@AE@%                           Void
  17971.  
  17972. ────────────────────────────────────────────────────────────────────────────
  17973. %@AB@%_setfont%@AE@% - Finds a single font that matches a specified set of
  17974. characteristics and makes this font the current font.%@NL@%
  17975. %@NL@%
  17976. %@AB@%Include%@AE@%                           GRAPH.H
  17977.  
  17978. %@AB@%Prototype%@AE@%                         %@AB@%short _far _setfont( unsigned char _far %@AE@%
  17979.                                   %@AB@%*%@AE@%%@AI@%options%@AE@%%@AB@%  );%@AE@%
  17980.  
  17981. %@AB@%Argument%@AE@%                          %@AI@%options%@AE@%     Font options string
  17982.  
  17983. %@AB@%Returns%@AE@%                           Void
  17984.  
  17985. ────────────────────────────────────────────────────────────────────────────
  17986. %@AB@%_unregisterfonts%@AE@% - Frees memory associated with fonts.%@NL@%
  17987. %@NL@%
  17988. %@AB@%Include%@AE@%                           GRAPH.H
  17989.  
  17990. %@AB@%Prototype%@AE@%                         %@AB@%void _far _unregisterfonts( void );%@AE@%
  17991.  
  17992. %@AB@%Arguments%@AE@%                         None
  17993.  
  17994. %@AB@%Returns%@AE@%                           Void
  17995.  
  17996. %@NL@%
  17997. %@2@%%@CR:C6A-B0010   @%%@AB@%Input and Output Routines%@AE@%%@EH@%%@NL@%
  17998. %@NL@%
  17999. The input and output (I/O) routines of the standard C library allow you to
  18000. read and write data to and from files and devices. In C, there are no
  18001. predefined file structures; all data is treated as sequences of bytes.  %@NL@%
  18002. %@NL@%
  18003. Three types of I/O functions are available:  %@NL@%
  18004. %@NL@%
  18005. %@NL@%
  18006.   ■   Stream I/O,  in which the data file is a stream of individual
  18007.       characters%@NL@%
  18008. %@NL@%
  18009.   ■   Low-level I/O, which uses the system's I/O capabilities directly%@NL@%
  18010. %@NL@%
  18011.   ■   Console and port I/O, which are stream routines for console or port%@NL@%
  18012. %@NL@%
  18013. %@NL@%
  18014. Stream I/O uses the %@AB@%FILE%@AE@% structure. The stream routines provide for
  18015. buffered, formatted, or unformatted input and output.  %@NL@%
  18016. %@NL@%
  18017. Low-level I/O uses a file "handle" to access files. This handle is an
  18018. integer value that is used to refer to the file in subsequent operations.  %@NL@%
  18019. %@NL@%
  18020. Do not mix stream and low-level routines on the same file or device.  %@NL@%
  18021. %@NL@%
  18022. %@NL@%
  18023. %@4@%%@AB@%Stream Routines%@AE@%%@EH@%%@NL@%
  18024. %@NL@%
  18025. In the stream routines listed below, the following manifest constants are
  18026. used:  %@NL@%
  18027. %@NL@%
  18028. %@NL@%
  18029.   ■   %@AB@%EOF%@AE@% is defined to be the value returned at end-of-file%@NL@%
  18030. %@NL@%
  18031.   ■   %@AB@%NULL%@AE@% is the null pointer%@NL@%
  18032. %@NL@%
  18033.   ■   %@AB@%FILE%@AE@% is the structure that maintains information about a stream%@NL@%
  18034. %@NL@%
  18035.   ■   %@AB@%BUFSIZ%@AE@% defines the default size of stream buffers, in bytes%@NL@%
  18036. %@NL@%
  18037. %@NL@%
  18038. ────────────────────────────────────────────────────────────────────────────
  18039. %@AB@%clearerr%@AE@% - Clears the error indicator for a stream.%@NL@%
  18040. %@NL@%
  18041. %@AB@%Include%@AE@%                           STDIO.H
  18042.  
  18043. %@AB@%Prototype%@AE@%                         %@AB@%void clearerr( FILE%@AE@% %@AB@%*%@AE@%%@AI@%stream  %@AE@%%@AB@%);%@AE@%
  18044.  
  18045. %@AB@%Argument%@AE@%                          %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18046.  
  18047. %@AB@%Returns%@AE@%                           Void
  18048.  
  18049. ────────────────────────────────────────────────────────────────────────────
  18050. %@AB@%fclose%@AE@% - Closes a stream.%@NL@%
  18051. %@NL@%
  18052. %@AB@%Include%@AE@%                           STDIO.H
  18053.  
  18054. %@AB@%Prototype%@AE@%                         %@AB@%int fclose( FILE *%@AE@%%@AI@%stream  %@AE@%%@AB@%);%@AE@%
  18055.  
  18056. %@AB@%Argument%@AE@%                          %@AI@%stream%@AE@%      Target %@AB@%FILE%@AE@% structure
  18057.  
  18058. %@AB@%Returns%@AE@%                           0 if successful, %@AB@%EOF%@AE@% if not
  18059.  
  18060. ────────────────────────────────────────────────────────────────────────────
  18061. %@AB@%feof%@AE@% - Tests for end-of-file on a stream.%@NL@%
  18062. %@NL@%
  18063. %@AB@%Include%@AE@%                           STDIO.H
  18064.  
  18065. %@AB@%Prototype%@AE@%                         %@AB@%int feof( FILE *%@AE@%%@AI@%stream  %@AE@%%@AB@%);%@AE@%
  18066.  
  18067. %@AB@%Argument%@AE@%                          %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18068.  
  18069. %@AB@%Returns%@AE@%                           A nonzero value when the current 
  18070.                                   position is  the end-of-file,
  18071.  
  18072.                                   0 if not
  18073.  
  18074. ────────────────────────────────────────────────────────────────────────────
  18075. %@AB@%ferror%@AE@% - Tests for error on a stream.%@NL@%
  18076. %@NL@%
  18077. %@AB@%Include%@AE@%                           STDIO.H
  18078.  
  18079. %@AB@%Prototype%@AE@%                         %@AB@%int ferror( FILE *%@AE@%%@AI@%stream  %@AE@%%@AB@%);%@AE@%
  18080.  
  18081. %@AB@%Argument%@AE@%                          %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18082.  
  18083. %@AB@%Returns%@AE@%                           A nonzero value to indicate an error in 
  18084.                                   stream,  0 to indicate
  18085.  
  18086.                                   no error
  18087.  
  18088. ────────────────────────────────────────────────────────────────────────────
  18089. %@AB@%fflush%@AE@% - Flushes a stream. %@NL@%
  18090. %@NL@%
  18091. %@AB@%Include%@AE@%                           STDIO.H
  18092.  
  18093. %@AB@%Prototype%@AE@%                         %@AB@%int fflush( FILE *%@AE@%%@AI@%stream  %@AE@%%@AB@%);%@AE@%
  18094.  
  18095. %@AB@%Argument%@AE@%                          %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18096.  
  18097. %@AB@%Returns%@AE@%                           0 if successful, if stream has no buffer,
  18098.                                   or  if stream is open
  18099.  
  18100.                                   only for reading; returns %@AB@%EOF%@AE@% otherwise
  18101.  
  18102. ────────────────────────────────────────────────────────────────────────────
  18103. %@AB@%fgetc%@AE@% - Reads a character from a stream (function version).%@NL@%
  18104. %@NL@%
  18105. %@AB@%Include%@AE@%                           STDIO.H
  18106.  
  18107. %@AB@%Prototype%@AE@%                         %@AB@%int fgetc( FILE *%@AE@%%@AI@%stream  %@AE@%%@AB@%);%@AE@%
  18108.  
  18109. %@AB@%Argument%@AE@%                          %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18110.  
  18111. %@AB@%Returns%@AE@%                           The character read; %@AB@%EOF%@AE@% may indicate  
  18112.                                   error
  18113.  
  18114. ────────────────────────────────────────────────────────────────────────────
  18115. %@AB@%fgetpos%@AE@% - Gets the position indicator of a stream.%@NL@%
  18116. %@NL@%
  18117. %@AB@%Include%@AE@%                           STDIO.H
  18118.  
  18119. %@AB@%Prototype%@AE@%                         %@AB@%int fgetpos( FILE *%@AE@%%@AI@%stream%@AE@%%@AB@%,  fpos_t *%@AE@%%@AI@%pos %@AE@%
  18120.                                   %@AB@%);%@AE@%
  18121.  
  18122. %@AB@%Arguments%@AE@%                         %@AI@%stream%@AE@%      Target stream
  18123.  
  18124.                                   %@AI@%pos%@AE@%         Position indicator storage
  18125.  
  18126. %@AB@%Returns%@AE@%                           0 if successful, a nonzero value if not
  18127.  
  18128.                                   %@AB@%errno%@AE@%:%@AB@%  EINVAL%@AE@%,%@AB@% EBADF%@AE@%
  18129.  
  18130. ────────────────────────────────────────────────────────────────────────────
  18131. %@AB@%fgets%@AE@% - Reads a string from a stream.%@NL@%
  18132. %@NL@%
  18133. %@AB@%Include%@AE@%                           STDIO.H
  18134.  
  18135. %@AB@%Prototype%@AE@%                         %@AB@%char *fgets( char *%@AE@%%@AI@%string%@AE@%%@AB@%,  int %@AE@%%@AI@%n%@AE@%%@AB@%, FILE %@AE@%
  18136.                                   %@AB@%*%@AE@%%@AI@%stream %@AE@%%@AB@%);%@AE@%
  18137.  
  18138. %@AB@%Arguments%@AE@%                         %@AI@%string%@AE@%      Storage location for data
  18139.  
  18140.                                   %@AI@%n%@AE@%           Number of characters stored
  18141.  
  18142.                                   %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18143.  
  18144. %@AB@%Returns%@AE@%                           A pointer to string if successful, %@AB@%NULL%@AE@% 
  18145.                                   if unsuccessful or at
  18146.  
  18147.                                   end-of-file
  18148.  
  18149. ────────────────────────────────────────────────────────────────────────────
  18150. %@AB@%fopen%@AE@% - Opens a stream.%@NL@%
  18151. %@NL@%
  18152. %@AB@%Include%@AE@%                           STDIO.H
  18153.  
  18154. %@AB@%Prototype%@AE@%                         %@AB@%FILE *fopen( const char *%@AE@%%@AI@%filename%@AE@%%@AB@%,  %@AE@%
  18155.                                   %@AB@%const char *%@AE@%%@AI@%mode %@AE@%%@AB@%);%@AE@%
  18156.  
  18157. %@AB@%Arguments%@AE@%                         %@AI@%filename%@AE@%    Path name of file
  18158.  
  18159.                                   %@AI@%mode%@AE@%        Type of access permitted 
  18160.                                               such as %@AB@%r%@AE@%, %@AB@%w%@AE@%,%@AB@%  a%@AE@%,%@AB@% r+%@AE@%,%@AB@% w+%@AE@%,%@AB@% a+%@AE@%
  18161.                                               ,%@AB@% t%@AE@%,%@AB@% b%@AE@%
  18162.  
  18163.                                   (appended to type to indicate mode)
  18164.  
  18165. %@AB@%Returns%@AE@%                           A pointer to the open file if successful,
  18166.                                   %@AB@%NULL%@AE@%  if not
  18167.  
  18168. ────────────────────────────────────────────────────────────────────────────
  18169. %@AB@%fprintf%@AE@% - Writes formatted data to a stream.%@NL@%
  18170. %@NL@%
  18171. %@AB@%Include%@AE@%                           STDIO.H
  18172.  
  18173. %@AB@%Prototype%@AE@%                         %@AB@%int fprintf( FILE *%@AE@%%@AI@%stream%@AE@%%@AB@%,  const char *%@AE@%
  18174.                                   %@AI@%format %@AE@%[[,%@AI@% argument%@AE@%]]...  );
  18175.  
  18176. %@AB@%Arguments%@AE@%                         %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18177.  
  18178.                                   %@AI@%format%@AE@%      Format-control string
  18179.  
  18180. %@AB@%Returns%@AE@%                           The number of characters printed
  18181.  
  18182. ────────────────────────────────────────────────────────────────────────────
  18183. %@AB@%fputc%@AE@% - Writes a character to a stream (function version).%@NL@%
  18184. %@NL@%
  18185. %@AB@%Include%@AE@%                           STDIO.H
  18186.  
  18187. %@AB@%Prototype%@AE@%                         %@AB@%int fputc( int %@AE@%%@AI@%c%@AE@%%@AB@%, FILE *%@AE@%%@AI@%stream%@AE@%%@AB@%  );%@AE@%
  18188.  
  18189. %@AB@%Arguments%@AE@%                         %@AI@%c%@AE@%           Character to be written
  18190.  
  18191.                                   %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18192.  
  18193. %@AB@%Returns%@AE@%                           The character written; %@AB@%EOF%@AE@% may indicate 
  18194.                                   error
  18195.  
  18196. ────────────────────────────────────────────────────────────────────────────
  18197. %@AB@%fputs%@AE@% - Writes a string to a stream.%@NL@%
  18198. %@NL@%
  18199. %@AB@%Include%@AE@%                           STDIO.H
  18200.  
  18201. %@AB@%Prototype%@AE@%                         %@AB@%int fputs( const char *%@AE@%%@AI@%string%@AE@%%@AB@%,  FILE *%@AE@%%@AI@%%@AE@%
  18202.                                   %@AI@%stream %@AE@%%@AB@%);%@AE@%
  18203.  
  18204. %@AB@%Arguments%@AE@%                         %@AI@%string%@AE@%      String to be output
  18205.  
  18206.                                   %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18207.  
  18208. %@AB@%Returns%@AE@%                           0 if successful, nonzero if not
  18209.  
  18210. ────────────────────────────────────────────────────────────────────────────
  18211. %@AB@%fread%@AE@% - Reads unformatted data from a stream. %@NL@%
  18212. %@NL@%
  18213. %@AB@%Include%@AE@%                           STDIO.H
  18214.  
  18215. %@AB@%Prototype%@AE@%                         %@AB@%size_t fread( void *%@AE@%%@AI@%buffer%@AE@%%@AB@%,  size_t %@AE@%%@AI@%size%@AE@%
  18216.                                   %@AB@%, size_t %@AE@%%@AI@%count%@AE@%%@AB@%, FILE *%@AE@%%@AI@%stream  %@AE@%%@AB@%);%@AE@%
  18217.  
  18218. %@AB@%Arguments%@AE@%                         %@AI@%buffer%@AE@%      Storage location for data
  18219.  
  18220.                                   %@AI@%size%@AE@%        Item size in bytes
  18221.  
  18222.                                   %@AI@%count%@AE@%       Maximum number of items to 
  18223.                                               be read
  18224.  
  18225.                                   %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18226.  
  18227. %@AB@%Returns%@AE@%                           The number of items actually read
  18228.  
  18229. ────────────────────────────────────────────────────────────────────────────
  18230. %@AB@%freopen%@AE@% - Reassigns a %@AB@%FILE%@AE@% pointer. %@NL@%
  18231. %@NL@%
  18232. %@AB@%Include%@AE@%                           STDIO.H
  18233.  
  18234. %@AB@%Prototype%@AE@%                         %@AB@%FILE *freopen( const char  *%@AE@%%@AI@%filename%@AE@%%@AB@%, %@AE@%
  18235.                                   %@AB@%const char *%@AE@%%@AI@%mode%@AE@%%@AB@%,%@AE@%
  18236.  
  18237.                                   FILE *%@AI@%stream %@AE@%%@AB@%);%@AE@%
  18238.  
  18239. %@AB@%Arguments%@AE@%                         %@AI@%filename%@AE@%    Path name of new file
  18240.  
  18241.                                   %@AI@%mode%@AE@%        Type of access permitted 
  18242.                                               such as %@AB@%r,  w,  a,  r+,  w+,%@AE@%
  18243.  
  18244.                                   a+,  t,  b (appended to type to indicate
  18245.                                   mode)
  18246.  
  18247.                                   %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18248.  
  18249. %@AB@%Returns%@AE@%                           A pointer to the newly opened file if 
  18250.                                   successful,  a %@AB@%NULL%@AE@%
  18251.  
  18252.                                   pointer if not
  18253.  
  18254. ────────────────────────────────────────────────────────────────────────────
  18255. %@AB@%fscanf%@AE@% - Reads formatted data from a stream.%@NL@%
  18256. %@NL@%
  18257. %@AB@%Include%@AE@%                           STDIO.H
  18258.  
  18259. %@AB@%Prototype%@AE@%                         %@AB@%int fscanf( FILE *%@AE@%%@AI@%stream%@AE@%%@AB@%,  const char* %@AE@%%@AI@%%@AE@%
  18260.                                   %@AI@%format %@AE@%%@AB@% %@AE@%[[%@AB@%,%@AE@%%@AI@% argument%@AE@%]]  ... );
  18261.  
  18262. %@AB@%Arguments%@AE@%                         %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18263.  
  18264.                                   %@AI@%format%@AE@%      Format-control string
  18265.  
  18266. %@AB@%Returns%@AE@%                           The number of fields successfully 
  18267.                                   converted and  assigned;
  18268.  
  18269.                                   %@AB@%EOF%@AE@% indicates an attempt to read the 
  18270.                                   end-of-file
  18271.  
  18272. ────────────────────────────────────────────────────────────────────────────
  18273. %@AB@%fseek%@AE@% - Repositions %@AB@%FILE%@AE@% pointer to given location.%@NL@%
  18274. %@NL@%
  18275. %@AB@%Include%@AE@%                           STDIO.H
  18276.  
  18277. %@AB@%Prototype%@AE@%                         %@AB@%int fseek( FILE *%@AE@%%@AI@%stream%@AE@%%@AB@%,  long %@AE@%%@AI@%offset%@AE@%%@AB@%, %@AE@%
  18278.                                   %@AB@%int %@AE@%%@AI@%origin%@AE@%%@AB@% );%@AE@%
  18279.  
  18280. %@AB@%Arguments%@AE@%                         %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18281.  
  18282.                                   %@AI@%offset%@AE@%      Number of bytes from origin
  18283.  
  18284.                                   %@AI@%origin%@AE@%      Initial position (%@AB@%SEEK_SET%@AE@%,%@AB@% %@AE@%
  18285.                                               %@AB@%SEEK_CUR%@AE@%,%@AB@%  SEEK_END)%@AE@%
  18286.  
  18287. %@AB@%Returns%@AE@%                           0 if successful, a nonzero value if not
  18288.  
  18289. ────────────────────────────────────────────────────────────────────────────
  18290. %@AB@%fsetpos%@AE@% - Sets the position indicator of a stream.%@NL@%
  18291. %@NL@%
  18292. %@AB@%Include%@AE@%                           STDIO.H
  18293.  
  18294. %@AB@%Prototype%@AE@%                         %@AB@%int fsetpos( FILE *%@AE@%%@AI@%stream%@AE@%%@AB@%,  const fpos_t%@AE@%
  18295.                                   %@AB@%*%@AE@%%@AI@%pos %@AE@%%@AB@%);%@AE@%
  18296.  
  18297. %@AB@%Arguments%@AE@%                         %@AI@%stream%@AE@%      Target stream
  18298.  
  18299.                                   %@AI@%pos%@AE@%         Position-indicator storage
  18300.  
  18301. %@AB@%Returns%@AE@%                           0 if successful, a nonzero value if not
  18302.  
  18303.                                   %@AB@%errno%@AE@%:  %@AB@%EINVAL%@AE@%, %@AB@%EBADF%@AE@%
  18304.  
  18305. ────────────────────────────────────────────────────────────────────────────
  18306. %@AB@%ftell%@AE@% - Gets current %@AB@%FILE%@AE@% pointer position.%@NL@%
  18307. %@NL@%
  18308. %@AB@%Include%@AE@%                           STDIO.H
  18309.  
  18310. %@AB@%Prototype%@AE@%                         %@AB@%long ftell( FILE *%@AE@%%@AI@%stream%@AE@%%@AB@%  );%@AE@%
  18311.  
  18312. %@AB@%Argument%@AE@%                          %@AI@%stream%@AE@%      Target %@AB@%FILE%@AE@% structure
  18313.  
  18314. %@AB@%Returns%@AE@%                           The current position if successful, -1L 
  18315.                                   if  not
  18316.  
  18317.                                   %@AB@%errno%@AE@%:  %@AB@%EINVAL%@AE@%, %@AB@%EBADF%@AE@%
  18318.  
  18319. ────────────────────────────────────────────────────────────────────────────
  18320. %@AB@%fwrite%@AE@% - Writes unformatted data items to a stream.%@NL@%
  18321. %@NL@%
  18322. %@AB@%Include%@AE@%                           STDIO.H
  18323.  
  18324. %@AB@%Prototype%@AE@%                         %@AB@%size_t fwrite( const void *%@AE@%%@AI@%buffer%@AE@%%@AB@%,  %@AE@%
  18325.                                   %@AB@%size_t %@AE@%%@AI@%size%@AE@%%@AB@%, size_t %@AE@%%@AI@%count%@AE@%%@AB@%,%@AE@%
  18326.  
  18327.                                   FILE *%@AI@%stream %@AE@%%@AB@%);%@AE@%
  18328.  
  18329. %@AB@%Arguments%@AE@%                         %@AI@%buffer%@AE@%      Pointer to data to be 
  18330.                                               written
  18331.  
  18332.                                   %@AI@%size%@AE@%        Item size in bytes
  18333.  
  18334.                                   %@AI@%count%@AE@%       Maximum number of items to 
  18335.                                               be written
  18336.  
  18337.                                   %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18338.  
  18339. %@AB@%Returns%@AE@%                           The number of full items actually 
  18340.                                   written
  18341.  
  18342. ────────────────────────────────────────────────────────────────────────────
  18343. %@AB@%getc%@AE@% - Reads a character from a stream (macro version). %@NL@%
  18344. %@NL@%
  18345. %@AB@%Include%@AE@%                           STDIO.H
  18346.  
  18347. %@AB@%Prototype%@AE@%                         %@AB@%int getc( FILE *%@AE@%%@AI@%stream  %@AE@%%@AB@%);%@AE@%
  18348.  
  18349. %@AB@%Argument%@AE@%                          %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18350.  
  18351. %@AB@%Returns%@AE@%                           The character read; %@AB@%EOF%@AE@% may indicate  
  18352.                                   error
  18353.  
  18354. ────────────────────────────────────────────────────────────────────────────
  18355. %@AB@%getchar%@AE@% - Reads a character from %@AB@%stdin%@AE@% (macro version).%@NL@%
  18356. %@NL@%
  18357. %@AB@%Include%@AE@%                           STDIO.H
  18358.  
  18359. %@AB@%Prototype%@AE@%                         %@AB@%int getchar( void );%@AE@%
  18360.  
  18361. %@AB@%Arguments%@AE@%                         None
  18362.  
  18363. %@AB@%Returns%@AE@%                           The character read; %@AB@%EOF%@AE@% may indicate  
  18364.                                   error
  18365.  
  18366. ────────────────────────────────────────────────────────────────────────────
  18367. %@AB@%gets%@AE@% - Reads a line from %@AB@%stdin%@AE@%.%@NL@%
  18368. %@NL@%
  18369. %@AB@%Include%@AE@%                           STDIO.H
  18370.  
  18371. %@AB@%Prototype%@AE@%                         %@AB@%char *gets( char *%@AE@%%@AI@%buffer%@AE@%%@AB@%  );%@AE@%
  18372.  
  18373. %@AB@%Argument%@AE@%                          %@AI@%buffer%@AE@%      Storage location for input 
  18374.                                               string
  18375.  
  18376. %@AB@%Returns%@AE@%                           A pointer to its argument if successful,
  18377.                                   a %@AB@%NULL%@AE@%  pointer if at
  18378.  
  18379.                                   end-of-file or unsuccessful
  18380.  
  18381. ────────────────────────────────────────────────────────────────────────────
  18382. %@AB@%printf%@AE@% - Writes formatted data to %@AB@%stdout%@AE@%.%@NL@%
  18383. %@NL@%
  18384. %@AB@%Include%@AE@%                           STDIO.H
  18385.  
  18386. %@AB@%Prototype%@AE@%                         %@AB@%int printf( const char *%@AE@%%@AI@%format%@AE@%%@AB@%  %@AE@%[[, %@AI@%%@AE@%
  18387.                                   %@AI@%argument%@AE@%]]... );
  18388.  
  18389. %@AB@%Argument%@AE@%                          %@AI@%format%@AE@%      Format-control string
  18390.  
  18391. %@AB@%Returns%@AE@%                           The number of characters printed
  18392.  
  18393. ────────────────────────────────────────────────────────────────────────────
  18394. %@AB@%putc%@AE@% - Writes a character to a stream (macro version). %@NL@%
  18395. %@NL@%
  18396. %@AB@%Include%@AE@%                           STDIO.H
  18397.  
  18398. %@AB@%Prototype%@AE@%                         %@AB@%int putc( int %@AE@%%@AI@%c%@AE@%%@AB@%, FILE *%@AE@%%@AI@%stream  %@AE@%%@AB@%);%@AE@%
  18399.  
  18400. %@AB@%Arguments%@AE@%                         %@AI@%c%@AE@%           Character to be written
  18401.  
  18402.                                   %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18403.  
  18404. %@AB@%Returns%@AE@%                           The character written; %@AB@%EOF%@AE@% may indicate 
  18405.                                   error
  18406.  
  18407. ────────────────────────────────────────────────────────────────────────────
  18408. %@AB@%putchar%@AE@% - Writes a character to %@AB@%stdout%@AE@% (macro version).%@NL@%
  18409. %@NL@%
  18410. %@AB@%Include%@AE@%                           STDIO.H
  18411.  
  18412. %@AB@%Prototype%@AE@%                         %@AB@%int putchar( int %@AE@%%@AI@%c %@AE@%%@AB@%);%@AE@%
  18413.  
  18414. %@AB@%Argument%@AE@%                          %@AI@%c%@AE@%           Character to be written
  18415.  
  18416. %@AB@%Returns%@AE@%                           The character written; %@AB@%EOF%@AE@% may indicate 
  18417.                                   error
  18418.  
  18419. ────────────────────────────────────────────────────────────────────────────
  18420. %@AB@%puts%@AE@% - Writes a line to a stream.%@NL@%
  18421. %@NL@%
  18422. %@AB@%Include%@AE@%                           STDIO.H
  18423.  
  18424. %@AB@%Prototype%@AE@%                         %@AB@%int puts( const char *%@AE@%%@AI@%string %@AE@%%@AB@%);%@AE@%
  18425.  
  18426. %@AB@%Argument%@AE@%                          %@AI@%string%@AE@%      String to be output
  18427.  
  18428. %@AB@%Returns%@AE@%                           0 if successful, nonzero if not
  18429.  
  18430. ────────────────────────────────────────────────────────────────────────────
  18431. %@AB@%rewind%@AE@% - Repositions %@AB@%FILE%@AE@% pointer to beginning of a stream.%@NL@%
  18432. %@NL@%
  18433. %@AB@%Include%@AE@%                           STDIO.H
  18434.  
  18435. %@AB@%Prototype%@AE@%                         %@AB@%void rewind( FILE *%@AE@%%@AI@%stream  %@AE@%%@AB@%);%@AE@%
  18436.  
  18437. %@AB@%Argument%@AE@%                          %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18438.  
  18439. %@AB@%Returns%@AE@%                           Void
  18440.  
  18441. ────────────────────────────────────────────────────────────────────────────
  18442. %@AB@%scanf%@AE@% - Reads formatted data from %@AB@%stdin%@AE@%.%@NL@%
  18443. %@NL@%
  18444. %@AB@%Include%@AE@%                           STDIO.H
  18445.  
  18446. %@AB@%Prototype%@AE@%                         %@AB@%int scanf( const char *%@AE@%%@AI@%format %@AE@%[[,  %@AI@%%@AE@%
  18447.                                   %@AI@%argument%@AE@%]]... );
  18448.  
  18449. %@AB@%Argument%@AE@%                          %@AI@%format%@AE@%      Format control string
  18450.  
  18451. %@AB@%Returns%@AE@%                           The number of fields converted and 
  18452.                                   assigned if  successful, 0 if
  18453.  
  18454.                                   no fields were assigned, %@AB@%EOF%@AE@% for an 
  18455.                                   attempt to read  end-of-file
  18456.  
  18457. ────────────────────────────────────────────────────────────────────────────
  18458. %@AB@%sprintf%@AE@% - Writes formatted data to string.%@NL@%
  18459. %@NL@%
  18460. %@AB@%Include%@AE@%                           STDIO.H
  18461.  
  18462. %@AB@%Prototype%@AE@%                         %@AB@%int sprintf( char *%@AE@%%@AI@%buffer%@AE@%%@AB@%, const  char *%@AE@%
  18463.                                   %@AI@%format %@AE@%[[, %@AI@%argument%@AE@%]]  ... );%@AI@%%@AE@%
  18464.  
  18465. %@AB@%Arguments%@AE@%                         %@AI@%buffer%@AE@%      Storage location for output
  18466.  
  18467.                                   %@AI@%format%@AE@%      Format-control string
  18468.  
  18469. %@AB@%Returns%@AE@%                           The number of characters stored in 
  18470.                                   buffer
  18471.  
  18472. ────────────────────────────────────────────────────────────────────────────
  18473. %@AB@%sscanf%@AE@% - Reads formatted data from string.%@NL@%
  18474. %@NL@%
  18475. %@AB@%Include%@AE@%                           STDIO.H
  18476.  
  18477. %@AB@%Prototype%@AE@%                         %@AB@%int sscanf( const char *%@AE@%%@AI@%buffer%@AE@%%@AB@%,  const %@AE@%
  18478.                                   %@AB@%char *%@AE@%%@AI@%format %@AE@%[[, %@AI@%argument%@AE@%]]  ... );
  18479.  
  18480. %@AB@%Arguments%@AE@%                         %@AI@%buffer%@AE@%      Stored data
  18481.  
  18482.                                   %@AI@%format%@AE@%      Format-control string
  18483.  
  18484. %@AB@%Returns%@AE@%                           The number of fields converted and 
  18485.                                   assigned if  successful, 0 if
  18486.  
  18487.                                   no fields were assigned, %@AB@%EOF%@AE@% for an 
  18488.                                   attempt to read  at end-of-string
  18489.  
  18490. ────────────────────────────────────────────────────────────────────────────
  18491. %@AB@%tmpfile%@AE@% - Creates a temporary file.%@NL@%
  18492. %@NL@%
  18493. %@AB@%Include%@AE@%                           STDIO.H
  18494.  
  18495. %@AB@%Prototype%@AE@%                         %@AB@%FILE *tmpfile( void );%@AE@%
  18496.  
  18497. %@AB@%Arguments%@AE@%                         None
  18498.  
  18499. %@AB@%Returns%@AE@%                           A stream pointer if successful, %@AB@%NULL%@AE@%  if
  18500.                                   not
  18501.  
  18502. ────────────────────────────────────────────────────────────────────────────
  18503. %@AB@%tmpnam%@AE@% - Generates a temporary file name.%@NL@%
  18504. %@NL@%
  18505. %@AB@%Include%@AE@%                           STDIO.H
  18506.  
  18507. %@AB@%Prototype%@AE@%                         %@AB@%char *tmpnam( char *%@AE@%%@AI@%string  %@AE@%%@AB@%);%@AE@%
  18508.  
  18509. %@AB@%Argument%@AE@%                          %@AI@%string%@AE@%      Pointer to temporary name
  18510.  
  18511. %@AB@%Returns%@AE@%                           A pointer to the new name if successful,
  18512.                                   %@AB@%NULL%@AE@%  if not
  18513.  
  18514. ────────────────────────────────────────────────────────────────────────────
  18515. %@AB@%ungetc%@AE@% - Places a character in the input stream buffer.%@NL@%
  18516. %@NL@%
  18517. %@AB@%Include%@AE@%                           STDIO.H
  18518.  
  18519. %@AB@%Prototype%@AE@%                         %@AB@%int ungetc( int %@AE@%%@AI@%c%@AE@%%@AB@%, FILE  *%@AE@%%@AI@%stream %@AE@%%@AB@%);%@AE@%
  18520.  
  18521. %@AB@%Arguments%@AE@%                         %@AI@%c%@AE@%           Character to be pushed
  18522.  
  18523.                                   %@AI@%stream%@AE@%      Pointer to %@AB@%FILE%@AE@% structure
  18524.  
  18525. %@AB@%Returns%@AE@%                           The character argument %@AI@%c%@AE@% if successful, 
  18526.                                   %@AB@%EOF%@AE@% if not
  18527.  
  18528. %@NL@%
  18529. %@4@%%@AB@%Low-Level Routines%@AE@%%@EH@%%@NL@%
  18530. %@NL@%
  18531. The low-level input and output calls do not buffer or format data.  %@NL@%
  18532. %@NL@%
  18533. Files opened by low-level calls are referenced by a "file handle," an
  18534. integer value used by the operating system to refer to the file.  %@NL@%
  18535. %@NL@%
  18536. ────────────────────────────────────────────────────────────────────────────
  18537. %@AB@%close%@AE@% - Closes a file.%@NL@%
  18538. %@NL@%
  18539. %@AB@%Include%@AE@%                           IO.H
  18540.  
  18541. %@AB@%Prototype%@AE@%                         %@AB@%int close( int %@AE@%%@AI@%handle%@AE@%%@AB@% );%@AE@%
  18542.  
  18543. %@AB@%Argument%@AE@%                          %@AI@%handle%@AE@%      Handle referring to open 
  18544.                                               file
  18545.  
  18546. %@AB@%Returns%@AE@%                           0 if successful, -1 if not
  18547.  
  18548.                                   %@AB@%errno%@AE@%: %@AB@%EBADF%@AE@%
  18549.  
  18550. ────────────────────────────────────────────────────────────────────────────
  18551. %@AB@%creat %@AE@% - Creates a file.%@NL@%
  18552. %@NL@%
  18553. %@AB@%Include%@AE@%                           IO.H, SYS\TYPES.H, SYS\STAT.H
  18554.  
  18555. %@AB@%Prototype%@AE@%                         %@AB@%int creat( char *%@AE@%%@AI@%filename%@AE@%%@AB@%, int  %@AE@%%@AI@%pmode %@AE@%%@AB@%);%@AE@%
  18556.  
  18557. %@AB@%Arguments%@AE@%                         %@AI@%filename%@AE@%    Path name of new file
  18558.  
  18559.                                   %@AI@%pmode%@AE@%       Permission setting ( %@AB@%%@AE@%
  18560.                                               %@AB@%S_IWRITE , S_IREAD%@AE@%,%@AB@%  %@AE@%
  18561.  
  18562.                                   S_IREAD | S_IWRITE)
  18563.  
  18564. %@AB@%Returns%@AE@%                           A handle if successful, -1 if not
  18565.  
  18566.                                   %@AB@%errno%@AE@%:  %@AB@%EACCES%@AE@%, %@AB@%EMFILE%@AE@%, %@AB@%ENOENT%@AE@%
  18567.  
  18568. ────────────────────────────────────────────────────────────────────────────
  18569. %@AB@%eof %@AE@% - Tests for end-of-file.%@NL@%
  18570. %@NL@%
  18571. %@AB@%Include%@AE@%                           IO.H
  18572.  
  18573. %@AB@%Prototype%@AE@%                         %@AB@%int eof( int %@AE@%%@AI@%handle%@AE@%%@AB@% );%@AE@%
  18574.  
  18575. %@AB@%Argument%@AE@%                          %@AI@%handle%@AE@%      Handle referring to open 
  18576.                                               file
  18577.  
  18578. %@AB@%Returns%@AE@%                           1 if the current position is the 
  18579.                                   end-of-file  and 0 if it is not,
  18580.  
  18581.                                   -1 to indicate an error
  18582.  
  18583.                                   %@AB@%errno%@AE@%:  %@AB@%EBADF%@AE@%
  18584.  
  18585. ────────────────────────────────────────────────────────────────────────────
  18586. %@AB@%lseek %@AE@% - Repositions file pointer to a given location. %@NL@%
  18587. %@NL@%
  18588. %@AB@%Include%@AE@%                           IO.H, STDIO.H
  18589.  
  18590. %@AB@%Prototype%@AE@%                         %@AB@%long lseek( int %@AE@%%@AI@%handle%@AE@%%@AB@%, long %@AE@%%@AI@%offset%@AE@%%@AB@%,  %@AE@%
  18591.                                   %@AB@%int %@AE@%%@AI@%origin%@AE@%%@AB@% );%@AE@%
  18592.  
  18593. %@AB@%Arguments%@AE@%                         %@AI@%handle%@AE@%      Handle referring to open 
  18594.                                               file
  18595.  
  18596.                                   %@AI@%offset%@AE@%      Number of bytes from origin
  18597.  
  18598.                                   %@AI@%origin%@AE@%      Initial position (%@AB@%SEEK_SET%@AE@%,%@AB@% %@AE@%
  18599.                                               %@AB@%SEEK_CUR%@AE@%,%@AB@%  SEEK_END)%@AE@%
  18600.  
  18601. %@AB@%Returns%@AE@%                           The new position offset (in bytes) from 
  18602.                                   the beginning  of
  18603.  
  18604.                                   the file if successful, -1L if not
  18605.  
  18606.                                   %@AB@%errno%@AE@%:  %@AB@%EBADF%@AE@%, %@AB@%EINVAL%@AE@%
  18607.  
  18608. ────────────────────────────────────────────────────────────────────────────
  18609. %@AB@%open %@AE@% - Opens a file.%@NL@%
  18610. %@NL@%
  18611. %@AB@%Include%@AE@%                           FCNTL.H, IO.H, SYS\TYPES.H, SYS\STAT.H
  18612.  
  18613. %@AB@%Prototype%@AE@%                         %@AB@%int open( char *%@AE@%%@AI@%path%@AE@%%@AB@%, int %@AE@%%@AI@%oflag %@AE@%[[,  int
  18614.                                   %@AI@%pmode%@AE@%]] );
  18615.  
  18616. %@AB@%Arguments%@AE@%                         %@AI@%path%@AE@%        File path name
  18617.  
  18618.                                   %@AI@%oflag%@AE@%       Type of operations allowed 
  18619.                                               such as %@AB@%O_APPEND%@AE@%,%@AB@%%@AE@%
  18620.  
  18621.                                   O_BINARY,%@AB@% O_CREAT%@AE@%,%@AB@%  O_EXCL%@AE@%, %@AB@%  O_RDONLY%@AE@%,%@AB@%%@AE@%
  18622.  
  18623.                                   O_RDWR,%@AB@%   O_TEXT%@AE@%,%@AB@%   O_TRUNC%@AE@%,%@AB@%  O_WRONLY%@AE@%
  18624.  
  18625.                                   (may be joined by%@AB@% |%@AE@% )
  18626.  
  18627.                                   %@AI@%pmode%@AE@%       Permission setting (%@AB@%S_IWRITE%@AE@%
  18628.                                               ,%@AB@%  S_IREAD%@AE@%,%@AB@%%@AE@%
  18629.  
  18630.                                   S_IREAD | S_IWRITE)
  18631.  
  18632. %@AB@%Returns%@AE@%                           A handle if successful, -1 if not
  18633.  
  18634.                                   %@AB@%errno%@AE@%:  %@AB@%EACCES%@AE@%, %@AB@%EEXIST%@AE@%, %@AB@%EMFILE%@AE@%,  %@AB@%ENOENT%@AE@%
  18635.  
  18636. ────────────────────────────────────────────────────────────────────────────
  18637. %@AB@%read %@AE@% - Reads data from a file.%@NL@%
  18638. %@NL@%
  18639. %@AB@%Include%@AE@%                           IO.H
  18640.  
  18641. %@AB@%Prototype%@AE@%                         %@AB@%int read( int %@AE@%%@AI@%handle%@AE@%%@AB@%, char *%@AE@%%@AI@%buffer%@AE@%%@AB@%,  %@AE@%
  18642.                                   %@AB@%unsigned int %@AE@%%@AI@%count%@AE@%%@AB@% );%@AE@%
  18643.  
  18644. %@AB@%Arguments%@AE@%                         %@AI@%handle%@AE@%      Handle referring to open 
  18645.                                               file
  18646.  
  18647.                                   %@AI@%buffer%@AE@%      Storage location of data
  18648.  
  18649.                                   %@AI@%count%@AE@%       Maximum number of bytes
  18650.  
  18651. %@AB@%Returns%@AE@%                           The number of bytes actually read or 0 
  18652.                                   at end-of-file  if
  18653.  
  18654.                                   successful; -1 if not
  18655.  
  18656.                                   %@AB@%errno%@AE@%:  %@AB@%EBADF%@AE@%
  18657.  
  18658. ────────────────────────────────────────────────────────────────────────────
  18659. %@AB@%tell %@AE@% - Gets current file-pointer position.%@NL@%
  18660. %@NL@%
  18661. %@AB@%Include%@AE@%                           IO.H
  18662.  
  18663. %@AB@%Prototype%@AE@%                         %@AB@%long tell( int %@AE@%%@AI@%handle %@AE@%%@AB@%);%@AE@%
  18664.  
  18665. %@AB@%Argument%@AE@%                          %@AI@%handle%@AE@%      Handle referring to open 
  18666.                                               file
  18667.  
  18668. %@AB@%Returns%@AE@%                           The current position if successful, -1L 
  18669.                                   if  not
  18670.  
  18671.                                   %@AB@%errno%@AE@%:  %@AB@%EBADF%@AE@%
  18672.  
  18673. ────────────────────────────────────────────────────────────────────────────
  18674. %@AB@%write %@AE@% - Writes data to a file.%@NL@%
  18675. %@NL@%
  18676. %@AB@%Include%@AE@%                           IO.H
  18677.  
  18678. %@AB@%Prototype%@AE@%                         %@AB@%int write( int %@AE@%%@AI@%handle%@AE@%%@AB@%, void *%@AE@%%@AI@%buffer%@AE@%%@AB@%,  %@AE@%
  18679.                                   %@AB@%unsigned int %@AE@%%@AI@%count %@AE@%%@AB@%);%@AE@%
  18680.  
  18681. %@AB@%Arguments%@AE@%                         %@AI@%handle%@AE@%      Handle referring to open 
  18682.                                               file
  18683.  
  18684.                                   %@AI@%buffer%@AE@%      Data to be written
  18685.  
  18686.                                   %@AI@%count%@AE@%       Number of bytes
  18687.  
  18688. %@AB@%Returns%@AE@%                           The number of bytes actually written if 
  18689.                                   successful,  -1 if not
  18690.  
  18691.                                   %@AB@%errno%@AE@%: %@AB@% EBADF%@AE@%, %@AB@%ENOSPC%@AE@%
  18692.  
  18693.   %@NL@%
  18694. %@NL@%
  18695. %@NL@%
  18696. %@4@%%@AB@%Console and Port I/O Routines%@AE@%%@EH@%%@NL@%
  18697. %@NL@%
  18698. The console and port I/O routines perform reading and writing operations on
  18699. your console or on the specified port.  %@NL@%
  18700. %@NL@%
  18701. The %@AB@%cgets%@AE@%, %@AB@%cscanf%@AE@%, %@AB@%getch%@AE@%, %@AB@%getche%@AE@%, and %@AB@%kbhit%@AE@% routines take input from the
  18702. console.  %@NL@%
  18703. %@NL@%
  18704. The %@AB@%cprintf%@AE@%, %@AB@%cputs%@AE@%, %@AB@%putch%@AE@%, and %@AB@%ungetch%@AE@% routines write to the console.  %@NL@%
  18705. %@NL@%
  18706. The console or port does not have to be opened or closed before I/O is
  18707. performed.  %@NL@%
  18708. %@NL@%
  18709. The console I/O routines use the corresponding MS-DOS system calls to read
  18710. and write characters. Since these routines are not compatible with stream or
  18711. low-level library routines, console routines should not be used with them.  %@NL@%
  18712. %@NL@%
  18713. ────────────────────────────────────────────────────────────────────────────
  18714. %@AB@%cgets%@AE@% - Reads a string from the console.%@NL@%
  18715. %@NL@%
  18716. %@AB@%Include%@AE@%                           CONIO.H
  18717.  
  18718. %@AB@%Prototype%@AE@%                         %@AB@%char *cgets( char *%@AE@%%@AI@%buffer  %@AE@%%@AB@%);%@AE@%
  18719.  
  18720. %@AB@%Argument%@AE@%                          %@AI@%buffer%@AE@%      Storage location for data
  18721.  
  18722. %@AB@%Returns%@AE@%                           A pointer to the start of the string, 
  18723.                                   which is  at %@AI@%str%@AE@%[2]
  18724.  
  18725. ────────────────────────────────────────────────────────────────────────────
  18726. %@AB@%cprintf%@AE@% - Writes formatted data to the console.%@NL@%
  18727. %@NL@%
  18728. %@AB@%Include%@AE@%                           CONIO.H
  18729.  
  18730. %@AB@%Prototype%@AE@%                         %@AB@%int cprintf( char *%@AE@%%@AI@%format %@AE@%[[,  %@AI@%argument%@AE@%]]
  18731.                                   ... );
  18732.  
  18733. %@AB@%Argument%@AE@%                          %@AI@%format%@AE@%      Format-control string
  18734.  
  18735. %@AB@%Returns%@AE@%                           The number of characters printed
  18736.  
  18737. ────────────────────────────────────────────────────────────────────────────
  18738. %@AB@%cputs%@AE@% - Writes a string to the console.%@NL@%
  18739. %@NL@%
  18740. %@AB@%Include%@AE@%                           CONIO.H
  18741.  
  18742. %@AB@%Prototype%@AE@%                         %@AB@%int cputs( char *%@AE@%%@AI@%string %@AE@%%@AB@%);%@AE@%
  18743.  
  18744. %@AB@%Argument%@AE@%                          %@AI@%string%@AE@%      Output string
  18745.  
  18746. %@AB@%Returns%@AE@%                           0 if successful, nonzero if not
  18747.  
  18748. ────────────────────────────────────────────────────────────────────────────
  18749. %@AB@%cscanf%@AE@% - Reads formatted data from the console.%@NL@%
  18750. %@NL@%
  18751. %@AB@%Include%@AE@%                           CONIO.H
  18752.  
  18753. %@AB@%Prototype%@AE@%                         %@AB@%int cscanf( char *%@AE@%%@AI@%format %@AE@%[[,  %@AI@%argument%@AE@%
  18754.                                   ]]... );
  18755.  
  18756. %@AB@%Argument%@AE@%                          %@AI@%format%@AE@%      Format-control string
  18757.  
  18758. %@AB@%Returns%@AE@%                           The number of fields converted and 
  18759.                                   assigned if  successful
  18760.  
  18761.                                   (0 means no fields were assigned), %@AB@%EOF%@AE@% 
  18762.                                   for an attempt  to read
  18763.  
  18764.                                   end-of-file
  18765.  
  18766. ────────────────────────────────────────────────────────────────────────────
  18767. %@AB@%getch%@AE@% - Reads a character from the console.%@NL@%
  18768. %@NL@%
  18769. %@AB@%Include%@AE@%                           CONIO.H
  18770.  
  18771. %@AB@%Prototype%@AE@%                         %@AB@%int getch( void );%@AE@%
  18772.  
  18773. %@AB@%Arguments%@AE@%                         None
  18774.  
  18775. %@AB@%Returns%@AE@%                           The character read
  18776.  
  18777. ────────────────────────────────────────────────────────────────────────────
  18778. %@AB@%getche%@AE@% - Reads a character from the console and echoes it.%@NL@%
  18779. %@NL@%
  18780. %@AB@%Include%@AE@%                           CONIO.H
  18781.  
  18782. %@AB@%Prototype%@AE@%                         %@AB@%int getche( void );%@AE@%
  18783.  
  18784. %@AB@%Arguments%@AE@%                         None
  18785.  
  18786. %@AB@%Returns%@AE@%                           The character read
  18787.  
  18788. ────────────────────────────────────────────────────────────────────────────
  18789. %@AB@%kbhit%@AE@% - Checks for a keystroke at the console.%@NL@%
  18790. %@NL@%
  18791. %@AB@%Include%@AE@%                           CONIO.H
  18792.  
  18793. %@AB@%Prototype%@AE@%                         %@AB@%int kbhit( void );%@AE@%
  18794.  
  18795. %@AB@%Arguments%@AE@%                         None
  18796.  
  18797. %@AB@%Returns%@AE@%                           A nonzero value if a key has been 
  18798.                                   pressed, 0  if not
  18799.  
  18800. ────────────────────────────────────────────────────────────────────────────
  18801. %@AB@%putch%@AE@% - Writes a character to the console.%@NL@%
  18802. %@NL@%
  18803. %@AB@%Include%@AE@%                           CONIO.H
  18804.  
  18805. %@AB@%Prototype%@AE@%                         %@AB@%int putch( int %@AE@%%@AI@%c%@AE@%%@AB@% );%@AE@%
  18806.  
  18807. %@AB@%Argument%@AE@%                          %@AI@%c%@AE@%           Character to be output
  18808.  
  18809. %@AB@%Returns%@AE@%                           The argument %@AI@%c%@AE@% if successful, %@AB@%EOF%@AE@%  if 
  18810.                                   not
  18811.  
  18812. ────────────────────────────────────────────────────────────────────────────
  18813. %@AB@%ungetch%@AE@% - "Ungets" the last character read from the console so that it
  18814. becomes the next character read.%@NL@%
  18815. %@NL@%
  18816. %@AB@%Include%@AE@%                           CONIO.H
  18817.  
  18818. %@AB@%Prototype%@AE@%                         %@AB@%int ungetch( int %@AE@%%@AI@%c %@AE@%%@AB@%);%@AE@%
  18819.  
  18820. %@AB@%Argument%@AE@%                          %@AI@%c%@AE@%           Character to be pushed
  18821.  
  18822. %@AB@%Returns%@AE@%                           The argument %@AI@%c%@AE@% if successful, %@AB@%EOF%@AE@%  if 
  18823.                                   not
  18824.  
  18825. %@NL@%
  18826. %@2@%%@CR:C6A-B0011   @%%@AB@%Math Routines%@AE@%%@EH@%%@NL@%
  18827. %@NL@%
  18828. The math routines allow you to perform common mathematical calculations.  %@NL@%
  18829. %@NL@%
  18830. All math routines work with floating-point values and therefore require
  18831. floating-point support.  %@NL@%
  18832. %@NL@%
  18833. ────────────────────────────────────────────────────────────────────────────
  18834. %@AB@%abs, fabs, labs%@AE@% - The %@AB@%abs%@AE@%, %@AB@%fabs%@AE@%, and %@AB@%labs%@AE@% routines return the absolute value
  18835. of an integer, a double, and a long argument, respectively.%@NL@%
  18836. %@NL@%
  18837. %@AB@%Includes%@AE@%                          STDLIB.H (%@AB@%abs%@AE@%, %@AB@%labs%@AE@%), MATH.H (%@AB@%fabs%@AE@%)
  18838.  
  18839. %@AB@%Prototypes%@AE@%                        %@AB@%int abs( int %@AE@%%@AI@%n %@AE@%%@AB@%)%@AE@%;
  18840.  
  18841.  
  18842.  
  18843.                                   %@AB@%double fabs( double%@AE@% %@AI@%x %@AE@%%@AB@%);%@AE@%
  18844.  
  18845.  
  18846.  
  18847.                                   long labs( long %@AI@%x %@AE@%%@AB@%);%@AE@%
  18848.  
  18849. %@AB@%Arguments%@AE@%                         %@AI@%n%@AE@%           Integer (%@AB@%abs%@AE@%) or long (%@AB@%labs%@AE@%)
  18850.                                               value
  18851.  
  18852.                                   %@AI@%x%@AE@%           Floating-point value
  18853.  
  18854. %@AB@%Returns%@AE@%                           Absolute value of its argument
  18855.  
  18856. ────────────────────────────────────────────────────────────────────────────
  18857. %@AB@%acos%@AE@% - Calculates the arccosine.%@NL@%
  18858. %@NL@%
  18859. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  18860.  
  18861. %@AB@%Prototype%@AE@%                         %@AB@%double acos( double %@AE@%%@AI@%x%@AE@%%@AB@% );%@AE@%
  18862.  
  18863. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%           Value whose arccosine is to 
  18864.                                               be calculated
  18865.  
  18866. %@AB@%Returns%@AE@%                           The arccosine result if successful, or 0
  18867.                                   if %@AI@%x%@AE@%  > 1
  18868.  
  18869.                                   %@AB@%errno%@AE@%:  %@AB@%EDOM%@AE@%
  18870.  
  18871. ────────────────────────────────────────────────────────────────────────────
  18872. %@AB@%asin%@AE@% - Calculates the arcsine.%@NL@%
  18873. %@NL@%
  18874. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  18875.  
  18876. %@AB@%Prototype%@AE@%                         %@AB@%double asin( double %@AE@%%@AI@%x %@AE@%%@AB@%);%@AE@%
  18877.  
  18878. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%           Value whose arcsine is to be
  18879.                                               calculated
  18880.  
  18881. %@AB@%Returns%@AE@%                           The arcsine result if successful, or 0 
  18882.                                   if %@AI@%x%@AE@%  >1
  18883.  
  18884.                                   %@AB@%errno%@AE@%:  %@AB@%EDOM%@AE@%
  18885.  
  18886. ────────────────────────────────────────────────────────────────────────────
  18887. %@AB@%atan, atan2%@AE@% - Calculates the arctangent of %@AI@%x%@AE@% (%@AB@%atan%@AE@%) or the arctangent of %@AI@%y%@AE@%/%@AI@%x%@AE@%
  18888. (%@AB@%atan2%@AE@%).%@NL@%
  18889. %@NL@%
  18890. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  18891.  
  18892. %@AB@%Prototypes%@AE@%                        %@AB@%double atan( double %@AE@%%@AI@%x%@AE@%%@AB@% );%@AE@%
  18893.  
  18894.  
  18895.  
  18896.                                   %@AB@%double atan2( double%@AE@% %@AI@%y%@AE@%%@AB@%, double %@AE@%%@AI@%x %@AE@%%@AB@%);%@AE@%
  18897.  
  18898. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%, %@AI@%y%@AE@%        Floating-point values
  18899.  
  18900. %@AB@%Returns%@AE@%                           %@AB@%atan%@AE@%: the arctangent result
  18901.  
  18902.                                   %@AB@%atan2%@AE@%: the arctangent of %@AI@%y%@AE@%/%@AI@%x%@AE@%, or 0 if 
  18903.                                   both arguments  are 0
  18904.  
  18905.                                   %@AB@%errno%@AE@%:  %@AB@%EDOM%@AE@%
  18906.  
  18907. ────────────────────────────────────────────────────────────────────────────
  18908. %@AB@%ceil%@AE@% - Rounds the argument up to an integer.%@NL@%
  18909. %@NL@%
  18910. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  18911.  
  18912. %@AB@%Prototype%@AE@%                         %@AB@%double ceil( double %@AE@%%@AI@%x %@AE@%%@AB@%);%@AE@%
  18913.  
  18914. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%           Floating-point value
  18915.  
  18916. %@AB@%Returns%@AE@%                           The double result
  18917.  
  18918. ────────────────────────────────────────────────────────────────────────────
  18919. %@AB@%cos, cosh%@AE@% - Calculates the cosine (%@AB@%cos%@AE@%) or the hyperbolic cosine (%@AB@%cosh%@AE@%).%@NL@%
  18920. %@NL@%
  18921. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  18922.  
  18923. %@AB@%Prototypes%@AE@%                        %@AB@%double cos( double %@AE@%%@AI@%x %@AE@%%@AB@%);%@AE@%
  18924.  
  18925.  
  18926.  
  18927.                                   %@AB@%double cosh( double%@AE@% %@AI@%x%@AE@%%@AB@% );%@AE@%
  18928.  
  18929. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%           Angle (in radians)
  18930.  
  18931. %@AB@%Returns%@AE@%                           %@AB@%cos%@AE@%: the cosine result if successful, 0 
  18932.                                   if not
  18933.  
  18934.                                   %@AB@%cosh%@AE@%: the hyperbolic result if 
  18935.                                   successful, or %@AB@%HUGE_VAL%@AE@%  if the
  18936.  
  18937.                                   result is too large
  18938.  
  18939.                                   %@AB@%errno:%@AE@%  %@AB@%ERANGE%@AE@%
  18940.  
  18941. ────────────────────────────────────────────────────────────────────────────
  18942. %@AB@%exp%@AE@% - Calculates the exponential function.%@NL@%
  18943. %@NL@%
  18944. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  18945.  
  18946. %@AB@%Prototype%@AE@%                         %@AB@%double exp( double %@AE@%%@AI@%x %@AE@%%@AB@%);%@AE@%
  18947.  
  18948. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%           Floating-point value
  18949.  
  18950. %@AB@%Returns%@AE@%                           The exponential value if successful, %@AB@%%@AE@%
  18951.                                   %@AB@%HUGE_VAL%@AE@%  on overflow,
  18952.  
  18953.                                   0 on underflow
  18954.  
  18955.                                   %@AB@%errno%@AE@%:  %@AB@%ERANGE%@AE@%
  18956.  
  18957. ────────────────────────────────────────────────────────────────────────────
  18958. %@AB@%floor%@AE@% - Rounds the argument down to an integer.%@NL@%
  18959. %@NL@%
  18960. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  18961.  
  18962. %@AB@%Prototype%@AE@%                         %@AB@%double floor( double %@AE@%%@AI@%x%@AE@%%@AB@% );%@AE@%
  18963.  
  18964. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%           Floating-point value
  18965.  
  18966. %@AB@%Returns%@AE@%                           The floating-point result
  18967.  
  18968. ────────────────────────────────────────────────────────────────────────────
  18969. %@AB@%fmod%@AE@% - Finds the floating-point remainder.%@NL@%
  18970. %@NL@%
  18971. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  18972.  
  18973. %@AB@%Prototype%@AE@%                         %@AB@%double fmod( double %@AE@%%@AI@%x%@AE@%%@AB@%, double %@AE@%%@AI@%y  %@AE@%%@AB@%);%@AE@%
  18974.  
  18975. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%,%@AI@% y%@AE@%        Floating-point values
  18976.  
  18977. %@AB@%Returns%@AE@%                           The floating-point remainder, or 0 if %@AI@%y%@AE@% 
  18978.                                   is 0
  18979.  
  18980. ────────────────────────────────────────────────────────────────────────────
  18981. %@AB@%frexp%@AE@% - Calculates an exponential value.%@NL@%
  18982. %@NL@%
  18983. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  18984.  
  18985. %@AB@%Prototype%@AE@%                         %@AB@%double frexp( double %@AE@%%@AI@%x%@AE@%%@AB@%, int *%@AE@%%@AI@%expptr  %@AE@%%@AB@%);%@AE@%
  18986.  
  18987. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%           Floating-point value
  18988.  
  18989.                                   %@AI@%expptr%@AE@%      Pointer to stored integer 
  18990.                                               exponent
  18991.  
  18992. %@AB@%Returns%@AE@%                           The mantissa, or 0 if %@AI@%x%@AE@% is 0
  18993.  
  18994. ────────────────────────────────────────────────────────────────────────────
  18995. %@AB@%ldexp%@AE@% - Calculates the argument times 2exp.%@NL@%
  18996. %@NL@%
  18997. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  18998.  
  18999. %@AB@%Prototype%@AE@%                         %@AB@%double ldexp( double %@AE@%%@AI@%x%@AE@%%@AB@%, int %@AE@%%@AI@%exp  %@AE@%%@AB@%);%@AE@%
  19000.  
  19001. %@AB@%Arguments%@AE@%                         %@AI@%x%@AE@%           Floating-point value
  19002.  
  19003.                                   %@AI@%exp%@AE@%         Integer exponent
  19004.  
  19005. %@AB@%Returns%@AE@%                           An exponential value if successful, %@AB@%%@AE@%
  19006.                                   %@AB@%HUGE_VAL%@AE@%  on overflow
  19007.  
  19008.                                   %@AB@%errno:%@AE@%  %@AB@%ERANGE%@AE@%
  19009.  
  19010. ────────────────────────────────────────────────────────────────────────────
  19011. %@AB@%log, log10%@AE@% - Calculates the natural logarithm (%@AB@%log%@AE@%) or the base-10 log
  19012. (%@AB@%log10%@AE@%).%@NL@%
  19013. %@NL@%
  19014. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  19015.  
  19016. %@AB@%Prototypes%@AE@%                        %@AB@%double log( double %@AE@%%@AI@%x%@AE@%%@AB@% );%@AE@%
  19017.  
  19018.  
  19019.  
  19020.                                   double log10( double %@AI@%x %@AE@%%@AB@%);%@AE@%
  19021.  
  19022. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%           Floating-point value
  19023.  
  19024. %@AB@%Returns%@AE@%                           A logarithm result if successful, %@AB@%%@AE@%
  19025.                                   %@AB@%-HUGE_VAL%@AE@%  if not
  19026.  
  19027.                                   %@AB@%errno%@AE@%: %@AB@%EDOM%@AE@% (if %@AI@%x%@AE@% < 0), %@AB@%ERANGE%@AE@%  (if %@AI@%x%@AE@% = 
  19028.                                   0)
  19029.  
  19030. ────────────────────────────────────────────────────────────────────────────
  19031. %@AB@%modf%@AE@% - Breaks argument into integer and fractional parts.%@NL@%
  19032. %@NL@%
  19033. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  19034.  
  19035. %@AB@%Prototype%@AE@%                         %@AB@%double modf( double %@AE@%%@AI@%x%@AE@%%@AB@%, double *%@AE@%%@AI@%intptr%@AE@%%@AB@%  %@AE@%
  19036.                                   %@AB@%);%@AE@%
  19037.  
  19038. %@AB@%Arguments%@AE@%                         %@AI@%x%@AE@%           Floating-point value
  19039.  
  19040.                                   %@AI@%intptr%@AE@%      Pointer to stored integer 
  19041.                                               position
  19042.  
  19043. %@AB@%Returns%@AE@%                           The signed fractional portion of %@AI@%x%@AE@%
  19044.  
  19045. ────────────────────────────────────────────────────────────────────────────
  19046. %@AB@%pow%@AE@% - Calculates a value raised to a power. %@NL@%
  19047. %@NL@%
  19048. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  19049.  
  19050. %@AB@%Prototype%@AE@%                         %@AB@%double pow( double %@AE@%%@AI@%x%@AE@%%@AB@%, double %@AE@%%@AI@%y  %@AE@%%@AB@%);%@AE@%
  19051.  
  19052. %@AB@%Arguments%@AE@%                         %@AI@%x%@AE@%           Number to be raised
  19053.  
  19054.                                   %@AI@%y%@AE@%           Power of %@AI@%x%@AE@%
  19055.  
  19056. %@AB@%Returns%@AE@%                           The argument %@AI@%x%@AE@% raised to the %@AI@%y%@AE@%  power if
  19057.                                   successful,
  19058.  
  19059.                                   %@AB@%HUGE_VAL%@AE@% if not
  19060.  
  19061. ────────────────────────────────────────────────────────────────────────────
  19062. %@AB@%rand, srand%@AE@% - The %@AB@%rand%@AE@% function returns a pseudorandom integer in the range
  19063. 0-32,767. The %@AB@%srand%@AE@% function initializes the random number generator.%@NL@%
  19064. %@NL@%
  19065. %@AB@%Include%@AE@%                           STDLIB.H
  19066.  
  19067. %@AB@%Prototypes%@AE@%                        %@AB@%int rand( void );%@AE@%
  19068.  
  19069.  
  19070.  
  19071.                                   %@AB@%void srand( unsigned%@AE@% %@AI@%seed %@AE@%%@AB@%)%@AE@%;
  19072.  
  19073. %@AB@%Argument%@AE@%                          %@AI@%seed%@AE@%        Seed for random-number 
  19074.                                               generation  (%@AB@%srand%@AE@%)
  19075.  
  19076. %@AB@%Returns%@AE@%                           %@AB@%rand%@AE@%: a pseudorandom number
  19077.  
  19078.                                   %@AB@%srand%@AE@%: void
  19079.  
  19080. ────────────────────────────────────────────────────────────────────────────
  19081. %@AB@%sin, sinh%@AE@% - Calculates the sine (%@AB@%sin%@AE@%) or hyperbolic sine (%@AB@%sinh%@AE@%).%@NL@%
  19082. %@NL@%
  19083. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  19084.  
  19085. %@AB@%Prototypes%@AE@%                        %@AB@%double sin( double %@AE@%%@AI@%x%@AE@%%@AB@% );%@AE@%
  19086.  
  19087.  
  19088.  
  19089.                                   %@AB@%double sinh( double%@AE@% %@AI@%x %@AE@%%@AB@%);%@AE@%
  19090.  
  19091. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%           Angle (in radians)
  19092.  
  19093. %@AB@%Returns%@AE@%                           %@AB@%sin%@AE@%: the sine of %@AI@%x%@AE@% if successful,  0 if 
  19094.                                   not
  19095.  
  19096.                                   %@AB@%sinh%@AE@%: the hyperbolic sine of %@AI@%x%@AE@% if 
  19097.                                   successful, %@AB@%HUGE_VAL%@AE@%  if not
  19098.  
  19099.                                   %@AB@%errno%@AE@%:  %@AB@%ERANGE%@AE@%
  19100.  
  19101. ────────────────────────────────────────────────────────────────────────────
  19102. %@AB@%sqrt%@AE@% - Finds the square root.%@NL@%
  19103. %@NL@%
  19104. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  19105.  
  19106. %@AB@%Prototype%@AE@%                         %@AB@%double sqrt( double %@AE@%%@AI@%x%@AE@%%@AB@% );%@AE@%
  19107.  
  19108. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%           Nonnegative floating-point 
  19109.                                               value
  19110.  
  19111. %@AB@%Returns%@AE@%                           A square root if successful, 0 if not
  19112.  
  19113.                                   %@AB@%errno%@AE@%:  %@AB@%EDOM%@AE@%
  19114.  
  19115. ────────────────────────────────────────────────────────────────────────────
  19116. %@AB@%tan, tanh%@AE@% - Calculates the tangent (%@AB@%tan%@AE@%) or hyperbolic tangent (%@AB@%tanh%@AE@%).%@NL@%
  19117. %@NL@%
  19118. %@AB@%Includes%@AE@%                          FLOAT.H, MATH.H
  19119.  
  19120. %@AB@%Prototypes%@AE@%                        %@AB@%double tan( double %@AE@%%@AI@%x%@AE@%%@AB@% );%@AE@%
  19121.  
  19122.  
  19123.  
  19124.                                   %@AB@%double tanh( double%@AE@% %@AI@%x%@AE@%%@AB@% );%@AE@%
  19125.  
  19126. %@AB@%Argument%@AE@%                          %@AI@%x%@AE@%           Angle (in radians)
  19127.  
  19128. %@AB@%Returns%@AE@%                           %@AB@%tan:%@AE@% the tangent of %@AI@%x%@AE@% if successful,  0 
  19129.                                   if not
  19130.  
  19131.                                   %@AB@%tanh:%@AE@% the hyperbolic tangent of %@AI@%x%@AE@%
  19132.  
  19133.                                   %@AB@%errno%@AE@%:  %@AB@%ERANGE%@AE@% (%@AB@%tan%@AE@% only)
  19134.  
  19135. %@NL@%
  19136. %@2@%%@CR:C6A-B0012   @%%@AB@%Memory-Allocation Routines%@AE@%%@EH@%%@NL@%
  19137. %@NL@%
  19138. The memory-allocation routines allocate, free, analyze, and reallocate
  19139. blocks of memory.  %@NL@%
  19140. %@NL@%
  19141. Many of the memory-allocation functions are prefixed by an %@AB@%_f%@AE@% or an %@AB@%_n%@AE@%. This
  19142. notation means use the far (%@AB@%_f%@AE@%) heap or the near (%@AB@%_n%@AE@%) heap.  %@NL@%
  19143. %@NL@%
  19144. The %@AB@%malloc%@AE@% family of routines (%@AB@%malloc%@AE@%, %@AB@%_fmalloc%@AE@%, and %@AB@%_nmalloc%@AE@%) allocates
  19145. memory blocks of a specified size. The %@AB@%calloc%@AE@% function allocates storage for
  19146. an array. The %@AB@%halloc%@AE@% function allocates storage for a huge array.  %@NL@%
  19147. %@NL@%
  19148. The %@AB@%realloc%@AE@% routine changes the size of an allocated block.  %@NL@%
  19149. %@NL@%
  19150. ────────────────────────────────────────────────────────────────────────────
  19151. %@AB@%calloc%@AE@% - Allocates storage for an array. %@NL@%
  19152. %@NL@%
  19153. %@AB@%Includes%@AE@%                          MALLOC.H, STDLIB.H
  19154.  
  19155. %@AB@%Prototype%@AE@%                         %@AB@%void *calloc( size_t %@AE@%%@AI@%num%@AE@%%@AB@%,  size_t %@AE@%%@AI@%size %@AE@%%@AB@%%@AE@%
  19156.                                   %@AB@%);%@AE@%
  19157.  
  19158. %@AB@%Arguments%@AE@%                         %@AI@%num%@AE@%         Number of elements
  19159.  
  19160.                                   %@AI@%size%@AE@%        Length in bytes of each 
  19161.                                               element
  19162.  
  19163. %@AB@%Returns%@AE@%                           A void pointer to the allocated space if
  19164.                                   successful,
  19165.  
  19166.                                   %@AB@%NULL%@AE@% if not
  19167.  
  19168. ────────────────────────────────────────────────────────────────────────────
  19169. %@AB@%free, _ffree, hfree, _nfree%@AE@% - Frees a block of memory previously allocated
  19170. by the corresponding %@AB@%malloc%@AE@% routine. The corresponding routines are listed
  19171. below:%@NL@%
  19172. %@NL@%
  19173. %@AB@%Free Function%@AE@%                     %@AB@%Allocation Function%@AE@%
  19174. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19175. %@AB@%_ffree%@AE@%                            %@AB@%_fmalloc%@AE@%
  19176.  
  19177. %@AB@%free%@AE@%                              %@AB@%calloc, malloc, realloc%@AE@%
  19178.  
  19179. %@AB@%hfree%@AE@%                             %@AB@%halloc%@AE@%
  19180.  
  19181. %@AB@%_nfree%@AE@%                            %@AB@%_nmalloc%@AE@%
  19182.  
  19183.                                   
  19184.  
  19185. %@AB@%Includes%@AE@%                          MALLOC.H, STDLIB.H (ANSI-compatible %@AB@%free%@AE@%
  19186.                                   only)
  19187.  
  19188. %@AB@%Prototypes%@AE@%                        %@AB@%void _ffree( void _far *%@AE@%%@AI@%memblock  %@AE@%%@AB@%);%@AE@%
  19189.  
  19190.  
  19191.  
  19192.                                   %@AB@%void free( void *%@AE@%%@AI@%memblock%@AE@%%@AB@% );%@AE@%
  19193.  
  19194.  
  19195.  
  19196.                                   void _nfree( void near *%@AI@%memblock%@AE@%%@AB@% );%@AE@%
  19197.  
  19198.  
  19199.  
  19200.                                               %@AB@%void hfree( void huge *%@AE@%%@AI@%%@AE@%
  19201.                                               %@AI@%memblock%@AE@%%@AB@% );%@AE@%
  19202.  
  19203. %@AB@%Argument%@AE@%                          %@AI@%memblock%@AE@%    Allocated memory block
  19204.  
  19205. %@AB@%Returns%@AE@%                           Void
  19206.  
  19207. ────────────────────────────────────────────────────────────────────────────
  19208. %@AB@%malloc , _fmalloc,  _nmalloc%@AE@% - Allocates a block of memory. The %@AB@%_fmalloc%@AE@%
  19209. function allocates the block in the far heap. The %@AB@%_nmalloc%@AE@% function
  19210. allocates the block in the near heap.%@NL@%
  19211. %@NL@%
  19212. %@AB@%Includes%@AE@%                          MALLOC.H, STDLIB.H (ANSI-compatible %@AB@%%@AE@%
  19213.                                   %@AB@%malloc%@AE@%  only)
  19214.  
  19215. %@AB@%Prototypes%@AE@%                        %@AB@%void *malloc( size_t %@AE@%%@AI@%size %@AE@%%@AB@%);%@AE@%
  19216.  
  19217.  
  19218.  
  19219.                                   void _far *_fmalloc( size_t %@AI@%size %@AE@%%@AB@%);%@AE@%
  19220.  
  19221.  
  19222.  
  19223.                                   void near *_nmalloc( size_t %@AI@%size %@AE@%%@AB@%);%@AE@%
  19224.  
  19225. %@AB@%Argument%@AE@%                          %@AI@%size%@AE@%        Bytes to allocate
  19226.  
  19227. %@AB@%Returns%@AE@%                           A void pointer to the allocated space if
  19228.                                   successful,  %@AB@%NULL%@AE@% if not
  19229.  
  19230. ────────────────────────────────────────────────────────────────────────────
  19231. %@AB@%realloc%@AE@% - Reallocates a block. %@NL@%
  19232. %@NL@%
  19233. %@AB@%Include%@AE@%                           MALLOC.H, STDLIB.H
  19234.  
  19235. %@AB@%Prototype%@AE@%                         %@AB@%void *realloc( void *%@AE@%%@AI@%memblock%@AE@%%@AB@%,  size_t %@AE@%%@AI@%%@AE@%
  19236.                                   %@AI@%size%@AE@%%@AB@% );%@AE@%
  19237.  
  19238. %@AB@%Arguments%@AE@%                         %@AI@%memblock%@AE@%    Pointer to previously 
  19239.                                               allocated  memory block
  19240.  
  19241.                                   %@AI@%size%@AE@%        New size in bytes
  19242.  
  19243. %@AB@%Returns%@AE@%                           A pointer to the reallocated memory if 
  19244.                                   successful,  %@AB@%NULL%@AE@%
  19245.  
  19246.                                   if not
  19247.  
  19248. %@NL@%
  19249. %@2@%%@CR:C6A-B0013   @%%@AB@%Process-Control Routines%@AE@%%@EH@%%@NL@%
  19250. %@NL@%
  19251. The term "process" refers to a program being executed by the operating
  19252. system.  %@NL@%
  19253. %@NL@%
  19254. Use the process-control routines to  %@NL@%
  19255. %@NL@%
  19256. %@NL@%
  19257.   ■   Terminate a process (%@AB@%abort%@AE@%, %@AB@%exit%@AE@%, and %@AB@%_exit%@AE@%)%@NL@%
  19258. %@NL@%
  19259.   ■   Call a new function when a process terminates (%@AB@%atexit%@AE@%)%@NL@%
  19260. %@NL@%
  19261.   ■   Start a new process (%@AB@%system%@AE@%) %@NL@%
  19262. %@NL@%
  19263. %@NL@%
  19264. Use the %@AB@%abort%@AE@% and %@AB@%_exit%@AE@% functions to exit without flushing stream buffers.
  19265. Use the %@AB@%exit%@AE@% function to exit after flushing stream buffers.  %@NL@%
  19266. %@NL@%
  19267. Use the %@AB@%atexit%@AE@% function to create a list of functions to be executed when
  19268. the calling program exits.  %@NL@%
  19269. %@NL@%
  19270. Use the %@AB@%system%@AE@% call to execute a given MS-DOS command.  %@NL@%
  19271. %@NL@%
  19272. ────────────────────────────────────────────────────────────────────────────
  19273. %@AB@%abort%@AE@% - Aborts a process.%@NL@%
  19274. %@NL@%
  19275. %@AB@%Include%@AE@%                           PROCESS.H or STDLIB.H
  19276.  
  19277. %@AB@%Prototype%@AE@%                         %@AB@%void abort( void );%@AE@%
  19278.  
  19279. %@AB@%Arguments%@AE@%                         None
  19280.  
  19281. %@AB@%Returns%@AE@%                           Void
  19282.  
  19283. ────────────────────────────────────────────────────────────────────────────
  19284. %@AB@%atexit%@AE@% - Executes functions at program termination.%@NL@%
  19285. %@NL@%
  19286. %@AB@%Include%@AE@%                           STDLIB.H
  19287.  
  19288. %@AB@%Prototype%@AE@%                         %@AB@%int atexit( void (*%@AE@%%@AI@%func%@AE@%%@AB@%)( void  ) );%@AE@%
  19289.  
  19290. %@AB@%Argument%@AE@%                          %@AI@%func%@AE@%        Function to be called
  19291.  
  19292. %@AB@%Returns%@AE@%                           A pointer to %@AI@%func%@AE@% if successful, %@AB@%NULL%@AE@%  
  19293.                                   if not
  19294.  
  19295. ────────────────────────────────────────────────────────────────────────────
  19296. %@AB@%exit, _exit%@AE@% - Terminates the process after flushing buffers (%@AB@%exit%@AE@%);
  19297. terminates the process without flushing buffers (%@AB@%_exit%@AE@%).%@NL@%
  19298. %@NL@%
  19299. %@AB@%Include%@AE@%                           PROCESS.H or%@AB@% %@AE@%STDLIB.H%@AB@%%@AE@%
  19300.  
  19301. %@AB@%Prototypes%@AE@%                        %@AB@%void exit( int %@AE@%%@AI@%status %@AE@%%@AB@%);%@AE@%
  19302.  
  19303.  
  19304.  
  19305.                                   %@AB@%void _exit( int %@AE@%%@AI@%status%@AE@%%@AB@% );%@AE@%
  19306.  
  19307. %@AB@%Argument%@AE@%                          %@AI@%status%@AE@%      Exit status
  19308.  
  19309. %@AB@%Returns%@AE@%                           Void
  19310.  
  19311. ────────────────────────────────────────────────────────────────────────────
  19312. %@AB@%system%@AE@% - Executes an MS-DOS command.%@NL@%
  19313. %@NL@%
  19314. %@AB@%Include%@AE@%                           PROCESS.H, STDLIB.H
  19315.  
  19316. %@AB@%Prototype%@AE@%                         %@AB@%int system( const char *%@AE@%%@AI@%command %@AE@%%@AB@%);%@AE@%
  19317.  
  19318. %@AB@%Argument%@AE@%                          %@AI@%command%@AE@%     Command to be executed%@AB@%%@AE@%
  19319.  
  19320. %@AB@%Returns%@AE@%                           0 if successful, -1 if not
  19321.  
  19322.                                   %@AB@%errno%@AE@%:  %@AB@%E2BIG, ENOENT, ENOEXEC, ENOMEM%@AE@%
  19323.  
  19324.  
  19325.  
  19326.  
  19327.  
  19328. %@NL@%
  19329. %@2@%%@CR:C6A-B0014   @%%@AB@%Searching and Sorting Routines%@AE@%%@EH@%%@NL@%
  19330. %@NL@%
  19331. The %@AB@%bsearch%@AE@%, %@AB@%lfind%@AE@%, %@AB@%lsearch%@AE@%, and %@AB@%qsort%@AE@% routines provide helpful
  19332. binary-search, linear-search, and quick-sort utilities.  %@NL@%
  19333. %@NL@%
  19334. ────────────────────────────────────────────────────────────────────────────
  19335. %@AB@%bsearch%@AE@% - Performs a binary search.%@NL@%
  19336. %@NL@%
  19337. %@AB@%Includes%@AE@%                          STDLIB.H, SEARCH.H
  19338.  
  19339. %@AB@%Prototype%@AE@%                         %@AB@%void *bsearch( const void *%@AE@%%@AI@%key%@AE@%%@AB@%,  const %@AE@%
  19340.                                   %@AB@%void *%@AE@%%@AI@%base%@AE@%%@AB@%,%@AE@%
  19341.  
  19342.                                   size_t %@AI@%num%@AE@%%@AB@%, size_t %@AE@%%@AI@%width%@AE@%%@AB@%, int( *%@AE@%%@AI@%compare %@AE@%
  19343.                                   %@AB@%)(  const void *%@AE@%%@AI@%elem1%@AE@%%@AB@%,%@AE@%
  19344.  
  19345.                                   const void *%@AI@%elem2%@AE@%%@AB@% ) );%@AE@%
  19346.  
  19347. %@AB@%Arguments%@AE@%                         %@AI@%key%@AE@%         Object to search for
  19348.  
  19349.                                   %@AI@%base%@AE@%        Pointer to base of search 
  19350.                                               data
  19351.  
  19352.                                   %@AI@%num%@AE@%         Number of elements
  19353.  
  19354.                                   %@AI@%width%@AE@%       Width of elements
  19355.  
  19356.                                   %@AI@%compare%@AE@%     Compare function
  19357.  
  19358.                                   %@AI@%elem1%@AE@%, %@AI@%%@AE@%     Array elements to compare
  19359.                                   %@AI@%elem2%@AE@%       
  19360.  
  19361. %@AB@%Returns%@AE@%                           A pointer if successful, %@AB@%NULL%@AE@% if  not
  19362.  
  19363. ────────────────────────────────────────────────────────────────────────────
  19364. %@AB@%lfind, lsearch%@AE@% - Performs a linear search for given value. If the value is
  19365. not found, %@AB@%lsearch%@AE@% adds it to the end of the list.%@NL@%
  19366. %@NL@%
  19367. %@AB@%Includes%@AE@%                          STDLIB.H, SEARCH.H
  19368.  
  19369. %@AB@%Prototypes%@AE@%                        %@AB@%char *lfind( char *%@AE@%%@AI@%key%@AE@%%@AB@%,  char *%@AE@%%@AI@%base%@AE@%%@AB@%, %@AE@%
  19370.                                   %@AB@%unsigned *%@AE@%%@AI@%num%@AE@%%@AB@%,%@AE@%
  19371.  
  19372.                                   unsigned %@AI@%width%@AE@%%@AB@%, int( *%@AE@%%@AI@%compare %@AE@%%@AB@%)( const %@AE@%
  19373.                                   %@AB@%void  *%@AE@%%@AI@%elem1%@AE@%%@AB@%,%@AE@%
  19374.  
  19375.                                   const void *%@AI@%elem2%@AE@%%@AB@% ) );%@AE@%
  19376.  
  19377.  
  19378.  
  19379.                                   char *lsearch( const char *%@AI@%key%@AE@%%@AB@%, const %@AE@%
  19380.                                   %@AB@%char  *%@AE@%%@AI@%base%@AE@%%@AB@%,%@AE@%
  19381.  
  19382.                                   unsigned *%@AI@%num%@AE@%%@AB@%, unsigned %@AE@%%@AI@%width%@AE@%%@AB@%, int( *%@AE@%%@AI@%%@AE@%
  19383.                                   %@AI@%compare  %@AE@%%@AB@%)%@AE@%
  19384.  
  19385.                                   ( const void *%@AI@%elem1%@AE@%%@AB@%, const void *%@AE@%%@AI@%elem2 %@AE@%%@AB@%)%@AE@%
  19386.                                   %@AB@%);%@AE@%
  19387.  
  19388. %@AB@%Arguments%@AE@%                         %@AI@%key%@AE@%         Object to search for
  19389.  
  19390.                                   %@AI@%base%@AE@%        Pointer to base of search 
  19391.                                               data
  19392.  
  19393.                                   %@AI@%num%@AE@%         Number of elements
  19394.  
  19395.                                   %@AI@%width%@AE@%       Width of elements
  19396.  
  19397.                                   %@AI@%compare%@AE@%     Compare function
  19398.  
  19399.                                   %@AI@%elem1%@AE@%, %@AI@%%@AE@%     Array elements to compare
  19400.                                   %@AI@%elem2%@AE@%       
  19401.  
  19402. %@AB@%Returns%@AE@%                           A pointer if successful, %@AB@%NULL%@AE@% if  not
  19403.  
  19404. ────────────────────────────────────────────────────────────────────────────
  19405. %@AB@%qsort%@AE@% - Performs a quick sort.%@NL@%
  19406. %@NL@%
  19407. %@AB@%Includes%@AE@%                          STDLIB.H, SEARCH.H
  19408.  
  19409. %@AB@%Prototype%@AE@%                         %@AB@%void qsort( void *%@AE@%%@AI@%base%@AE@%%@AB@%, size_t  %@AE@%%@AI@%num%@AE@%%@AB@%, %@AE@%
  19410.                                   %@AB@%size_t %@AE@%%@AI@%width%@AE@%%@AB@%,%@AE@%
  19411.  
  19412.                                   int( *%@AI@%compare%@AE@%%@AB@% )( const void *%@AE@%%@AI@%elem1%@AE@%%@AB@%, %@AE@%
  19413.                                   %@AB@%const  void *%@AE@%%@AI@%elem2 %@AE@%%@AB@%) );%@AE@%
  19414.  
  19415. %@AB@%Arguments%@AE@%                         %@AI@%base%@AE@%        Start of target array
  19416.  
  19417.                                   %@AI@%num%@AE@%         Array size in elements
  19418.  
  19419.                                   %@AI@%width%@AE@%       Element size in bytes
  19420.  
  19421.                                   %@AI@%compare%@AE@%     Compare function
  19422.  
  19423.                                   %@AI@%elem1%@AE@%, %@AI@%%@AE@%     Array elements to compare
  19424.                                   %@AI@%elem2%@AE@%       
  19425.  
  19426. %@AB@%Returns%@AE@%                           Void%@AB@%%@AE@%
  19427.  
  19428. %@NL@%
  19429. %@2@%%@CR:C6A-B0015   @%%@AB@%String-Manipulation Routines%@AE@%%@EH@%%@NL@%
  19430. %@NL@%
  19431. A wide variety of string routines is available in the run-time library. With
  19432. these functions, you can do the following:  %@NL@%
  19433. %@NL@%
  19434. %@NL@%
  19435.   ■   Copy strings (%@AB@%strcat%@AE@%, %@AB@%strcpy%@AE@%, %@AB@%strdup%@AE@%, %@AB@%strncat%@AE@%, %@AB@%strncpy%@AE@%)%@NL@%
  19436. %@NL@%
  19437.   ■   Search for strings, individual characters, or characters from a given
  19438.       set (%@AB@%strchr%@AE@%, %@AB@%strcspn%@AE@%, %@AB@%strpbrk%@AE@%, %@AB@%strrchr%@AE@%, %@AB@%strspn%@AE@%, %@AB@%strstr%@AE@%)%@NL@%
  19439. %@NL@%
  19440.   ■   Perform string comparisons (%@AB@%strcmp%@AE@%, %@AB@%strcmpi%@AE@%, %@AB@%stricmp%@AE@%, %@AB@%strncmp%@AE@%,
  19441.       %@AB@%strnicmp%@AE@%)%@NL@%
  19442. %@NL@%
  19443.   ■   Find the length of a string (%@AB@%strlen%@AE@%)%@NL@%
  19444. %@NL@%
  19445.   ■   Convert strings to a different case (%@AB@%strlwr%@AE@%, %@AB@%strupr%@AE@%)%@NL@%
  19446. %@NL@%
  19447.   ■   Set characters of the string to a given character (%@AB@%strnset%@AE@%, %@AB@%strset%@AE@%)%@NL@%
  19448. %@NL@%
  19449.   ■   Break strings into tokens (%@AB@%strtok%@AE@%)%@NL@%
  19450. %@NL@%
  19451. %@NL@%
  19452. All string functions work on null-terminated character strings.  %@NL@%
  19453. %@NL@%
  19454. Use the buffer-manipulation routines described earlier in this appendix for
  19455. manipulating character arrays that do not end with a null character.  %@NL@%
  19456. %@NL@%
  19457. ────────────────────────────────────────────────────────────────────────────
  19458. %@AB@%strcat, strcpy, strdup, strncat, strncpy%@AE@% - Use these routines to copy and
  19459. concatenate strings. The list below describes each function.%@NL@%
  19460. %@NL@%
  19461. %@AB@%Function%@AE@%                          %@AB@%Action%@AE@%
  19462. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19463. %@AB@%strcat%@AE@%                            Append (concatenate) a string
  19464.  
  19465. %@AB@%strcpy%@AE@%                            Copy one string to another
  19466.  
  19467. %@AB@%strdup%@AE@%                            Duplicate a string
  19468.  
  19469. %@AB@%strncat%@AE@%                           Append a specified number of characters 
  19470.                                   to a string
  19471.  
  19472. %@AB@%strncpy%@AE@%                           Copy a specified number of characters 
  19473.                                   from one string to another
  19474.  
  19475. %@AB@%Include%@AE@%                           STRING.H
  19476.  
  19477. %@AB@%Prototypes%@AE@%                        %@AB@%char *strcat( char *%@AE@%%@AI@%dest%@AE@%%@AB@%,  const char *%@AE@%%@AI@%%@AE@%
  19478.                                   %@AI@%src%@AE@% );
  19479.  
  19480.  
  19481.  
  19482.                                   char *strcpy( char *%@AI@%dest%@AE@%%@AB@%, const char *%@AE@%%@AI@%%@AE@%
  19483.                                   %@AI@%src%@AE@%  );
  19484.  
  19485.  
  19486.  
  19487.                                   char *strdup( const char *%@AI@%string %@AE@%%@AB@%);%@AE@%
  19488.  
  19489.  
  19490.  
  19491.                                   char *strncat( char *%@AI@%dest%@AE@%%@AB@%, const char *%@AE@%%@AI@%%@AE@%
  19492.                                   %@AI@%src%@AE@%%@AB@%,  size_t %@AE@%%@AI@%n%@AE@%%@AB@% );%@AE@%
  19493.  
  19494.  
  19495.  
  19496.                                   char *strncpy( char *%@AI@%dest%@AE@%%@AB@%, const char *%@AE@%%@AI@%%@AE@%
  19497.                                   %@AI@%src%@AE@%%@AB@%,  size_t %@AE@%%@AI@%n %@AE@%%@AB@%);%@AE@%
  19498.  
  19499. %@AB@%Arguments%@AE@%                         %@AI@%dest%@AE@%        Destination string
  19500.  
  19501.                                   %@AI@%src%@AE@%         Source string
  19502.  
  19503.                                   %@AI@%string%@AE@%      Null-terminated string
  19504.  
  19505.                                   %@AI@%n%@AE@%           Number of characters
  19506.  
  19507. %@AB@%Returns%@AE@%                           %@AB@%strcat:%@AE@% a pointer to the concatenated 
  19508.                                   string
  19509.  
  19510.                                   %@AB@%strcpy%@AE@%: %@AI@%dest%@AE@% string
  19511.  
  19512.                                   %@AB@%strdup%@AE@%: a pointer if successful, %@AB@%NULL%@AE@% if
  19513.                                   not
  19514.  
  19515.                                   %@AB@%strncat, strncpy%@AE@%: a pointer to%@AI@% dest%@AE@% 
  19516.                                   string
  19517.  
  19518. ────────────────────────────────────────────────────────────────────────────
  19519. %@AB@%strchr, strcspn, strpbrk, strrchr, strspn, strstr%@AE@% - Use these routines to
  19520. search strings. The list below describes each function.%@NL@%
  19521. %@NL@%
  19522. %@AB@%Function%@AE@%                          %@AB@%Action%@AE@%
  19523. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19524. %@AB@%strchr%@AE@%                            Finds first occurrence of a given 
  19525.                                   character in a string
  19526.  
  19527. %@AB@%strcspn%@AE@%                           Finds first occurrence of a character 
  19528.                                   from a given character set in a string 
  19529.  
  19530. %@AB@%strpbrk%@AE@%                           Finds first occurrence of a character 
  19531.                                   from one string in another
  19532.  
  19533. %@AB@%strrchr%@AE@%                           Finds last occurrence of a given 
  19534.                                   character in a string
  19535.  
  19536. %@AB@%strspn%@AE@%                            Finds first substring from a given 
  19537.                                   character set in a string
  19538.  
  19539. %@AB@%strstr%@AE@%                            Finds first occurrence of a given string
  19540.                                   in another string
  19541.  
  19542. %@AB@%Include%@AE@%                           STRING.H
  19543.  
  19544. %@AB@%Prototypes%@AE@%                        %@AB@%char *strchr( const char *%@AE@%%@AI@%string%@AE@%%@AB@%,  int%@AE@%%@AI@% c%@AE@%
  19545.                                   %@AB@% );%@AE@%
  19546.  
  19547.  
  19548.  
  19549.                                   size_t strcspn( const char *%@AI@%string1%@AE@%%@AB@%, %@AE@%
  19550.                                   %@AB@%const char *%@AE@%%@AI@%string2  %@AE@%%@AB@%);%@AE@%
  19551.  
  19552.  
  19553.  
  19554.                                   char *strpbrk( const char *%@AI@%string1%@AE@%%@AB@%, %@AE@%
  19555.                                   %@AB@%const char  *%@AE@%%@AI@%string2%@AE@%%@AB@% );%@AE@%
  19556.  
  19557.  
  19558.  
  19559.                                   char *strrchr( const char *%@AI@%string%@AE@%%@AB@%, int %@AE@%%@AI@%c%@AE@%
  19560.                                   %@AB@%  );%@AE@%
  19561.  
  19562.  
  19563.  
  19564.                                   size_t strspn( const char *%@AI@%string1%@AE@%%@AB@%, %@AE@%
  19565.                                   %@AB@%const char *%@AE@%%@AI@%string2  %@AE@%%@AB@%);%@AE@%
  19566.  
  19567.  
  19568.  
  19569.                                   char *strstr( const char *%@AI@%string1%@AE@%%@AB@%, const%@AE@%
  19570.                                   %@AB@%char  *%@AE@%%@AI@%string2%@AE@%%@AB@% );%@AE@%
  19571.  
  19572. %@AB@%Arguments%@AE@%                         %@AI@%string%@AE@%, %@AI@%%@AE@%    Null-terminated  strings
  19573.                                   %@AI@%string1%@AE@%, %@AI@%%@AE@%   
  19574.                                   %@AI@%string2%@AE@%     
  19575.  
  19576.                                   %@AI@%c%@AE@%           Character
  19577.  
  19578. %@AB@%Returns%@AE@%                           %@AB@%strchr%@AE@%: a pointer if successful, %@AB@%NULL%@AE@%  
  19579.                                   if not
  19580.  
  19581.                                   %@AB@%strcspn%@AE@%: an offset into %@AI@%string1%@AE@%
  19582.  
  19583.                                   %@AB@%strpbrk%@AE@%: a pointer to the first matching
  19584.                                   character in %@AI@%string1%@AE@%,  
  19585.  
  19586.                                   %@AB@%NULL%@AE@% if no match is found
  19587.  
  19588.                                   %@AB@%strrchr%@AE@%: a pointer to the last 
  19589.                                   occurrence of %@AI@%c%@AE@% in%@AI@%  string%@AE@%, %@AB@%NULL%@AE@%
  19590.  
  19591.                                   if %@AI@%c%@AE@% is not found
  19592.  
  19593.                                   %@AB@%strspn%@AE@%: the position of the first 
  19594.                                   nonmatching character in  %@AI@%string1%@AE@%
  19595.  
  19596.                                   %@AB@%strstr%@AE@%: a pointer to the first 
  19597.                                   occurrence of%@AI@% string2%@AE@%  in %@AI@%string1%@AE@%,
  19598.  
  19599.                                   or %@AB@%NULL%@AE@% if %@AI@%string2%@AE@% is not found
  19600.  
  19601. ────────────────────────────────────────────────────────────────────────────
  19602. %@AB@%strcmp, strcmpi, stricmp, strncmp, strnicmp%@AE@% - Use these routines to compare
  19603. strings. The list below describes the operation of each function. An "%@AB@%n%@AE@%" in
  19604. the function name means to use up to %@AB@%n%@AE@% characters; "%@AB@%i%@AE@%" in the name means to
  19605. operate without regard to the case of the string.%@NL@%
  19606. %@NL@%
  19607. %@AB@%Function%@AE@%                          %@AB@%Action%@AE@%
  19608. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%
  19609. %@AB@%strcmp%@AE@%                            Compares two strings
  19610.  
  19611. %@AB@%strcmpi%@AE@%                           Compares two strings without regard to 
  19612.                                   case ("%@AB@%i%@AE@%" 
  19613.                                   indicates that this function is case 
  19614.                                   insensitive)
  19615.  
  19616. %@AB@%stricmp%@AE@%                           Compares two strings without regard to 
  19617.                                   case (identical to %@AB@%strcmpi%@AE@%)
  19618.  
  19619. %@AB@%strncmp%@AE@%                           Compares characters of two strings
  19620.  
  19621. %@AB@%strnicmp%@AE@%                          Compares characters of two strings 
  19622.                                   without regard to case
  19623.  
  19624. %@AB@%Include%@AE@%                           STRING.H
  19625.  
  19626. %@AB@%Prototypes%@AE@%                        %@AB@%int strcmp( const char *%@AE@%%@AI@%string1%@AE@%%@AB@%,  const %@AE@%
  19627.                                   %@AB@%char *%@AE@%%@AI@%string2 %@AE@%%@AB@%);%@AE@%
  19628.  
  19629.  
  19630.  
  19631.                                   int strcmpi( const char *%@AI@%string1%@AE@%%@AB@%, const %@AE@%
  19632.                                   %@AB@%char *%@AE@%%@AI@%string2%@AE@%%@AB@%  );%@AE@%
  19633.  
  19634.  
  19635.  
  19636.                                   int stricmp( const char *%@AI@%string1%@AE@%%@AB@%, const %@AE@%
  19637.                                   %@AB@%char *%@AE@%%@AI@%string2  %@AE@%%@AB@%);%@AE@%
  19638.  
  19639.  
  19640.  
  19641.                                   int strncmp( const char *%@AI@%string1%@AE@%%@AB@%, const %@AE@%
  19642.                                   %@AB@%char *%@AE@%%@AI@%string2%@AE@%%@AB@%,  size_t %@AE@%%@AI@%n%@AE@%%@AB@% );%@AE@%
  19643.  
  19644.  
  19645.  
  19646.                                   int strnicmp( const char *%@AI@%string1%@AE@%%@AB@%, const%@AE@%
  19647.                                   %@AB@%char *%@AE@%%@AI@%string2%@AE@%%@AB@%,  size_t %@AE@%%@AI@%n %@AE@%%@AB@%);%@AE@%
  19648.  
  19649. %@AB@%Arguments%@AE@%                         %@AI@%string1%@AE@%     Destination string
  19650.  
  19651.                                   %@AI@%string2%@AE@%     Source string
  19652.  
  19653.                                   %@AI@%n%@AE@%           Number of characters
  19654.  
  19655. %@AB@%Returns%@AE@%                           A negative value if %@AI@%string1%@AE@%, 0  if %@AI@%%@AE@%
  19656.                                   %@AI@%string1%@AE@% = %@AI@%string2%@AE@%,
  19657.  
  19658.                                   a positive value if%@AI@% string1>string2%@AE@%
  19659.  
  19660. ────────────────────────────────────────────────────────────────────────────
  19661. %@AB@%strlen%@AE@% - The %@AB@%strlen%@AE@% function returns the length in bytes of the string, not
  19662. including the terminating null character (%@AB@%\0%@AE@%).%@NL@%
  19663. %@NL@%
  19664. %@AB@%Include%@AE@%                           STRING.H
  19665.  
  19666. %@AB@%Prototype%@AE@%                         %@AB@%size_t strlen( const char *%@AE@%%@AI@%string%@AE@%%@AB@%  );%@AE@%
  19667.  
  19668. %@AB@%Argument%@AE@%                          %@AI@%string%@AE@%      Null-terminated string
  19669.  
  19670. %@AB@%Returns%@AE@%                           The string length
  19671.  
  19672. ────────────────────────────────────────────────────────────────────────────
  19673. %@AB@%strlwr, strupr%@AE@% - The %@AB@%strlwr%@AE@% and %@AB@%strupr%@AE@% routines convert the characters of a
  19674. string to lowercase and uppercase, respectively.%@NL@%
  19675. %@NL@%
  19676. %@AB@%Include%@AE@%                           STRING.H
  19677.  
  19678. %@AB@%Prototypes%@AE@%                        %@AB@%char *strlwr( char *%@AE@%%@AI@%string  %@AE@%%@AB@%);%@AE@%
  19679.  
  19680.  
  19681.  
  19682.                                   %@AB@%char *strupr( char *%@AE@%%@AI@%string %@AE@%%@AB@%);%@AE@%
  19683.  
  19684. %@AB@%Argument%@AE@%                          %@AI@%string%@AE@%      String to be converted
  19685.  
  19686. %@AB@%Returns%@AE@%                           A pointer to a copy of the converted 
  19687.                                   input string
  19688.  
  19689. ────────────────────────────────────────────────────────────────────────────
  19690. %@AB@%strnset, strset%@AE@% - The routines %@AB@%strnset%@AE@% and %@AB@%strset%@AE@% set the characters of a
  19691. string to a specified character. The%@AB@% strnset%@AE@% function sets the first %@AI@%n%@AE@%
  19692. characters in the string to the specified character. The %@AB@%strset%@AE@% function
  19693. sets the entire string to the specified character.%@NL@%
  19694. %@NL@%
  19695. %@AB@%Include%@AE@%                           STRING.H
  19696.  
  19697. %@AB@%Prototypes%@AE@%                        %@AB@%char *strnset( char *%@AE@%%@AI@%string%@AE@%%@AB@%,  int %@AE@%%@AI@%c%@AE@%%@AB@%, %@AE@%
  19698.                                   %@AB@%size_t %@AE@%%@AI@%n%@AE@%%@AB@% );%@AE@%
  19699.  
  19700.  
  19701.  
  19702.                                   char*strset( char *%@AB@%string, int c );%@AE@%
  19703.  
  19704. %@AB@%Arguments%@AE@%                         %@AI@%string%@AE@%      String to be set
  19705.  
  19706.                                   %@AI@%c%@AE@%           Character setting
  19707.  
  19708.                                   %@AI@%n%@AE@%           Number of characters set
  19709.  
  19710. %@AB@%Returns%@AE@%                           A pointer to %@AI@%string%@AE@%
  19711.  
  19712.  
  19713.  
  19714.  
  19715.  
  19716.  
  19717.  
  19718. ────────────────────────────────────────────────────────────────────────────
  19719. %@AB@%strtok%@AE@% - The %@AB@%strtok%@AE@% function finds a token in a string. A "token" is a
  19720. series of characters delimited by a character from a specified set. For
  19721. example, use the %@AB@%strtok%@AE@% function to break an input line into the component
  19722. words.%@NL@%
  19723. %@NL@%
  19724. %@AB@%Include%@AE@%                           STRING.H
  19725.  
  19726. %@AB@%Prototype%@AE@%                         %@AB@%char *strtok( char *%@AE@%%@AI@%string1%@AE@%%@AB@%,  const char%@AE@%
  19727.                                   %@AB@%*%@AE@%%@AI@%string2%@AE@%%@AB@% );%@AE@%
  19728.  
  19729. %@AB@%Arguments%@AE@%                         %@AI@%string1%@AE@%     String containing tokens
  19730.  
  19731.                                   %@AI@%string2%@AE@%     Set of delimiter characters
  19732.  
  19733. %@AB@%Returns%@AE@%                           A pointer to a token in %@AI@%string1%@AE@%
  19734.  
  19735. %@NL@%
  19736. %@2@%%@CR:C6A-B0016   @%%@AB@%Time Routines%@AE@%%@EH@%%@NL@%
  19737. %@NL@%
  19738. Use the time routines to get the current time, convert it to a convenient
  19739. format, and store it according to your particular needs.  %@NL@%
  19740. %@NL@%
  19741. The current time is always taken from the system time.  %@NL@%
  19742. %@NL@%
  19743. The %@AB@%time%@AE@% function returns the current time as the number of seconds elapsed
  19744. since Greenwich mean time, January 1, 1970.  %@NL@%
  19745. %@NL@%
  19746. Use the %@AB@%asctime%@AE@%, %@AB@%ctime%@AE@%, %@AB@%gmtime%@AE@%, and %@AB@%mktime%@AE@% functions to manipulate the time
  19747. value.  %@NL@%
  19748. %@NL@%
  19749. ────────────────────────────────────────────────────────────────────────────
  19750. %@AB@%asctime%@AE@% - Converts a time from a structure to a character string.%@NL@%
  19751. %@NL@%
  19752. %@AB@%Include%@AE@%                           TIME.H
  19753.  
  19754. %@AB@%Prototype%@AE@%                         %@AB@%char *asctime( const struct tm *%@AE@%%@AI@%timeptr %@AE@%
  19755.                                   %@AI@%%@AE@%%@AB@%);%@AE@%
  19756.  
  19757. %@AB@%Argument%@AE@%                          %@AI@%timeptr%@AE@%     Time structure
  19758.  
  19759. %@AB@%Returns%@AE@%                           A pointer to string result
  19760.  
  19761. ────────────────────────────────────────────────────────────────────────────
  19762. %@AB@%clock%@AE@% - Returns the elapsed CPU time for a process.%@NL@%
  19763. %@NL@%
  19764. %@AB@%Include%@AE@%                           TIME.H
  19765.  
  19766. %@AB@%Prototype%@AE@%                         %@AB@%clock_t clock( void );%@AE@%
  19767.  
  19768. %@AB@%Arguments%@AE@%                         None
  19769.  
  19770. %@AB@%Returns%@AE@%                           The elapsed processor time if successful,
  19771.                                   -1  if not
  19772.  
  19773. ────────────────────────────────────────────────────────────────────────────
  19774. %@AB@%ctime%@AE@% - Converts time from a long integer to a character string.%@NL@%
  19775. %@NL@%
  19776. %@AB@%Include%@AE@%                           TIME.H
  19777.  
  19778. %@AB@%Prototype%@AE@%                         %@AB@%char *ctime( const time_t *%@AE@%%@AI@%timer  %@AE@%%@AB@%);%@AE@%
  19779.  
  19780. %@AB@%Argument%@AE@%                          %@AI@%timer%@AE@%       Pointer to stored time
  19781.  
  19782. %@AB@%Returns%@AE@%                           A pointer to string result; %@AB@%NULL%@AE@%  if 
  19783.                                   time represents a date
  19784.  
  19785.                                   before 1980
  19786.  
  19787. ────────────────────────────────────────────────────────────────────────────
  19788. %@AB@%difftime%@AE@% - Computes the difference between two times.%@NL@%
  19789. %@NL@%
  19790. %@AB@%Include%@AE@%                           TIME.H
  19791.  
  19792. %@AB@%Prototype%@AE@%                         %@AB@%double difftime( time_t %@AE@%%@AI@%timer1%@AE@%%@AB@%, time_t  %@AE@%
  19793.                                   %@AI@%timer0 %@AE@%%@AB@%);%@AE@%
  19794.  
  19795. %@AB@%Arguments%@AE@%                         %@AI@%timer0%@AE@%,%@AI@% %@AE@%    Beginning and ending  times
  19796.                                   %@AI@%timer1%@AE@%      
  19797.  
  19798. %@AB@%Returns%@AE@%                           The difference in elapsed time between%@AI@% %@AE@%
  19799.                                   %@AI@%timer1%@AE@%  and%@AI@% timer0%@AE@%
  19800.  
  19801. ────────────────────────────────────────────────────────────────────────────
  19802. %@AB@%ftime%@AE@% - Gets current system time as structure.%@NL@%
  19803. %@NL@%
  19804. %@AB@%Includes%@AE@%                          SYS\TYPES.H, SYS\TIMEB.H
  19805.  
  19806. %@AB@%Prototype%@AE@%                         %@AB@%void ftime( struct timeb *%@AE@%%@AI@%timeptr  %@AE@%%@AB@%);%@AE@%
  19807.  
  19808. %@AB@%Argument%@AE@%                          %@AI@%timeptr%@AE@%     Pointer to time structure
  19809.  
  19810. %@AB@%Returns%@AE@%                           Void
  19811.  
  19812. ────────────────────────────────────────────────────────────────────────────
  19813. %@AB@%gmtime%@AE@% - Converts time from integer to structure.%@NL@%
  19814. %@NL@%
  19815. %@AB@%Include%@AE@%                           TIME.H
  19816.  
  19817. %@AB@%Prototype%@AE@%                         %@AB@%struct tm *gmtime( const time_t *%@AE@%%@AI@%timer  %@AE@%
  19818.                                   %@AB@%);%@AE@%
  19819.  
  19820. %@AB@%Argument%@AE@%                          %@AI@%timer%@AE@%       Pointer to stored time
  19821.  
  19822. %@AB@%Returns%@AE@%                           A pointer to a structure
  19823.  
  19824. ────────────────────────────────────────────────────────────────────────────
  19825. %@AB@%mktime%@AE@% - Converts time to a calendar value.%@NL@%
  19826. %@NL@%
  19827. %@AB@%Include%@AE@%                           TIME.H
  19828.  
  19829. %@AB@%Prototype%@AE@%                         %@AB@%time_t mktime( struct tm *%@AE@%%@AI@%timeptr  %@AE@%%@AB@%);%@AE@%
  19830.  
  19831. %@AB@%Argument%@AE@%                          %@AI@%timeptr%@AE@%     Local time structure
  19832.  
  19833. %@AB@%Returns%@AE@%                           The encoded calendar time if successful,
  19834.                                   -1  if not
  19835.  
  19836. ────────────────────────────────────────────────────────────────────────────
  19837. %@AB@%time%@AE@% - Gets current system time as a long integer.%@NL@%
  19838. %@NL@%
  19839. %@AB@%Include%@AE@%                           TIME.H
  19840.  
  19841. %@AB@%Prototype%@AE@%                         %@AB@%time_t time( time_t *%@AE@%%@AI@%timer%@AE@%%@AB@% );%@AE@%
  19842.  
  19843. %@AB@%Argument%@AE@%                          %@AI@%timer%@AE@%       Storage location for time
  19844.  
  19845. %@AB@%Returns%@AE@%                           The elapsed time
  19846.  
  19847. %@NL@%
  19848. %@NL@%
  19849. %@NL@%
  19850.  %@NL@%
  19851. %@NL@%
  19852. %@NL@%
  19853. %@NL@%
  19854. %@NL@%
  19855. %@CR:C6A-B0028   @%%@1@%%@AB@%Glossary%@AE@%%@EH@%%@NL@%
  19856. %@AB@%────────────────────────────────────────────────────────────────────────────%@AE@%%@NL@%%@NL@%
  19857. %@NL@%
  19858. %@2@%%@AB@%8087 or 80287 coprocessor:%@AE@%%@EH@%%@NL@%
  19859. %@3@%Intel hardware products that provide very fast and precise floating-point%@EH@%
  19860. number processing.%@NL@%%@NL@%
  19861. %@NL@%
  19862. %@2@%%@AB@%%@CR:C6A00170029 @%%@CR:C6A00170030 @%aggregate types:%@AE@%%@EH@%%@NL@%
  19863. %@3@%Arrays, structures, and unions.%@NL@%%@NL@%%@EH@%
  19864. %@NL@%
  19865. %@2@%%@AB@%%@CR:C6A00170031 @%ANSI (American National Standards Institute):%@AE@%%@EH@%%@NL@%
  19866. %@3@%The national institute responsible for defining programming-language%@EH@%
  19867. standards to promote portability of these languages between different
  19868. computer systems. The ANSI standard for C will become official in 1990.%@NL@%%@NL@%
  19869. %@NL@%
  19870. %@2@%%@AB@%argc:%@AE@%%@EH@%%@NL@%
  19871. %@3@%The traditional name for the first argument to the %@AB@%main%@AE@% function in a C%@EH@%
  19872. source program. It is an integer that specifies how many arguments are
  19873. passed to the program from the command line.%@NL@%%@NL@%
  19874. %@NL@%
  19875. %@2@%%@AB@%%@CR:C6A00170032 @%argument:%@AE@%%@EH@%%@NL@%
  19876. %@3@%A value passed to a function.%@NL@%%@NL@%%@EH@%
  19877. %@NL@%
  19878. %@2@%%@AB@%argv:%@AE@%%@EH@%%@NL@%
  19879. %@3@%The traditional name for the second argument to the %@AB@%main%@AE@% function in a C%@EH@%
  19880. source program. It is a pointer to an array of strings. Traditionally, the
  19881. first string is the program name, and each following string is an argument
  19882. passed to the program from the command line.%@NL@%%@NL@%
  19883. %@NL@%
  19884. %@2@%%@AB@%%@CR:C6A00170033 @%array:%@AE@%%@EH@%%@NL@%
  19885. %@3@%A set of elements with the same type.%@NL@%%@NL@%%@EH@%
  19886. %@NL@%
  19887. %@2@%%@AB@%array pointer:%@AE@%%@EH@%%@NL@%
  19888. %@3@%A pointer that holds the address of any element of an array.%@NL@%%@NL@%%@EH@%
  19889. %@NL@%
  19890. %@2@%%@AB@%%@CR:C6A00170034 @%ASCII (American Standard Code for Information Interchange):%@AE@%%@EH@%%@NL@%
  19891. %@3@%A set of 256 codes that many computers use to represent letters, digits,%@EH@%
  19892. special characters, and other symbols. Only the first 128 of these codes are
  19893. standardized; the remaining 128 are special characters that are defined by
  19894. the computer manufacturer.%@NL@%%@NL@%
  19895. %@NL@%
  19896. %@2@%%@AB@%%@CR:C6A00170035 @%%@CR:C6A00170036 @%automatic variable:%@AE@%%@EH@%%@NL@%
  19897. %@3@%A variable, declared in a block, whose value is discarded when the program%@EH@%
  19898. exits from the block. See "static variable" and "lifetime."%@NL@%%@NL@%
  19899. %@NL@%
  19900. %@2@%%@AB@%background color:%@AE@%%@EH@%%@NL@%
  19901. %@3@%A long integer representing the background color of the display screen. In%@EH@%
  19902. graphics modes, the background color applies to the entire screen. In text
  19903. modes, the background color specifies the text background for each
  19904. character. See "foreground color."%@NL@%%@NL@%
  19905. %@NL@%
  19906. %@2@%%@AB@%basic data types:%@CR:C6A00170037 @%%@CR:C6A00170038 @%%@AE@%%@EH@%%@NL@%
  19907. %@3@%The integral, enumerated, floating-point, and pointer types in the C%@EH@%
  19908. language.%@NL@%%@NL@%
  19909. %@NL@%
  19910. %@2@%%@AB@%binary file:%@CR:C6A00170039 @%%@AE@%%@EH@%%@NL@%
  19911. %@3@%A file that is not used for text processing. It may be an executable file, a%@EH@%
  19912. data file, or some other nontext file.%@NL@%%@NL@%
  19913. %@NL@%
  19914. %@2@%%@AB@%binary format:%@CR:C6A00170040 @%%@AE@%%@EH@%%@NL@%
  19915. %@3@%A method of data representation in which data are stored directly from%@EH@%
  19916. memory to disk with no translations. In binary format, numeric values are
  19917. stored as binary numbers and are not translated to ASCII characters.%@NL@%%@NL@%
  19918. %@NL@%
  19919. %@2@%%@AB@%binary mode:%@CR:C6A00170041 @%%@AE@%%@EH@%%@NL@%
  19920. %@3@%A method of accessing files in which no translations are performed. There is%@EH@%
  19921. no specific end-of-file character.%@NL@%%@NL@%
  19922. %@NL@%
  19923. %@2@%%@AB@%binary operator:%@CR:C6A00170042 @%%@CR:C6A00170043 @%%@AE@%%@EH@%%@NL@%
  19924. %@3@%An operator that takes two operands. Binary operators in the C language are%@EH@%
  19925. the multiplicative operators (%@AB@%*/%@AE@%), additive operators (%@AB@%+ -%@AE@%), shift operators
  19926. (%@AB@%<<  >>%@AE@%), relational operators (%@AB@%< >>  <=  >=  ==  !=%@AE@%), bitwise operators (%@AB@%&
  19927. %@AB@%| ^%@AE@%), logical operators (%@AB@%&& ||%@AE@%), and the sequential-evaluation operator (%@AB@%,%@AE@%).%@NL@%%@NL@%
  19928. %@NL@%
  19929. %@2@%%@AB@%bit:%@CR:C6A00170044 @%%@AE@%%@EH@%%@NL@%
  19930. %@3@%A binary digit (either 0 or 1), the smallest unit of information used with%@EH@%
  19931. computers. Eight bits make up one byte.%@NL@%%@NL@%
  19932. %@NL@%
  19933. %@2@%%@AB@%bit field:%@CR:C6A00170045 @%%@CR:C6A00170046 @%%@AE@%%@EH@%%@NL@%
  19934. %@3@%A type of structure that allows manipulation of individual bits or groups of%@EH@%
  19935. bits. %@NL@%%@NL@%
  19936. %@NL@%
  19937. %@2@%%@AB@%bit-mapped font:%@CR:C6A00170047 @%%@AE@%%@EH@%%@NL@%
  19938. %@3@%A font in which each character is defined by (mapped to) the bits of an%@EH@%
  19939. array.%@NL@%%@NL@%
  19940. %@NL@%
  19941. %@2@%%@AB@%bitwise operator:%@CR:C6A00170048 @%%@CR:C6A00170049 @%%@CR:C6A00170050 @%%@CR:C6A00170051 @%%@CR:C6A00170052 @%%@CR:C6A00170053 @%%@CR:C6A00170054 @%%@CR:C6A00170055 @%%@CR:C6A00170056 @%%@CR:C6A00170057 @%%@CR:C6A00170058 @%%@EH@%
  19942. %@AB@%%@CR:C6A00170059 @%%@CR:C6A00170060 @%%@CR:C6A00170061 @%%@CR:C6A00170062 @%%@AE@%%@NL@%
  19943. %@3@%An operator used to manipulate bits in an integer expression. Bitwise%@EH@%
  19944. operators in the C language are %@AB@%&%@AE@% (AND),%@AB@% |%@AE@% (inclusive OR), %@AB@%^%@AE@% (exclusive OR),
  19945. %@AB@%%@AE@% (left shift), %@AB@%>>%@AE@% (right shift), and %@AB@%~%@AE@% (one's complement).%@NL@%%@NL@%
  19946. %@NL@%
  19947. %@2@%%@AB@%block:%@CR:C6A00170063 @%%@AE@%%@EH@%%@NL@%
  19948. %@3@%A sequence of declarations, definitions, and statements enclosed within%@EH@%
  19949. curly braces ({}).%@NL@%%@NL@%
  19950. %@NL@%
  19951. %@2@%%@AB@%bounding rectangle:%@CR:C6A00170064 @%%@AE@%%@EH@%%@NL@%
  19952. %@3@%An imaginary rectangle that defines the outer limits of a rounded shape such%@EH@%
  19953. as an ellipse, arc, or pie.%@NL@%%@NL@%
  19954. %@NL@%
  19955. %@2@%%@AB@%byte:%@CR:C6A00170065 @%%@AE@%%@EH@%%@NL@%
  19956. %@3@%The unit of measure used for computer memory and data storage. One byte%@EH@%
  19957. contains eight bits and can store one ASCII character.%@NL@%%@NL@%
  19958. %@NL@%
  19959. %@2@%%@AB@%case label:%@CR:C6A00170066 @%%@AE@%%@EH@%%@NL@%
  19960. %@3@%The %@AB@%case%@AE@% keyword and the constant, or constant expression, that follows it. %@NL@%%@NL@%%@EH@%
  19961. %@NL@%
  19962. %@2@%%@AB@%CGA:%@AE@%%@EH@%%@NL@%
  19963. %@3@%IBM's Color Graphics Adapter.%@NL@%%@NL@%%@EH@%
  19964. %@NL@%
  19965. %@2@%%@AB@%character code:%@AE@%%@EH@%%@NL@%
  19966. %@3@%A numeric code that represents a character. The default ASCII character set%@EH@%
  19967. used in all PCs and PS/2s comprises 256 eight-bit character codes.%@NL@%%@NL@%
  19968. %@NL@%
  19969. %@2@%%@AB@%character constant:%@CR:C6A00170067 @%%@AE@%%@EH@%%@NL@%
  19970. %@3@%A character enclosed in single quotes, for example, %@AS@%'p'%@AE@%. A character%@EH@%
  19971. constant has a type of %@AB@%char%@AE@%. See "string constant."%@NL@%%@NL@%
  19972. %@NL@%
  19973. %@2@%%@AB@%character set:%@AE@%%@EH@%%@NL@%
  19974. %@3@%A set of alphabetic and numeric characters and symbols.%@NL@%%@NL@%%@EH@%
  19975. %@NL@%
  19976. %@2@%%@AB@%clipping:%@AE@%%@EH@%%@NL@%
  19977. %@3@%The process of determining which parts of a graphics image lie within the%@EH@%
  19978. clipping region. Parts of the image that lie outside this region are
  19979. "clipped"; that is, they are not displayed.%@NL@%%@NL@%
  19980. %@NL@%
  19981. %@2@%%@AB@%clipping region:%@CR:C6A00170068 @%%@AE@%%@EH@%%@NL@%
  19982. %@3@%The rectangular area of the screen where graphics display occurs.%@NL@%%@NL@%%@EH@%
  19983. %@NL@%
  19984. %@2@%%@AB@%color index:%@CR:C6A00170069 @%%@AE@%%@EH@%%@NL@%
  19985. %@3@%A short integer that represents a displayable color. See "remapping" and%@EH@%
  19986. "color value."%@NL@%%@NL@%
  19987. %@NL@%
  19988. %@2@%%@AB@%color value:%@CR:C6A00170070 @%%@AE@%%@EH@%%@NL@%
  19989. %@3@%A long integer representing an absolute color. See "remapping" and "color%@EH@%
  19990. index."%@NL@%%@NL@%
  19991. %@NL@%
  19992. %@2@%%@AB@%command-line argument:%@AE@%%@EH@%%@NL@%
  19993. %@3@%A value passed to a program when the program begins execution.%@NL@%%@NL@%%@EH@%
  19994. %@NL@%
  19995. %@2@%%@AB@%%@CR:C6A00170071 @%conditional expression:%@AE@%%@EH@%%@NL@%
  19996. %@3@%An expression consisting of three operands joined by the ternary (%@AB@%? :%@AE@%)%@EH@%
  19997. operator. Similar to an %@AB@%if%@AE@%-%@AB@%else%@AE@% construct, a conditional expression is used
  19998. to evaluate either of two expressions depending on the value of a third
  19999. expression. %@NL@%%@NL@%
  20000. %@NL@%
  20001. %@2@%%@AB@%constant expression:%@CR:C6A00170072 @%%@CR:C6A00170073 @%%@AE@%%@EH@%%@NL@%
  20002. %@3@%An expression that evaluates to a constant. A constant expression may%@EH@%
  20003. involve integer constants, character constants, floating-point constants,
  20004. enumeration constants, type casts to integral and floating-point types, and
  20005. other constant expressions. %@NL@%%@NL@%
  20006. %@NL@%
  20007. %@2@%%@AB@%current color:%@CR:C6A00170074 @%%@CR:C6A00170075 @%%@AE@%%@EH@%%@NL@%
  20008. %@3@%The color index for the color in which graphics pixels are displayed. The%@EH@%
  20009. current color can be examined with %@AB@%_getcolor%@AE@% or changed with%@AB@% _setcolor%@AE@%. %@NL@%%@NL@%
  20010. %@NL@%
  20011. %@2@%%@AB@%declaration:%@CR:C6A00170076 @%%@AE@%%@EH@%%@NL@%
  20012. %@3@%A construct that associates the name and the attributes of a variable,%@EH@%
  20013. function, or type. %@NL@%%@NL@%
  20014. %@NL@%
  20015. %@2@%%@AB@%default:%@AE@%%@EH@%%@NL@%
  20016. %@3@%A condition that is assumed by a program if not specified.%@NL@%%@NL@%%@EH@%
  20017. %@NL@%
  20018. %@2@%%@AB@%definition:%@CR:C6A00170077 @%%@AE@%%@EH@%%@NL@%
  20019. %@3@%A construct that initializes and allocates storage for a variable or that%@EH@%
  20020. specifies the name, formal parameters, body, and return type of a function.%@NL@%%@NL@%
  20021. %@NL@%
  20022. %@2@%%@AB@%%@CR:C6A00170078 @%%@CR:C6A00170079 @%dimension:%@AE@%%@EH@%%@NL@%
  20023. %@3@%The number of subscripts required to specify a single array element.%@NL@%%@NL@%%@EH@%
  20024. %@NL@%
  20025. %@2@%%@AB@%directive:%@CR:C6A00170080 @%%@AE@%%@EH@%%@NL@%
  20026. %@3@%An instruction to the C preprocessor to perform an action on source-program%@EH@%
  20027. text before compilation.%@NL@%%@NL@%
  20028. %@NL@%
  20029. %@2@%%@AB@%double precision:%@CR:C6A00170081 @%%@AE@%%@EH@%%@NL@%
  20030. %@3@%A real (floating-point) value that occupies eight bytes of memory. Double%@EH@%
  20031. precision values are accurate to 15 or 16 digits.%@NL@%%@NL@%
  20032. %@NL@%
  20033. %@2@%%@AB@%EGA:%@AE@%%@EH@%%@NL@%
  20034. %@3@%Enhanced Graphics Adapter.%@NL@%%@NL@%%@EH@%
  20035. %@NL@%
  20036. %@2@%%@AB@%enumeration type:%@CR:C6A00170082 @%%@CR:C6A00170083 @%%@AE@%%@EH@%%@NL@%
  20037. %@3@%A user-defined data type with values that range over a set of named integral%@EH@%
  20038. constants.%@NL@%%@NL@%
  20039. %@NL@%
  20040. %@2@%%@AB@%escape sequence:%@CR:C6A00170084 @%%@AE@%%@EH@%%@NL@%
  20041. %@3@%A specific combination of a backslash (%@AB@%\%@AE@%) followed by a letter or%@EH@%
  20042. combination of digits, which represents white space and nonprinting
  20043. characters within strings and character constants. %@NL@%%@NL@%
  20044. %@NL@%
  20045. %@2@%%@AB@%expression:%@CR:C6A00170085 @%%@AE@%%@EH@%%@NL@%
  20046. %@3@%A combination of operands and operators that yields a single value.%@NL@%%@NL@%%@EH@%
  20047. %@NL@%
  20048. %@2@%%@AB@%%@CR:C6A00170086 @%%@CR:C6A00170087 @%external variable:%@AE@%%@EH@%%@NL@%
  20049. %@3@%A variable that is defined outside any function in a C source file and is%@EH@%
  20050. used in other source files in the same program.%@NL@%%@NL@%
  20051. %@NL@%
  20052. %@2@%%@AB@%file handle:%@CR:C6A00170088 @%%@AE@%%@EH@%%@NL@%
  20053. %@3@%An integer value that is returned when a library function that performs%@EH@%
  20054. low-level input/output opens or creates a file. The file handle is used to
  20055. refer to that file in later operations.%@NL@%%@NL@%
  20056. %@NL@%
  20057. %@2@%%@AB@%file pointer:%@CR:C6A00170089 @%%@CR:C6A00170090 @%%@CR:C6A00170091 @%%@AE@%%@EH@%%@NL@%
  20058. %@3@%A value that keeps track of the current position in an input or output%@EH@%
  20059. stream. It is updated to reflect the new position each time a read or write
  20060. operation takes place.%@NL@%%@NL@%
  20061. %@NL@%
  20062. %@2@%%@AB@%FILE pointer:%@AE@%%@EH@%%@NL@%
  20063. %@3@%A pointer to a structure of type FILE that contains information about a%@EH@%
  20064. file. It is returned by library functions that create or open files and use
  20065. stream input/output.%@NL@%%@NL@%
  20066. %@NL@%
  20067. %@2@%%@AB@%fill flag:%@CR:C6A00170092 @%%@AE@%%@EH@%%@NL@%
  20068. %@3@%A parameter that determines whether a shape will be drawn as a solid.%@NL@%%@NL@%%@EH@%
  20069. %@NL@%
  20070. %@2@%%@AB@%%@CR:C6A00170093 @%fill mask:%@AE@%%@EH@%%@NL@%
  20071. %@3@%A group of pixels that defines the pattern used to fill a graphics shape.%@NL@%%@NL@%%@EH@%
  20072. %@NL@%
  20073. %@2@%%@AB@%fill pattern:%@CR:C6A00170094 @%%@AE@%%@EH@%%@NL@%
  20074. %@3@%The design defined by the fill mask and used to fill a shape.%@NL@%%@NL@%%@EH@%
  20075. %@NL@%
  20076. %@2@%%@AB@%font:%@CR:C6A00170095 @%%@AE@%%@EH@%%@NL@%
  20077. %@3@%A description of the style and shapes of the characters in a character set. %@NL@%%@NL@%%@EH@%
  20078. %@NL@%
  20079. %@2@%%@AB@%foreground color:%@CR:C6A00170096 @%%@AE@%%@EH@%%@NL@%
  20080. %@3@%The color index for the color in which text is displayed. See "background%@EH@%
  20081. color."%@NL@%%@NL@%
  20082. %@NL@%
  20083. %@2@%%@AB@%format specification:%@CR:C6A00170097 @%%@AE@%%@EH@%%@NL@%
  20084. %@3@%A string that specifies how the %@AB@%printf%@AE@% and %@AB@%scanf%@AE@% families of functions%@EH@%
  20085. interpret input and output data.%@NL@%%@NL@%
  20086. %@NL@%
  20087. %@2@%%@AB@%function:%@CR:C6A00170098 @%%@AE@%%@EH@%%@NL@%
  20088. %@3@%A collection of declarations and statements that has a unique name and can%@EH@%
  20089. return a value. %@NL@%%@NL@%
  20090. %@NL@%
  20091. %@2@%%@AB@%function body:%@AE@%%@EH@%%@NL@%
  20092. %@3@%A statement block containing the local variable declarations and statements%@EH@%
  20093. of a function.%@NL@%%@NL@%
  20094. %@NL@%
  20095. %@2@%%@AB@%function call:%@CR:C6A00170099 @%%@AE@%%@EH@%%@NL@%
  20096. %@3@%An expression that passes control and arguments (if any) to a function.%@NL@%%@NL@%%@EH@%
  20097. %@NL@%
  20098. %@2@%%@AB@%function declaration:%@CR:C6A00170100 @%%@CR:C6A00170101 @%%@AE@%%@EH@%%@NL@%
  20099. %@3@%A declaration that states the name, return type, and storage class of a%@EH@%
  20100. function that is defined explicitly elsewhere in the program.%@NL@%%@NL@%
  20101. %@NL@%
  20102. %@2@%%@AB@%function definition:%@CR:C6A00170102 @%%@AE@%%@EH@%%@NL@%
  20103. %@3@%A definition that specifies a function's name, its formal parameters, the%@EH@%
  20104. declarations and statements that define what it does, and (optionally) its
  20105. return type and storage class.%@NL@%%@NL@%
  20106. %@NL@%
  20107. %@2@%%@AB@%function pointer:%@CR:C6A00170103 @%%@AE@%%@EH@%%@NL@%
  20108. %@3@%A pointer that holds the address of a function.%@NL@%%@NL@%%@EH@%
  20109. %@NL@%
  20110. %@2@%%@AB@%function prototype:%@CR:C6A00170104 @%%@CR:C6A00170105 @%%@AE@%%@EH@%%@NL@%
  20111. %@3@%A function declaration that includes a list of the names and types of formal%@EH@%
  20112. parameters in the parentheses following the function name.%@NL@%%@NL@%
  20113. %@NL@%
  20114. %@2@%%@AB@%global:%@AE@%%@EH@%%@NL@%
  20115. %@3@%See "visibility."%@NL@%%@NL@%%@EH@%
  20116. %@NL@%
  20117. %@2@%%@AB@%graphics mode:%@CR:C6A00170106 @%%@AE@%%@EH@%%@NL@%
  20118. %@3@%See "video mode."%@NL@%%@NL@%%@EH@%
  20119. %@NL@%
  20120. %@2@%%@AB@%header file:%@AE@%%@EH@%%@NL@%
  20121. %@3@%An external source file that contains commonly used declarations and%@EH@%
  20122. definitions. The %@AB@%#include%@AE@% directive is used to insert the contents of a
  20123. header file into a C source file.%@NL@%%@NL@%
  20124. %@NL@%
  20125. %@2@%%@AB@%hexadecimal:%@CR:C6A00170107 @%%@AE@%%@EH@%%@NL@%
  20126. %@3@%The base-16 numbering system whose digits are 0 through F. The letters A%@EH@%
  20127. through F represent the decimal numbers 10 through 15. It is often used in
  20128. computer programming because it is easily converted to and from binary, the
  20129. base-2 numbering system the computer itself uses.%@NL@%%@NL@%
  20130. %@NL@%
  20131. %@2@%%@AB@%HGC:%@AE@%%@EH@%%@NL@%
  20132. %@3@%Hercules monochrome Graphics Card. %@NL@%%@NL@%%@EH@%
  20133. %@NL@%
  20134. %@2@%%@AB@%identifier:%@CR:C6A00170108 @%%@AE@%%@EH@%%@NL@%
  20135. %@3@%A user-defined name in a C program. Identifiers name variables, functions,%@EH@%
  20136. macros, constants, and data types.%@NL@%%@NL@%
  20137. %@NL@%
  20138. %@2@%%@AB@%include file:%@CR:C6A00170109 @%%@AE@%%@EH@%%@NL@%
  20139. %@3@%See "header file."%@NL@%%@NL@%%@EH@%
  20140. %@NL@%
  20141. %@2@%%@AB@%Incolor Card:%@CR:C6A00170110 @%%@CR:C6A00170111 @%%@AE@%%@EH@%%@NL@%
  20142. %@3@%Hercules InColor Card, a 16-color version of the HGC+.%@NL@%%@NL@%%@EH@%
  20143. %@NL@%
  20144. %@2@%%@AB@%indirection:%@CR:C6A00170112 @%%@AE@%%@EH@%%@NL@%
  20145. %@3@%Accessing a data object through a pointer, rather than directly by name.%@NL@%%@NL@%%@EH@%
  20146. %@NL@%
  20147. %@2@%%@AB@%initialize:%@CR:C6A00170113 @%%@AE@%%@EH@%%@NL@%
  20148. %@3@%To assign a value to a variable, often at the time the variable is declared.%@NL@%%@NL@%%@EH@%
  20149. %@NL@%
  20150. %@2@%%@AB@%in-line assembler:%@CR:C6A00170114 @%%@AE@%%@EH@%%@NL@%
  20151. %@3@%The part of QuickC that converts assembly-language instructions into machine%@EH@%
  20152. language.%@NL@%%@NL@%
  20153. %@NL@%
  20154. %@2@%%@AB@%in-line assembly code:%@CR:C6A00170115 @%%@AE@%%@EH@%%@NL@%
  20155. %@3@%Assembly language instructions that appear within a QuickC source program.%@NL@%%@NL@%%@EH@%
  20156. %@NL@%
  20157. %@2@%%@AB@%input/output:%@AE@%%@EH@%%@NL@%
  20158. %@3@%The processes involved in reading (input) and writing (output) data.%@NL@%%@NL@%%@EH@%
  20159. %@NL@%
  20160. %@2@%%@AB@%integer:%@CR:C6A00170116 @%%@AE@%%@EH@%%@NL@%
  20161. %@3@%A whole number represented in the machine as a 16-bit two's-complement%@EH@%
  20162. binary number. A signed integer has a range of -32,768 to 32,767. An
  20163. unsigned integer has a range of 0 to 65,535. See "long integer."%@NL@%%@NL@%
  20164. %@NL@%
  20165. %@2@%%@AB@%I/O:%@CR:C6A00170117 @%%@AE@%%@EH@%%@NL@%
  20166. %@3@%Abbreviation for input/output.%@NL@%%@NL@%%@EH@%
  20167. %@NL@%
  20168. %@2@%%@AB@%keyword:%@CR:C6A00170118 @%%@AE@%%@EH@%%@NL@%
  20169. %@3@%A word with a special, predefined meaning for the C compiler. %@NL@%%@NL@%%@EH@%
  20170. %@NL@%
  20171. %@2@%%@AB@%%@CR:C6A00170119 @%label:%@AE@%%@EH@%%@NL@%
  20172. %@3@%A unique name followed by a colon. Labels are used to denote statements to%@EH@%
  20173. which a %@AB@%goto%@AE@% statement can branch. See "%@AB@%case%@AE@% label."%@NL@%%@NL@%
  20174. %@NL@%
  20175. %@2@%%@AB@%library:%@CR:C6A00170120 @%%@AE@%%@EH@%%@NL@%
  20176. %@3@%A file containing compiled modules. The linker extracts modules from the%@EH@%
  20177. library file and combines them with the user-created object file to form an
  20178. executable program.%@NL@%%@NL@%
  20179. %@NL@%
  20180. %@2@%%@AB@%lifetime:%@CR:C6A00170121 @%%@CR:C6A00170122 @%%@AE@%%@EH@%%@NL@%
  20181. %@3@%The time, during program execution, that a variable or function exists. An%@EH@%
  20182. "automatic" variable has storage and a defined value only in the block where
  20183. it is defined or declared. A "static" variable exists for the duration of
  20184. the program. %@NL@%%@NL@%
  20185. %@NL@%
  20186. %@2@%%@AB@%line style:%@CR:C6A00170123 @%%@AE@%%@EH@%%@NL@%
  20187. %@3@%An unsigned short integer (16 bits) that specifies the pattern with which%@EH@%
  20188. lines will be drawn. Each bit specifies whether a corresponding pixel in the
  20189. line will be displayed. The default line style is a solid line.%@NL@%%@NL@%
  20190. %@NL@%
  20191. %@2@%%@AB@%local:%@AE@%%@EH@%%@NL@%
  20192. %@3@%See "visibility."%@NL@%%@NL@%%@EH@%
  20193. %@NL@%
  20194. %@2@%%@AB@%long integer:%@AE@%%@EH@%%@NL@%
  20195. %@3@%A whole number represented inside the machine as a 32-bit two's-complement%@EH@%
  20196. binary number. A signed long integer has a range of -2,147,483,648 to
  20197. 2,147,483,647. An unsigned long integer has a range of 0 to 4,294,967,295.
  20198. See "integer."%@NL@%%@NL@%
  20199. %@NL@%
  20200. %@2@%%@AB@%low-level input and output routines:%@AE@%%@EH@%%@NL@%
  20201. %@3@%Run-time library routines that perform unbuffered, unformatted I/O%@EH@%
  20202. operations, for example, %@AB@%creat%@AE@%, %@AB@%read%@AE@%, %@AB@%write%@AE@%, and %@AB@%lseek%@AE@%.%@NL@%%@NL@%
  20203. %@NL@%
  20204. %@2@%%@AB@%lvalue:%@CR:C6A00170124 @%%@AE@%%@EH@%%@NL@%
  20205. %@3@%An expression (such as a variable name) that refers to a memory location and%@EH@%
  20206. is required as the left-hand operand of an assignment operation, or as the
  20207. single operand of a unary operator.%@NL@%%@NL@%
  20208. %@NL@%
  20209. %@2@%%@AB@%machine language:%@CR:C6A00170125 @%%@AE@%%@EH@%%@NL@%
  20210. %@3@%A series of binary numbers that a computer executes as program instructions.%@EH@%
  20211. %@NL@%%@NL@%
  20212. %@NL@%
  20213. %@2@%%@AB@%macro:%@CR:C6A00170126 @%%@AE@%%@EH@%%@NL@%
  20214. %@3@%An identifier defined in a %@AB@%#define%@AE@% preprocessor directive to represent%@EH@%
  20215. another series of characters. %@NL@%%@NL@%
  20216. %@NL@%
  20217. %@2@%%@AB@%main function:%@CR:C6A00170127 @%%@CR:C6A00170128 @%%@AE@%%@EH@%%@NL@%
  20218. %@3@%The function with which program execution begins (the program's entry%@EH@%
  20219. point).%@NL@%%@NL@%
  20220. %@NL@%
  20221. %@2@%%@AB@%manifest constant:%@AE@%%@EH@%%@NL@%
  20222. %@3@%See "symbolic constant." %@NL@%%@NL@%%@EH@%
  20223. %@NL@%
  20224. %@2@%%@AB@%MCGA (%@AB@%Multicolor Graphics Array%@AE@%):%@CR:C6A00170129 @%%@AE@%%@EH@%%@NL@%
  20225. %@3@%The video subsystem integrated into the PS/2 Model 30. Also, Memory%@EH@%
  20226. Controller Gate Array, one of the components of the Model 30's video
  20227. subsystem. %@NL@%%@NL@%
  20228. %@NL@%
  20229. %@2@%%@AB@%member:%@CR:C6A00170130 @%%@AE@%%@EH@%%@NL@%
  20230. %@3@%One of the elements of a structure or union.%@NL@%%@NL@%%@EH@%
  20231. %@NL@%
  20232. %@2@%%@AB@%member-of operator:%@AE@%%@EH@%%@NL@%
  20233. %@3@%The dot operator (%@AB@%.%@AE@%), which is used with the name of a structure and one or%@EH@%
  20234. more fields to identify a structure member.%@NL@%%@NL@%
  20235. %@NL@%
  20236. %@2@%%@AB@%mode:%@CR:C6A00170131 @%%@AE@%%@EH@%%@NL@%
  20237. %@3@%See "video mode."%@NL@%%@NL@%%@EH@%
  20238. %@NL@%
  20239. %@2@%%@AB@%monochrome display:%@AE@%%@EH@%%@NL@%
  20240. %@3@%A computer monitor capable of showing only two colors─black and a second%@EH@%
  20241. color such as white, green, or amber. Some monochrome monitors can also show
  20242. the second color with higher intensity or with underlined text.%@NL@%%@NL@%
  20243. %@NL@%
  20244. %@2@%%@AB@%Monochrome Display Adapter (MDA):%@CR:C6A00170132 @%%@AE@%%@EH@%%@NL@%
  20245. %@3@%A printed-circuit card that controls the display and can show text only at%@EH@%
  20246. medium resolution in one color.%@NL@%%@NL@%
  20247. %@NL@%
  20248. %@2@%%@AB@%newline character:%@CR:C6A00170133 @%%@CR:C6A00170134 @%%@AE@%%@EH@%%@NL@%
  20249. %@3@%The character used to mark the end of a line in a text file, or the escape%@EH@%
  20250. sequence (%@AB@%\n%@AE@%) used to represent this character. %@NL@%%@NL@%
  20251. %@NL@%
  20252. %@2@%%@AB@%%@CR:C6A00170135 @%%@CR:C6A00170136 @%null character:%@AE@%%@EH@%%@NL@%
  20253. %@3@%The ASCII character encoded as the value 0, represented as the escape%@EH@%
  20254. sequence (%@AB@%\0%@AE@%) in a source file. A null character marks the end of a string.%@NL@%%@NL@%
  20255. %@NL@%
  20256. %@2@%%@AB@%%@CR:C6A00170137 @%%@CR:C6A00170138 @%null pointer:%@AE@%%@EH@%%@NL@%
  20257. %@3@%A pointer to nothing, expressed as the value 0.%@NL@%%@NL@%%@EH@%
  20258. %@NL@%
  20259. %@2@%%@AB@%one's complement:%@AE@%%@EH@%%@NL@%
  20260. %@3@%The arithmetic operation in which all 1 bits are converted to 0 bits and%@EH@%
  20261. vice versa. The tilde character (%@AB@%~%@AE@%) is the one's-complement operator.%@NL@%%@NL@%
  20262. %@NL@%
  20263. %@2@%%@AB@%%@CR:C6A00170139 @%operand:%@AE@%%@EH@%%@NL@%
  20264. %@3@%A constant or variable value that is manipulated in an expression.%@NL@%%@NL@%%@EH@%
  20265. %@NL@%
  20266. %@2@%%@AB@%operator:%@CR:C6A00170140 @%%@AE@%%@EH@%%@NL@%
  20267. %@3@%One or more symbols that specify how the operand or operands of an%@EH@%
  20268. expression are manipulated. See "unary operator," "binary operator," and
  20269. "ternary operator."%@NL@%%@NL@%
  20270. %@NL@%
  20271. %@2@%%@AB@%origin:%@CR:C6A00170141 @%%@AE@%%@EH@%%@NL@%
  20272. %@3@%The point on the screen at which the %@AI@%x%@AE@% and %@AI@%y%@AE@% coordinates are both equal to%@EH@%
  20273. 0. On the physical screen, the origin is at the upper left corner%@AB@%.%@AE@%%@NL@%%@NL@%
  20274. %@NL@%
  20275. %@2@%%@AB@%palette:%@CR:C6A00170142 @%%@AE@%%@EH@%%@NL@%
  20276. %@3@%The displayable colors for a given video mode. The CGA modes operate with a%@EH@%
  20277. set of predetermined palette colors. The EGA, VGA, and MCGA color modes
  20278. operate with a redefinable palette of colors. %@NL@%%@NL@%
  20279. %@NL@%
  20280. %@2@%%@AB@%parameter:%@CR:C6A00170143 @%%@AE@%%@EH@%%@NL@%
  20281. %@3@%An identifier that receives a value passed to a function.%@NL@%%@NL@%%@EH@%
  20282. %@NL@%
  20283. %@2@%%@AB@%path:%@CR:C6A00170144 @%%@AE@%%@EH@%%@NL@%
  20284. %@3@%The name that defines the location of a file or directory. A path may%@EH@%
  20285. include a drive name and one or more directory names.%@NL@%%@NL@%
  20286. %@NL@%
  20287. %@2@%%@AB@%PGA (Professional Graphics Adapter):%@CR:C6A00170145 @%%@AE@%%@EH@%%@NL@%
  20288. %@3@%Another name for IBM's PGC.%@NL@%%@NL@%%@EH@%
  20289. %@NL@%
  20290. %@2@%%@AB@%physical coordinates:%@CR:C6A00170146 @%%@AE@%%@EH@%%@NL@%
  20291. %@3@%The coordinate system defined by the hardware. The physical coordinate%@EH@%
  20292. system has the origin (0, 0) at the upper left corner of the screen. The
  20293. value of %@AI@%x%@AE@% increases from left to right, and the value of %@AI@%y%@AE@% increases from
  20294. top to bottom. See "viewport coordinates."%@NL@%%@NL@%
  20295. %@NL@%
  20296. %@2@%%@AB@%pixel:%@CR:C6A00170147 @%%@AE@%%@EH@%%@NL@%
  20297. %@3@%A single dot on the screen. It is the smallest item that may be manipulated%@EH@%
  20298. with the graphics library, and it is the basic unit of the
  20299. viewport-coordinate system. %@NL@%%@NL@%
  20300. %@NL@%
  20301. %@2@%%@AB@%pointer:%@CR:C6A00170148 @%%@AE@%%@EH@%%@NL@%
  20302. %@3@%A variable containing the address of another variable, function, or%@EH@%
  20303. constant. %@NL@%%@NL@%
  20304. %@NL@%
  20305. %@2@%%@AB@%pointer arithmetic:%@CR:C6A00170149 @%%@CR:C6A00170150 @%%@AE@%%@EH@%%@NL@%
  20306. %@3@%The use of addition or subtraction to change a pointer's value. Pointer%@EH@%
  20307. arithmetic is typically used with array pointers, though it is not illegal
  20308. on other kinds of pointers.%@NL@%%@NL@%
  20309. %@NL@%
  20310. %@2@%%@AB@%pointer-member operator:%@CR:C6A00170151 @%%@CR:C6A00170152 @%%@CR:C6A00170153 @%%@AE@%%@EH@%%@NL@%
  20311. %@3@%The %@AB@%->%@AE@% operator, used with structure pointers to name a structure member.%@NL@%%@NL@%%@EH@%
  20312. %@NL@%
  20313. %@2@%%@AB@%pragma:%@CR:C6A00170154 @%%@AE@%%@EH@%%@NL@%
  20314. %@3@%An instruction to the compiler to perform an action at compile time.%@NL@%%@NL@%%@EH@%
  20315. %@NL@%
  20316. %@2@%%@AB@%precedence:%@CR:C6A00170155 @%%@AE@%%@EH@%%@NL@%
  20317. %@3@%The relative position of an operator in the hierarchy that determines the%@EH@%
  20318. order in which expressions are evaluated.%@NL@%%@NL@%
  20319. %@NL@%
  20320. %@2@%%@AB@%preprocessor:%@CR:C6A00170156 @%%@AE@%%@EH@%%@NL@%
  20321. %@3@%A text processor that manipulates the contents of a C source file during the%@EH@%
  20322. first phase of compilation.%@NL@%%@NL@%
  20323. %@NL@%
  20324. %@2@%%@AB@%preprocessor directive:%@AE@%%@EH@%%@NL@%
  20325. %@3@%See "directive."%@NL@%%@NL@%%@EH@%
  20326. %@NL@%
  20327. %@2@%%@AB@%prototype:%@AE@%%@EH@%%@NL@%
  20328. %@3@%See "function prototype."%@NL@%%@NL@%%@EH@%
  20329. %@NL@%
  20330. %@2@%%@AB@%recursion:%@CR:C6A00170157 @%%@AE@%%@EH@%%@NL@%
  20331. %@3@%The process by which a function calls itself.%@NL@%%@NL@%%@EH@%
  20332. %@NL@%
  20333. %@2@%%@AB@%%@CR:C6A00170158 @%register variable:%@AE@%%@EH@%%@NL@%
  20334. %@3@%An integer variable that is placed in a machine register, which may cause%@EH@%
  20335. the program to be smaller and faster.%@NL@%%@NL@%
  20336. %@NL@%
  20337. %@2@%%@AB@%remapping:%@AE@%%@EH@%%@NL@%
  20338. %@3@%%@CR:C6A00170159 @%The process of assigning new color values to color indexes. Remapping a%@EH@%
  20339. color index changes the screen color of any pixels that have been drawn with
  20340. that color index.%@NL@%%@NL@%
  20341. %@NL@%
  20342. %@2@%%@AB@%reserved word:%@AE@%%@EH@%%@NL@%
  20343. %@3@%See "keyword."%@NL@%%@NL@%%@EH@%
  20344. %@NL@%
  20345. %@2@%%@AB@%return value:%@AE@%%@EH@%%@NL@%
  20346. %@3@%%@CR:C6A00170160 @%The value that a function returns to the calling function.%@NL@%%@NL@%%@EH@%
  20347. %@NL@%
  20348. %@2@%%@AB@%run time:%@AE@%%@EH@%%@NL@%
  20349. %@3@%%@CR:C6A00170161 @%The time during which a previously compiled and linked program is executing.%@NL@%%@NL@%%@EH@%
  20350. %@NL@%
  20351. %@2@%%@AB@%run-time library:%@AE@%%@EH@%%@NL@%
  20352. %@3@%A file containing the routines needed to implement certain functions of the%@EH@%
  20353. Microsoft QuickC language.%@NL@%%@NL@%
  20354. %@NL@%
  20355. %@2@%%@AB@%scaling:%@AE@%%@EH@%%@NL@%
  20356. %@3@%The mapping of real-window coordinates to viewport coordinates.%@NL@%%@NL@%%@EH@%
  20357. %@NL@%
  20358. %@2@%%@AB@%%@CR:C6A00170162 @%scope:%@AE@%%@EH@%%@NL@%
  20359. %@3@%The parts of a program in which an item can be referenced by name. The scope%@EH@%
  20360. of an item may be limited to the file, function, block, or function
  20361. prototype in which it appears.%@NL@%%@NL@%
  20362. %@NL@%
  20363. %@2@%%@AB@%screen mode:%@AE@%%@EH@%%@NL@%
  20364. %@3@%See "video mode."%@NL@%%@NL@%%@EH@%
  20365. %@NL@%
  20366. %@2@%%@AB@%single precision:%@AE@%%@EH@%%@NL@%
  20367. %@3@%%@CR:C6A00170163 @%A real (floating-point) value that occupies four bytes of memory. Single-%@EH@%
  20368. precision values are accurate to seven decimal places. %@NL@%%@NL@%
  20369. %@NL@%
  20370. %@2@%%@AB@%sizeof operator:%@AE@%%@EH@%%@NL@%
  20371. %@3@%%@CR:C6A00170164 @%%@CR:C6A00170165 @%%@CR:C6A00170166 @%A C operator that returns the amount of storage, in bytes, associated with%@EH@%
  20372. an identifier or a type.%@NL@%%@NL@%
  20373. %@NL@%
  20374. %@2@%%@AB@%source file:%@AE@%%@EH@%%@NL@%
  20375. %@3@%A text file containing C language code.%@NL@%%@NL@%%@EH@%
  20376. %@NL@%
  20377. %@2@%%@AB@%standard error:%@AE@%%@EH@%%@NL@%
  20378. %@3@%The device to which a program sends its error messages unless the error%@EH@%
  20379. output is redirected. In normal DOS operation, standard error is the
  20380. display. The predefined stream %@AB@%stderr%@AE@% is associated with standard error in
  20381. the C language. %@NL@%%@NL@%
  20382. %@NL@%
  20383. %@2@%%@AB@%%@CR:C6A00170167 @%standard input:%@AE@%%@EH@%%@NL@%
  20384. %@3@%The device from which a program reads its input unless the input is%@EH@%
  20385. redirected. In normal DOS operation, standard input is the keyboard. The
  20386. predefined stream %@AB@%stdin%@AE@% is associated with standard input in the C language.%@NL@%%@NL@%
  20387. %@NL@%
  20388. %@2@%%@AB@%standard output:%@AE@%%@EH@%%@NL@%
  20389. %@3@%%@CR:C6A00170168 @%The device to which a program sends its output unless the output is%@EH@%
  20390. redirected. In normal DOS operation, standard output is the display. The
  20391. predefined stream %@AB@%stdout%@AE@% is associated with standard output in the C
  20392. language.%@NL@%%@NL@%
  20393. %@NL@%
  20394. %@2@%%@AB@%%@CR:C6A00170169 @%static variable:%@AE@%%@EH@%%@NL@%
  20395. %@3@%A variable that keeps its value even after the program exits the block in%@EH@%
  20396. which the variable is declared.%@NL@%%@NL@%
  20397. %@NL@%
  20398. %@2@%%@AB@%stream:%@AE@%%@EH@%%@NL@%
  20399. %@3@%%@CR:C6A00170170 @%A sequence of bytes flowing into (input) or out of (output) a program.%@NL@%%@NL@%%@EH@%
  20400. %@NL@%
  20401. %@2@%%@AB@%stream functions:%@AE@%%@EH@%%@NL@%
  20402. %@3@%Run-time library functions that treat data files and data items as "streams"%@EH@%
  20403. of individual characters.%@NL@%%@NL@%
  20404. %@NL@%
  20405. %@2@%%@AB@%string:%@AE@%%@EH@%%@NL@%
  20406. %@3@%%@CR:C6A00170171 @%An array of characters, terminated by a null character (%@AB@%\0%@AE@%).%@NL@%%@NL@%%@EH@%
  20407. %@NL@%
  20408. %@2@%%@AB@%string constant:%@AE@%%@EH@%%@NL@%
  20409. %@3@%A string of characters and escape sequences enclosed in double quotes ("").%@EH@%
  20410. Every string constant is an array of elements of type %@AB@%char%@AE@%. See "character
  20411. constant."%@NL@%%@NL@%
  20412. %@NL@%
  20413. %@2@%%@AB@%structure:%@AE@%%@EH@%%@NL@%
  20414. %@3@%%@CR:C6A00170172 @%A set of elements, which may be of different types, grouped under a single%@EH@%
  20415. name.%@NL@%%@NL@%
  20416. %@NL@%
  20417. %@2@%%@AB@%structure member:%@AE@%%@EH@%%@NL@%
  20418. %@3@%One of the elements of a structure.%@NL@%%@NL@%%@EH@%
  20419. %@NL@%
  20420. %@2@%%@AB@%structure pointer:%@AE@%%@EH@%%@NL@%
  20421. %@3@%%@CR:C6A00170173 @%%@CR:C6A00170174 @%A pointer to a structure. Structure pointers identify structure members by%@EH@%
  20422. specifying the name of the structure, the pointer-member operator (%@AB@%->%@AE@%), and
  20423. the member name.%@NL@%%@NL@%
  20424. %@NL@%
  20425. %@2@%%@AB@%symbolic constant:%@AE@%%@EH@%%@NL@%
  20426. %@3@%%@CR:C6A00170175 @%An identifier defined in a %@AB@%#define%@AE@% preprocessor directive to represent a%@EH@%
  20427. constant value.%@NL@%%@NL@%
  20428. %@NL@%
  20429. %@2@%%@AB@%tag:%@AE@%%@EH@%%@NL@%
  20430. %@3@%%@CR:C6A00170176 @%The name assigned to a structure, union, or enumeration type.%@NL@%%@NL@%%@EH@%
  20431. %@NL@%
  20432. %@2@%%@AB@%ternary operator:%@AE@%%@EH@%%@NL@%
  20433. %@3@%An operator used in ternary (three-part) expressions. C has one ternary%@EH@%
  20434. operator, the conditional operator (%@AB@%? :%@AE@%).%@NL@%%@NL@%
  20435. %@NL@%
  20436. %@2@%%@AB@%text:%@AE@%%@EH@%%@NL@%
  20437. %@3@%Ordinary, readable characters, including the uppercase and lowercase letters%@EH@%
  20438. of the alphabet, the numerals 0-9, and punctuation marks.%@NL@%%@NL@%
  20439. %@NL@%
  20440. %@2@%%@AB@%text file:%@AE@%%@EH@%%@NL@%
  20441. %@3@%A file of ASCII characters that you can read with the TYPE command or a word%@EH@%
  20442. processor.%@NL@%%@NL@%
  20443. %@NL@%
  20444. %@2@%%@AB@%text format:%@AE@%%@EH@%%@NL@%
  20445. %@3@%%@CR:C6A00170177 @%A method of disk storage in which all data are converted to ASCII format.%@NL@%%@NL@%%@EH@%
  20446. %@NL@%
  20447. %@2@%%@AB@%text mode:%@AE@%%@EH@%%@NL@%
  20448. %@3@%%@CR:C6A00170178 @%%@CR:C6A00170179 @%See "video mode."%@NL@%%@NL@%%@EH@%
  20449. %@NL@%
  20450. %@2@%%@AB@%text window:%@AE@%%@EH@%%@NL@%
  20451. %@3@%%@CR:C6A00170180 @%%@CR:C6A00170181 @%A window defined in row and column coordinates where text output to the%@EH@%
  20452. screen will be displayed. Text printed beyond the edge of the text window is
  20453. not visible. The default text window is the whole screen.%@NL@%%@NL@%
  20454. %@NL@%
  20455. %@2@%%@AB@%two's complement:%@AE@%%@EH@%%@NL@%
  20456. %@3@%A kind of base-2 notation used to represent positive and negative numbers in%@EH@%
  20457. which negative values are formed by complementing all bits and adding 1 to
  20458. the results.%@NL@%%@NL@%
  20459. %@NL@%
  20460. %@2@%%@AB@%type:%@AE@%%@EH@%%@NL@%
  20461. %@3@%%@CR:C6A00170182 @%%@CR:C6A00170183 @%%@CR:C6A00170184 @%%@CR:C6A00170185 @%A description of a set of values. For example, the type %@AB@%char%@AE@% comprises the%@EH@%
  20462. 256 values in the ASCII character set.%@NL@%%@NL@%
  20463. %@NL@%
  20464. %@2@%%@AB@%type cast:%@AE@%%@EH@%%@NL@%
  20465. %@3@%%@CR:C6A00170186 @%An operation in which a value of one type is converted to a value of a%@EH@%
  20466. different type.%@NL@%%@NL@%
  20467. %@NL@%
  20468. %@2@%%@AB@%type checking:%@AE@%%@EH@%%@NL@%
  20469. %@3@%%@CR:C6A00170187 @%An operation in which the compiler verifies that the operands of an operator%@EH@%
  20470. are valid, or that the actual arguments in a function call are of the same
  20471. types as the corresponding formal parameters in the function definition and
  20472. function prototype.%@NL@%%@NL@%
  20473. %@NL@%
  20474. %@2@%%@AB@%type declaration:%@AE@%%@EH@%%@NL@%
  20475. %@3@%%@CR:C6A00170188 @%A declaration that defines the name and members of a structure or union%@EH@%
  20476. type, or the name and enumeration set of an enumeration type.%@NL@%%@NL@%
  20477. %@NL@%
  20478. %@2@%%@AB@%typedef declaration:%@AE@%%@EH@%%@NL@%
  20479. %@3@%A declaration that defines a shorter or more meaningful name for an existing%@EH@%
  20480. C data type or for a user-defined data type. Names defined in a %@AB@%typedef%@AE@%
  20481. declaration are often referred to as "typedefs." %@NL@%%@NL@%
  20482. %@NL@%
  20483. %@2@%%@AB@%typeface:%@AE@%%@EH@%%@NL@%
  20484. %@3@%%@CR:C6A00170189 @%%@CR:C6A00170190 @%The style of displayed text.%@NL@%%@NL@%%@EH@%
  20485. %@NL@%
  20486. %@2@%%@AB@%type name:%@AE@%%@EH@%%@NL@%
  20487. %@3@%The name of a data type. See "type."%@NL@%%@NL@%%@EH@%
  20488. %@NL@%
  20489. %@2@%%@AB@%type qualifier:%@AE@%%@EH@%%@NL@%
  20490. %@3@%The keywords %@AB@%short%@AE@%, %@AB@%long%@AE@%, %@AB@%signed%@AE@%, and %@AB@%unsigned%@AE@%, which modify a basic data%@EH@%
  20491. type.%@NL@%%@NL@%
  20492. %@NL@%
  20493. %@2@%%@AB@%type size:%@AE@%%@EH@%%@NL@%
  20494. %@3@%%@CR:C6A00170191 @%%@CR:C6A00170192 @%%@CR:C6A00170193 @%A measure of the screen area occupied by individual characters in a font,%@EH@%
  20495. typically specified in pixels.%@NL@%%@NL@%
  20496. %@NL@%
  20497. %@2@%%@AB@%unary expression:%@AE@%%@EH@%%@NL@%
  20498. %@3@%An expression consisting of a single operand preceded or followed by a unary%@EH@%
  20499. operator.%@NL@%%@NL@%
  20500. %@NL@%
  20501. %@2@%%@AB@%unary operator:%@AE@%%@EH@%%@NL@%
  20502. %@3@%An operator that takes a single operand. Unary operators in the C language%@EH@%
  20503. are the complement operators (%@AB@%- ~ !%@AE@%), indirection operator %@AB@%(*%@AE@%), increment
  20504. (%@AB@%++%@AE@%) and decrement (%@AB@%- -%@AE@%) operators, address-of operator (%@AB@%&%@AE@%), and %@AB@%sizeof%@AE@%
  20505. operator. The unary plus (%@AB@%+%@AE@%) operator is legal but has no effect.%@NL@%%@NL@%
  20506. %@NL@%
  20507. %@2@%%@AB@%union:%@AE@%%@EH@%%@NL@%
  20508. %@3@%%@CR:C6A00170194 @%%@CR:C6A00170195 @%%@CR:C6A00170196 @%%@CR:C6A00170197 @%A set of values of different types that occupy the same storage space.%@NL@%%@NL@%%@EH@%
  20509. %@NL@%
  20510. %@2@%%@AB@%vector-mapped font:%@AE@%%@EH@%%@NL@%
  20511. %@3@%%@CR:C6A00170198 @%A font in which each character is defined in terms of lines and arcs. %@NL@%%@NL@%%@EH@%
  20512. %@NL@%
  20513. %@2@%%@AB@%VGA (Video Graphics Array):%@AE@%%@EH@%%@NL@%
  20514. %@3@%%@CR:C6A00170199 @% Many users refer to the video subsystem integrated into the PS/2 Models 50,%@EH@%
  20515. 60, and 80, as well as the IBM PS/2 Display Adapter, as the "VGA."%@NL@%%@NL@%
  20516. %@NL@%
  20517. %@2@%%@AB@%video adapter:%@AE@%%@EH@%%@NL@%
  20518. %@3@%%@CR:C6A00170200 @%A printed-circuit card that generates video output. Well-known IBM PC video%@EH@%
  20519. adapters include the MDA, CGA, HGC, EGA, MCGA, and VGA Adapters.%@NL@%%@NL@%
  20520. %@NL@%
  20521. %@2@%%@AB@%video mode:%@AE@%%@EH@%%@NL@%
  20522. %@3@%%@CR:C6A00170201 @%An integer that specifies the resolution and other characteristics of video%@EH@%
  20523. output. QuickC supports 17 different video modes, although some of them are
  20524. available only with certain video adapters.%@NL@%%@NL@%
  20525. %@NL@%
  20526. %@2@%%@AB@%viewport:%@AE@%%@EH@%%@NL@%
  20527. %@3@%%@CR:C6A00170202 @%A clipping region in which the origin (0, 0) may be redefined. The initial%@EH@%
  20528. origin of a viewport is the upper left corner.%@NL@%%@NL@%
  20529. %@NL@%
  20530. %@2@%%@AB@%viewport coordinates:%@AE@%%@EH@%%@NL@%
  20531. %@3@%The integer coordinate system defined by the programmer for a specific%@EH@%
  20532. viewport. By default, the viewport-coordinate system has the origin (0, 0)
  20533. at the upper left corner of the viewport, but this may be changed by a call
  20534. to %@AB@%_setvieworg%@AE@%.%@NL@%%@NL@%
  20535. %@NL@%
  20536. %@2@%%@AB@%visibility:%@AE@%%@EH@%%@NL@%
  20537. %@3@%%@CR:C6A00170203 @%The parts of the program in which a particular variable or function can be%@EH@%
  20538. referenced by name. An item has global visibility if it is visible in all
  20539. source files constituting the program and local visibility if its use is
  20540. restricted.%@NL@%%@NL@%
  20541. %@NL@%
  20542. %@2@%%@AB@%white-space character:%@AE@%%@EH@%%@NL@%
  20543. %@3@%%@CR:C6A00170204 @%A space, tab, line-feed, carriage-return, form-feed, vertical-tab, or%@EH@%
  20544. newline character.%@NL@%%@NL@%
  20545. %@NL@%
  20546. %@2@%%@AB@%window:%@AE@%%@EH@%%@NL@%
  20547. %@3@%%@CR:C6A00170205 @%%@CR:C6A00170206 @%%@CR:C6A00170207 @%An imaginary rectangle on the screen where output takes place. See "text%@EH@%
  20548. window" and "window coordinates."%@NL@%%@NL@%
  20549. %@NL@%
  20550. %@2@%%@AB@%window coordinates:%@AE@%%@EH@%%@NL@%
  20551. %@3@%%@CR:C6A00170208 @%The coordinate system defined by the programmer.%@NL@%%@NL@%%@EH@%
  20552. %@NL@%
  20553. %@NL@%
  20554. %@NL@%
  20555. %@NL@%
  20556.