logo资料库

Pointers on C英文版.pdf

第1页 / 共609页
第2页 / 共609页
第3页 / 共609页
第4页 / 共609页
第5页 / 共609页
第6页 / 共609页
第7页 / 共609页
第8页 / 共609页
资料共609页,剩余部分请下载后查看
Cover
Chapter 1 -- A Quick Start
1.1 Introduction
1.1.1 Spacing and Comments
1.1.2 Preprocessor Directives
1.1.3 The Main Function
1.1.4 The read_column_numbers Function
1.2 Other Capabilities
1.3 Compiling
1.4 Summary
1.5 Summary of Cautions
1.6 Summary of Programming Tips
1.7 Questions
1.8 Programming Exercises
Chapter 2 -- Basic Concepts
2.1 Environments
2.1.1 Translation
Filename Conventions
Compiling and Linking
2.1.2 Execution
2.2 Lexical Rules
2.2.1 Characters
2.2.2 Comments
2.2.3 Free Form Source Code
2.2.4 Identifiers
2.2.5 Form of a Program
2.3 Program Style
2.4 Summary
2.5 Summary of Cautions
2.6 Summary of Programming Tips
2.7 Questions
2.8 Programming Exercises
Chapter 3 -- Data
3.1 Basic Data Types
3.1.1 The Integer Family
Integer Literals
Enumerated Type
3.1.2 Floating-Pint Types
3.1.3 Pointers
Pointer Constants
String Literals
3.2 Basic Declarations
3.2.1 Initialization
3.2.2 Declaring Simple Arrays
3.2.3 Declaring Pointers
3.2.4 Implicit Declarations
3.3 Typedef
3.4 Constants
3.5 Scope
3.5.1 Block Scope
3.5.2 File Scope
3.5.3 Prototype Scope
3.5.4 Function Scope
3.6 Linkage
3.7 Storage Class
3.7.1 Initialization
3.8 The Static Keyword
3.9 Scope, Linkage, and Storage Class Example
3.10 Summary
3.11 Summary of Cautions
3.12 Summary of Programming Tips
3.13 Questions
Chapter 4 -- Statements
4.1 Empty Statement
4.2 Expression Statement
4.3 Statement Blocks
4.4 If Statement
4.5 While Statement
4.5.1 Break and Continue Statements
4.5.2 Execution of the While
4.6 For Statement
4.6.1 Execution of a For
4.7 Do statement
4.8 Switch Statement
4.8.1 break in a switch
4.8.2 Defaults
4.8.3 Execution of the Switch
4.9 Goto Statement
4.10 Summary
4.11 Summary of Cautions
4.12 Summary of Programming Tips
4.13 Questions
4.14 Programming Exercises
Chapter 5 -- Operators and Expressions
5.1 Operators
5.1.1 Arithmetic
5.1.2 Shifting
5.1.3 Bitwise
Bit Manipulation
5.1.4 Assignment
Compound Assignment
5.1.5 Unary
5.1.6 Relational
5.1.7 Logical
5.1.8 Conditional
5.1.9 Comma
5.1.10 Subscript, Function Call, and Structure Member
5.2 Boolean Values
5.3 L-values and R-values
5.4 Expression Evaluation
5.4.1 Implicit Type Conversions
5.4.2 Arithmetic Conversions
5.4.3 Properties of Operators
5.4.4 Precedence and Order of Evaluation
5.5 Summary
5.6 Summary of Cautions
5.7 Summary of Programming Tips
5.8 Summary
5.9 Programming Exercises
Chapter 6 -- Pointers
6.1 Memory and Addresses
6.1.1 Address Versus Contents
6.2 Values and Their Types
6.3 Contents of a Pointer Variable
6.4 Indirection Operator
6.5 Uninitialized and Illegal Pointer
6.6 The Null Pointer
6.7 Pointers, Indirection, and L-values
6.8 Pointers, Indirection, and Variables
6.9 Pointer Constants
6.10 Pointers to Pointers
6.11 Pointer Expressions
6.12 Examples
6.13 Pointer Arithmetic
6.13.1 Arithmetic Operations
6.13.2 Relational Operations
6.14 Summary
6.15 Summary of Cautions
6.16 Summary of Programming Tips
6.17 Questions
6.18 Programming Exercises
Chapter 7 -- Functions
7.1 Function Definition
7.1.1 Return Statement
7.2 Function Declaration
7.2.1 Prototypes
7.2.2 Default Function Assumptions
7.3 Function Arguments
7.4 ADTs and Black Boxes
7.5 Recursion
7.5.1 Tracing a Recursive Function
7.5.2 Recursion versus Iteration
7.6 Variable Argument Lists
7.6.1 The stdarg Macros
7.6.2 Limitations of Variable Arguments
7.7 Summary
7.8 Summary of Cautions
7.9 Summary of Programming Tips
7.10 Questions
7.11 Programming Exercises
Chapter 8 -- Arrays
8.1 One-Dimensional Arrays
8.1.1 Array Names
8.1.2 Subscripts
8.1.3 Pointers versus Subscripts
8.1.4 Pointer Efficiency
Switching to Pointers
Bringing Back the Counter
Register Pointer Variables
Eliminating the Counter
Conclusions
8.1.5 Arrays and Pointers
8.1.6 Array Names as Function Arguments
8.1.7 Declaring Array Parameters
8.1.8 Initialization
Static and Automatic Initialization
8.1.9 Incomplete Initialization
8.1.10 Automatic Array Sizing
8.1.11 Character Array Initialization
8.2 Multidimensional Arrays
8.2.1 Storage Order
8.2.2 Array Names
8.2.3 Subscripts
8.2.4 Pointers to Arrays
8.2.5 Multidimensional Arrays as Function Arguments
8.2.6 Initialization
8.2.7 Automatic Array Sizing
8.3 Arrays of Pointers
8.4 Summary
8.5 Summary of Cautions
8.6 Summary of Programming Tips
8.7 Questions
8.8 Programming Exercises
Chapter 9 -- Strings, Characters, and Bytes
9.1 String Basics
9.2 String Length
9.3 Unrestricted String Functions
9.3.1 Copying Strings
9.3.2 Concatenating Strings
9.3.3 Function Return Value
9.3.4 String Comparisons
9.4 Length-Restricted String Functions
9.5 Basic String Searching
9.5.1 Finding a Character
9.5.2 Finding Any of Several Characters
9.5.3 Finding a Substring
9.6 Advanced String Searching
9.6.1 Finding String Prefixes
9.6.2 Finding Tokens
9.7 Error Messages
9.8 Character Operations
9.8.1 Character Classification
9.8.2 Character Transformation
9.9 Memory Operations
9.10 Summary
9.11 Summary of Cautions
9.12 Summary of Programming Tips
9.13 Questions
9.14 Programming Exercises
Chapter 10 -- Structures and Unions
10.1 Structure Basics
10.1.1 Structure Declarations
10.1.2 Structure Members
10.1.3 Direct Member Access
10.1.4 Indirect Member Access
10.1.5 Self-Referential Structures
10.1.6 Incomplete Declarations
10.1.7 Initializing Structures
10.2 Structures, Pointers, and Members
10.2.1 Accessing the Pointer
10.2.2 Accessing the Structure
10.2.3 Accessing Structure Members
10.2.4 Accessing a Nested Structure
10.2.5 Accessing a Pointer Member
10.3 Structure Storage Allocation
10.4 Structures as Function Arguments
10.5 Bit Fields
10.6 Unions
10.6.1 Variant Records
10.6.2 Initializing Unions
10.7 Summary
10.8 Summary of Cautions
10.9 Summary of Programming Tips
10.10 Questions
10.11 Programming Exercises
Chapter 11 -- Dynamic Memory Allocation
11.1 Why Use Dynamic Allocation
11.2 Malloc and Free
11.3 Calloc and Realloc
11.4 Using Dynamically Allocated Memory
11.5 Common Dynamic Memory Errors
11.5.1 Memory Leaks
11.6 Memory Allocation Examples
11.7 Summary
11.8 Summary of Cautions
11.9 Summary of Programming Tips
11.10 Questions
11.11 Programming Exercises
Chapter 12 -- Using Structures and Pointers
12.1 Linked Lists
12.2 Singly Linked Lists
12.2.1 Inserting into a Singly Linked List
Debugging the Insert Function
Optimizing the Insert Function
12.2.2 Other List Operations
12.3 Doubly Linked Lists
12.3.1 Inserting into a Doubly Linked List
Simplifying the Insert Function
12.3.2 Other List Operations
12.4 Summary
12.5 Summary of Cautions
12.6 Summary of Programming Tips
12.7 Questions
12.8 Programming Exercises
Chapter 13 -- Advanced Pointers Topics
13.1 More Pointers to Pointers
13.2 Advanced Declarations
13.3 Pointers to Functions
13.3.1 Callback Functions
13.3.2 Jump Tables
13.4 Command Line Arguments
13.4.1 Passing Command Line Arguments
13.4.2 Processing Command Line Arguments
13.5 String Literals
13.6 Summary
13.7 Summary of Cautions
13.8 Summary of Programming Tips
13.9 Questions
13.10 Programming Exercises
Chapter 14 -- The Preprocessor
14.1 Predefined Symbols
14.2 #define
14.2.1 Macros
14.2.2 #define Substitution
14.2.3 Macros versus Functions
14.2.4 Macro Arguments with Side Effects
14.2.5 Naming Conventions
14.2.6 #undef
14.2.7 Command Line Definitions
14.3 Conditional Compilation
14.3.1 If Defined
14.3.2 Nested Directives
14.4 File Inclusion
14.4.1 Library Includes
14.4.2 Local Includes
14.4.3 Nested File Inclusion
14.5 Other Directives
14.6 Summary
14.7 Summary of Cautions
14.8 Summary of Programming Tips
14.9 Questions
14.10 Programming Exercises
Chapter 15 -- Input/Output Functions
15.1 Error Reporting
15.2 Terminating Execution
15.3 The Standard I/O Library
15.4 ANSI I/O Concepts
15.4.1 Streams
Text Streams
Binary Streams
15.4.2 FILEs
15.4.3 Standard I/O Constants
15.5 Overview of Stream I/O
15.6 Opening Streams
15.7 Closing Streams
15.8 Character I/O
15.8.1 Character I/O Macros
15.8.2 Undoing Character I/O
15.9 Unformatted Line I/O
15.10 Formatted Line I/O
15.10.1 The scanf Family
15.10.2 scanf Format Codes
15.10.3 The printf Family
15.10.4 printf Format Codes
15.11 Binary I/O
15.12 Flushing and Seeking Functions
15.13 Changing the Buffering
15.14 Stream Error Functions
15.15 Temporary Files
15.16 File Manipulation Functions
15.17 Summary
15.18 Summary of Cautions
15.19 Summary of Programming Tips
15.20 Questions
15.21 Programming Exercises
Chapter 16 -- Standard Library
16.1 Integer Functions
16.1.1 Arithmetic
16.1.2 Random Numbers
16.1.3 String Conversion
16.2 Floating-Point Functions
16.2.1 Trigonometry
16.2.2 Hyperbolic
16.2.3 Logarithm and Exponent
16.2.4 Floating-point Representation
16.2.5 Power
16.2.6 Floor, Ceiling, Absolute Value, and Remainder
16.2.7 String Conversion
16.3 Date and Time Functions
16.3.1 Processor Time
16.3.2 Time of Day
Date and Time Conversions
16.4 Nonlocal Jumps
16.4.1 Example
16.4.2 When to Use Nonlocal Jumps
16.5 Signals
16.5.1 Signal Names
16.5.2 Processing Signals
16.5.3 Signal Handlers
Volatile Data
Returning From a Handler
16.6 Printing Variable Argument Lists
16.7 Execution Environment
16.7.1 Terminating Execution
16.7.2 Assertions
16.7.3 The Environment
16.7.4 Executing System Commands
16.8 Sorting and Searching
16.9 Locales
16.9.1 Numeric and Monetary Formatting
Numeric Formatting
Monetary Formatting
16.9.2 Strings and Locales
16.9.3 Effects of Changing the Locale
16.10 Summary
16.11 Summary of Cautions
16.12 Summary of Programming Tips
16.13 Questions
16.14 Programming Exercises
Chapter 17 -- Classic Abstract Data Types
17.1 Memory Allocation
17.2 Stacks
17.2.1 Stack Interface
17.2.2 Implementing a Stack
An Arrayed Stack
A Dynamically Arrayed Stack
A Linked Stack
17.3 Queues
17.3.1 Queue Interface
17.3.2 Implementing a Queue
An Arrayed Queue
Dynamically Arrayed and Linked Queues
17.4 Trees
17.4.1 Insertions into a Binary Search Tree
17.4.2 Deletions from a Binary Search Tree
17.4.3 Searching a Binary Search Tree
17.4.4 Tree Traversals
17.4.5 Binary Search Tree Interface
17.4.6 Implementing a Binary Search Tree
An Arrayed, Binary Search Tree
A Linked Binary Search Tree
Variations on the Tree Interface
17.5 Improvements in Implementation
17.5.1 Having More Than One Stack
17.5.2 Having More Than One Type
17.5.3 Name Clashes
17.5.4 Standard Libraries of ADTs
17.6 Summary
17.7 Summary of Cautions
17.8 Summary of Programming Tips
17.9 Questions
17.10 Programming Exercises
Chapter 18 -- Runtime Environment
18.1 Determining the Runtime Environment
18.1.1 Test Program
18.1.2 Static Variables and Initialization
18.1.3 The Stack Frame
18.1.4 Register Variables
18.1.5 Length of External Identifiers
18.1.6 Determining the Stack Frame Layout
Passing Function Arguments
Function Prologue
Argument Ordering on the Stack
Final Stack Frame Layout
Function Epilogue
Return Values
18.1.7 Expression Side Effects
18.2 Interfacing With Assembly Language
18.3 Runtime Efficiency
18.3.1 Improving Efficiency
18.4 Summary
18.5 Summary of Cautions
18.6 Summary of Programming Tips
18.7 Questions
18.8 Programming Exercises
APPENDIX -- Selected Problem Solutions
Chapter 1 Questions
Chapter 1 Programming Exercises
Chapter 2 Questions
Chapter 2 Programming Exercises
Chapter 3 Questions
Chapter 4 Questions
Chapter 4 Programming Exercises
Chapter 5 Questions
Chapter 5 Programming Exercises
Chapter 6 Questions
Chapter 6 Programming Exercises
Chapter 7 Questions
Chapter 7 Programming Exercises
Chapter 8 Questions
Chapter 8 Programming Exercises
Chapter 9 Questions
Chapter 9 Programming Exercises
Chapter 10 Questions
Chapter 10 Programming Exercises
Chapter 11 Questions
Chapter 11 Programming Exercises
Chapter 12 Questions
Chapter 12 Programming Exercises
Chapter 13 Questions
Chapter 13 Programming Exercises
Chapter 14 Questions
Chapter 14 Programming Exercises
Chapter 15 Questions
Chapter 15 Programming Exercises
Chapter 16 Questions
Chapter 16 Programming Exercises
Chapter 17 Questions
Chapter 17 Programming Exercises
Chapter 18 Questions
Chapter 18 Programming Exercises
orced version 1.0, by vivisimo, and posted in http://library.nu last modified: 2011.06.05 1 A Quick Start Introduction 1.1 It is always difficult to start describing a programming language because little  details  do  not  make  much  sense  until  one  knows  enough  to  understand  the  ʺbig  picture.ʺ In this chapter, I try to give you a glimpse of the big picture by looking at a  sample program and explaining its workings line by line. This sample program also  shows you how familiar procedures are accomplished in C. This information plus the  other topics discussed in the chapter introduce you to the basics of the C language so  that you can begin writing useful programs.    The  program  we  dissect  reads  text  from  the  standard  input,  modifies  it,  and  writes it to the standard output. Program l.l first reads a list of column numbers. These  numbers  are  pairs  and  indicate  ranges  of  columns  in  the  input  line.  The  list  is  terminated with a negative number. The remaining input lines are read and printed,  then the selected columns from the input lines are extracted and primed. Note that the  first column in a line is number zero. For example, if the input is    4 9 12 20 -1 abcdefghijklmnopqrstuvwxyz Hello there, how are you? I am fine, thanks. See you! Bye   then the program would produce:    Original input : abcdefghijklmnopqxstuvwxyz Rearranged line: efghijmnopqrstu
2  Chapter 1 A Quick Start Original input : Hello there, how are you? Rearranged line: o ther how are Original input : I am fine, thanks. Rearranged line: fine, thanks. Original input : See you! Rearranged line: you! Original input : Bye Rearranged line:   The  important  point  about  this  program  is  that  it  illustrates  most  of  the  basic  techniques you need to know to begin writing C programs.                  /* ** This program reads input lines from standard input and prints ** each input line, followed by just some portions of the line, to ** the standard output. ** ** The first input is a lint of column numbers, which ends with a ** negative number. The column numbers are paired and specify ** ranges of columns from the input line that are to be printed. ** For example, 0 3 10 12 -1 indicates that only columns 0 through 3 ** and columns 10 through 12 will be printed. */ #include #inc1ude #include #define MAX_COLS #define MAX_INPUT int read_column_numbers( int columns[], int max ); void rearrange( char *output, char const *input, int n_columns, int const columns[] ); int main( void ) {   Program 1.1  Rearrange characters  /* # of columns to process */ /* the columns to process */ /*array for input line */ /*array for output line */ int n_columns; int columns[MAX_COLS]; char input[MAX_INPUT]; char output[MAX_INPUT]; 20 1000 /* max len of input & output lines */ /* max # of columns to process */     …         continue
1.1 Introduction 3 /* ** Read the list of column numbers */ n_columns = read_column_numbers( columns, MAX_COLS );   /* ** Discard the rest of the line that contained the final   Program 1.1  Rearrange characters             continue …  /* ** Read, process and print the remaining lines of input */ while( gets(input ) != NULL ){ } return EXIT_SUCCESS; printf( "Original input : %s\n", input ); rearrange( output, input, n_columns, columns ); printf( "Rearranged line: %s\n", output ); int num = 0; int ch; } /* ** Read the list of column numbers, ignoring any beyond the specified ** maximum. */ int read_column_numbers( int columns[], int max ) { /* ** Make sure we have an even number of inputs, as they are ** supposed to be paired. */ if( num % 2 != 0 ){ } /* ** Get the numbers, stopping at eof or when a number is < 0. */ while( num < max && scanf( "%d", &columns[num] ) == 1 &&columns[num] >= 0 ) num +=1; puts( "Last column number is not paired." ); exit( EXIT_FAILURE );
Chapter 1 A Quick Start 4             continue …  in n_columns, int const columns[] ) len = strlen( input ); output_col = 0; int col; int output_col; int len; ** number. */ while( (ch = getchar()) != EOF && ch != '\n' ) return num; ; /* subscript for columns array */ /* output column counter */ /* length of input line */ } /* ** Process a line of input by concatenating the characters from ** the indicated columns. The output line is the NUL terminated, */ void rearrange( char *output, char const *input, {   Program 1.1  Rearrange characters  /* ** If the input line isn't this long or the output ** array is full, we're done */ if( columns[col] >= len || ** Process each pair of column numbers. */ for( col = 0; col < n_columns; col += 2 ){ /* ** If there isn't room in the output array, only copy ** what will fit. */ if( output_col + nchars > MAX_INPUT – 1) /* nchars = MAX_INPUT – output_col – 1; output_col == MAX_INPUT – 1 ) break; int nchars = columns[col + 1] – columns[col] + 1; /*
1.1 Introduction 5 ** Copy the relevant data. */ strncpy( output + output_col, input + columns[col], output_col += nchars; nchars ); output[output_col] = '\0'; } } Program 1.1  Rearrange characters          1.1.1 Spacing and Comments            rearrang.c     Now, let’s take a closer look at this program. The first point to notice is the spacing of  the program: the blank lines that separate different parts from one another, the use of  tabs to indent statements to display the program structure, and so forth. C is a free‐ form language, so there are no rules as to how you must write statements. However, a  little discipline when writing the program pays off later by making it easier to read  and modify. More on this issue in a bit.  While it is important to display the structure of the program clearly, it is even  more  important  to  tell  the  reader  what  the  program  does  and  how  it  works.  Comments fulfill this role      /* ** This program reads input lines from the standard input and prints ** each input line, followed by just: some portions of the lines, to ** the standard output . ** ** The first input; is a list of column numbers, which ends with a ** negative number . The column numbers are paired and specify ** ranges of columns from the input line that are to be printed. ** For example, 0 3 l0 12 —l indicates that only columns 0 through 3 ** and columns 10 through 12 will be printed */     This  block  of  text  is  a  comment.  Comments  begin  with  the  /*  characters  and  end with the */ characters. They may appear anywhere in a C program in which white  space  may  appear.  However,  comments  cannot  contain  other  comments,  that  is,  the  First */ terminates the comment no matter how many /*ʹs have appeared earlier. 
6  Chapter 1 A Quick Start Comments are sometimes used in other languages to ʺcomment outʺ code, thus  removing the code from the program without physically deleting it from the source  file. This practice is a bad idea in C, because it won’t work if the code you‘re trying to  get rid of has any comments in it. A better way to logically delete code in a C program  is the #if directive. When used like this:    #if 0   #endif statements  the program statements between the #if and the #endif are effectively removed from  the program. Comments contained in the statements have no effect on this construct,  thus it is a much safer way to accomplish the objective. There is much more that you  can do with this directive, which I explain fully in Chapter 14.        1.1.2 Preprocessor Directives #include #include #include #define MAX_COLS #define MAX_INPUT 20 1000 /* max len of input & output lines */ /* max # of columns to process */ These five lines are called preprocessor directives, or just directives, because they  are interpreted by the preprocessor The preprocessor reads the source code, modifies  it as indicated by any preprocessor directives, and then passes the modified code to  the compiler.  In our sample program, the preprocessor replaces the first #include statement  with the contents of the library header named stdio.h; the result is the same as if the  contents  of  stdio.h  had  been  written  verbatim  at  this  point  in  the  source  file.  The  second and third directives do the same with stdlib.h and string.h.  The stdio.h header gives us access to functions from the Standard I/O Library, a  collection  of  functions  that  perform  input  and  output,  stdlib.h  defines  the  EXIT_SUCCESS  and  EXIT_FAILURE  symbols.  We  need  string.h  to  use  the  string  manipulation functions.    This technique is also a handy way to manage your declarations if they are needed in  several different source files—you write the declarations in a separate file and then use  #include to read them into each relevant source tile. Thus there is only one copy of the  declarations; they are not duplicated in many different places, which would be more  error prone to maintain.  TIP
1.1 Introduction 7 TIP The other directive is  #define, which defines the name  MAX_COLS to be the value 20,  and MAX_INPUT to be the value 1000. Wherever either name appears later in the source  tile,  it  is  replaced  by  the  appropriate  value.  Because  they  are  defined  as  literal  constants, these names cannot be used in some places where ordinary variables can be  used (for example, on the left side of an assignment). Making their names uppercase  serves as a reminder that they are not ordinary variables. #define directives are used  for the same kinds of things as symbolic constants in other languages and for the same  reasons. If we later decide that 20 columns are not enough, we can simply change the  definition of MAX_COLS. There is no need to hunt through the program looking for 20’s  to change and possibly missing one or changing a 20 that had nothing to do with the  maximum number of columns.       int read_column_numbers( int columns[], int max ); void rearrange( char *output, char const *input, int n_columns, int const columns[] ); These  declarations  are  called  function  prototypes.  They  tell  the  compiler  about  the characteristics of functions that are defined later in the source tile. The compiler  can then check calls to these functions for accuracy. Each prototype begins with a type  name that describes the value that is returned. The type name is followed by the name  of  function  are  next,  so  read_column_numbers returns  an  integer  and  takes  two  arguments,  an  array  of  integers and an integer scalar. The argument names are not required; I give them here  to serve as a reminder of what each argument is supposed to be.  function.  The  arguments  expected  by  the  the  The rearrange function takes four arguments. The first and second are pointers.  A  pointer  specifies  where  a  value  resides  in  the  computer’s  memory,  much  like  a  house number specifies where a particular family resides on a street. Pointers are what  give the C language its power and are covered in great detail starting in Chapter 6.  The second and fourth arguments are declared const, which means that the function  promises  not  to  modify  the  callerʹs  arguments.  The  keyword  void  indicates  that  the  function does not return any value at all; such a function would be called a procedure in  other languages.    If  the  source  code  for  this  program  was  contained  in  several  source  tiles,  function  prototypes  would  have  to  be  written  in  each  tile  using  the  function.  Putting  the  prototypes  in  header  files  and  using  a #include  to  access  them  avoids  the  maintenance problem caused by having multiple copies of the same declarations.  TIP
8  Chapter 1 A Quick Start 1.1.3 The Main Function int main( void ) {     These  lines  begin  the  definition  of  a  function  called  main.  Every  C  program  must have a main function, because this is where execution begins. The keyword int  indicates that the function returns an integer value; the keyword void indicates that it  expects  no  arguments.  The  body  of  the  function  includes  everything  between  this  opening brace and its matching closing brace.  Observe how the indentation clearly shows what is included in the function.    int n_columns; int columns[MAX_COLS]; char input[MAX_INPUT]; char output[MAX_INPUT]; /* # of columns to process */ /* the columns to process */ /*array for input line */ /*array for output line */ These  lines  declare  four  variables:  an  integer  scalar,  an  array  of  integers,  and  two arrays of characters. All four of these variables are local to the main function, so  they  cannot  be  accessed  by  name  from  any  other  functions.  They  can,  of  course,  be  passed as arguments to other functions.    /* ** Read the list of column numbers */ n_columns = read_column_numbers( columns, MAX_COLS );   This  statement  calls  the  function  read_column_numbers.  The  array  columns  and  the  constant  represented  by MAX_COLS (20)  are  passed  as  arguments.  In  C,  array  arguments  behave  as  though  they  are  passed  by  reference,  and  scalar  variables  and  constants are passed by value (like var parameters and value parameters, respectively,  in Pascal or Modula). Thus, any changes made by a function to a scalar argument are  lost  when  the  function  returns;  the  function  cannot  change  the  value  of  the  calling  programʹs argument in this manner. When a function changes the value of an element  of an array argument, however, the array in the calling program is actually modified.    The rule about how parameters are passed to C functions actually states:    All arguments to functions are passed by value.    Nevertheless, an array name as an argument produces the call‐by‐reference behavior
分享到:
收藏