ECS 36A编程辅导、辅导c/c++程序语言、Programming编程设计讲解

- 首页 >> Matlab编程
ECS 36A: Programming Assignment #5
Instructor: Aaron Kaloti
Fall 2020
Contents
1 Changelog 1
2 General Submission Details 1
3 Grading Breakdown 2
4 Submitting on Gradescope 2
4.1 Regarding Autograder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
4.1.1 Number of Visible vs. Hidden Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
4.1.2 Visible Test Cases’ Inputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
5 File I/O 2
6 Programming Problems 5
6.1 File Organization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
6.2 Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
6.3 Part #1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
6.4 Part #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
6.5 Part #3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
6.6 Part #4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
6.7 Part #5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1 Changelog
You should always refer to the latest version of this document.
• v.1: Initial version.
• v.2: For part #2, you should close any file that your function opens.
• v.3: Added clarifications regarding input validation to part #1 (and reformatted that part of the directions); the new
information is marked in red.
• v.4: Pushed deadline back to Sunday night.
• v.5:
– Autograder details.
– Explicitly stated that for part #2, whether you closed the file or not will be checked by valgrind.
2 General Submission Details
Partnering on this assignment is prohibited. If you have not already, you should read the section on
academic misconduct in the syllabus.
This assignment is due the night of Sunday, November 22. Gradescope will say 12:30 AM on Monday, November 23, due
to the “grace period” (as described in the syllabus). Be careful about relying on the grace period for extra time; this could be
risky.
∗This content is protected and may not be shared, uploaded, or distributed.
1
You should use the -Wall and -Werror flags when compiling. The autograder will use these flags when it compiles your
program.
3 Grading Breakdown
The autograder score will be out of 80 points. Each of the five parts will be worth 16 points.
4 Submitting on Gradescope
You should only submit your C files with the names indicated below. You may be penalized for submitting additional
files. You have infinite submissions until the deadline.
During the 10/02 lecture, I talked about how to change the active submission, just in case that is something that you
find yourself wanting to do.
4.1 Regarding Autograder
Your output must match mine exactly.
There is a description about how to interpret some of the autograder error messages in the directions for the previous
two programming assignments. I will not repeat that description here.
Only submit prog5.c.
4.1.1 Number of Visible vs. Hidden Cases
Below is the breakdown of visible vs. hidden test cases on each part.
Part No. Cases No. Visible No. Hidden
1 10 6 4
2 4 2 2
3 4 1 3
4 7 4 3
5 3 2 1
4.1.2 Visible Test Cases’ Inputs
See the C files added to the Autograder folder in the P5 folder on Canvas.
5 File I/O
You will do file I/O in this programming assignment. We might talk more about file I/O during lecture, but below are
enough details to get you through this assignment.
You should have learned about file I/O in ECS 32A or the equivalent. There is not much difference between how file I/O
is done in Python (or most other programming languages) vs. C. In both languages, we call a function to open a file, and we
specify a certain mode. In the case of C, that function is fopen()1
. The fopen() function returns NULL if it cannot open the file.
Below are modes that you might find useful when dealing with text files in C. I think most of these are the same in Python.
• "r": open existing2
text file for reading.
• "w": open/create file for writing, clearing its contents first.
• "a": open/create file for writing at end.
• "r+": open for reading and writing.
After we have successfully opened a file we are given a pointer to an instance of FILE3
, and we can use this file pointer in
the same way in which we would use a “file object” in Python. We can then use any of the various I/O functions declared in
1There is the open() function in the header, for compilers that support the C POSIX library, but we won’t talk about that here. The
file I/O functions in the C POSIX Library make it easier to access features specific to any filesystem (such as the filesystems supported by most
Linux distributions) that is POSIX-compliant, such as directories, file permissions, and soft/hard links. The file I/O functions in , such
as fopen(), do not make this easy, since these functions – being part of the C standard – have to support filesystems that are not POSIX-compliant.
2Fails if file doesn’t exist, just like how Python’s open() function raises a FileNotFoundError exception if you try to open a nonexistent file.
3FILE is what is known as a user-defined type, because it isn’t a built-in type like int or char are. We will learn more about user-defined types
when we talk about structs, but for now, you can think of FILE as a built-in type even though it technically is not; the distinction is unimportant
here.
2
to read from the file, such as fscanf() or fgets(). (You can look up others.) As with Python, we still have to close
the file when we are done with it.
Below is an example in which we use fgets() to read a file line-by-line, taking advantage of the fact that fgets() returns
NULL – which, as you should recall, is a false value – once there is no more to read.
1 $ cat poem . txt
2 There once was a man from Peru ;
3 who dreamed he was eating his shoe .
4 He woke with a fright
5 in the middle of the night
6 to find that his dream had come true .
7 $ cat files1 .c
8 # include < stdio .h >
9
10 // Effectively means 98 , because of the newline character ( which fgets () reads )
11 // and the null terminator .
12 # define MAX_LINE_SIZE 100
13
14 int main ()
15 {
16 FILE * fp = fopen (" poem . txt ", "r ") ;
17 char buf [ MAX_LINE_SIZE ];
18 int lineCounter = 0;
19 while ( fgets ( buf , MAX_LINE_SIZE , fp ))
20 {
21 // No newline character at end of format string because fgets () already
22 // put the newline character at the end of buf .
23 printf (" Line #% d: %s", lineCounter , buf );
24 lineCounter += 1;
25 }
26 fclose ( fp );
27 return 0;
28 }
29 $ gcc - Wall - Werror files1 .c
30 $ ./ a. out
31 Line #0: There once was a man from Peru ;
32 Line #1: who dreamed he was eating his shoe .
33 Line #2: He woke with a fright
34 Line #3: in the middle of the night
35 Line #4: to find that his dream had come true .
36 $
Below is an example in which we use fscanf(). fscanf() is probably more helpful when we know the file will be formatted
in a certain way, but this may not occur often. Sometimes, even when a text file has a certain format, you may prefer to use
fgets() and then parse the line that was read, e.g. with strtok() and type conversion functions such as atoi() or sscanf(). It’s
all subjective, but in many cases, you probably can’t go wrong with either.
1 $ cat values . txt
2 58
3 abc 8.3
4
5 & *
6 678
7 $ cat files2 .c
8 # include < stdio .h >
9
10 # define BUF_LEN 15
11
12 int main ()
13 {
14 FILE * fp = fopen (" values . txt ", "r ") ;
15 int x , numRead ;
16 float y;
17 char z , buf [ BUF_LEN ];
18 numRead = fscanf (fp , "% d %s %f", &x , buf , &y);
19 printf (" numRead : %d\ n", numRead ) ;
20 printf (" x: %d\n ", x);
21 printf (" buf : %s \n", buf );
22 printf (" y: %f\n ", y);
23 printf ("===\ n ") ;
24 // Note leading whitespace in format string
25 // since reading character and want to ignore
26 // whitespace .
3
27 numRead = fscanf (fp , " % c", &z);
28 printf (" numRead : %d\ n", numRead ) ;
29 printf (" z: %c\n ", z);
30 printf ("===\ n ") ;
31 numRead = fscanf (fp , "% s", buf );
32 printf (" numRead : %d\ n", numRead ) ;
33 printf (" buf : %s \n", buf );
34 printf ("===\ n ") ;
35 // Leading whitespace in format string
36 // for reading the character .
37 numRead = fscanf (fp , " % c %d ", &z , &x);
38 printf (" numRead : %d\ n", numRead ) ;
39 printf (" z: %c\n ", z);
40 printf (" x: %d\n ", x);
41 printf ("===\ n ") ;
42 // fscanf () returns EOF when end -of - file is reached .
43 // EOF is likely -1 , but you should not depend on that and should
44 // instead use EOF .
45 // fscanf () returns 0 if it tries to read a value that does not match
46 // the format specifier , but that is different from reaching the end
47 // of the file .
48 numRead = fscanf (fp , "% d", &x ); // no more to read
49 printf (" numRead : %d\ n", numRead ) ;
50 fclose ( fp );
51 }
52 $ gcc - Wall - Werror files2 .c
53 $ ./ a. out
54 numRead : 3
55 x: 58
56 buf : abc
57 y: 8.300000
58 ===
59 numRead : 1
60 z: &
61 ===
62 numRead : 1
63 buf : *
64 ===
65 numRead : 2
66 z: 6
67 x: 78
68 ===
69 numRead : -1
70 $
The example below shows that fscanf() ignores whitespace in the format string, except to use whitespace as a separator.
As was the case with scanf(), fscanf() is probably not as convenient as fgets() when trying to read a string that consists of
multiple words.
1 $ cat goo . txt
2 what
3 89
4 22
5 $ cat files3 .c
6 # include < stdio .h >
7
8 # define BUF_LEN 15
9
10 int main ()
11 {
12 FILE * fp = fopen (" goo . txt " , " r ") ;
13 char buf [ BUF_LEN ];
14 int a , b;
15 fscanf ( fp , "% s %d %d", buf , &a , &b);
16 printf (" s =% s , a =%d , b =% d\n", buf , a , b );
17 fclose ( fp );
18 return 0;
19 }
20 $ gcc - Wall - Werror files3 .c
21 $ ./ a. out
22 s= what , a =89 , b =22
23 $
Writing to a file can be done with fprintf(), fputs(), or other functions that you can look up. Below is an example.
4
1 $ ls tmp
2 $ cat files4 .c
3 # include < stdio .h >
4
5 int main ()
6 {
7 FILE * fp = fopen (" tmp / output ", "w ") ;
8 fputs (" Hi there \n ", fp );
9 fprintf (fp , "% s %d %f \n", " blah ", 53 , 8.2) ;
10 fclose ( fp );
11 }
12 $ gcc - Wall - Werror files4 .c
13 $ ./ a. out
14 $ cat tmp / output
15 Hi there
16 blah 53 8.200000
17 $
6 Programming Problems
6.1 File Organization
Each function that is declared in prog5.h (provided on Canvas) will be defined in a file called prog5.c. You will need to
create prog5.c from scratch. We will eventually talk about managing C code that spans multiple files, but for now, it suffices
to think of the purpose of prog5.h as being to allow prog5.c and the tester programs (which have their own implementations
of main()) to “know about” the same functions and those functions’ information. Compiling files that involve multiple C files
is not much more difficult than the compilation you’ve done so far, and you can see how such compilation is done in the
examples for each part.
6.2 Restrictions
When you submit your prog5.c to Gradescope, it cannot have a main() implementation in it.
Since you will only submit prog5.c to the autograder, you are not allowed to modify prog5.h. Note that you can still
write your own helper functions in prog5.c; there is no reason for these helper functions to be in prog5.h, since the autograder
is certainly not going to call your helper functions.
Below is a list of headers that you are allowed to include in prog5.c. You may not need all of these.
• prog5.h






6.3 Part #1
In this part, you will implement the function sumSubrectangle() that is declared in prog5.h. This function takes as arguments
a two-dimensional (2D) rectangular array of integers, the dimensions of this rectangular array, four “coordinates” (rowStart,
rowEnd, colStart, and colEnd), and a reference to a variable in which to place the result. This function should compute the sum
of all of the values in the given 2D array that are both in the rows whose indices are between rowStart and rowEnd (inclusive)
and in the columns whose indices are between colStart and colEnd (inclusive). In other words, if we visualize the given
rectangular array as a rectangle, we can view the four coordinates (again, rowStart, rowEnd, colStart, and colEnd) as defining
a smaller rectangle contained within the rectangular array, and we want to find the sum of the integers contained in this
smaller rectangle.
Return false if the input is invalid; otherwise, return true.
Regarding input validation:
• You should check any condition that, if unchecked, could cause your function to dereference a null pointer.
• It is possible that a row of the two-dimensional array is NULL; this should be considered invalid input. You may asssume
that numCols is always correct and that the two-dimensional array is rectangular (ignoring NULL rows).
5
• Assuming arr is not NULL, there is nothing you can do to validate numRows. Think of the one-dimensional case: if I gave
you a one-dimensional array and told you the wrong length, it would be impossible to determine that the length I gave
was incorrect.
• Update: If rowStart > rowEnd or colStart > colEnd, then that should be considered invalid input.
• Update: Out-of-bounds coordinates (e.g. rowEnd is 8 even though there are only 3 rows) should be considered invalid
input.
Below are examples of how your function should behave.
1 $ cat test_sumSubrectangle .c
2 # include " prog5 .h"
3 # include < stdio .h >
4
5 int main ()
6 {
7 int nr = 4 , nc = 3;
8 int row1 [] = { -2 , 6, 1};
9 int row2 [] = { -5 , 3, 9};
10 int row3 [] = {4 , 2 , 0};
11 int row4 [] = {5 , 10 , -8};
12 int * arr [] = { row1 , row2 , row3 , row4 };
13 int result = -1;
14 printf ("=== Case 1 ===\ n ") ;
15 printf (" retval =% d \n", sumSubrectangle (
16 arr , nr , nc , 1, 2, 1, 2, & result )) ;
17 printf (" result =% d \n", result ) ;
18 printf ("=== Case 2 ===\ n ") ;
19 printf (" retval =% d \n", sumSubrectangle (
20 arr , nr , nc , 0, nr -1 , 0, nc -1 , & result ));
21 printf (" result =% d \n", result ) ;
22
23 nr = 1;
24 nc = 5;
25 result = -1;
26 int row [] = {8 , -5 , 2, 5, 9};
27 int * arr2 [] = { row };
28 printf ("=== Case 3 ===\ n ") ;
29 printf (" retval =% d \n", sumSubrectangle (
30 arr2 , nr , nc , 0, 0, 1, 3, & result ) );
31 printf (" result =% d \n", result ) ;
32 }
33 $ gcc - Wall - Werror test_sumSubrectangle .c prog5 .c -o test_sumSubrectangle
34 $ ./ test_sumSubrectangle
35 === Case 1 ===
36 retval =1
37 result =14
38 === Case 2 ===
39 retval =1
40 result =25
41 === Case 3 ===
42 retval =1
43 result =2
44 $
6.4 Part #2
You should not start this part until you have a sufficient understanding of how to do file I/O in C. Make sure to understand
the material on file I/O towards the beginning of this document.
In this part, you will implement the function parseForHighest() that is declared in prog5.h. The first argument that this
function takes is the name of a file that is assumed to contain one integer per line. (You don’t need to validate that it contains
one integer per line; just assume it.) The function should determine the highest integer in the file and store that integer in
the int variable referenced by the second argument.
You need not worry about overflow or underflow, so long as you use the int type instead of something like short. Don’t
forget to close the file when you are done with it.
Return −1 if either argument is a null pointer. Return −2 if the file cannot be opened.
Don’t forget to close any file that you open. (This will be checked with valgrind.)
Below are examples of how your function should behave. Regarding the output of valgrind, you don’t need to worry about
details such as the values between the equal signs or the number of bytes allocated in total; the autograder will simply use
valgrind to check for if you closed the file.
6
1 $ cat test_parseForHighest .c
2 # include " prog5 .h"
3
4 # include < stdio .h >
5
6 int main ()
7 {
8 int highest = 0 , retval = 0;
9 retval = parseForHighest (" values1 . txt ", & highest );
10 printf (" retval : %d\n ", retval );
11 printf (" highest : %d\ n", highest ) ;
12 retval = parseForHighest ( NULL , & highest ) ;
13 printf (" retval : %d\n ", retval );
14 retval = parseForHighest (" values1 . txt ", NULL ) ;
15 printf (" retval : %d\n ", retval );
16 }
17 $ cat values1 . txt
18 18
19 34
20 6
21 -3
22 5
23 $ gcc - Wall - Werror test_parseForHighest .c prog5 .c -o test_parseForHighest
24 $ ./ test_parseForHighest
25 retval : 0
26 highest : 34
27 retval : -1
28 retval : -1
29 $ valgrind ./ test_parseForHighest
30 ==1956== Memcheck , a memory error detector
31 ==1956== Copyright ( C) 2002 -2017 , and GNU GPL ’d , by Julian Seward et al .
32 ==1956== Using Valgrind -3.13.0 and LibVEX ; rerun with -h for copyright info
33 ==1956== Command : ./ test_parseForHighest
34 ==1956==
35 retval : 0
36 highest : 34
37 retval : -1
38 retval : -1
39 ==1956==
40 ==1956== HEAP SUMMARY :
41 ==1956== in use at exit : 0 bytes in 0 blocks
42 ==1956== total heap usage : 3 allocs , 3 frees , 5 ,672 bytes allocated
43 ==1956==
44 ==1956== All heap blocks were freed -- no leaks are possible
45 ==1956==
46 ==1956== For counts of detected and suppressed errors , rerun with : -v
47 ==1956== ERROR SUMMARY : 0 errors from 0 contexts ( suppressed : 0 from 0)
48 $
6.5 Part #3
You should not start this part until we talk about dynamic memory allocation during lecture.
In this part, you will implement the function getAllHigherThan() that is declared in prog5.h. This function takes four
arguments: an array of integers, the length of that array, a threshold integer, and a pointer to an int. getAllHigherThan()
should return an array of all integers in the first argument that are higher than the given threshold. Just for fun, the integers
in this new array must appear in the opposite order compared to the order in which they appear in the original array. The
length of the new array must be stored in the integer referenced by the fourth argument.
Return NULL if the function is given any null pointers.
Below are examples of how your function should behave.
1 $ cat test_getAllHigherThan . c
2 # include " prog5 .h"
3
4 # include < stdio .h >
5 # include < stdlib .h >
6
7 int main ()
8 {
9 int arr [] = {18 , 12 , 22 , 37 , 15};
10 unsigned newArrlen = 0;
11 int * higherThan = getAllHigherThan ( arr , 5 , 15 , & newArrlen );
7
12 for ( unsigned i = 0; i < newArrlen ; ++ i)
13 printf (" Index % u: %d\n" , i , higherThan [ i ]) ;
14 free ( higherThan ) ;
15 printf ("===\ n ") ;
16 int arr2 [] = {38 , 15 , 16 , 22 , 9, 32 , 25 , 20};
17 higherThan = getAllHigherThan ( arr2 , 8, 19 , & newArrlen ) ;
18 for ( unsigned i = 0; i < newArrlen ; ++ i)
19 printf (" Index % u: %d\n" , i , higherThan [ i ]) ;
20 free ( higherThan ) ;
21 }
22 $ gcc - Wall - Werror -g test_getAllHigherThan .c prog5 .c -o test_getAllHigherThan
23 $ ./ test_getAllHigherThan
24 Index 0: 37
25 Index 1: 22
26 Index 2: 18
27 ===
28 Index 0: 20
29 Index 1: 25
30 Index 2: 32
31 Index 3: 22
32 Index 4: 38
33 $
6.6 Part #4
You should not start this part until we talk about dynamic memory allocation during lecture.
In this part, you will implement the function calculateRowSums() that is declared in prog5.h. This function’s parameters
are:
• vals: a two-dimensional jagged array of integers. (A jagged array, as opposed to a rectangular array, can have rows of
different lengths.)
• numRows: exactly what it sounds like. Assuming vals and rowWidths are not null pointers, you may assume that numRows is
correct (i.e. that the number of rows in vals equals numRows and that the number of values in rowWidths equals numRows).
• rowWidths: an array of the widths of each row (since, as stated above, vals is a jagged array).
calculateRowSums() should return an array (i.e. a one-dimensional array) containing the sum of each row in the given
two-dimensional array vals. This returned array needs to be dynamically allocated; if the array is statically allocated, then
it could be randomly destroyed/overwritten at any point after the function ends.
Regarding input validation, you should check any condition that, if unchecked, could cause your function to dereference
a null pointer. Return NULL if the input is invalid. Note that it is possible that a row of the jagged array is NULL, in which
case the corresponding member in rowWidths would be wrong. This should be considered invalid input. Besides this case, you
may assume that the values in rowWidths are always correct.
For this part, you will be penalized if your function creates any memory leaks. The autograder will deallocate the array
that is returned by your function.
Below are examples of how your function should behave. Regarding the output of valgrind, you don’t need to worry about
details such as the values between the equal signs or the number of bytes allocated in total; the autograder will simply use
valgrind to check for memory leaks.
1 $ cat test_calculateRowSums . c
2 # include < stdlib .h >
3 # include < stdio .h >
4
5 # include " prog5 .h"
6
7 int main ()
8 {
9 int row1 [] = {5 , 8 , 3};
10 int row2 [] = {9 , 2};
11 int row3 [] = {4 , -2, 1 , 8 , 9};
12 int rowWidths [] = {3 , 2 , 5};
13 int numRows = 3;
14 int * rows [] = { row1 , row2 , row3 };
15 int * sums = calculateRowSums ( rows , numRows , rowWidths ) ;
16 for ( int i = 0; i < numRows ; ++ i)
17 printf (" sums [% d ]=% d\n ", i , sums [ i ]) ;
18 free ( sums );
19 }
20 $ gcc - Wall - Werror test_calculateRowSums .c prog5 .c -o test_calculateRowSums
8
21 $ ./ test_calculateRowSums
22 sums [0]=16
23 sums [1]=11
24 sums [2]=20
25 $ valgrind ./ test_calculateRowSums
26 ==22999== Memcheck , a memory error detector
27 ==22999== Copyright ( C) 2002 -2017 , and GNU GPL ’d , by Julian Seward et al .
28 ==22999== Using Valgrind -3.13.0 and LibVEX ; rerun with -h for copyright info
29 ==22999== Command : ./ test_calculateRowSums
30 ==22999==
31 sums [0]=16
32 sums [1]=11
33 sums [2]=20
34 ==22999==
35 ==22999== HEAP SUMMARY :
36 ==22999== in use at exit : 0 bytes in 0 blocks
37 ==22999== total heap usage : 2 allocs , 2 frees , 1 ,036 bytes allocated
38 ==22999==
39 ==22999== All heap blocks were freed -- no leaks are possible
40 ==22999==
41 ==22999== For counts of detected and suppressed errors , rerun with : -v
42 ==22999== ERROR SUMMARY : 0 errors from 0 contexts ( suppressed : 0 from 0)
43 $
6.7 Part #5
You should not start this part until we talk about dynamic memory allocation and function pointers during lecture.
In this part, you will implement the function applyTransformation() that is declared in prog5.h. This function takes as
arguments an array of strings, the number of strings, and a pointer to a function (what I’ll call our “transformation function”)
that takes a string as argument and returns an integer. applyTransformation() should apply the “transformation function” to
each string in the given array of strings and return the results in an array of integers.
For this function, you may assume the input is always valid/correct. (You won’t fail any test cases if you do perform
input validation, but you won’t fail any if you do not perform it, either.)
Below are examples of how your function should behave. I make use of blocks (code between curly braces) to reuse
variable names and give them new types (because the block defines a scope, and once a variable goes out of scope, it may be
destroyed); this does not impact the behavior of the function.
1 $ cat test_applyTransformation .c
2 # include < stdlib .h >
3 # include < stdio .h >
4 # include < string .h >
5
6 # include " prog5 .h"
7
8 int testTransform1 ( char * str )
9 {
10 if (! strcmp ( str , " abc ") ) return 0;
11 else if (! strcmp ( str , " def ") ) return 1;
12 else return 2;
13 }
14
15 int testTransform2 ( char * str )
16 {
17 if ( strlen ( str ) < 3) return 0;
18 else return str [2];
19 }
20
21 int main ()
22 {
23 {
24 printf ("=== Case 1 ===\ n ") ;
25 int len = 4;
26 char * terms [] = {" abc ", " def " , " ghi ", " def "};
27 int * arr = applyTransformation ( terms , len , testTransform1 );
28 for ( int i = 0; i < len ; ++ i)
29 printf (" arr [% d ]=% d\n" , i , arr [i ]) ;
30 free ( arr );
31 }
32 {
33 printf ("=== Case 2 ===\ n ") ;
9
34 int len = 5;
35 char * terms [] = {" ab " , " cde ", " efgh ", "" , " ijk "};
36 int * arr = applyTransformation ( terms , len , testTransform2 );
37 for ( int i = 0; i < len ; ++ i)
38 printf (" arr [% d ]=% d\n" , i , arr [i ]) ;
39 free ( arr );
40 }
41 }
42 $ gcc - Wall - Werror test_applyTransformation .c prog5 .c -o test_applyTransformation
43 $ ./ test_applyTransformation
44 === Case 1 ===
45 arr [0]=0
46 arr [1]=1
47 arr [2]=2
48 arr [3]=1
49 === Case 2 ===
50 arr [0]=0
51 arr [1]=101
52 arr [2]=103
53 arr [3]=0
54 arr [4]=107
55 $
10

站长地图