📄 ct3
字号:
.NHIncrement and Decrement Operators.PPIn addition to the usual`\(mi',C also has two other interestingunaryoperators, `++' (increment) and `\(mi\(mi' (decrement).Suppose we want to count the linesin a file..E1main( ) { int c,n; n = 0; while( (c=getchar( )) != '\\0' ) if( c \*= '\\n' ) \*+n; printf("%d lines\\n", n);}.E2.UL \*+n is equivalent to.UL n=n+1but clearer,particularly when.UL nis a complicated expression.`++' and `\(mi\(mi' can be applied only to.UL int'sand.UL char's(and.UL pointerswhich we haven't got to yet)..PPThe unusual feature of `++' and `\(mi\(mi' is that theycan be used either before or after a variable.The value of.UL \*+kis the value of.UL k.ulafterit has been incremented.The value of.UL k\*+is.UL k.ulbeforeit is incremented.Suppose.UL kis 5.Then.E1x = \*+k;.E2increments.UL kto 6 and then sets.UL xtothe resulting value,i.e., to 6.But.E1x = k\*+;.E2first sets.UL xtoto 5,and.ulthenincrements.UL kto 6.The incrementing effect of.UL \*+kand.UL k\*+is the same,but their values are respectively 5 and 6.We shall soon see examples where both of these uses are important..NHArrays.PPIn C, as in Fortran or PL/I, it is possible to make arrayswhose elements are basic types.Thus we can make an array of 10integerswith the declaration.E1int x[10];.E2The square bracketsmean.ulsubscripting;parentheses are used only for function references.Array indexes begin at .ulzero,so the elements of.UL xare.E1x[0], x[1], x[2], \*.\*.\*., x[9].E2If an array has.UL nelements, the largest subscript is.UL n\(mi1\*..PPMultiple-dimension arrays are provided,though not much used above two dimensions.The declaration and use look like.E1int name[10] [20];n = name[i+j] [1] + name[k] [2];.E2Subscripts can be arbitrary integer expressions.Multi-dimension arrays are stored by row (opposite to Fortran),so the rightmost subscript varies fastest;.UL namehas 10 rows and 20 columns..PPHere is a program which reads a line,stores it in a buffer,and prints its length (excluding the newline at the end)..E1.ne 8main( ) { int n, c; char line[100]; n = 0; while( (c=getchar( )) != '\\n' ) { if( n < 100 ) line[n] = c; n\*+; } printf("length = %d\\n", n);}.E2.PPAs a more complicated problem,suppose we want to print the count for each line in the input,still storing the first 100 characters of each line.Try it as an exercise before looking at the solution:.E1main( ) { int n, c; char line[100]; n = 0; while( (c=getchar( )) != '\\0' ) if( c \*= '\\n' ) { printf("%d\n", n); n = 0; } else { if( n < 100 ) line[n] = c; n\*+; }}.E2.NHCharacter Arrays; Strings.PPText is usually kept as an array of characters,as we did with.UL line[ .UL ]in the example above.By convention in C,the last character in a character array should be a `\\0'because most programs that manipulate character arraysexpect it.For example,.UL printfuses the `\\0' to detect the end of a character arraywhen printing it out with a `%s'..PPWe can copy a character array.UL sinto another.UL tlike this:.E1 i = 0; while( (t[i]=s[i]) != '\\0' ) i\*+;.E2.PPMost of the time we have to put in our own `\\0' at the end of a string;if we want to print the line with.UL printf,it's necessary.This code prints the character count before the line:.E1main( ) { int n; char line[100]; n = 0; while( (line[n\*+]=getchar( )) != '\\n' ); line[n] = '\\0'; printf("%d:\\t%s", n, line);}.E2Here we increment .UL nin the subscript itself,but only after the previous value has been used.The character is read, placed in .UL line[n],and only then.UL nis incremented..PPThere is one place and one place onlywhere C puts in the `\\0' at the end of a character array for you,and that is in the construction.E1"stuff between double quotes".E2The compiler puts a `\\0' at the end automatically.Text enclosed in double quotes is called a.ulstring;its properties are precisely those of an (initialized) array of characters..NHFor Statement.PPThe.UL forstatement is a somewhat generalized.UL whilethat lets us put the initialization and increment partsof a loop into a single statement along with the test.The general form of the.UL foris.E1for( initialization; expression; increment ) statement.E2The meaning is exactly.E1 initialization; while( expression ) { statement increment; }.E2Thus, the following code does the same array copy as the example in the previous section:.E1 for( i=0; (t[i]=s[i]) != '\\0'; i\*+ );.E2This slightly moreornate example adds up the elements of an array:.E1 sum = 0; for( i=0; i<n; i\*+) sum = sum + array[i];.E2.PPIn the.UL forstatement,the initializationcan be left out if you want,but the semicolon has to be there.The increment isalso optional.It is.ulnotfollowed by a semicolon.The second clause, the test,works the same way as in the.UL while:if the expression is true (not zero)do another loop,otherwise get on with the next statement.As with the.UL while,the.UL forloop may be done zero times.If the expression is left out, it is taken to be always true, so.E1for( ; ; ) \*.\*.\*..E2and.E1while( 1 ) \*.\*.\*..E2are both infinite loops..PPYou might ask why we use a.UL forsince it's so much like a.UL while\*.(You might also ask why we use a.UL whilebecause...)The.UL for is usually preferable because it keeps the code where it's usedand sometimes eliminates the need for compound statements,as in this code that zeros a two-dimensional array:.E1for( i=0; i<n; i\*+ ) for( j=0; j<m; j\*+ ) array[i][j] = 0;.E2.NHFunctions; Comments.PPSuppose we want,as part of a larger program,to count the occurrences of the asciicharacters in some input text.Let us also map illegal characters(those with value>127 or <0) into one pile.Since this is presumably an isolated part of the program,good practice dictates making it a separate function.Here is one way:.E1.ne 7main(~) { int hist[129]; /\** 128 legal chars + 1 illegal group \**/ \*.\*.\*. count(hist, 128); /\** count the letters into hist \**/ printf( \*.\*.\*. ); /\** comments look like this; use them \**/ \*.\*.\*. /\** anywhere blanks, tabs or newlines could appear \**/}.SPcount(buf, size) int size, buf[ ]; { int i, c; for( i=0; i<=size; i\*+ ) buf[i] = 0; /\** set buf to zero \**/ while( (c=getchar(~)) != '\\0' ) { /\** read til eof \**/ if( c > size \*| c < 0 ) c = size; /\** fix illegal input \**/ buf[c]\*+; } return;}.E2We have already seen many examples of calling a function,so let us concentrate on how to .uldefineone.Since .UL counthas two arguments, we need to declare them,as shown,giving their types, and in the case of.UL buf,the factthat it is an array.The declarations of arguments go.ulbetweenthe argument listand the opening `{'.There is no need to specify the size of the array .UL buf,for it is defined outside of.UL count\*..PPThe.UL returnstatement simply says to go back to the calling routine.In fact, we could have omitted it,since a return is implied at the end of a function..PPWhat if we wanted .UL countto return a value, say the number of characters read?~The .UL returnstatement allows for this too:.E1 int i, c, nchar; nchar = 0; \*.\*.\*. while( (c=getchar(~)) != '\\0' ) { if( c > size \*| c < 0 ) c = size; buf[c]\*+; nchar\*+; } return(nchar);.E2Any expression can appear within the parentheses.Here is a function to compute the minimum of two integers:.E1.ne 4min(a, b) int a, b; { return( a < b ? a : b );}.E2.PP.PPTo copy a character array,we could write the function.E1.ne 5strcopy(s1, s2) /\** copies s1 to s2 \**/ char s1[ ], s2[ ]; { int i; for( i = 0; (s2[i] = s1[i]) != '\\0'; i\*+ );}.E2As is often the case, all the work is done by the assignment statementembedded in the test part of the.UL for\*.Again, the declarations of the arguments .UL s1 and.UL s2omit the sizes, because they don't matter to.UL strcopy\*.(In the section on pointers, we will see a more efficientway to do a string copy.).PPThere is a subtletyin function usage which can trap the unsuspecting Fortran programmer.Simple variables (not arrays) are passed in C by``call by value'',which means that the called function is givena copy of its arguments,and doesn't know their addresses.This makes it impossible to change the value of one of the actual input arguments..a.PPThere are two ways out of this dilemma.One is to make special arrangements to pass to the functionthe address of a variable instead of its value.The other is to make the variable a global or external variable,which is known to each function by its name.We will discuss both possibilities in the next few sections..NHLocal and External Variables.PPIf we say.E1f( ) { int x; \*.\*.\*.}g( ) { int x; \*.\*.\*.}.E2each .UL xis.ullocalto its own routine _the.UL xin.UL fis unrelated to the.UL xin.UL g\*.(Local variables are also called ``automatic''.)Furthermore each local variable in a routine appears only whenthe function is called, and.uldisappearswhen the function is exited.Local variables have no memory from one call to the nextand must be explicitly initialized upon each entry.(There is a.UL staticstorage class for making local variables with memory;we won't discuss it.).PPAs opposed to local variables,.ulexternal variablesare defined external to all functions,and are (potentially) available to all functions.External storage.ne 6always remains in existence.To make variables external we have to.uldefinethem external to all functions,and, wherever we want to use them,make a.uldeclaration..E1main(~) { extern int nchar, hist[ ]; \*.\*.\*. count(~); \*.\*.\*.}.SP.ne 7count(~) { extern int nchar, hist[ ]; int i, c; \*.\*.\*.}.SPint hist[129]; /\** space for histogram \**/int nchar; /\** character count \**/.E2Roughly speaking, any function that wishes to access an external variablemust contain an.UL externdeclarationfor it.The declaration is the same as others,except for the added keyword.UL extern\*.Furthermore, there must somewhere be a.uldefinitionof the external variables external to all functions..PPExternal variables can be initialized;they are set to zero if not explicitlyinitialized.In its simplest form,initialization is done by putting the value (which must be a constant) after the definition:.E1int nchar 0;char flag 'f';.ft R etc\*..E2This is discussed further in a later section..SP.PPThis ends our discussion of what might be calledthe central core of C.You now have enough to write quite substantialC programs,and it would probably be a good idea if you pausedlong enough to do so.The rest of this tutorialwill describe some more ornate constructions,useful but not essential..SP.SP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -