Table of Contents for
Intermediate C Programming

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition Intermediate C Programming by Yung-Hsiang Lu Published by CRC Press, 2015
  1. Front Cover
  2. Contents (1/2)
  3. Contents (2/2)
  4. List of Figures (1/2)
  5. List of Figures (2/2)
  6. List of Tables
  7. Foreword
  8. Preface
  9. Author, Reviewers, and Artist
  10. Rules in Software Development
  11. Source Code
  12. I. Computer Storage: Memory and File
  13. 1. Program Execution (1/2)
  14. 1. Program Execution (2/2)
  15. 2. Stack Memory (1/5)
  16. 2. Stack Memory (2/5)
  17. 2. Stack Memory (3/5)
  18. 2. Stack Memory (4/5)
  19. 2. Stack Memory (5/5)
  20. 3. Prevent, Detect, and Remove Bugs (1/2)
  21. 3. Prevent, Detect, and Remove Bugs (2/2)
  22. 4. Pointers (1/6)
  23. 4. Pointers (2/6)
  24. 4. Pointers (3/6)
  25. 4. Pointers (4/6)
  26. 4. Pointers (5/6)
  27. 4. Pointers (6/6)
  28. 5. Writing and Testing Programs (1/4)
  29. 5. Writing and Testing Programs (2/4)
  30. 5. Writing and Testing Programs (3/4)
  31. 5. Writing and Testing Programs (4/4)
  32. 6. Strings (1/3)
  33. 6. Strings (2/3)
  34. 6. Strings (3/3)
  35. 7. Programming Problems and Debugging (1/4)
  36. 7. Programming Problems and Debugging (2/4)
  37. 7. Programming Problems and Debugging (3/4)
  38. 7. Programming Problems and Debugging (4/4)
  39. 8. Heap Memory (1/3)
  40. 8. Heap Memory (2/3)
  41. 8. Heap Memory (3/3)
  42. 9. Programming Problems Using Heap Memory (1/4)
  43. 9. Programming Problems Using Heap Memory (2/4)
  44. 9. Programming Problems Using Heap Memory (3/4)
  45. 9. Programming Problems Using Heap Memory (4/4)
  46. 10. Reading and Writing Files (1/3)
  47. 10. Reading and Writing Files (2/3)
  48. 10. Reading and Writing Files (3/3)
  49. 11. Programming Problems Using File (1/2)
  50. 11. Programming Problems Using File (2/2)
  51. II. Recursion
  52. 12. Recursion (1/4)
  53. 12. Recursion (2/4)
  54. 12. Recursion (3/4)
  55. 12. Recursion (4/4)
  56. 13. Recursive C Functions (1/4)
  57. 13. Recursive C Functions (2/4)
  58. 13. Recursive C Functions (3/4)
  59. 13. Recursive C Functions (4/4)
  60. 14. Integer Partition (1/5)
  61. 14. Integer Partition (2/5)
  62. 14. Integer Partition (3/5)
  63. 14. Integer Partition (4/5)
  64. 14. Integer Partition (5/5)
  65. 15. Programming Problems Using Recursion (1/5)
  66. 15. Programming Problems Using Recursion (2/5)
  67. 15. Programming Problems Using Recursion (3/5)
  68. 15. Programming Problems Using Recursion (4/5)
  69. 15. Programming Problems Using Recursion (5/5)
  70. III. Structure
  71. 16. Programmer-Defined Data Types (1/6)
  72. 16. Programmer-Defined Data Types (2/6)
  73. 16. Programmer-Defined Data Types (3/6)
  74. 16. Programmer-Defined Data Types (4/6)
  75. 16. Programmer-Defined Data Types (5/6)
  76. 16. Programmer-Defined Data Types (6/6)
  77. 17. Programming Problems Using Structure (1/4)
  78. 17. Programming Problems Using Structure (2/4)
  79. 17. Programming Problems Using Structure (3/4)
  80. 17. Programming Problems Using Structure (4/4)
  81. 18. Linked Lists (1/3)
  82. 18. Linked Lists (2/3)
  83. 18. Linked Lists (3/3)
  84. 19. Programming Problems Using Linked List (1/2)
  85. 19. Programming Problems Using Linked List (2/2)
  86. 20. Binary Search Trees (1/4)
  87. 20. Binary Search Trees (2/4)
  88. 20. Binary Search Trees (3/4)
  89. 20. Binary Search Trees (4/4)
  90. 21. Parallel Programming Using Threads (1/5)
  91. 21. Parallel Programming Using Threads (2/5)
  92. 21. Parallel Programming Using Threads (3/5)
  93. 21. Parallel Programming Using Threads (4/5)
  94. 21. Parallel Programming Using Threads (5/5)
  95. IV. Applications
  96. 22. Finding the Exit of a Maze (1/5)
  97. 22. Finding the Exit of a Maze (2/5)
  98. 22. Finding the Exit of a Maze (3/5)
  99. 22. Finding the Exit of a Maze (4/5)
  100. 22. Finding the Exit of a Maze (5/5)
  101. 23. Image Processing (1/3)
  102. 23. Image Processing (2/3)
  103. 23. Image Processing (3/3)
  104. 24. Huffman Compression (1/10)
  105. 24. Huffman Compression (2/10)
  106. 24. Huffman Compression (3/10)
  107. 24. Huffman Compression (4/10)
  108. 24. Huffman Compression (5/10)
  109. 24. Huffman Compression (6/10)
  110. 24. Huffman Compression (7/10)
  111. 24. Huffman Compression (8/10)
  112. 24. Huffman Compression (9/10)
  113. 24. Huffman Compression (10/10)
  114. A. Linux
  115. B. Version Control
  116. C. Integrated Development Environments (IDE) (1/3)
  117. C. Integrated Development Environments (IDE) (2/3)
  118. C. Integrated Development Environments (IDE) (3/3)
Programming Problems Using Recursion 243
printf (" f(% d) = %d , count = %d \n" , val , fv , count );22
return EXIT _SUCCES S ;23
}24
The program prints two values at line 22: fv and count. Their values can be computed
independently. Fig. 15.2 shows one way of computing both using an approach similar to
that shown in Section 14.2.
FIGURE 15.2: Determine the values of fv and count using a graphical illustration of the
calling relations.
The value of fv is 5. The value of count increments every time func is called. The figure
shows that both func and count are called 9 times.
This is a “top-down” approach to computing func. To compute func(4), the program
calls func(3). To compute func(3), func(2) is called. Computing func(4) calls func(2)
three times and each time that happens it needs to call func(1) + func(1). This is inef-
ficient. It would be more efficient if the program remembers the values of func(2) so that
it does not need to be recomputed. The following implementation shows a different way of
computing func. It is a “bottom-up” approach: func(2) and func(3) are computed before
computing func(4). This is more efficient because the program remembers the value of
func(2), and therefore does not need to recompute it.
// bottomu p . c1
#in clude < stdio .h >2
#in clude < stdlib .h >3
int func ( i n t n )4
{5
int * arr ;6
// need n + 1 for arr [ n]7
arr = malloc ( s i z e o f ( i nt ) * (n + 1) );8
arr [0] = 1;9
arr [1] = 1;10
int ind ;11
for ( ind = 2; ind <= n ; ind ++)12
{13
arr [ ind ] = arr [ ind - 1] + arr [ ind / 2];14
}15
int val = arr [ n ];16
free ( arr );17
return val ;18
}19
244 Intermediate C Programming
int main ( i n t argc , char * * argv )20
{21
int val = 4;22
int fv = func ( val );23
printf (" f(% d) = % d\n " , val , fv ) ;24
return EXIT _SUCCES S ;25
}26
Some people mistakenly believe that recursion is slow. This is not true. The problem
is not recursion. The problem is redundant computation: func(2) is recomputed multiple
times. Recursion is fast when it is used correctly. Binary search and quick sort are two
examples. Some problems, such as integer partition, permutations, and combinations can
be solved naturally with recursion. Recursion is particularly helpful when the solution has
some symmetry with smaller solutions. This is indeed the case with all our recursive ex-
amples. Solving these types of problems using for or while loops is more difficult. In each
case working out the required number of iterations is non-obvious, and the implementation
details would be quite complicated. What makes recursion simple is that it is possible to
assume that the simpler cases are already solved. It is only necessary to figure out how to
express a solution in terms of smaller solutions, and then, so long as the base cases are
correct, the whole thing will work. This book puts great emphasis on recursion not because
recursion is always a good strategy, but because recursion is an excellent approach for solv-
ing certain classes of problems. Attempting to solve these problems with other techniques
can be difficult. If you understand recursion, then you can use it when recursion is a good
approach.
15.6 A Recursive Function with a Mistake
Consider the following incorrect implementation of binary search. One line in
binarysearch is incorrect, as marked by a comment. What is the output of this program?
// sear chbug . c1
#in clude < stdio .h >2
#in clude < stdlib .h >3
int binary Search ( i n t * arr , in t key , i n t len ) ;4
#d ef in e ARRAYSIZ E 105
int main ( i n t argc , char * * argv )6
{7
int arr [ ARRAYS I ZE ] = {1 , 12 , 23 , 44 , 65 ,8
76 , 77 , 98 , 109 , 110};9
int ind ;10
for ( ind = 0; ind < ARRAYSIZE ; ind ++)11
{12
printf (" %d\ n" , b inarySe a rch ( arr , arr [ ind ],13
ARRAYSIZE )) ;14
}15
return EXIT _SUCCES S ;16
}17
18
int bina rySear chHel p ( in t * arr , i n t key , in t low , i n t high )19
Programming Problems Using Recursion 245
{20
i f ( low >= high ) /* ERROR : should be >, not >= */21
{22
return -1;23
}24
int mid = ( low + high ) / 2;25
i f ( arr [ mid ] == key )26
{27
return mid ;28
}29
i f ( arr [ mid ] > key )30
{31
return bin arySe archHe lp ( arr , key , low , mid - 1) ;32
}33
return bin arySe archHe lp ( arr , key , mid + 1 , high );34
}35
36
int binary Search ( i n t * arr , in t key , i n t len )37
{38
return bin arySe archHe lp ( arr , key , 0 , len - 1) ;39
}40
The program searches the array’s elements one by one. If binarySearchHelp were cor-
rect, the program would print:
0
1
2
3
4
5
6
7
8
9
When searching for 1, the arguments low and high change as shown in the following:
low high mid arr[mid] key
0 9 4 65 1
0 3 1 12 1
0 0 0 1 1
The problem occurs when low and high are both zero and binarySearchHelp re-
turns 1 without checking whether arr[mid] is the same as key. Does this mistake cause
binarySearchHelp to always return 1? Consider searching for 12:
low high mid arr[mid] key
0 9 4 65 12
0 3 1 12 12
The function correctly returns 1. What will the function return when searching for 23?
246 Intermediate C Programming
low high mid arr[mid] key
0 9 4 65 23
0 3 1 12 23
2 3 2 23 23
The function correctly returns 2. The program’s output is:
-1
1
2
-1
4
5
-1
7
8
-1
As you can see, this program sometimes produces correct results and sometimes produces
incorrect results. This program has a 60% chance of producing correct results. This reinforces
the need to have a strategy for testing. It is usually important to automate testing so that
you can test many cases easily. A common mistake among beginning programmers is that
they test several cases and then believe their programs are correct.