Programming In C Volume 2 Composite Data Structures And Modularization Zhou download
Programming In C Volume 2 Composite Data Structures And Modularization Zhou download
https://ebookbell.com/product/programming-in-c-
volume-2-composite-data-structures-and-modularization-
zhou-22736722
https://ebookbell.com/product/programming-in-c-volume-2-composite-
data-structures-and-modularization-50338946
https://ebookbell.com/product/ms-course-10266a-programming-in-c-with-
microsoft-visual-studio-2010-trainer-edition-
volume-2-microsoft-2113634
https://ebookbell.com/product/thinking-in-c-volume-2-practical-
programming-us-ed-bruce-eckel-1136612
https://ebookbell.com/product/programming-in-c-volume-1-basic-data-
structures-and-program-statements-xingni-zhou-50339330
Ms Course 10266a Programming In C With Microsoft Visual Studio 2010
Trainer Edition Volume 1 Microsoft
https://ebookbell.com/product/ms-course-10266a-programming-in-c-with-
microsoft-visual-studio-2010-trainer-edition-
volume-1-microsoft-2113632
https://ebookbell.com/product/art-of-computer-programming-
volume-4a-combinatorial-algorithms-part-1-1st-edition-donald-e-
knuth-2226790
https://ebookbell.com/product/programming-in-c-object-oriented-
features-laxmisha-rai-editor-china-science-publishing-media-ltd-
editor-51127748
https://ebookbell.com/product/programming-in-c-for-engineering-and-
science-1st-edition-nyhoff-55234332
https://ebookbell.com/product/programming-in-c-part-one-introduction-
to-c-leonard-robbie-56204050
Xingni Zhou, Qiguang Miao and Lei Feng
Programming in C
Also of interest
Programming in C, vol. : Basic Data Structures and Program
Statements
Xingni Zhou, Qiguang Miao, Lei Feng,
ISBN ----, e-ISBN (PDF) ----,
e-ISBN (EPUB) ----
C++ Programming
Li Zheng, Yuan Dong, Fang Yang,
ISBN ----, e-ISBN (PDF) ----,
e-ISBN (EPUB) ----
MATLAB® Programming
Dingyü Xue,
ISBN ----, e-ISBN (PDF) ----,
e-ISBN (EPUB) ----
Programming in C++
Laxmisha Rai,
ISBN ----, e-ISBN (PDF) ----,
e-ISBN (EPUB) ----
Xingni Zhou, Qiguang Miao and Lei Feng
Programming in C
Lei Feng
School of Telecommunication Engineering
Xidian University
Xi’an, Shaanxi Province
People’s Republic of China
fenglei@mail.xidian.edu.cn
ISBN 978-3-11-069229-7
e-ISBN (PDF) 978-3-11-069230-3
e-ISBN (EPUB) 978-3-11-069250-1
www.degruyter.com
Contents
1 Arrays 1
1.1 Concept of arrays 1
1.1.1 Processing data of the same type 1
1.1.2 Representation of data of the same type 5
1.2 Storage of arrays 6
1.2.1 Definition of arrays 6
1.2.1.1 Definition of arrays 6
1.2.1.2 Reference of array elements 7
1.2.1.3 Storage characteristics of arrays 8
1.2.1.4 Comparison of variables of the same type with plain
variables 9
1.2.2 Initialization of arrays 10
1.2.2.1 Initialize all elements 10
1.2.2.2 Initialize some elements 11
1.2.2.3 Array size determined by number of initial values 11
1.2.3 Memory layout of arrays 11
1.2.3.1 Memory layout of one-dimensional arrays 11
1.2.3.2 Memory layout of two-dimensional arrays 11
1.2.4 Memory inspection of arrays 12
1.3 Operations on one-dimensional arrays 16
1.4 Operations on two-dimensional arrays 26
1.5 Operations on character arrays 37
1.6 Summary 45
1.7 Exercises 48
1.7.1 Multiple-choice questions 48
1.7.2 Fill in the tables 50
1.7.3 Programming exercises 51
2 Pointers 53
2.1 Concept of pointers 53
2.1.1 Reference by name and reference by address 53
2.1.2 Management of storage space 55
2.1.2.1 Management of computer memory space 57
2.1.2.2 Storage rules of data in memory 58
2.1.2.3 Address management in memory 58
2.1.3 Definition of pointers 60
2.1.3.1 Comparison of pointer variables and plain variables 60
2.1.3.2 Syntax of pointer definitions 61
2.2 Pointer operations 61
2.2.1 Pointer operators 62
VI Contents
3 Composite data 93
3.1 Concept of structures 93
3.1.1 Introduction 93
3.1.2 Storage solution of mixed data table 94
3.1.2.1 Discussion of possible storage solution of mixed data table 94
3.1.2.2 Issues of constructing “combinatorial data” 95
3.1.2.3 Key elements of constructional data 95
3.2 Storage of structures 96
3.2.1 Type definitions of structures 96
3.2.2 Definition of structure variables 98
3.2.3 Structure initialization 99
3.2.4 Memory allocation of structure variables 100
3.2.4.1 Definitions related to structure 100
3.2.4.2 Memory layout of structure variables 100
3.2.4.3 Inspection of memory layout of structure variables 100
3.2.4.4 Data alignment of structures 102
3.2.5 Referencing structure members 105
3.3 Applications of structures 106
3.4 Union 117
3.4.1 Introduction 117
3.4.2 Memory layout of unions 118
3.4.2.1 Union-type definition 118
Contents VII
4 Functions 139
4.1 Concept of functions 139
4.1.1 Introduction 139
4.1.1.1 Modularization and module reuse in practice 139
4.1.1.2 Abstraction of practical problems: independent code
modules 140
4.1.2 Concept of modules 141
4.1.2.1 Coordination problems in teamwork 141
4.1.2.2 Coordination problems in modularization of programs 141
4.1.2.3 Concept of modules 142
4.2 Function form design 143
4.2.1 Methods of communication between modules 143
4.2.2 Function form design 144
4.2.2.1 Analysis of outsourcing structure 144
4.2.2.2 Abstraction of outsourcing structure 145
4.2.2.3 Function form design 145
4.2.2.4 Information transmission mechanism design 146
4.2.2.5 Three syntaxes related to functions 147
VIII Contents
Index 287
1 Arrays
Main contents
– Concept, usage, and available methods of arrays
– Introduction of representation and nature of arrays through comparison between array/
array elements and plain variables
– Storage characteristics and debugging techniques of arrays
– Programming techniques of multidimensional arrays
– Top-down algorithm design practices
Learning objectives
– Know how to define and initialize arrays as well as how to access array elements
– Be able to define and use multidimensional arrays
– Know how to deal with character arrays
Program statements and data construct programs. They are sequences of instruc-
tions created through algorithm design that conform to program control structures.
However, are we able to solve all problems after learning statements, basic data
types, program control structures, and algorithm implementation methods of C?
Let us look at a few problems in practice.
https://doi.org/10.1515/9783110692303-001
2 1 Arrays
Case study 1
Encryption and decryption of Caesar code
Mr. Brown stared at the ciphertext and thought that it would not be hard to design
an algorithm to solve the problem. He could simply shift each character in the ciphertext
by one position in the alphabet and repeat this process 26 times to list all possible plain-
texts, in which the one that is not nonsense would be the real plaintext. A universal al-
gorithm could be designed using this technique to crack ciphertexts of arbitrary length.
– If the length of the ciphertext is 2, we shift letters by one position in the alpha-
bet each time and list all 26 possible plaintexts.
– If the length of the ciphertext is 10, we shift letters by one position in the alpha-
bet each time and list all 26 possible plaintexts.
– If the length of the ciphertext is 100, we shift letters by one position in the al-
phabet each time and list all 26 possible plaintexts.
Discussion: Solving a problem with computers involves two major steps: first, we should use
reasonable data structures to describe the problem to store data into computers; second, we
create algorithms to solve it. To answer the earlier questions, we need to find a mechanism that
describes variables of the same type and handles them consistently.
Code implementation of the algorithm that solves Caesar codes is rather complicated,
so we shall introduce it later. Before that, let us consider a reversed order problem
that is more trivial.
Case study 2
Reversing 100 numbers
We need a way to
represent variables of
X1 X2 X3 ......... Xi .......... X99 X100 the same type so that
they can be processed
consistently
The flow of outputting 100 numbers backward is given in Figure 1.3. The pro-
gram reads the numbers in a loop starting from X1, and outputs them using a loop
starting from X100.
Start
End
01 int main(void )
02 {
03 int i;
04 int x[100];
05 for ( i=1;i<=100; i++) scanf ("%d", &x[i] );
06 for ( i=100; i>=1; i-- ) printf ("%d", x[i] );
07 return 0;
08 }
On line 4, the statement defines 100 variables with subscripts of type int. It is more
convenient to “batch” define variables of the same type.
It is worth noting that the starting subscripts on line 5 and line 6 do not follow
the convention of using C arrays exactly.
4 1 Arrays
Subscripts of arrays start from 0 in C. Here, we are trying to make the flow more
intuitive by not following this rule.
Case study 3
Simple table processing
i 0 1 2 3 4 5
grade[i] 80 82 91 68 77 78
Pseudo code
Store grades in int grade[6]
Total score total = 0; Counter i = 0;
while i < 6
total= total+grade[i];
i++;
Average= total / 6
We use a while loop to add each grade[i] to total grade total. The value of i increases
in each iteration so that all variables are handled.
It is clear that the algorithm is trivial as long as we find a way to store and rep-
resent data of the same type. This also shows that the way data are organized and
represented is a crucial issue when solving problems with computers.
Case study 4
Complex table processing
We can use a for loop to process grades for a single student and use another
one to calculate average grades for all of them. The algorithm and code implemen-
tation will be given in the section of two-dimensional arrays.
The discussion earlier showed that a new mechanism is necessary to handle data of
the same type. With respect to data representation and processing, arrays are a
data structure that regularly expresses data so that they are processed regularly.
Since arrays are collections of variables whose names have a pattern, they are sup-
posed to have features of variables. Figure 1.6 compares arrays with plain variables.
During the definition of a plain variable, the system allocates memory according to
its type specified by programmers. The definition of an array consists of type, name
and, in particular, the number of variables in the array.
There are multiple variable values in an array, so they should be stored in mul-
tiple storage units, whose sizes depend on types of the variables. The size of a stor-
age unit is measured in bytes and can be computed using the sizeof operator.
Besides, a referencing method of the address of a storage unit is necessary so
that programmers can inspect the unit.
We can infer from the examples earlier that the referencing method of variable
values in an array is to use the array name with an index.
Moreover, we should be able to initialize an array since we can do the same
with plain variables. Hence, a corresponding syntax is necessary.
There are four issues related to array storage, namely definition, initialization, mem-
ory allocation, and memory inspection.
Arrays
E.g.
Number of Number of Memory size
Definition Type Name
dimensions variables
int x[ 100 ] int x 1 100 100* sizeof(int)
char c[2][3] char c 2 2*3 2*3* sizeof(char)
In the figure above, the first row defines a one-dimensional integer array x with 100
variables. To compute the size of its memory space, we can obtain the size of its
type using the sizeof operator and multiply it with the number of variables. The second
row defines a two-dimensional character array with two rows and three columns. In
other words, it has six variables in total. The array name is c.
Think and discuss Do contents inside square brackets in an array definition and an element ref-
erence refer to the same thing?
Discussion: The index of an array element is a numerical expression, which indicates the posi-
tion of the element in an array; the object inside square brackets in an array definition has to
be a constant, which indicates the number of elements in the corresponding dimension. It is
worth noting that the number of elements must not be a variable. Like plain variables, arrays
obtain memory space from the system during array definition. The size of the allocated space
does not change during execution once the array is defined. Such a way of memory utilization
and management is called static memory allocation. On the other hand, C also provides “dy-
namic memory allocation,” which will be introduced in examples in chapter “Functions”.
Indices of array elements in C must start from 0. Accessing an array out of bound leads to a
logic error, but it is not a syntax error.
For example, the one-dimensional array x defined in Figure 1.8 has 100 elements with an
index range 0 to 99. If we try to access an element outside this range, we are accessing the
array out of bound. Grammatically, it is equivalent to using undefined variables.
Array elements
E.g.
Definition Index range Correct usage Out of bound examples
int x[ 100 ] [0]~[99] x[0], x[6], x[99] x[-1], x[100]
The reason that out-of-bound errors are not syntax errors is that the compiler will not check whether
the index is valid. As a result, programmers should take care of indices when using arrays.
8 1 Arrays
Having learned how to define arrays and how to reference array elements, we can
complete the program for number reversing problem.
01 int main(void )
02 {
03 int i;
04 int x[100]; // Array definition
//x[i] references array elements, the index is an expression
05 for ( i=0;i<100; i++) scanf ("%d", &x[i] );
06 for ( i=99; i>=0; i-- ) printf ("%d", x[i] );
07 return 0;
08 }
Line 4 contains definition of an array. Note how we reference array elements on line
5 and line 6.
Indices in square brackets on line 5 and 6 are variables, which are special forms
of expression. They start from 0 and end at 99.
Grammatically, the index of an array element should be a numerical expression
and the index of the first element of an array must be 0.
We can modify the keyboard input part in the code implementation of the number
reversing problem so that the array is initialized with values. The revised program
is as follows:
01 int main(void )
02 {
03 int i; //Defines an array and initializes array elements
04 int x[10]={1,2,3,4,5,6,7,8,9,10};
05 //for ( i=0;i<10; i++) scanf ("%d", &x[i] );
06 for ( i=9; i>=0; i-- ) printf ("%d", x[i] );
07 return 0;
08 }
Statement on line 4 defines the array and initializes array elements, so the keyboard
input assignment can be skipped.
What is the advantage of initializing an array? If we have to debug the program
multiple times, it is more efficient to initialize the array than typing in numbers
repeatedly.
Array initialization defines an array and initializes its elements at the same time.
There are three ways to initialize an array in C, as shown in Figure 1.11.
Array initialization
An array initialization defines an array and initializes its elements at the same time
int n[ ] = {1,3,5,7,9} 5
Array size determined by
3 String termination mark ‘\0’
number of initial values char c[ ] =“abcde”; 6
is also an element
three columns, so it consists of six elements. Note that how curly brackets are used
when assigning all six values.
the beginning position of the 0th row and a[1] denotes the beginning position of the
first row.
C defines that the one-dimensional form of a two-dimensional array which de-
notes “row address”.
With the help of IDE, we can inspect how arrays are stored in the memory. We shall
start from cases where arrays are initialized. The program is as follows:
On line 6, we define an integer array m of size 5 and initialize it. If we type in the
array name m in the Watch window, we can see the beginning address of the array
and values of each element, as shown in Figure 1.14.
m n c
x a
String termination
mark \‘0’ is
automatically
inserted by the
system
On line 7, we define an integer array n without specifying the size and initialize it
with four initial values. We can see that 4 memory units are allocated to it.
On line 8, we define an integer array x of size 8 and partially initialize it. It is
clear that the uninitialized elements are set to 0 by the system.
On line 9, we define a character array c without specifying the size and initialize
it with a string of five characters. The system allocates six storage units, where the
last one has value 0. This is the string termination mark inserted by the system
automatically. It also takes up one storage unit.
On line 10, we define a 2 by 3 two-dimensional array a and initialize it. Each row
of the array has a beginning address, where the address of the first row is also the
beginning address of the entire array.
14 1 Arrays
0 1 2 Row i 0 1
a[0] → 0 1 3 5 Column j 0 1 2 0 1 2
a[1] → 1 2 4 6 a[i][j] 1 3 5 2 4 6
Similarly, int a[2][3] takes up a continuous block of memory with size 6*4 bytes, as
shown in Figure 1.17.
Note that the array name refers to the address of the entire array, which is also the
beginning address of the array.
With rules of storage and elements referencing, we may now process data in
arrays.
16 1 Arrays
2. Algorithm description
We have seen this problem in section “representation of algorithms”, where the scores were
read from keyboard input. Now we can store scores given by referees in an array score[10]. The
algorithm can then be updated accordingly, as shown in Figure 1.18.
In the second refinement, a counter i is used to record the number of comparisons. Variable
Largest is initialized with score[0]; then, Largest is compared with score[i] repeatedly and up-
dated with the larger value in the loop body. Once the loop is done, Largest is printed.
3. Code implementation
01 //Finding the maximum number in an array
02 #include <stdio.h>
03 #define SIZE 10
04
05 int main(void)
06 {
07 int score[SIZE]
08 = {89,92,97,95,90,96,94,92,90,98};
09 int i; //Counter
10 int Largest =score[0]; //Initialize Largest with score [0] as a comparison basis
11 for ( i = 0; i < SIZE; i++ )
12 {
13 if (Largest < score[i])
14 Largest=score[i]; //Find the maximum
15 }
16 printf( "The highest score is %d\n", Largest );
17 return 0;
18 }
1.3 Operations on one-dimensional arrays 17
Program result:
The highest score is 98
Note: the score array is initialized on line 8 so that testing becomes easier.
On lines 11–15, the for loop finds the largest value and stores it in variable Largest.
Based on this program, it is trivial to write a program that finds the minimum number. Now we
can discard both the highest score and the lowest score by replacing them with 0.
4. Debugging
One should carefully design test cases for inspection or verification. Critical points in the de-
bugging of the earlier program are shown in Figure 1.19.
Debugging
plan 11 for ( i= 0; i< SIZE; i++ )
12 {
– Inspect memory layout of 1-d array
13 if (Largest < score[i])
– Reference of array elements
14 Largest=score[i];
– Use breakpoints to find required values quickly
// Find the maximum
15 }
Figure 1.20 shows the score array in the Watch window. There are 10 elements, each of which
are initialized with an initial value. The maximum value Largest is initialized with the value of
score[0], which is 89.
In Figure 1.21, the condition of if statement in the for loop evaluates to false when i = 0, so
Largest keeps unchanged.
18 1 Arrays
In Figure 1.24, we insert a breakpoint in the line pointed by the yellow arrow to inspect pro-
gram execution conveniently. Using the Go command, we can interrupt the program at this
statement whenever the condition of if statement evaluates to true. Here i = 2 and score[2] has
value 97, which is larger than the value of Largest, 92.
In Figure 1.25, we execute the Go command and the program pauses again. Now, i = 9 and
score[9] has value 98, which is larger than the value of Largest, 97.
20 1 Arrays
In Figure 1.26, the loop terminates and the final value of Largest is 98.
[Analysis]
1. Algorithm design
The algorithm is shown in Figure 1.27. Code implementation can be easily adapted from the pseudo
code in the second refinement.
1.3 Operations on one-dimensional arrays 21
After eliminating the highest score and the lowest score, we can compute the total score that
complies with the scoring rule.
2. Code implementation
01 //Compute sum of array elements
02 #include <stdio.h>
03 #define SIZE 10
04
05 int main(void)
06 {
07 int score[ SIZE ] = {98,92,89,95,90,96,94,92,90,97};
08 int i; //counter
09 int total = 0; //sum
10
11 for ( i = 0; i < SIZE; i++ )
12 {
13 total +=score[ i ]; //Compute sum of array elements
14 }
15 printf( "The total score is %d\n", total );
16 return 0;
17 }
Program result:
The total score is 933
[Analysis]
1. Algorithm analysis
Let low denote the position of the minimum value in the searching range, and high denote the
position of the maximum value in the searching range. The comparison position in binary search
is then mid = (low + high)/2. Comparing key value with the element at position mid yields one of
the following results:
– Equal: the element at position mid is what we are looking for.
– Greater: we will look for the element in the lower range by setting low = mid + 1.
– Less: we will look for the element in the higher range by setting high = mid – 1.
22 1 Arrays
Figures 1.28 and 1.29 illustrate processes of finding values 19 and 66.
Search for
19
R[] 5 10 19 21 31 37 42 48 50 55
Position 0 1 2 3 4 5 6 7 8 9
R[] 5 10 19 21 31 37 42 48 50 55
Position 0 1 2 3 4 5 6 7 8 9
Search for
66
R[] 5 10 19 21 31 37 42 48 50 55
Position 0 1 2 3 4 5 6 7 8 9
R[] 5 10 19 21 31 37 42 48 50 55
Position 0 1 2 3 4 5 6 7 8 9
R[] 5 10 19 21 31 37 42 48 50 55
Position 0 1 2 3 4 5 6 7 8 9
low mid
Now mid=9, R[mid].key=55<k, we proceed in range
R[10…9].Because low>high, the search failed.
2. Code implementation
#include <stdio.h>
#define N 10
int main(void)
{
int a[N]={5,10,19,21,31,37,42,48,50,55};
int low=0, high=N-1,mid;
int key;
int flag=0; //Search flag, 0=fail, 1=success
printf("Please enter number to search:");
scanf("%d",&key);
while (low<=high) //Search range is not empty
{
mid = (low+high+1)/2;
if (a[mid]== key) //Match
{
flag=1;
break;
}
else
{
if (a[mid]> key) high = mid-1; //Continue searching in lower range
else low = mid+1; // Continue searching in higher range
}
}
if (flag==1)
printf("Search succeeded, index of %d is %d\n",key,mid);
else
printf("Search failed\n");
return 0;
}
[Analysis]
1. Data structure design
Since indices and values in the Fibonacci sequence are 1-to-1 corresponded, we can store values
into a one-dimensional integer array, which will be represented by int f[20] in this example.
2. Algorithm design
We shall construct the first 20 entries based on the recurrence equation of the Fibonacci se-
quence, store them into the array and eventually output them.
24 1 Arrays
3. Code implementation
1 //Find first 20 entries in Fibonacci sequence
2 #include <stdio.h>
3 int main(void)
4 {
5 int i;
6 int f[20]={0, 1}; //Array initialization
7
8 for (i=2; i<20; i++) //Generate the sequence
9 {
10 f[i]=f[i-1]+f[i-2]; //Recurrence equation of Fibonacci equation
11 }
12 for (i=0; i<20; i++) //Output array elements
13 {
14 if (i%5==0) printf("\n"); //Print 5 entries on each line
15 printf("%8d", f[i]);
16 }
17 return 0;
18 }
Program result:
0 1 1 2 3
5 8 13 21 34
55 89 144 233 377
610 987 1597 2584 4181
4. Program analysis
We shall analyze characteristics of iterated data processing by reading the program.
Lines 8–11 insert values into the Fibonacci array. Let the index be i, which corresponds to
array element f[i]. We can construct a table for them and fill in it with their values, as shown in
Figure 1.31. In addition to dynamic tracing and debugging, a static approach like this can also
help us analyze patterns in program execution. Note that indices start from 0, so the index of
the last element should be one less than the array size.
1.3 Operations on one-dimensional arrays 25
Index i 0 1 2 3 4 5 … 18 19 20
f[i] 0 1 2 3 5 8 … … … …
5. Discussion
(1) What if we do not initialize array f?
Discussion: If so, values of f[0] and f[1] will be arbitrary values, so further computation
will be wrong.
(2) How can we construct the Fibonacci sequence of arbitrary size?
Discussion: We can make the array size a symbol constant, so the program can be easily
adapted.
(3) What if we change the execution condition of the first for loop (line 8) to i ≤ 20?
Discussion: An out-of-bound error will happen because we are going to write to f[20],
which is not in the range of the array. This is a logic error in the program.
1. Algorithm description
Let the ratings array be rating[ ]. It records number of occurrences of each score. The index i can
be computed by subtracting 6 from score x (6 ≤ x ≤ 10), that is, i = x–6, so we can use values
score–6 as indices of the ratings array. Whenever we find a new occurrence of a certain score,
we add one to the corresponding array element.
2. Code implementation
1 #include<stdio.h>
2 #define RESPONSE_NUM 50 //Size of review array
3 #define RATING_SIZE 5 //Size of ratings array
4
5 int main(void)
6 {
7 int answer; //Counter
8 int counter;
9
10 int rating[RATING_SIZE]={0}; //Rating array
11 int responses[RESPONSE_NUM] //Review array that stores students’reviews
12 ={ 6,8,9,10,6,9,8,7,7,10,6,9,7,7,7,6,8,10,7,
13 10,8,7,7,6,7,8,9,7,8,7,10,6,7,6,7,7,10,8,
14 6,7,7,8,6,6,7,8,9,7,7,10
15 };
16
26 1 Arrays
Program result:
Rating Number of occurrences
6 10
7 19
8 9
9 5
10 7
[Analysis]
1. Data description
As shown in Figure 1.32, we can store the scores in a two-dimensional array.
Essentially, this problem is equivalent to finding the maximum value in a two-dimensional
array with N rows and M columns and its row and column indices. To do this, we can simply
repeat the process of finding the maximum value in a one-dimensional array N times.
Figure 1.33 shows how row and column indices change when traversing the array in a row-
first manner. We first traverse row 0, with column index changing from 0 to M–1. Then we tra-
verse row 1, with column index changing from 0 to M–1 as well. We repeat this process until we
reach row N–1.
1.4 Operations on two-dimensional arrays 27
Group Grade
1 80 77 75 68 82 78
2 78 83 82 72 80 66
3 73 50 62 60 91 72
Column
0 1 2 3 4 5
Row
0 80 77 75 68 82 78
1 78 83 82 72 80 66
2 73 50 62 60 91 72
2. Algorithm description
Figures 1.34 and 1.35 show the pseudo code of the algorithm.
3. Code implementation
We can write the code based on the second refinement, in which we use for statements to
implement while loops. The complete code is as follows:
01 #include <stdio.h>
02 #define N 3
03 #define M 6
04
05 int main(void)
06 {
07 int i,j,max,line,col;
08 int a[N][M]= { {80,77,75,68,82,78},
09 {78,83,82,72,80,66},
10 {73,50,62,60,91,72}
11 };
12 max=a[0][0];
13 line=col=0;
14 for (i=0; i<N; i++)
15 {
16 for ( j=0; j<M; j++)
17 {
18 if (max<a[i][j])
19 {
20 max=a[i][j];
21 line=i;
22 col=j;
23 }
24 }
25 }
26 printf("max=%d\t line=%d\t col=%d\n",max,line,col);
1.4 Operations on two-dimensional arrays 29
27 return 0;
28 }
Program result:
max=91 line=2 col=4。
4. Debugging
Based on the characteristics of two-dimensional arrays and key points of this problem, we
designed a few test cases for debugging, as shown in Figure 1.36.
18 if(max<a[i][j])
Debugging 19 {
plan 20 max=a[i][j];
• Inspect memory layout of 2-d array 21 line=i;
• Pattern of row and column indices 22 col=j;
• Use breakpoints to find required values quickly 23 }
Figure 1.36: Key points of debugging the program that finds maximum value in a two-dimensional
array.
One may notice that the row addresses of a two-dimensional array are represented in the form of
a one-dimensional array in the IDE debugger, as shown in Figure 1.37. To traverse the entire array,
we traverse every column for each row. Note that a two-dimensional array is stored row by row in
memory (each row as a one-dimensional array).
Address Row 0 1 2 3 4 5
a[0] 0x18feec 0 80 77 75 68 82 78
a[1] 0x18ff04 1 78 83 82 72 80 66
a[2] 0x18ff1c 2 73 50 62 60 91 72
As shown in Figure 1.38, we insert one breakpoint to the line where the current maximum
value is updated and to the line where the result gets printed. When the program enters the
first loop, as shown in Figure 1.39, the 0th element of the array is selected as the comparison
basis, whose value is a[0][0] = 80. In Figure 1.40, the program pauses after we execute the Go
command. The value of the element with index i = 0 and j = 4 is 82, which is larger than max.
Figure 1.38: Debugging the program that finds maximum in two-dimensional array 1.
Figure 1.39: Debugging the program that finds maximum in two-dimensional array 2.
1.4 Operations on two-dimensional arrays 31
Figure 1.40: Debugging the program that finds maximum in two-dimensional array 3.
In Figure 1.41, the program pauses after we execute the Go command. The value of the element
with index i = 1 and j = 1 is 83, which is larger than max.
Figure 1.41: Debugging the program that finds maximum in two-dimensional array 4.
In Figure 1.42, the program pauses after we execute the Go command. The value of the element
with index i = 2 and j = 4 is 91, which is larger than max.
Figure 1.42: Debugging the program that finds maximum in two-dimensional array 5.
In Figure 1.43, the program completed scanning the array, and the loop is terminated. Now, i = 3,
j = 6, and the maximum value of the array is max = 91.
32 1 Arrays
Figure 1.43: Debugging the program that finds maximum in two-dimensional array 6.
Outer loop F
condition
T
1 for(i=0;i< N;i++)
2 { Inner loop F
3 for( j=0;j< M;j++) condition
4 { T
5 if (max<a[i][j])
Outer Inner loop body
6 { max=a[i][j]; Inner loop
7 line=i; loop
Inner loop
8 col=j;}
increment
9 }
10 } Outer loop
increment
1. Algorithm description
The program uses random functions srand and rand to generate positions at which moles ap-
pear. The following Whac-A-Mole program has a 3 by 3 “ground” and treats user input coordi-
nates as positions the mallet hits. Although it is a console program and has a simple user
interface, the way it works is the same as a Whac-A-Mole game with beautiful graphics.
2. Code implementation
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//To simplify the code, we omitted curly brackets for some of the if-else statements
int main(void)
{
int times = 0; //Number of chances
int mousey = 0; //Row index of the mole
int mousex = 0; //Column index of the mole
int posy = 0; //Row index of the mallet
int posx = 0; //Column index of the mallet
int hits = 0; //Number of hits
int missed = 0; //Number of misses
int num = 0, row = 0, col = 0;
srand(time(0));
//Obtain game chances
printf("How many times do you want to play?:");
scanf("%d", ×);
//Print the map
printf("***\n***\n***\n");
printf("Mallet position input should be row index followed by column index, separated by
space\n");
//Actual game process
for (num = 1;num <= times;num++)
{
//Obtain position of mole and mallet
mousey = rand() % 3 + 1;
mousex = rand() % 3 + 1;
do
{
printf("Enter mallet position:");
scanf("%d %d", &posy, &posx);
} while (posy < 1 || posy > 3 || posx < 1 || posx > 3);
//Update number of hits and misses
if (mousey == posy && mousex == posx) hits++;
else missed++;
//Print the map
for (row = 1;row <= 3;row++)
{
for (col = 1;col <= 3;col++)
{
34 1 Arrays
[Analysis]
1. Data analysis
We shall first use the given information to eliminate the wrong answers.
Based on conditions 1, 2, and 3, we can conclude that A is not American, E is not Russian,
and C is not German. Based on occupation limits (A and the German have different jobs, so do E
and the American, E and the German, C and the American, and C and the Russian), it is clear
that A is neither Russian nor German, E is neither American nor German, and C is neither
American nor Russian.
It can be inferred from conditions 4 and 5 that neither B nor F is German, A is not French, and
C is not Italian.
Given condition 6, we know B is neither American nor French (because B and the French are
going to different cities next week), and C is not French.
To sum up:
A: A is not American, Russian, German, or French.
B: B is not German, American, or French.
C: C is not German, American, Russian, Italian, or French.
D: no information.
E: E is not American or German.
F: F is not German.
1.4 Operations on two-dimensional arrays 35
We can store the earlier information into matrix a, and country names into another one-
dimensional array countries, as shown in Figure 1.45.
Rows of matrix a represent these guests, while columns represent their home countries. The
0th row is a special row for progress flags, which is either 1 for not processed or 0 for proc-
essed. The values of other elements indicate nationalities. For example, 4 represents Germany
in the countries array. If a value is 0, the person represented by the row does not come from the
country represented by the column.
2. Algorithm design
Following steps 2 and 3 in Figure 1.45, we can find the solution by repeatedly zeroing out rows.
0 1 2 3 4 5 6
Am Br Fr Ge It Ru
1
Column data process flag
0 1 1 1 1 1 1
1: not processed, 0:processed
1 A 0 2 0 0 5 0
2 B 0 2 0 0 5 6
3 C 0 2 0 0 0 0 3
5 E 0 2 3 0 5 6
6 F 1 2 3 0 5 6
2
Find a column y with only one non-zero element
Counter num=1, row index x=4, column index y=4
0 1 2 3 4 5 6
American British French German Italian Russian
3. Code implementation
#include<stdio.h>
char *countries[7]={" ","American","British","French","German","Italian","Russian"};
//The asterisk before countries indicates that the array stores addresses,
//which are beginning addresses of strings
int main(void)
{
int a[7][7],i,j,k,num,x,y;
for(i=0;i<7;i++) //Initialize the matrix
for(j=0;j<7;j++) a[i][j]=j; //Row for person, column for country,
//and value for nationality
for(i=1;i<7;i++) a[0][i]=1; //0-th element in each column is the progress mark,
//1 means not processed
//Enter know information, 0 means the person is not from a country
a[1][1] = a[1][3] = a[1][4] = a[1][6] = 0; // A is not American, Russian, German or French
a[2][1]= a[2][3]= a[2][4] =0; // B is not German, American or French
a[3][1] = a[3][3] = a[3][4]= a[3][5] =a[3][6] = 0;
// C is not German, American, Russian, Italian or French
36 1 Arrays
Program result:
A is Italian
B is Russian
1.5 Operations on character arrays 37
C is British
D is German
E is French
F is American
Index 0 1 2 3 4 5 6 7 8 9 ... 18 19
Registered
'a' 'b' 'c' '2' '4' '6' '8' '0'
password
[Analysis]
1. Storage structure of data
If we use character arrays to store passwords, there are two possible ways to assign initial val-
ues: the first is to assign characters one by one, while the other is to assign a string. Characters
stored in these two approaches are the same, but termination mark ‘\0’ will be automatically
inserted to the end of the string by the system, as shown in Figure 1.47.
Storage
solution 1 char password1[20]={'a','b','c','2','4','6','8','0'};
What is the
Storage difference between
solution 2 char password2[20]="abc 24680";
these two solutions?
Solution 1
Index 0 1 2 3 4 5 6 7 8 9 ... 18 19
Registered
password 'a' 'b' 'c' '2' '4' '6' '8' '0'
Solution 2
The string has
Index 0 1 2 3 4 5 6 7 8 9 ... 18 19
termination mark
Registered
password 'a' 'b' 'c' '2' '4' '6' '8' '0' \0
Note: one can store strings of any length in C. When storing strings in character arrays, pro-
grammers need to make sure that the array size is large enough so that the longest string can
fit in; if the string is longer than the array, characters beyond the array bound will override data
after the array in memory.
2. Algorithm description
Figure 1.48 shows the stepwise refined algorithm.
38 1 Arrays
Second refinement
char password[20]; int i=0;
ch=getchar();
while (ch!='\n')
if (ch != password[i])
printf(“Password is wrong");
Jump out of loop
ch=getchar();
i++;
if ( i==strlen(password) )
printf(“Password is correct");
In the second refinement, ch! = ‘\n’ checks whether there are more inputs. The loop control
variable i acts as a counter as well. strlen is a library function that computes string length (not
counting termination mark ‘\0’). To determine whether the entire string has been checked, we
compare i with the string length.
3. Code implementation
01 #include <stdio.h>
02 #include <string.h>
03 int main(void )
04 {
05 int i=0;
06 char ch;
07 char password[20]="abc24680";
08 ch=getchar();
09 while (ch!='\n')
10 {
11 if (ch != password[i]) break;
12 ch=getchar();
13 i++;
14 }
15 if (i==strlen(password)) printf("Password is correct\n");
16 else printf("Password is wrong\n");
17 return 0;
18 }
Note that the header file for library function strlen on line 19 is included on line 2.
1.5 Operations on character arrays 39
Ciphertext Plaintext
Decryption
[Analysis]
1. Data processing
Without loss of generality, we shall use right shift (the alphabet is shifted by one character to its
right each time) in the following discussion. To crack the ciphertext, we can list all 26 possible
results and look for a meaningful string. Figure 1.50 shows the case of shifting by one character.
2. Algorithm description
Figure 1.51 shows the pseudo code of the algorithm.
In the second refinement, ‘\0’ is used to determine whether the entire string has been proc-
essed. Space is represented by a space wrapped with single quotation marks. The shifted ci-
phertext is computed using the formula we derived earlier. When printing strings, a number
indicating the number of characters shifted is added to the beginning. Finally, we need to find a
meaningful string in printed contents manually.
3. Code implementation
01 #include "stdio.h"
02 #define SIZE 80
03 int main(void)
04 {
05 char ciphertext[SIZE]="lettc fmvxlhec hehhc pszi csy";
06 int i=0,j=0;
07 printf( "%s\n",ciphertext);
08 while (j<26)
09 {
Second refinement
while(j<26)
while(ciphertext[i]!='\0') //while not reaching string end
if (ciphertext[i] !=‘ ’) //skipspace
ciphertext[i]=(ciphertext[i]+1-‘a’)%26+‘a’ //right shift by 1
i++ Finally, we need
printf( "%d:%s\n", j, ciphertext ) to manually find
meaningful string
i=0
j++
ebookbell.com