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)
206 Intermediate C Programming
partition
val 106 1
left 105 4
ind 104 0
arr 103 10000
RL 102 line 44
main
arr 101 10000
n 100 4
(a) Stack Memory
Symbol Address Value
arr[3] 10012 1
arr[2] 10008 1
arr[1] 10004 1
arr[0] 10000 1
(b) Heap Memory
Now the value of left is 0 and the terminating condition at line 18 is true. This means
that we have reached a base case, and line 20 calls printPartition and prints the 4
elements in the array. Four elements are printed because ind is 4. Remember, ind gives
the next position to write an element into arr, and it also gives the length of the partition
so far. If you think about it carefully, you will see that these two things are equivalent.
Therefore, we can pass ind as the length of the array to printPartition. The program
now prints:
1 + 1 + 1 + 1
The function then returns because of line 21. The return statement at line 21 is not strictly
necessary, because the function will not call itself again. This is because the for loop starts
at 1 and val must be smaller than or equal to left. Because left is zero the function will
not enter the for loop, and will return normally anyway.
It is good practice to put the line 21 return statement. When people read recursive
functions they expect the functions to be divided neatly into the base case and the recursive
case. The return statement makes the base case clear. Clearly no recursion is going to
happen. No further analysis is required. Making code as clear as possible is one of the most
important parts of good programs. After meeting the terminating condition, the top frame
of the call stack is popped, and the program continues at line 27.
Frame Symbol Address Value
partition
val 121 1
left 120 1
ind 119 3
arr 118 10000
RL 117 line 27
partition
val 116 1
left 115 2
ind 114 2
arr 113 10000
RL 112 line 27
Integer Partition 207
partition
val 111 1
left 110 3
ind 109 1
arr 108 10000
RL 107 line 27
partition
val 106 1
left 105 4
ind 104 0
arr 103 10000
RL 102 line 44
main
arr 101 10000
n 100 4
(a) Stack Memory
Symbol Address Value
arr[3] 10012 1
arr[2] 10008 1
arr[1] 10004 1
arr[0] 10000 1
(b) Heap Memory
For the next iteration, val increments to two. This violates the condition val <= left
and the for loop exists. Since the function has nothing else to do after the for loop, the
top frame is popped. The program now continues at line 27.
Frame Symbol Address Value
partition
val 116 1
left 115 2
ind 114 2
arr 113 10000
RL 112 line 27
partition
val 111 1
left 110 3
ind 109 1
arr 108 10000
RL 107 line 27
partition
val 106 1
left 105 4
ind 104 0
arr 103 10000
RL 102 line 44
main
arr 101 10000
n 100 4
(a) Stack Memory
208 Intermediate C Programming
Symbol Address Value
arr[3] 10012 1
arr[2] 10008 1
arr[1] 10004 1
arr[0] 10000 1
(b) Heap Memory
Now the for loop enters the next iteration: val becomes 2 and the condition val <=
left is satisfied. Line 25 assigns 2 to arr[2] and line 26 calls the function itself again.
Frame Symbol Address Value
partition
val 121 garbage
left 120 0
ind 119 3
arr 118 10000
RL 117 line 27
partition
val 116 2
left 115 2
ind 114 2
arr 113 10000
RL 112 line 27
partition
val 111 1
left 110 3
ind 109 1
arr 108 10000
RL 107 line 27
partition
val 106 1
left 105 4
ind 104 0
arr 103 10000
RL 102 line 44
main
arr 101 10000
n 100 4
(a) Stack Memory
Symbol Address Value
arr[3] 10012 1
arr[2] 10008 1 2
arr[1] 10004 1
arr[0] 10000 1
(b) Heap Memory
Because left is zero, the terminating condition at line 18 is true. The program prints
the first 3 elements (because ind is 3) in arr. So the program prints:
1 + 1 + 2
Line 21 returns and the top frame is popped.
Integer Partition 209
Frame Symbol Address Value
partition
val 116 2
left 115 2
ind 114 2
arr 113 10000
RL 112 line 27
partition
val 111 1
left 110 3
ind 109 1
arr 108 10000
RL 107 line 27
partition
val 106 1
left 105 4
ind 104 0
arr 103 10000
RL 102 line 44
main
arr 101 10000
n 100 4
(a) Stack Memory
Symbol Address Value
arr[3] 10012 1
arr[2] 10008 2
arr[1] 10004 1
arr[0] 10000 1
(b) Heap Memory
The next iteration increments val to 3 but the condition val <= left is not satisfied.
The function exits the for loop. Since the function has nothing else to do after the for
loop, the function returns and the top frame is popped.
Frame Symbol Address Value
partition
val 111 1
left 110 3
ind 109 1
arr 108 10000
RL 107 line 27
partition
val 106 1
left 105 4
ind 104 0
arr 103 10000
RL 102 line 44
main
arr 101 10000
n 100 4
(a) Stack Memory
210 Intermediate C Programming
Symbol Address Value
arr[3] 10012 1
arr[2] 10008 2
arr[1] 10004 1
arr[0] 10000 1
(b) Heap Memory
For the next iteration, val becomes 2 and assigns 2 to arr[1].
Frame Symbol Address Value
partition
val 111 2
left 110 3
ind 109 1
arr 108 10000
RL 107 line 27
partition
val 106 1
left 105 4
ind 104 0
arr 103 10000
RL 102 line 44
main
arr 101 10000
n 100 4
(a) Stack Memory
Symbol Address Value
arr[3] 10012 1
arr[2] 10008 2
arr[1] 10004 1 2
arr[0] 10000 1
(b) Heap Memory
This process may seem tedious. Fortunately, computers are good at tedious work. Please
practice a few times and ensure that you fully understand the changes in the call stack and
heap memory. Then, leave the details to computers.
14.2 Trace Recursive Function Calls
Another way to understand this program is to draw its call tree. A call tree is a graphical
representation of the relationship between function calls. This tree is drawn “inverted” with
the root at the top, and the leaves at the bottom. Consider the following example:
void f1 ()1
{2
f2 () ;3
}4
Fig. 14.1 illustrates the calling relation of the two functions.
Here is another example and Fig. 14.2 shows the calling relations: