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)
254 Intermediate C Programming
as when passing other types of arguments, such as int and double: A copy of the argument
is passed. The following example shows a separate function for printing Vector objects:
// vector3 .c1
#in clude < stdio .h >2
#in clude < stdlib .h >3
#in clude < string .h >4
#in clude " vector .h "5
void printVe ctor ( Vector v)6
{7
printf (" The vector is (% d, %d , % d) .\ n ", v .x, v .y, v .z) ;8
}9
10
int main ( i n t argc , char * argv [])11
{12
Vector v1 ;13
v1 .x = 3;14
v1 .y = 6;15
v1 .z = -2;16
printV ector ( v1 );17
return EXIT _SUCCES S ;18
}19
Frame Symbol Address Value
printVector
v.z 124 2
v.y 120 6
v.x 116 3
return location 112 line 18
main
v1.z 108 2
v1.y 104 6
v1.x 100 3
How do we know that the attributes are copied? In the following program changeVector
changes the Vector object passed to it. However, inside main, the attributes of v1 are
unchanged.
// vector4 .c1
#in clude < stdio .h >2
#in clude < stdlib .h >3
#in clude < string .h >4
#in clude " vector .h "5
void printVe ctor ( Vector v)6
{7
printf (" The vector is (% d, %d , % d) .\ n ", v .x, v .y, v .z) ;8
}9
10
void change Vector ( Vector v )11
{12
v. x = 5;13
v. y = -3;14
v. z = 7;15
printV ector ( v) ;16
Programmer-Defined Data Types 255
}17
18
int main ( i n t argc , char * argv [])19
{20
Vector v1 ;21
v1 .x = 3;22
v1 .y = 6;23
v1 .z = -2;24
printV ector ( v1 );25
chang eVector ( v1 );26
printV ector ( v1 );27
return EXIT _SUCCES S ;28
}29
The output of this program is:
The vector is (3, 6, -2).
The vector is (5, -3, 7).
The vector is (3, 6, -2).
What really happens when a function’s argument is an object? This can be explained
by showing the call stack before calling changeVector:
Frame Symbol Address Value
main
v1.z 108 2
v1.y 104 6
v1.x 100 3
Calling changeVector pushes a new frame to the call stack. The argument is an object
that has three attributes. The values are copied from the calling function into the new
frame.
Frame Symbol Address Value
changeVector
v.z 124 2
v.y 120 6
v.x 116 3
return location 112 line 27
main
v1.z 108 2
v1.y 104 6
v1.x 100 3
The function changeVector changes the attributes of the object in its own frame.
Frame Symbol Address Value
changeVector
v.z 124 7
v.y 120 3
v.x 116 5
return location 112 line 27
main
v1.z 108 2
v1.y 104 6
v1.x 100 3
When changeVector finishes, the frame is popped and the program resumes at main.
The call stack is shown below:
256 Intermediate C Programming
Frame Symbol Address Value
main
v1.z 108 2
v1.y 104 6
v1.x 100 3
Note that the attributes of v1 are unchanged.
16.3 Objects and Pointers
Is it possible to change an object’s attributes inside a function and keep the changes
even after the function returns? The answer is yes. To do this, we need to use pointers.
// vect orptr . c1
#in clude < stdio .h >2
#in clude < stdlib .h >3
#in clude < string .h >4
#in clude " vector .h "5
void printVe ctor ( Vector v)6
{7
printf (" The vector is (% d, %d , % d) .\ n ", v .x, v .y, v .z) ;8
}9
10
void change Vector ( Vector * p )11
{12
p -> x = 5;13
p -> y = -3;14
p -> z = 7;15
printV ector (* p) ;16
}17
18
int main ( i n t argc , char * argv [])19
{20
Vector v1 ;21
v1 .x = 3;22
v1 .y = 6;23
v1 .z = -2;24
printV ector ( v1 );25
chang eVector (& v1 );26
printV ector ( v1 );27
return EXIT _SUCCES S ;28
}29
At line 11 changeVector’s argument is a pointer:
void change Vector ( Vector * p )11
This means that p is a pointer in the frame of the function changeVector. If you refer
back to Table 4.1, this is the first way of using *. When calling changeVector at line 26,
main must provide the address of a Vector object, i.e., & v1. This is best understood by
showing the call stack:
Programmer-Defined Data Types 257
Frame Symbol Address Value
changeVector
p 116 100
return location 112 line 27
main
v1.z 108 2
v1.y 104 6
v1.x 100 3
Instead of copying the whole object, attribute by attribute, the argument p stores only
the address of the object v1. This is the address of the first attribute.
What is the -> symbol inside changeVector? The -> symbol takes the value at the
address, and then gets the attribute as if applying a . to a structure. Pointers are used with
structures often and C has this special syntax. It is equivalent to saying:
p -> x13
is the same as
(* p) .x13
This dereferences p first, and then applies . for x. Dereferencing is the second way of using
* as explained in Table 4.1. Note that this means -> can only be used on a pointer to a
structure. It is illegal to use it in any other circumstance. If -> is at the left hand side (LHS)
of an assignment, then the attribute is modified (i.e., written). If -> is at the right hand
side (RHS) of an assignment, then the attribute is read. The statement,
p -> x = 5;13
changes the value at address 100.
Frame Symbol Address Value
changeVector
p 116 100
return location 112 line 27
main
v1.z 108 2
v1.y 104 6
v1.x 100 3 5
p -> y = -3;14
changes the value at address 104.
Frame Symbol Address Value
changeVector
p 116 100
return location 112 line 27
main
v1.z 108 2
v1.y 104 6 -3
v1.x 100 5
Why do we need to add * in front of p when changeVector calls printVector? In
changeVector, p is a pointer. However, printVector expects an object because there is
no * in the line:
void printVe ctor ( Vector v)6
In changeVector, adding * in front of p dereferences the pointer, as explained in
Table 4.1. Thus, the object stored at addresses 100–108 is copied to the argument of
printVector. How do we know that the object is copied? In C, arguments are always copied
when passed to functions. If the argument were Vector *, then a copy of the pointer would
258 Intermediate C Programming
be passed. There is no * after Vector in printVector and the argument is an object. As
a result, the object is copied. If v’s attributes are changed inside printVector, then the
changes will be lost when the function finishes. The syntax for using objects is:
If p’s value is an address of an object, use p -> x. It is allowed to put a space before
or after -> but no space can be added between - and >.
If v is an object (not an address), use v.x.
16.3.1 Returning an Object
Can a function return a Vector object? Yes. The following example shows a constructor
function that creates and initializes a new object:
// vector5 .c1
#in clude < stdio .h >2
#in clude < stdlib .h >3
#in clude < string .h >4
#in clude " vector .h "5
Vector Ve ctor_ constr uct ( i n t a , i n t b , in t c)6
{7
Vector v;8
v. x = a;9
v. y = b;10
v. z = c;11
return v ;12
}13
14
void Vector _print ( Vector v )15
{16
printf (" The vector is (% d, %d , % d) .\ n ", v .x, v .y, v .z) ;17
}18
19
int main ( i n t argc , char * argv [])20
{21
Vector v1 = Vecto r_con struct (3 , 6 , -2) ;22
Vecto r_print ( v1 );23
return EXIT _SUCCES S ;24
}25
What is the advantage of creating constructor functions? One good reason is that they
make programs easier to read. The three arguments remind programmers that a Vector
object has three attributes. Constructors should guarantee that all attributes are always
initialized. Uninitialized variables can make your programs behave in surprising ways. Before
calling the constructor, v1 is already on the call stack in the frame of the main function.
When the constructor returns the object, the attributes of v are copied to v1’s attributes
one by one. Then, the constructor’s frame is popped and v does not exist any more.
16.3.2 Objects and malloc
Is it possible to create an object that exists in heap memory, instead of stack memory?
Yes. Here is how to do it:
// ve ctormal l oc . c1