Chapter 7
Programming Problems and Debugging
7.1 Implementing String Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
7.1.1 The C Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
7.1.2 Header File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
7.1.3 mystring.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
7.1.4 Creating Inputs and Correct Outputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
7.1.5 Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
7.1.6 mystring.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
7.1.7 Using const . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
7.2 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
7.2.1 Find Infinite Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
7.2.2 Find Invalid Memory Accesses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
7.2.3 Detect Invalid Memory Accesses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
7.1 Implementing String Functions
This problem asks you to implement several string functions. Even though these func-
tions are already available in the C standard library, it is instructive to learn how these
functions are implemented. You will create your own versions of these functions, without
using the ones from the C library.
7.1.1 The C Library
Many functions are defined in the standard C library. These functions are commonly used
so they are provided in the C language. Programmers do not have to write these functions.
The C library can significantly reduce the amount of work each programmer needs to do.
Examples of these functions include printf, strlen, and strcpy. During linking, gcc adds
the library functions from libc.so. This file is stored at /usr/lib.
Why is C designed in this way? What are the advantages of using library functions?
Improving portability. In computing, portability means running the same program
across different operating systems, such as Linux, Windows, and MacOS. Library
functions handle low-level activities related to hardware, such as reading files from
a disk or sending packets through a network interface. It is better to implement the
hardware-specific details in libraries so that the same program can run on different
computers, as long as the program uses the correct libraries. Usually the source needs
to be recompiled using the compiler on the new machine.
Reusing other programs. Some people take efforts creating functions useful to them-
selves and other people. Good programmers take advantage of well-written libraries.
Libraries can be used to add new features that do not exist in the programming lan-
guage. One example is the OpenCV library for image processing and computer vision.
97
98 Intermediate C Programming
The original C language does not support image processing or any specific computer
vision functionality. OpenCV provides these features as an extension to the language.
If a library is not from the original C language, you need to tell gcc to link to the
library. For example, if a program uses mathematical functions declared in math.h,
-lm needs to be added when linking the object files into an executable program.
Enhancing performance. Libraries are usually well optimized so that programs can
have better performance.
7.1.2 Header File
So far we have seen something like:
#in clude < stdio .h >1
#in clude < stdlib .h >2
#in clude < string .h >3
These lines have been placed at the top of the file, before the main function. The header
files from the C language are stored in the directory /usr/include. What are they, and
why are they necessary? They are part of the header files of the standard C library. These
header files declare useful functions, and must be included before the functions are used.
For example:
If a C file uses the printf function, the file needs to include stdio.h. This is the
header file for standard input and output functions for reading and writing to the
Terminal and files.
If a C file uses EXIT SUCCESS, then the file needs to include stdlib.h because the
symbol EXIT SUCCESS is defined in that header file.
If a C file calls mathematical functions, such as sin or log, then the file needs to
include math.h.
Header files have a .h extension. A header may be used for the following purposes:
Define symbolic constants, for example:
# define MATH_PI 3.141591
# define M AX_LENGTH 502
Declare functions, for example:
int areDist inct ( in t * arr , int len ) ;1
Header files must not contain function implementations (definition).
Define programmer-created data types. We will explore this feature further in Chap-
ter 16.
Include other header files, for example
# include < stdio .h >1
It is very important that header files do not contain any function definitions. That means
that all functions listed in a header file must end in a ; character. If there is a block of code
(statements between { and }), then you will likely run into problems while linking code.
The implementations of functions should be kept in .c files (or libraries), and not in header
files. Header files are included; .c files are compiled and linked. Never include .c files. Pro-
grammers generally write .h and .c files in pairs: The .c file contains the implementation,
and the .h file contains only the function declarations. The first two lines and the very last
line of a header file are usually something like:
Programming Problems and Debugging 99
#i f n d e f FILENAME_H1
#d ef in e FILENA ME_H2
// The rest of the header file3
#e ndif // do not add F I LENAME_H4
The #ifdef is matched with an #endif that appears at the very end of the file.
It is important to replace FILENAME H with the actual name of the file. FILENAME H is a
symbol and can only contain alphanumeric characters and the underscore. Thus program-
mers generally replace the “.” that appears before a file extension with in the symbol.
As a matter of style, symbols are always typed in upper case. The purpose of #ifndef
... #define ... #endif is to prevent multiple inclusion. Sometimes, the same header file is
included multiple times, for example included by two different header files, and both of
them are included by the same .c file. Without this three lines at the very top and the
very bottom, gcc will report an error when the same header file is included multiple times.
Some other languages have no such problems; for example, in Java, the same package can
be imported multiple times.
When a header file is included, if this header file is from the standard C library, or some
library that is installed on the system, then < and > are used to enclose the file name, for
example:
#in clude < stdio .h >1
#in clude < stdilib .h >2
#in clude < math .h >3
When a programmer-defined header file is included, the file name is enclosed by double
quotations, such as:
#in clude " myheader .h "1
7.1.3 mystring.h
This programming problem has a header file called mystring.h and it declares several
string functions:
// mystrin g . h1
#i f n d e f MYSTRING_H2
#d ef in e MYSTRI NG_H3
// Count the number of characte r s in a string .4
// Example : my_st r len (" foo ") should be 3.5
int my_strlen ( const char * str ) ;6
// - --- --- --- --- --- --- --- - --- --- --- --- --- --- --- - --- --- -7
// Count the number of occurre nces of a p a rticular8
// char acter c in a string .9
// Example : my _ countch ar (" foo " , o ) should be 2.10
//11
int my_cou ntchar ( const char * str , char c) ;12
// - --- --- --- --- --- --- --- - --- --- --- --- --- --- --- - --- --- -13
// Convert a string to uppercase . Only alphab etical14
// cha racters should be c o nverted ; numbers and symbols15
// should not be affected . Hint : toupper ( c) is a macro16
// that is the u ppercase ve r s i o n of a character c.17
// Example : char * str = " foobar ";18
// my _ strupper ( foobar ) is " FOOBAR ".19
100 Intermediate C Programming
void my_stru pper ( char * str );20
// - --- --- --- --- --- --- --- - --- --- --- --- --- --- --- - --- --- -21
// Return the pointer to the first o ccurrence of the character22
// If the character is not in the string , return NULL .23
// Example : char * str = " foobar ";24
// my_s trchr ( foobar , b ) is the address of str [3]25
char * m y_strchr ( const char * str , char ch) ;26
#e ndif /* M YSTRING_H */27
Notice that my strlen and my countchar have const for the arguments but
my strupper does not. By adding const in front of an argument, this header file says
the input argument is a constant and cannot be changed inside of the function. This is im-
portant when an argument is a pointer. A pointer’s value is a memory address. Through the
pointer, it is possible to change the value at that memory address. Adding const prevents
a function from making such a change. If the function unintentionally changes the value at
that memory address, gcc will detect that. This is a good strategy in writing programs:
asking gcc to detect unintended changes. The function my strupper has no const because
the input string will be changed: The lowercase letters are changed to the uppercase letters.
7.1.4 Creating Inputs and Correct Outputs
Before writing a program, we should first develop a strategy for testing. To do this we
need test inputs and the correct outputs for those inputs. For this program, we use the
beginning of Albert Einstein’s Nobel speech as the test input:
If we co nsider that part of the theory of re l ativi t y which may1
now adays in a sense be r egard ed as bona fide scient ific knowledge , we2
note two aspects which have a maj or bear ing on this theory . The whole3
deve lopment of the theory turns on the q uesti on of whet her there are4
phy s ically p refer red stat es of motion in N ature ( p hysic al rela tivity5
problem ) . Also , co ncept s and disti nctions are only admis sible to the6
extent that obser vable facts can be assig ned to them without7
amb iguit y ( stipu l ation that conc epts and disti n ctions should have8
meaning ) . This postulate , perta i ning to epistemology , proves to be of9
fund amental i mporta nce .10
11
These two aspects bec ome clear when applied to a special case , e . g.12
to classical mecha nics . Firstly we see that at any point filled with13
matter there exists a p referr ed state of motion , namely that of the14
sub stanc e at the point consid ered . Our pro blem starts howe ver with15
the que stion whether p hysica lly pre ferred states of motion exist in16
ref erenc e to ex tensi ve regions . From the viewpoint of cl assica l17
mec hanic s the answer is in the affir mative ; the physic ally p refer red18
states of motion from the view point of mecha nics are those of the19
ine rtial frames .20
21
This assertion , in co mmon with the basis of the whole of m echan ics as22
it generally used to be descr ibed before the relat ivity theory , far23
from meets the above " sti pulatio n of meani ng ". Motion can only be24
con ceive d as the relat ive motion of bodies . In mechanics , motion25
rel ative to the system of coor d inates is implied when merely mot ion26
is refe rred to . Neve r theless this i n terpreta t i on does not c omply with27
the " stip u lation of meaning " i f the coor dinate system is consi dered28
as something purely imagi nary . If we turn our atte ntion to29
Programming Problems and Debugging 101
expe r imental physics we see that there the coord i nate system is30
inv a riably r eprese n ted by a " pra c ticall y rigid " body . Furthe rmore it31
is assumed that such rigid bod ies can be p ositio ned in rest rela tive32
to one an othe r33
The main function takes three arguments:
1. argv[0] is always the name of the program.
2. argv[1] is a command. It can be one of the three options: “strlen”, “countchar”, or
“strupper”.
3. argv[2] is the name of the input file.
4. argv[3] is the name of the output file.
The main function calls one of the three functions declared in mystring.h. This program
takes the input file and calls the three functions in the following ways:
When argv[1] is “strlen”, we write the length of each line to the output file. For
example, if a line is “development of the theory turns on the question of whether
there are”, then the output is 69. Each line contains an invisible new line character
n’ at the end. This character is the reason why the line ends.
When argv[1] is “countchar”, then the program takes the first character of each line
and counts the occurrence of this character in that line. If a line is “nowadays in a
sense be regarded as bona fide scientific knowledge, we”, the output is 6 because the
character n occurs 6 times in this line.
When argv[1] is “strupper”, the program converts the lowercase characters in the
input file to uppercase. For example, if a line is “These two aspects become clear
when applied to a special case, e.g. to”, then the output is “THESE TWO ASPECTS
BECOME CLEAR WHEN APPLIED TO A SPECIAL CASE, E.G. TO”.
This main function contains some functions that have not been explained yet. Below we
will describe the lines to pay attention to.
// main . c1
#in clude " mystring .h "2
#in clude < stdio .h >3
#in clude < stdlib .h >4
#in clude < string .h >5
#d ef in e LINE_SIZ E 1000 // a line has at most 999 charact ers6
int main ( i n t argc , char * argv [])7
{8
i f ( argc != 4)9
{10
printf (" usage : %s command input output n" , argv [0]) ;11
return EXIT _FAILUR E ;12
}13
14
FILE * infptr = fopen ( argv [2] , "r ");15
i f ( infptr == NULL )16
{17
printf (" unable to open file % s! n" , argv [2]) ;18
return EXIT _FAILUR E ;19
}20
FILE * outfptr = fopen ( argv [3] , " w ") ;21
i f ( outfptr == NULL )22
{23
printf (" unable to open file % s! n" , argv [3]) ;24
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset