home *** CD-ROM | disk | FTP | other *** search
-
- ├ ╠ANGUAGE ╘UTORIAL
- -------------------
- ╨ART 9 OF 11
-
-
- ╬╧╘┼: ╙╒┬╙╘╔╘╒╘╔╧╬╙ ╞╧╥ ╙╨┼├╔┴╠ ├
- ╠┴╬╟╒┴╟┼ ├╚┴╥┴├╘┼╥╙:
-
- ╠┼╞╘ ├╒╥╠┘ ┬╥┴├╦┼╘: █
- ╥╔╟╚╘ ├╒╥╠┘ ┬╥┴├╦┼╘: ▌
- ┬┴├╦ ╙╠┴╙╚: \
- ╘╔╠─┼: »
- ╓┼╥╘╔├┴╠ ┬┴╥: ▀
- ╒╬─┼╥╙├╧╥┼: ñ
-
-
- ╘HE ╙╫╔╘├╚ -
-
- ┘OU MAY RECALL, FROM AN EARLIER
- LESSON, THAT WE CHECKED VARIOUS CASES
- BY USING THE 'IF, ELSE IF, ELSE'
- CONSTRUCTION:
-
- 1 IF ( SUCH-AND-SUCH)
- 2 ----DO THIS-----
- 3
- 4 ELSE IF (THIS-OR-THAT)
- 5 ----DO THIS-----
- 6
- 7 ELSE IF ( WHATEVER )
- 8 ----DO THIS-----
- 9
- 10 ELSE
- 11 ----DO THIS-----
- 12
- 13 ----CONTINUATION OF PROGRAM
-
- ╥EALIZE THAT ONLY ONE OF THE
- STATEMENTS 2, 5, 8, 11 WILL BE
- EXECUTED, DEPENDING UPON WHICH OF THE
- CONDITIONS 1, 4, 7, 10 IS SATISFIED
- FIRST. (╔F NONE OF 1,4 OR 7 ARE
- SATISFIED, THEN 10 ╔╙ SATISFIED AND
- 11 WILL BE EXECUTED). ╫E CAN THINK OF
- CONDITION 10 AS A DEFAULT CONDITION.
-
- ┼VEN IF THE CONDITIONS 1 AND 4 AND 7
- ARE ALL SATISFIED, ONLY STATEMENT(S)
- 2 WILL BE EXECUTED, THEN THE PROGRAM
- WILL CONTINUE WITH STATEMENT 13, ETC.
-
- (╘HERE'S A ═╧╥┴╠ HERE. ╘O SPEED UP
- EXECUTION, PUT THE MOST PROBABLE
- CONDITION FIRST ... THEN THE PROGRAM
- WON'T HAVE TO DO SO MUCH CHECKING).
-
- ┬UT THERE'S ANOTHER (MORE NATURAL)
- WAY OF CHECKING A NUMBER OF CASES IN
- ├ CALLED A ╙╫╔╘├╚:
-
- SWITCH (X) █
- /* ┬EGIN ╙╫╔╘├╚ ON THE INTEGER X */
- CASE 1:
- /* ╔F X IS THE INTEGER 1, THEN */
- DO THIS;
- /* EXECUTE THIS STATEMENT... */
- AND THIS;
- /* AND THIS TOO */
- CASE 2:
- /* ╔F X IS THE INTEGER 2, THEN */
- DO THIS;
- /* EXECUTE THIS STATEMENT... */
- AND THIS;
- /* AND THIS TOO */
- CASE 3:
- /* ╔F X IS THE INTEGER 3, THEN */
- DO THIS;
- /* EXECUTE THIS STATEMENT... */
- AND THIS;
- /* AND THIS TOO */
- AND THIS;
- /* AND THIS TOO */
- AND THIS;
- /* AND THIS TOO */
- CASE 4:
- /* ╔F X IS THE INTEGER 4, THEN */
- DO THIS;
- /* EXECUTE THIS STATEMENT... */
- DEFAULT:
- /* ╔F X IS NONE OF THE ABOVE,THEN */
- DO THIS;
- /* EXECUTE THIS STATEMENT... */
- /* END OF SWITCH */
- ▌
- ╬OTICE THE OPENING AND CLOSING
- BRACKETS FOR THE ╙╫╔╘├╚!
-
- SWITCH (X) █
- /* ...CASES AND DEFAULT HERE... */
-
-
- AND HERE'S A VARIATION ...
-
- 1 SWITCH (X) █
- /* ┬EGIN ╙╫╔╘├╚ ON THE INTEGER X */
- 2 CASE 1:
- /* ╔F X IS THE INTEGER 1, THEN */
- 3 CASE 2:
- /* ╔F X IS THE INTEGER 2, THEN */
- 4 CASE 3:
- /* ╔F X IS THE INTEGER 3, THEN */
- 5 DO THIS;
- /* EXECUTE THIS STATEMENT ... */
- 6 AND THIS;
- /* AND THIS TOO. */
- 7 AND THIS;
- /* AND THIS TOO. */
- 8 AND THIS;
- /* AND THIS TOO. */
- 9 CASE 4:
- /* ╔F X IS THE INTEGER 4, THEN */
- 10 DO THIS;
- /* EXECUTE THIS STATEMENT ... */
- 11 DEFAULT:
- /* ╔F X IS NONE OF THE ABOVE,THEN */
- 12 DO THIS;
- /* EXECUTE THIS STATEMENT ... */
- 13 ▌
-
- ╔F THE INTEGER X IS EQUAL TO 1 OR 2
- OR 3 THEN STATEMENTS 5 TO 8 WILL BE
- EXECUTED! (...SO THE ╙╫╔╘├╚ WILL ╬╧╘
- ╙╘╧╨ WITH THE FIRST CASE THAT IS
- SATISFIED, BUT WILL CHECK ┴╠╠
- ╙╒┬╙┼╤╒┼╬╘ ├┴╙┼╙!) ╔F YOU DON'T WANT
- THAT TO HAPPEN, THEN YOU MAY
- TERMINATE A CASE WITH A ┬╥┼┴╦.
-
- 1 SWITCH (X) █
- /* ┬EGIN ╙╫╔╘├╚ ON THE INTEGER X */
- 2 CASE 1:
- /* ╔F X IS THE INTEGER 1, THEN */
- 3 CASE 2:
- /* ╔F X IS THE INTEGER 2, THEN */
- 4 CASE 3:
- /* ╔F X IS THE INTEGER 3, THEN */
- 5 DO THIS;
- /* EXECUTE THIS STATEMENT ... */
- 6 AND THIS;
- /* AND THIS TOO. */
- 7 AND THIS;
- /* AND THIS TOO. */
- 8 AND THIS;
- /* AND THIS TOO. */
- 9 BREAK;
- /* AND NOW ┬╥┼┴╦ ╧╒╘ ╧╞ ╘╚┼ ╙╫╔╘├╚ */
- 10 CASE 4:
- /* ╔F X IS THE INTEGER 4, THEN */
- 11 DO THIS;
- /* EXECUTE THIS STATEMENT... */
- 12 DEFAULT:
- /* ╔F X IS NONE OF THE ABOVE, THEN */
- 13 DO THIS;
- /* EXECUTE THIS STATEMENT... */
- 14 ▌ /* END OF SWITCH */
-
- ╬OW, IF X IS A 1 OR 2 OR 3, THE
- STATEMENTS 5 TO 8 WILL BE EXECUTED
- AND (BECAUSE OF THE BREAK; IN LINE 9)
- WE LEAVE THE ╙╫╔╘├╚ AND CONTINUE
- BEYOND LINE 14. ╔F, HOWEVER X IS A 4,
- THEN ONLY THE STATEMENT(S) FOR THIS
- CASE ARE EXECUTED (LINE 11, IN THIS
- EXAMPLE). ╧NLY IF ALL CASES FAIL WILL
- THE DEFAULT STATEMENT(S) BE EXECUTED
- (FOR EXAMPLE, IF X IS A 6 THEN
- STATEMENT 13 IS EXECUTED).
-
- ╟OOD PROGRAMMING PRACTICE IS TO PLACE
- A BREAK AT THE END OF EACH CASE
- ╒╬╠┼╙╙ YOU ╙╨┼├╔╞╔├┴╠╠┘ ╫┴╬╘ CASE-
- CHECKING TO FALL THROUGH TO
- SUBSEQUENT CASES. ╘HIS IS A BIT OF
- DEFENSIVE PROGRAMMING WHICH CAN SAVE
- YOU FROM HAVING TO DO DIFFICULT
- DEBUGGING LATER ON.
-
-
-
- ═ORE ╙╫╔╘├╚ING -
-
- ┘OU MAY SWITCH ON ANY TYPE OF
- VARIABLE (NOT JUST INTEGERS). ╞OR
- EXAMPLE YOU MAY HAVE DECLARED X TO BE
- A CHAR, SO ...
-
- 1 SWITCH (X) █
- /* ┬EGIN ╙╫╔╘├╚ ON THE CHAR X */
- 2 CASE '┴':
- /* ╔F X IS THE CHARACTER '┴',THEN */
- 3 CASE 'U':
- /* ╔F X IS THE CHARACTER 'U',THEN */
- 4 CASE '#':
- /* ╔F X IS THE CHARACTER '#',THEN */
- 5 DO THIS;
- /* EXECUTE THIS STATEMENT... */
- 6 AND THIS;
- /* AND THIS TOO */
- 7 AND THIS;
- /* AND THIS TOO */
- 8 AND THIS;
- /* AND THIS TOO */
- 9 BREAK;
- /* NOW ┬╥┼┴╦ ╧╒╘ ╧╞ ╘╚┼ ╙╫╔╘├╚ */
-
- ╬OTE THAT THE CASE COMPARISON MUST BE
- CONSISTENT WITH THE VARIABLE TYPE.
-
- ╔F X IS AN INT
- THEN YOU MAY USE CASE 7:
-
- ╔F X IS A CHAR
- THEN YOU MAY USE CASE '+':
-
- ╔F X IS A FLOAT
- THEN YOU MAY USE CASE -1.234:
-
- ╘HINK OF THE CASE COMPARISONS AS
- BEING EQUIVALENT TO:
-
- IF (X==7) OR IF (X=='+') OR
- IF (X==-1.234) ETC.
-
- ┘OU MAY LEAVE OUT THE DEFAULT IF YOU
- WISH BUT THIS IS ╬╧╘ ADVISABLE.
- ╨UTTING A DEFAULT OPTION AT THE END
- OF A SWITCH WILL SAVE YOU FROM
- UNFORSEEN PROGRAMMING ERRORS OR
- CONDITIONS WHICH YOU DID NOT
- ANTICIPATE. ╔T IS GOOD PROGRAMMING
- PRACTICE AND STYLE TO PUT A DEFAULT
- AT THE END OF EVERY SWITCH.
-
-
-
- ├┴╠╠ ┬┘ ╓┴╠╒┼ AND ├┴╠╠ ┬┘ ╥┼╞┼╥┼╬├┼ -
-
- ╬OTE: WHERE YOU HAVE SOMETHING LIKE
- THE FOLLOWING -
-
- GETVAL()
- █
- INT A, B, C;
-
- C = AVERAGE(A,B);
-
- ...ETC.
-
- AVERAGE(X,Y)
- INT X, Y;
- █
- INT M;
-
- ...ETC.
-
- RETURN(M);
- ▌
- ...IN THIS CASE GETVAL() IS THE
- ├┴╠╠╔╬╟ FUNCTION AND AVERAGE() IS THE
- ├┴╠╠┼─ FUNCTION.
-
- ╫E MENTIONED IN AN EARLIER LESSON
- THAT A FUNCTION CALL, IN WHICH YOU
- PASS CERTAIN PARAMETERS ( LIKE
- AVERAGE(A,B) ), GIVES TO THE CALLED
- FUNCTION COPIES OF THE PARAMETERS.
- ╥EMEMBER THAT THESE ARE ONLY COPIES
- WHICH ARE PASSED TO THE CALLED
- FUNCTION. ╘HESE COPIES ARE KNOWN AS
- ╘┼═╨╧╥┴╥┘ ╓┴╥╔┴┬╠┼╙. ╘HE CALLED
- FUNCTION MAY CHANGE, OR WORK WITH,
- ITS TEMPORARY VARIABLES BUT THE
- "ORIGINALS" OF THE CALLING FUNCTION
- WON'T BE CHANGED. ╒NLESS YOU EXERCISE
- CERTAIN SPECIFIC OPTIONS IN WRITING
- YOUR PROGRAM THE VALUES CREATED BY A
- CALLED FUNCTION SIMPLY DISAPPEAR WHEN
- THE CALLED FUNCTION IS FINISHED
- EXECUTING. ╘HIS IS ├┴╠╠ ┬┘ ╓┴╠╒┼.
-
- ╧N FIRST SIGHT, CALL BY VALUE MAY
- SEEM LIKE AN INCONVENIENCE AND AN
- OBSTACLE. ╚OWEVER, YOU SHOULD
- CONSIDER THAT CALL BY VALUE ( A MAJOR
- FEATURE OF THE ├ LANGUAGE ) PREVENTS
- FUNCTIONS FROM CHANGING VARIABLE
- VALUES UNLESS YOU ╙╨┼├╔╞╔├┴╠╠┘ ─┼├╔─┼
- THAT YOU WANT TO HAVE THOSE VALUES
- CHANGED. ╚OW DO YOU GET A CALLED
- FUNCTION TO CHANGE VARIABLE VALUES IN
- THE CALLING FUNCTION?
-
- ╘O HAVE A FUNCTION CHANGE THE
- "ORIGINALS" YOU MUST TELL THE
- FUNCTION WHERE, IN MEMORY, THE
- "ORIGINALS" LIVE. ╘O DO THIS YOU MAY
- PASS THE ADDRESSES OF THE PARAMETERS
- TO THE CALLED FUNCTION. ╘HIS MEANS
- THAT YOU PASS ╨╧╔╬╘┼╥╙ TO THE CALLED
- FUNCTION. ╘HIS IS ├┴╠╠ ┬┘ ╥┼╞┼╥┼╬├┼.
- ╘HE CALLING FUNCTION MUST TELL THE
- CALLED FUNCTION WHERE IN MEMORY ITS
- "ORIGINAL" VARIABLES LIVE. ╘O DO THIS
- THE CALLING FUNCTION PASSES THE
- CALLED FUNCTION A POINTER TO THE
- PARAMETER THAT IT IS PASSING.
- ╥EMEMBER THAT A POINTER IS A VARIABLE
- THAT CONTAINS THE ADDRESS OF ANOTHER
- VARIABLE. ╫HEN A CALLED FUNCTION IS
- GIVEN THE ADDRESS OF A VARIABLE IT IS
- ABLE TO ╥┼╞┼╥ TO THAT VARIABLE BY
- MEANS OF THE POINTER WHICH THE
- CALLING FUNCTION HAS PASSED TO IT.
- ╘HIS IS THE MEANING OF ├┴╠╠ ┬┘
- ╥┼╞┼╥┼╬├┼.
-
-
-
-
- ╔╬─╔╥┼├╘╔╧╬ -
-
- ╦NOWING WHERE THE "ORIGINAL"
- PARAMETERS ARE, IN MEMORY, A FUNCTION
- MAY NOW MODIFY THEM. ╙UPPOSE YOU WANT
- TO EXCHANGE() THE VALUES OF TWO
- FLOATING POINT NUMBERS, SAY X AND Y,
- BY CALLING UPON A FUNCTION
- EXCHANGE():
-
- EXCHANGE(&X,&Y);
- /* CALL THE FUNCTION, AND
- GIVE IT ADDRESSES OF X,Y*/
-
- ╘HE EXCHANGE FUNTION MAY LOOK LIKE:
-
- 1 EXCHANGE(U,V)
- /* FUNCTION EXCHANGES TWO "FLOATS" */
-
- 2 FLOAT *U, *V;
- /* DECLARE U AND V AS POINTERS
- TO "FLOATS".*/
- █
- 3 /* THE OPENING BRACKET FOR
- EXCHANGE() */
-
- 4 FLOAT TEMP;
- /* DECLARE A TEMPORARY FLOAT */
-
- 5 TEMP=*U;
- /* MAKE IT EQUAL TO
- "WHAT U POINTS TO" */
-
- 6 *U=*V;
- /* PLACE THE CONTENTS OF V INTO U */
-
- 7 *V=TEMP;
- /* PLACE THE "TEMP"ORARY FLOAT
- INTO V */
-
- 8 ▌ /* FLOATS HAVE BEEN EXCHANGED */
-
- ╙OMETHING ╓┼╥┘ ╔═╨╧╥╘┴╬╘ IS HAPPENING
- ABOVE IN LINES 5, 6, & 7. ╫HEN A
- CALLED FUNCTION WANTS TO USE POINTERS
- PASSED FROM A CALLING FUNCTION TO
- ALTER THE "ORIGINALS" IN THE CALLING
- FUNCTION IT MUST USE A PROCESS KNOWN
- AS ╔╬─╔╥┼├╘╔╧╬.
- ╫HENEVER YOU ACCESS THE
- CONTENTS OF A VARIABLE BY WAY OF A
- POINTER TO THAT VARIABLE YOU ARE
- USING THE PROCESS CALLED INDIRECTION.
- ╘O SPECIFY THAT YOU WANT THE POINTER
- TO ACCESS WHAT IT IS POINTING TO YOU
- MUST USE THE ASTERISK (*) OPERATOR IN
- THE APPROPRIATE STATEMENTS IN YOUR
- FUNCTION. ╘HIS IS ─╔╞╞┼╥┼╬╘ FROM
- USING THE ASTERISK (*) TO DECLARE A
- POINTER VARIABLE AND THE ASTERISK (*)
- HAS A DIFFERENT MEANING IN THIS CASE.
- ╔N LINES 5, 6, & 7 ABOVE WE HAVE USED
- INDIRECTION TO ACCESS WHAT THE
- POINTER VARIABLES ( U AND V ) POINT
- TO. ╫HAT THIS MEANS IS THAT IF YOU
- DECLARE A POINTER VARIABLE AND ASSIGN
- IT TO POINT TO A VARIABLE OF THE SAME
- TYPE THEN, WHEN YOU USE INDIRECTION,
- BOTH THE POINTER AND THE VARIABLE
- REPRESENT EXACTLY THE SAME THING.
- ╠OOK AT THE FOLLOWING:
-
- REPF()
- █
- INT NUMBER, *PTR_NUM, X;
-
- PTR_NUM = &NUMBER;
-
- ...HAVING DONE THIS MUCH, WE CAN SEE
- THAT THE POINTER VARIABLE 'PTR_NUM'
- NOW POINTS TO THE VARIABLE 'NUMBER'.
- ╔N MOST CASES, IF WE WANTED VARIABLE
- 'X' TO EQUAL 'NUMBER' WE WOULD SAY:
-
- X = NUMBER;
-
- ...BUT NOW WE CAN USE INDIRECTION
- ( REMEMBER THE ASTERISK MEANS
- SOMETHING ELSE NOW ) AND WE CAN SAY:
-
- X = *PTR_NUM;
-
- ┬ECAUSE 'PTR_NUM' WAS DECLARED AS A
- POINTER-TO-INT IT CAN BE ASSIGNED TO
- POINT TO THE INTEGER 'NUMBER' AND
- FROM THEN ON WE CAN USE INDIRECTION
- TO USE 'PTR_NUM' ANYWHERE THAT WE
- WOULD USE 'NUMBER'. ╔F THE ASTERISK
- HAD BEEN LEFT OUT IN THE ABOVE
- STATEMENT AND WE HAD SAID:
-
- X = PTR_NUM;
-
- ...THEN 'X' WOULD HAVE BEEN EQUAL TO
- THE ADDRESS OF 'NUMBER' AND ╬╧╘ TO
- THE VALUE OF 'NUMBER'. ╔T WOULD HAVE
- BEEN A STRAIGHT ASSIGNMENT STATEMENT
- WITHOUT INDIRECTION.
-
- ╘HE USE OF ╨╧╔╬╘┼╥╙ AND ╔╬─╔╥┼├╘╔╧╬
- CAN BE A DIFFICULT TOPIC FOR THE
- NEWCOMER TO THE ├ LANGUAGE BUT IF YOU
- STUDY IT A BIT AND PRACTICE BY
- WRITING AND COMPILING SIMPLE EXAMPLES
- OF YOUR OWN YOU WILL GET THE HANG OF
- IT AND SOON DISCOVER HOW VALUABLE
- THEY ARE TO ALL OF YOUR PROGRAMMING.
-
- ╚ERE IS A COMPLETE PROGRAM WITH WHICH
- TO TRY OUT ├┴╠╠ ┬┘ ╥┼╞┼╥┼╬├┼ AND
- ╔╬─╔╥┼├╘╔╧╬:
-
- MAIN()
- █
- FLOAT X=1.23, Y=4.56;
- /* DECLARE AND DEFINE TWO FLOATS */
- PRINTF("\NX=%F, Y=%F",X,Y);
- /* PRINTF THEIR VALUES */
- EXCHANGE(&X,&Y);
- /* CALL THE EXCHANGE PROGRAM */
- PRINTF("\NX=%F, Y=%F",X,Y);
- /* PRINTF THEIR VALUES AGAIN!*/
- ▌ /* THAT'S THE END OF MAIN() */
-
- EXCHANGE(U,V)
- /* THIS FUNCTION EXCHANGES TWO
- "FLOATS" */
- FLOAT *U, *V;
- /* DECLARE U AND V AS POINTERS TO
- "FLOATS" */
- █ /* THE OPENING BRACKET FOR
- EXCHANGE() */
- FLOAT TEMP;
- /* DECLARE A TEMPORARY FLOAT */
- TEMP=*U;
- /* MAKE TEMP EQUAL TO
- "WHAT U POINTS TO" USING
- INDIRECTION */
- *U=*V;
- /* PLACE THE CONTENTS OF V INTO U
- USING INDIRECTION */
- *V=TEMP;
- /* PLACE "TEMP" INTO V USING
- INDIRECTION */
- ▌
- /* FLOATS HAVE BEEN EXCHANGED AND
- EXECUTION RETURNS TO THE CALLING
- FUNCTION MAIN() */
-
- ╬OW EXIT THE TEXT EDITOR, SAVING THE
- ABOVE WITH THE NAME SAM.C, THEN
- COMPILE USING CC SAM, THEN LINK USING
- LINK SAM, THEN EXECUTE VIA:
-
- SAM
-
- AND GET:
-
- X=1.230000, Y=4.560000
- X=4.560000, Y=1.230000
-
-
- ╚ERE'S ANOTHER VARIATION OF
- EXCHANGE(), LOOK FOR DIFFERENCES FROM
- THE FIRST VERSION:
-
- 1 EXCHANGE(U,V)
- /* THIS FUNCTION EXCHANGES TWO
- "FLOATS" */
- 2 FLOAT *U, *V;
- /* DECLARE U AND V AS POINTERS TO
- "FLOATS" */
- 3█ /* OPENING BRACKET FOR
- EXCHANGE() */
- 4 FLOAT *TEMP;
- /* DECLARE A TEMPORARY POINTER */
- 5 TEMP=U;
- /* MAKE IT EQUAL TO POINTER "U" */
- 6 U=V;
- /* MAKE "U" POINT TO WHAT "V" POINTS
- TO */
- 7 V=TEMP;
- /* MAKE "V" POINT TO WHAT "TEMP"
- POINTS TO */
- 9▌ /* FLOATS HAVE NOT BEEN
- EXCHANGED? */
-
- ╫HY WON'T THE ABOVE FUNCTION WORK?
-
- ╔N THIS VARIATION, THE POINTERS U AND
- V ARE COPIES AND ALTHOUGH THIS
- FUNCTION DOES CHANGE THESE COPIES OF
- THE POINTERS THESE VALUES DISAPPEAR
- WHEN EXCHANGE() IS FINISHED
- EXECUTING. ╬O REFERENCE WAS MADE TO
- THE "ORIGINALS" HELD IN MAIN(). ╫E
- FORGOT TO USE INDIRECTION AND SO THE
- FLOATS NEVER DO GET EXCHANGED!
- ┬┼╫┴╥┼!
-
- ╔F YOU'RE STILL HAVING TROUBLE WITH
- THE DIFFERENCE BETWEEN A VARIABLE AND
- ITS ADDRESS TRY THINKING OF THE ╨╧╦┼
- STATEMENT USED IN ┬┴╙╔├. ╘O CHANGE A
- VALUE IN MEMORY YOU SUPPLY BOTH THE
- ADDRESS AND THE NEW VALUE WHICH IT IS
- TO CONTAIN. ╞OR EXAMPLE: ╨╧╦┼ 51764,77
- ╘HIS ┬┴╙╔├ STATEMENT STORES THE VALUE
- 77 AT THE ADDRESS 51764. ╔N THE ├
- LANGUAGE YOU CAN DO THE SAME THING
- WITH A POINTER AND YOU DON'T HAVE TO
- KNOW WHAT THE EXACT ADDRESS IS. ╠OOK
- AT THE FOLLOWING EXAMPLE:
-
- 1 MAIN()
- 2 █
- 3 INT I, *PI; /* WE DECLARE BOTH AN
- INT AND A POINTER
- TO AN INT */
- 4 I = 0;
- 5 PI = I;
- 6 *PI = 77;
- 7 ▌
-
- ╔N LINE 4 WE SET THE VARIABLE I EQUAL
- TO 0. ╘HIS MEANS THAT WHEREVER IN
- MEMORY I IS LOCATED A VALUE OF 0 IS
- STORED. ╔N LINE 5 WE SET THE POINTER
- PI TO POINT TO I. ╫HAT THIS MEANS IS
- THAT THE ADDRESS, OR PLACE IN MEMORY,
- WHERE PI IS STORED CONTAINS THE VALUE
- OF THE ADDRESS, OR PLACE OF STORAGE,
- OF I. ╘HIS IS HOW PI 'POINTS' TO I.
- ╨╧╔╬╘┼╥╙ ┴╥┼ ╓┴╥╔┴┬╠┼╙ ╫╚╔├╚ ├╧╬╘┴╔╬
- ╘╚┼ ┴──╥┼╙╙┼╙ ╧╞ ╧╘╚┼╥ ╓┴╥╔┴┬╠┼╙.
- ╔N LINE 6 WE USE INDIRECTION WHICH
- ALLOWS THE POINTER PI TO BE USED JUST
- AS IF IT ACTUALLY WERE THE INT I AND
- SO STORE THE VALUE 77 AT THE MEMORY
- LOCATION OF I. ╔N EFFECT WE HAVE USED
- THE POINTER PI, AND THE PROCESS OF
- INDIRECTION, TO 'POKE' 77 INTO WHERE
- I IS LOCATED IN MEMORY.
-
-
-
- ╨ASSING ╞╒╬├╘╔╧╬╙ TO ╞╒╬├╘╔╧╬╙ -
-
- ╔N AN EARLIER LESSON WE COMPUTED THE
- ROOTS OF SOME EQUATION X=F(X), WITH
- F(X)=2*SIN(X).
-
- 1 DOUBLE X=1.0, Y, E;
- /* DECLARE DOUBLE PRECISION */
- 2 DO █
- /* START OF THE DO-WHILE LOOP*/
- 3 Y=2.0*SIN(X);
- /* CALCULATE Y */
- 4 E=FABS(Y-X);
- /* CALCULATE ERROR */
- 5 X=Y;
- /* CHANGE X TO Y */
- 6 ▌ WHILE (E>.0000005);
- /* END CONDITION */
- 7 PRINTF("X-2SIN(X)=%F WHEN X=%F",E,X);
-
- ╬OTE THAT IN THE ABOVE SIN() AND
- FABS() ARE ├ LIBRARY STANDARD
- FUNCTIONS WHICH YOU DO NOT HAVE TO
- WRITE. ╘HEY WILL BE PUT INTO YOUR
- PROGRAM AT THE LINK STAGE OF
- COMPILATION. SIN() RETURNS THE
- TRIGONOMETRIC SINE OF A NUMBER AND
- FABS() RETURNS THE ABSOLUTE VALUE OF
- A FLOATING POINT NUMBER. ╔F YOU
- AREN'T FAMILIAR WITH THE MATHEMATICS
- HERE DON'T BE TOO CONCERNED AS IT
- ISN'T CRUCIAL TO UNDERSTANDING THE
- EXAMPLE. ╔N LINE 3 'X' IS PASSED TO
- SIN() AND Y IS ASSIGNED TO TWICE THE
- VALUE RETURNED FROM SIN(). ╔N LINE 4
- WE PASS THE DIFFERENCE BETWEEN 'X'
- AND 'Y' TO FABS() AND ASSIGN THE
- RETURN VALUE TO 'E'. ╔N LINE 5 'X' IS
- ASSIGNED THE VALUE OF 'Y'. ╠INE 6
- CHECKS TO SEE IF 'E' IS GREATER THAN
- .0000005 AND IF IT IS THE DO-WHILE
- LOOP IS RE-EXECUTED UNTIL 'E' BECOMES
- LESS-THAN-OR-EQUAL-TO .0000005. ╔N
- GENERAL, THE FUNCTION GETS AN
- APPROXIMATE ROOT OF 'X' AND THE DO-
- WHILE LOOP KEEPS EXECUTING UNTIL THE
- ROOT THAT IS FOUND IS WITHIN THE
- SPECIFIED ERROR FACTOR (.0000005) OF
- BEING THE EXACT ROOT OF 'X'.
-
- ╬OW SUPPOSE WE TURN THIS PIECE OF
- CODE INTO A FUNCTION, SOLVE() WHICH
- WE CALL VIA:
-
- ROOT = SOLVE(F,X,E);
-
- WHERE WE PASS TO SOLVE() THE FUNCTION
- F(X), AND SOME INITIAL GUESS OF THE
- ROOT, NAMELY X, AND AN ERROR
- SPECIFICATION E. ╫E EXPECT
- SOLVE(F,X,E) TO RETURN A ROOT (WHICH,
- NATURALLY, WE CALL ROOT!).
-
- ╫E MAY WRITE SOLVE() LIKE SO:
-
- 1 FLOAT SOLVE(FCN,X,ERROR)
- /* RETURNS A ╞╠╧┴╘!*/
- 2 FLOAT (*FCN)();
- /* SOMETHING ╬┼╫ */
- 3 FLOAT X, ERROR;
- /* X-VALUE & ERROR ARE FLOATS */
- 4 █
- 5 FLOAT Y, E;
- /* DECLARES 2 FLOATS */
- 6 DO /* START OF THE DO-LOOP */
- 7 Y=(*FCN)(X);
- /* CALCULATES Y */
- 8 E=FABS(Y-X);
- /* CALCULATE ABSOLUTE VALUE OF Y-X */
- 9 X=Y;
- /* CHANGE X TO Y */
- 10 WHILE (E>ERROR);
- /* CHECK ERROR IF E IS TOO LARGE */
- 11 RETURN(X);
- /* RETURN X=ROOT IF E<=ERROR */
- 12 ▌
-
- ╠INE 1 DECLARES THE FUNCTION SOLVE()
- TO BE OF THE TYPE 'FLOAT'. ╘HIS KIND
- OF DECLARATION IS NECESSARY IF A
- CALLED FUNCTION IS GOING TO RETURN A
- VALUE TO ITS CALLING FUNCTION.
- ╙TRICTLY SPEAKING YOU DON'T HAVE TO
- DECLARE A FUNCTION OF THE TYPE 'INT'
- IF IT IS RETURNING AN INTEGER BECAUSE
- THE COMPILER WILL ┴╠╫┴┘╙ ASSUME THAT
- ┴╠╠ FUNCTIONS ARE OF ╘┘╨┼ ╔╬╘ UNLESS
- YOU TELL IT OTHERWISE BUT IT IS GOOD
- PROGRAMMING PRACTICE TO MAKE A TYPE
- DECLARATION FOR ANY FUNCTION WHICH IS
- EXPECTED TO RETURN A VALUE TO ANOTHER
- FUNCTION.
-
- ╠INE 2 HAS THE CURIOUS DECLARATION OF
- FCN() AS A FUNCTION POINTER. ╘HE
- (*FCN) SAYS IT'S A POINTER, AND THE
- () SAYS IT POINTS TO A FUNCTION AND
- THE FLOAT SAYS THIS FCN RETURNS A
- FLOAT! ╬OTE TOO, IN LINE 7, THAT
- WHEREAS FCN IS A POINTER, *FCN ╔╙ THE
- FUNCTION BECAUSE IN LINE 7 WE ARE
- USING INDIRECTION! ( THE PARENTHESES
- ARE NECESSARY TO ENSURE THE PROPER
- ORDER OF OPERATIONS ). ╥EMEMBER,
- THROUGH INDIRECTION A POINTER IS MADE
- TO BE WHAT IT POINTS TO.
-
-
- MAIN()
- █
- FLOAT F1(), F2(), F3(), SOLVE();
- /* DECLARE FUNCTIONS USED */
-
- PRINTF("\N┴ ROOT OF X=F1(X) IS %F",
- /* PRINTF THE ROOT ...*/
-
- SOLVE(F1,1,.00005));
- /* SOLVE X=F1(X) */
-
- PRINTF("\N┴ ROOT OF X=F2(X) IS %F",
- /* PRINTF THE ROOT ...*/
-
- SOLVE(F2,-1,.00005));
- /* SOLVE X=F2(X) */
-
- PRINTF("\N┴ ROOT OF X=F3(X) IS %F",
- /* PRINTF THE ROOT ...*/
-
- SOLVE(F3,2,.00005));
- /* SOLVE X=F3(X) */
-
- ▌ /* END OF MAIN() */
-
- FLOAT SOLVE(FCN,X,ERROR)
- /* RETURNS A ╞╠╧┴╘!*/
- FLOAT (*FCN)();
- /* SOMETHING ╬┼╫ */
- FLOAT X, ERROR;
- /* X-VALUE & ERROR ARE FLOATS */
- █
- FLOAT Y, E;
- /* DECLARES 2 FLOATS */
- DO /* START OF THE DO-LOOP */
- Y=(*FCN)(X);
- /* CALCULATES Y */
- E=FABS(Y-X);
- /* CALCULATE ABSOLUTE VALUE OF Y-X */
- X=Y;
- /* CHANGE X TO Y */
- WHILE (E>ERROR);
- /* CHECK ERROR IF E IS TOO LARGE */
- RETURN(X);
- /* RETURN X=ROOT IF E<=ERROR */
- ▌
-
- FLOAT F1(X)
- FLOAT X;
- █
- RETURN(2.*SIN(X));
- ▌
- /* F1(X) = 2 SIN(X) */
-
- FLOAT F2(X)
- FLOAT X;
- █
- RETURN(2.-X/2.);
- ▌
- /* F2(X) = 2-X/2 */
-
- FLOAT F3(X)
- FLOAT X;
- █
- RETURN(1.+1./X);
- ▌
- /* F3(X) = 1+1/X */
-
- ╔T IS NOT NECESSARY THAT YOU
- UNDERSTAND EXACTLY WHAT IS
- MATHEMATICALLY OCCURRING IN THE ABOVE
- PROGRAM. ┘OU SHOULD CONCENTRATE ON
- STUDYING HOW POINTERS TO FUNCTIONS
- CAN BE PASSED JUST LIKE POINTERS TO
- VARIABLES AND HOW THESE FUNCTIONS MAY
- THEN BE ACCESSED USING INDIRECTION.
-
-
- ╚ERE ARE SOME COMMENTS ON PARTS OF
- THE ABOVE PROGRAM:
-
- FLOAT F1(), F2(), F3(), SOLVE();
- /* DECLARE TYPES OF FUNCTIONS USED */
-
- ╚ERE WE DECLARE ALL THE FUNCTIONS WE
- USE ( THEY ALL RETURN A FLOAT).
-
- PRINTF("\N┴ ROOT OF X=F1(X) IS %F",
- /* PRINTF THE ROOT...*/
- SOLVE(F1,1,.00005));
- /* SOLVE X=F1(X) */
-
- ╚ERE WE PRINT (AFTER A NEWLINE) ┴
- ROOT OF X=F1(X) IS FOLLOWED BY THE
- %FLOAT RETURNED BY
- SOLVE(F1,1,.00005).
- ╬OTE THAT WE PASS THE POINTER F1,
- A STARTING VALUE 1 AND AN ERROR
- SPECIFICATION OF .00005
- ...THEN WE CONTINUE WITH TWO MORE
- FUNCTIONS F2(X) AND F3(X), EACH TIME
- SPECIFYING NOT ONLY THE POINTER TO
- THE FUNCTION BUT ALSO A STARTING
- VALUE AND ERROR SPECIFICATION.
-
- ╔F YOU TRY COMPILING AND RUNNING THE
- ABOVE PROGRAM YOU WILL GET OUTPUT
- SOMETHING LIKE THE FOLLOWING, THOUGH
- LIMITATIONS OF COMPUTER ARCHITECTURE
- MAY GENERATE DIFFERENT RESULTS:
-
- ┴ ROOT OF X=F1(X) IS 1.895475
- ┴ ROOT OF X=F2(X) IS 1.333324
- ┴ ROOT OF X=F3(X) IS 1.618026
-
- AND (BECAUSE WE USE ONLY FLOAT AND
- NOT DOUBLE, AND WE GAVE AN ERROR
- SPECIFICATION OF .00005) WE GET
- (ROUGHLY) 4 DECIMAL PLACE ACCURACY.
-
- ╫ELL, THE PROGRAMMING AIN'T TOO SEXY
- ( HOW USEFUL ARE THESE 3 BUILT-IN
- FUNCTIONS, F1(X), F2(X) AND F3(X) ? )
- AND THE MATHEMATICS IS EVEN WORSE
- (YOU CAN'T GUARANTEE THAT THE PROGRAM
- WON'T GET STUCK IN THE SOLVE()
- FUNCTION ... FOREVER TRYING TO REDUCE
- A GROWING ERROR!), ┬╒╘ ...WE GET THE
- IDEA ...RIGHT?
-
-
- ╥┼═┼═┬┼╥: ╘O PASS THE FUNCTION
- SAM(A,B,C) AS AN ARGUMENT TO ANOTHER
- FUNCTION YOU WOULD USE:
-
- GEORGE(SAM,X,Y);
-
- ...THEN WITHIN THE BODY OF THE
- FUNCTION GEORGE() YOU WOULD MAKE
- THE DECLARATION:
-
- FLOAT (*SAM)();
-
- AND USE IT WITHIN THE FUNCTION
- GEORGE() AS:
-
- (*SAM)(A,B,C);
-
- ╔F SAM() RETURNS AN INT OR CHAR THEN
- (OF COURSE) IT SHOULD BE DECLARED AS
- INT (*SAM)() OR CHAR (*SAM)()!
-
-
-
- [┼ND OF PART 9 OF 11]
-