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)
340 Intermediate C Programming
{29
printf (" %d\ n" , kval );30
int ind ;31
for ( ind = 0; ind < num ; ind ++)32
{33
printf (" %d\ n" , arr [ ind ]) ;34
}35
}36
int main ( i n t argc , char ** argv )37
{38
i f ( argc < 4)39
{40
return EXIT _FAILUR E ;41
}42
int numInt = ( in t ) strtol ( argv [1] , NULL , 10) ;43
int isValid = ( in t ) strtol ( argv [2] , NULL , 10) ;44
int hasSol = ( in t ) strtol ( argv [3] , NULL , 10) ;45
i f (( numInt < 3) || ( numInt > 31) )46
{47
return EXIT _FAILUR E ;48
}49
i f (( hasSol != 0) && ( hasSol != 1) )50
{51
return EXIT _FAILUR E ;52
}53
i f (( hasSol != 0) && ( hasSol != 1) )54
{55
return EXIT _FAILUR E ;56
}57
srand ( time ( NULL )) ; // set the seed58
int kval = 0;59
int * arr = malloc ( s i z e o f ( i n t ) * numInt );60
int ind ;61
// the array is increasi n g and all elem e nts are distin c t62
arr [0] = rand () % 100;63
for ( ind = 1; ind < numInt ; ind ++)64
{65
arr [ ind ] = arr [ ind - 1] + ( rand () % 10000) + 1;66
}67
i f ( isValid == 0)68
{69
i f (( rand () % 2) == 0)70
{71
// make two elements the same72
arr [ numInt - 1] = arr [0];73
}74
e l s e75
{76
// make an element negative or zero77
arr [0] = - ( rand () % 10000) ;78
}79
Parallel Programming Using Threads 341
// kval irrelevan t when the array is invalid80
kval = rand () % 10000 + 1;81
}82
e l s e83
{84
for ( ind = 0; ind < numInt ; ind ++)85
{86
i f ( hasSol == 0)87
{88
// kval > sum of all el e ments89
kval += arr [ ind ] + 1;90
}91
e l s e92
{93
i f (( rand () % 3) == 1)94
{95
kval += arr [ ind ];96
}97
}98
}99
i f ( kval == 0) // only if hasSol is 1100
{101
kval = arr [0];102
}103
}104
shuff leArray ( arr , numInt ) ;105
printAr r ay ( arr , numInt , kval );106
free ( arr );107
return EXIT _SUCCES S ;108
}109
It is important to understand the value of a test generator. Writing test generators is
often necessary. Creating test cases by hand is really too much work. The main problem of
hand-generated tests is that only a few cases can be produced. As a result, the tests often
miss some important cases.
21.4.2 Sequential Solution
One obvious solution to the subset sum problem is to enumerate each subset of A and
then check each to see if the sum of the elements is k. This will take exponential time since
a set of size n has 2
n
subsets. The number of possible subsets becomes really large. For
example, a set of size 400 has 2
400
subsets; this is more than the number of atoms in the
observable universe.
There is no known “quick” way of solving the subset sum problem. In computer science,
“quick” usually means that there is a polynomial-time algorithm that solves the problem. A
polynomial-time algorithm is an algorithm whose execution time is bounded by a polynomial
function of the input size. For example, if we are searching a linked list for a given value,
then we may need to traverse the entire list. If the list has n elements (the input data) then
the execution time of the search is bounded by a polynomial function of n. For a polynomial
of degree p, the largest term is n
p
. For any constant p > 1, the following statement is true:
342 Intermediate C Programming
lim
n→∞
2
n
n
p
= . (21.1)
This means that the exponential function eventually grows faster than any polynomial.
There is always a value of n such that 2
n
is larger than n
p
, no matter what p is. This can
be proved by using the L’Hospital’s Rule from calculus.
This section asks you to write a program that counts the number of subsets whose sums
are equal to the given value k. Instead of finding a sophisticated algorithm, the section uses
a simple solution that enumerates all subsets (excluding the empty set). The program must
read the value of k and then the set’s elements from a file. After reading the data from the
file, the program checks whether the set is valid. The set is invalid if any element is zero
or negative, or if two elements have the same value. If the set is invalid, then the program
does not attempt to solve the subset sum problem.
If the set is valid, then the program generates all possible subsets of the given set. This
program first calculates the number of possible subsets. If a set has n elements, then there
are 2
n
subsets including the empty set. If each subset is given a number, then the subsets
are numbers between 0 and 2
n
1 inclusively. The empty set is not considered because
k 6= 0, and thus we only need to consider the subsets labeled 1 to 2
n
1. Note that since
each number corresponds to a subset, and we will check to total sum of the numbers in that
subset, we have each number corresponding to a subset sum. The following table explains
how the numbers are related to the subset sums:
Value Sum
1 a
1
2 a
2
3 a
1
+ a
2
4 a
3
5 a
1
+ a
3
6 a
2
+ a
3
7 a
1
+ a
2
+ a
3
8 a
4
.
.
.
.
.
.
2
n
1 a
1
+ a
2
+ a
3
+ ... + a
n
The test generator is restricted to at most 31 elements so that 2
n
can fit in a four-byte
integer. This following is a sample implementation of the sequential program as described
above. First is the main function:
// main . c1
#in clude < pthread .h >2
#in clude < stdio .h >3
#in clude < stdlib .h >4
#in clude " subset s um .h "5
int main ( i n t argc , char * argv [])6
{7
// read the data from a file8
i f ( argc < 2)9
{10
printf (" Need input file name \ n" );11
return EXIT _FAILUR E ;12
}13
FILE * fptr = fopen ( argv [1] , "r ");14
Parallel Programming Using Threads 343
i f ( fptr == NULL )15
{16
printf (" fopen fail \n ");17
return EXIT _FAILUR E ;18
}19
int numInt = cou ntIntege r ( fptr );20
// go back to the beginning of the file21
fseek ( fptr , 0 , SEEK_SET );22
int kval ; // the value equal to the sum23
i f ( fscanf ( fptr , " %d " , & kval ) != 1)24
{25
printf (" fscanf error \n ");26
fclose ( fptr );27
return EXIT _FAILUR E ;28
}29
numInt - -; // kval is not part of the set30
int * setA = malloc ( s i z e o f ( i n t ) * numInt );31
int ind = 0;32
for ( ind = 0; ind < numInt ; ind ++)33
{34
int aval ;35
i f ( fscanf ( fptr , " %d " , & aval ) != 1)36
{37
printf (" fscanf error \n ");38
fclose ( fptr );39
return EXIT _FAILUR E ;40
}41
setA [ ind ] = aval ;42
}43
fclose ( fptr );44
i f ( isV alidSet ( setA , numInt ) == 1)45
{46
printf (" There are %d subsets whose sums are % d\ n" ,47
subsetSum ( setA , numInt , kval ) , kval );48
}49
e l s e50
{51
printf (" Invalid set \n" );52
}53
free ( setA ) ;54
return EXIT _SUCCES S ;55
}56
This main function calls several other functions that are declared in this header file.
// subs e tsum . h1
#i f n d e f SUBSETSU M_H2
#d ef in e SUBS E TSUM_H3
#in clude < stdio .h >4
int subsetE qual ( in t * setA , i nt sizeA , int kval ,5
unsigned int code );6
// return 1 if the subset expressed by the code sums to kval7
344 Intermediate C Programming
// return 0 if the sum is d i fferent from kval8
int subsetSum ( i n t * setA , i nt sizeA , in t kval );9
// the number of subsets in setA equal10
int isValidS e t ( i n t * setA , i nt sizeA ) ;11
// valid if el e m ents are posi t i ve and distinc t12
// return 1 if valid , 0 if invalid13
int countI nteger ( FILE * fptr );14
// how many integers in a file15
// fptr must not be NULL , checked by the caller16
#e ndif17
The functions isValid and countInt should be straightforward:
// isvalid .c1
#in clude < stdio .h >2
int isValidS e t ( i n t * setA , i nt sizeA )3
// valid if every element is p o s itive and dist i nct4
// return 1 if valid , 0 if invalid5
{6
int ind1 ;7
int ind2 ;8
for ( ind1 = 0; ind1 < sizeA ; ind1 ++)9
{10
i f ( setA [ ind1 ] <= 0)11
{12
return 0;13
}14
for ( ind2 = ind1 + 1; ind2 < sizeA ; ind2 ++)15
{16
i f ( setA [ ind1 ] == setA [ ind2 ])17
{18
return 0;19
}20
}21
}22
return 1;23
}24
// countin t . c1
#in clude < stdio .h >2
int countI nteger ( FILE * fptr )3
{4
int numInt = 0; // how many integers5
int value ;6
while ( fscanf ( fptr , " %d" , & value ) == 1)7
{8
numInt ++;9
}10
return numInt ;11
}12
The function subsetSum counts the number of subsets: