287 lines
14 KiB
HTML
287 lines
14 KiB
HTML
<!--startcut ==========================================================-->
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
|
<HTML>
|
|
<HEAD>
|
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
|
<META NAME="GENERATOR" CONTENT="Mozilla/4.07 [en] (X11; I; Linux 2.0.36 i686) [Netscape]">
|
|
<META NAME="Author" CONTENT="James M. Rogers">
|
|
<META NAME="Description" CONTENT="This article is the fifth in a series designed to explore the Standard C library implementation available for Linux">
|
|
<META NAME="Keywords" CONTENT="linux, standard c library, character functions">
|
|
<META NAME="Classification" CONTENT="Second Year Programming">
|
|
<TITLE>The Standard C Library for Linux LG 39</TITLE>
|
|
</HEAD>
|
|
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#0000AF" ALINK="#FF0000">
|
|
<!--endcut ==========================================================-->
|
|
"Linux Gazette...<I>making Linux just a little more fun!</I>"
|
|
<BR>
|
|
<HR>
|
|
<BR>
|
|
<CENTER>
|
|
<H1>
|
|
<FONT COLOR="#800000">The Standard C Library for Linux</FONT></H1></CENTER>
|
|
|
|
<CENTER>
|
|
<H3>
|
|
<FONT COLOR="#000080">Part Five: <stdlib.h> Miscellaneous Functions</FONT></H3></CENTER>
|
|
|
|
<CENTER>
|
|
<H4>
|
|
By <A HREF="mailto:jrogers@u.washington.edu">James M. Rogers</A></H4></CENTER>
|
|
|
|
<HR>
|
|
<P>The last article was on <ctype.h> character handling. This
|
|
article is on <stdlib.h> which contains many small sections: integer
|
|
math, sorting and searching, random numbers, string to number conversions,
|
|
multibyte character conversions, memory allocation and environmental functions.
|
|
Because this library contains so many small yet very important sections
|
|
I want to discuss each of these groups in its own section. An example
|
|
will be given in each section below because these functions are too diverse
|
|
to have a single example for all of them.
|
|
<P>I am assuming a knowledge of c programming on the part of the reader.
|
|
There is no guarantee of accuracy in any of this information nor suitability
|
|
for any purpose.
|
|
<P>As always, if you see an error in my documentation please tell me and
|
|
I will correct myself in a later document. See corrections at end
|
|
of the document to review corrections to the previous articles.
|
|
<P><B><FONT SIZE=+1>Integer Math</FONT></B>
|
|
<UL><TT>#include <stdlib.h></TT>
|
|
<P><TT>int abs(int x);</TT>
|
|
<BR><TT>div_t div(int numerator, int denominator);</TT>
|
|
<BR><TT>long int labs(long int x);</TT>
|
|
<BR><TT>ldiv_t ldiv(long int numerator, long int denominator);</TT></UL>
|
|
<TT>int x</TT>
|
|
<BR><TT>int numerator</TT>
|
|
<BR><TT>int denominator</TT>
|
|
<BR><TT>The long int versions are the same as the three int arguments.</TT>
|
|
<P><TT>abs</TT> returns the absolute value of the argument.
|
|
<BR><TT>div</TT> returns a data structure that contains both the quotient
|
|
and remainder.
|
|
<BR><TT>labs</TT> is the long version of the abs function.
|
|
<BR><TT>ldiv</TT> is the long version of the div function.
|
|
<P>Integer math is math using whole numbers. No fractions.
|
|
This is math from the fourth grade. If you remember the numerator
|
|
is divided by the denominator and the answer is the quotient with the left
|
|
over stuff being the remainder then you have got it. The div_t and
|
|
ldiv_t are structures that hold the quotient and the remainder. These
|
|
structures look like this:
|
|
<P><TT>struct div_t {</TT>
|
|
<BR><TT> int quot;</TT>
|
|
<BR><TT> int rem;</TT>
|
|
<BR><TT>}</TT><TT></TT>
|
|
<P><TT>struct ldiv_t {</TT>
|
|
<BR><TT> long int quot;</TT>
|
|
<BR><TT> long int rem;</TT>
|
|
<BR><TT>}</TT>
|
|
<P>These types are already defined for you in the <stdlib.h> library.
|
|
The <A HREF="rogers_example05a.c">example file</A> shows a few ways to
|
|
use these four functions.
|
|
<P><B><FONT SIZE=+1>String to Number Conversions</FONT></B>
|
|
<UL><TT>#include <stdlib.h></TT>
|
|
<P><TT>double atof(const char *string);</TT>
|
|
<BR><TT>int atoi(const char *string);</TT>
|
|
<BR><TT>long int atol(const char *string);</TT>
|
|
<BR><TT>double strtod(const char *string, char **endptr);</TT>
|
|
<BR><TT>long int strtol(const char *string, char **endptr, int base);</TT>
|
|
<BR><TT>unsigned long int strtoul(const char *string, char **endptr, int
|
|
base);</TT></UL>
|
|
<TT>const char *string</TT>
|
|
<BR><TT>char **endptr</TT>
|
|
<BR><TT>int base</TT>
|
|
<P><TT>atof</TT> is acsii to float conversion.
|
|
<BR><TT>atoi</TT> is ascii to integer conversion.
|
|
<BR><TT>atol</TT> is acsii to long conversion.
|
|
<BR><TT>strtod</TT> is string to double conversion.
|
|
<BR><TT>strtol </TT>is string to long and the string can contain numbers
|
|
in bases other than base 10.
|
|
<BR><TT>strtoul</TT> is the same as strtol, except that it returns an unsigned
|
|
long.
|
|
<P>If you are reading in a number from user input then you will need to
|
|
use these routines to convert from the digits '1' '2' '3' to the number
|
|
123. The easiest way to convert the other way, from a number to a
|
|
string, is to use the sprintf() function.
|
|
<P>The <A HREF="rogers_example05b.c">example program</A> is just a sample
|
|
of use of each of the above commands.
|
|
<P><B><FONT SIZE=+1>Searching and Sorting</FONT></B>
|
|
<UL><TT>#include <stdlib.h></TT>
|
|
<P><TT>void qsort(void *base, size_t num_of_objs, size_t size_of_obj, int
|
|
(*compar)(const void *, const void *));</TT>
|
|
<BR><TT>void bsearch(const void *key, void *base, size_t num_of_objs, size_t
|
|
size_of_obj, int (*compar)(const void *, const void *));</TT></UL>
|
|
<TT>void *base</TT>
|
|
<BR><TT>size_t num_of_objs</TT>
|
|
<BR><TT>size_t size_of_obj</TT>
|
|
<BR><TT>const void *</TT>
|
|
<BR><TT>const void *key</TT>
|
|
<P><TT>qsort</TT> will sort the array of strings using a comparison function
|
|
that you write yourself.
|
|
<BR><TT>bsearch </TT>will search the sorted array using a comparison function
|
|
that you write yourself.
|
|
<P>You do not need to write your own sorting routines yourself. Through
|
|
the use of these functions you can sort and search through memory arrays.
|
|
<P>It is important to realize that you must sort an array before you can
|
|
search it because of the search method used.
|
|
<P>In order to generate the information to have something to sort I combined
|
|
<A HREF="rogers_example05c.c">this
|
|
example</A> with the random number generation. I initialize a string
|
|
array with a series of random numbers and then sort it. I then look
|
|
to see if the string 1000 is in the table. I finally print out the
|
|
sorted array.
|
|
<P><B><FONT SIZE=+1>Memory Allocation</FONT></B>
|
|
<UL><TT>#include <stdlib.h></TT>
|
|
<P><TT>void *calloc(size_t num_of_objs, size_t size_of_objs);</TT>
|
|
<BR><TT>void free(void *pointer_to_obj);</TT>
|
|
<BR><TT>void *malloc(size_t size_of_object);</TT>
|
|
<BR><TT>void *realloc(void *pointer_to_obj, size_t size_of_obj);</TT></UL>
|
|
<TT>size_t num_of_objs</TT>
|
|
<BR><TT>size_t size_of_objs</TT>
|
|
<BR><TT>void *pointer_to_obj</TT>
|
|
<P><TT>free </TT>will free the specified memory that was previously allocated.
|
|
You will core dump if you try to free memory twice.
|
|
<BR><TT>malloc</TT> will allocate the specified number of bytes and return
|
|
a pointer to the memory.
|
|
<BR><TT>calloc </TT>will allocate the array and return a pointer to the
|
|
array.
|
|
<BR><TT>realloc</TT> allows you to change the size of a memory area "on-the-fly".
|
|
You can shrink and grow the memory as you need, be aware that trying to
|
|
access memory beyond what you have allocated will cause a core dump.
|
|
<P>Runtime memory allocation allows you to write a program that only uses
|
|
the memory that is needed for that program run. No need to change
|
|
a value and recompile if you ask for the memory at runtime. Also
|
|
no need to setup arrays to the maximum possible size when the average run
|
|
is a fraction the size of the maximum.
|
|
<P>The danger of using memory this way is that in complex programs it is
|
|
easy to forget to free memory when you are done with it. These "memory
|
|
leaks" will eventually cause your program to use all available memory on
|
|
a system and cause a dump. It is also important to not assume that
|
|
a memory allocation will always work. Attempting to use a pointer
|
|
to a memory location that your program doesn't own will cause a core dump.
|
|
A more serious problem is when a pointer is overwriting your own programs
|
|
memory. This will cause your program to work very erratically and
|
|
will be hard to pinpoint the exact problem.
|
|
<P>I had to write two different examples to demonstrate all the diversity
|
|
of these functions. In order to actually demonstrate their use I
|
|
had to actually program something halfway useful.
|
|
<P>The <A HREF="rogers_example05d.c">first example</A> is a stack program
|
|
that allocates and deallocates the memory as you push and pop values from
|
|
the stack.
|
|
<P>The <A HREF="rogers_example05e.c">second example</A> reads any file
|
|
into the computers memory, reallocating the memory as it goes. I
|
|
left debug statements in the second program so that you can see that
|
|
the memory is only reallocated when the program needs more memory.
|
|
<P><B><FONT SIZE=+1>Environmental</FONT></B>
|
|
<UL><TT>#include <stdlib.h></TT>
|
|
<P><TT>void abort ( void );</TT>
|
|
<BR><TT>int atexit ( void ( *func )( void ) );</TT>
|
|
<BR><TT>void exit ( int status);</TT>
|
|
<BR><TT>char *getenv( const char *string);</TT>
|
|
<BR><TT>int setenv ( const char *name, const char *value, int overwrite
|
|
);</TT>
|
|
<BR><TT>int unsetenv ( const char *name, const char *value, int overwrite
|
|
);</TT>
|
|
<BR><TT>int system ( const char *string );</TT></UL>
|
|
<TT>void</TT>
|
|
<BR><TT>void (*func)(void)</TT>
|
|
<BR><TT>int status</TT>
|
|
<BR><TT>const char *string</TT>
|
|
<BR><TT>const char *name</TT>
|
|
<BR><TT>const char *value</TT>
|
|
<BR><TT>int overwrite</TT>
|
|
<P><TT>abort </TT>causes the signal SIGABORT to be sent to your program.
|
|
Unless your program handles the signal it will exit with an abort error.
|
|
<BR><TT>atexit </TT>will allow you to run a set of function calls upon
|
|
exit from your program. You can stack them up quite a bit, I seem
|
|
to remember that you can have up to 32 of these.
|
|
<BR><TT>exit</TT> will exit your program with the specified integer return
|
|
value.
|
|
<BR><TT>getenv</TT> will return the value of the environmental variable
|
|
specified or a NULL if the environmental variable is not set.
|
|
<BR>setenv will set the specified variable to the specified value, will
|
|
return a -1 on an error.
|
|
<BR>unsetenv will unset the specified variable
|
|
<BR>system will execute the specified command string and return the exit
|
|
value of the command.
|
|
<P>These functions allow you to connect back to the unix environment that
|
|
you ran your program from and set exit values, read the values of environmental
|
|
variables and run commands from within a c program.
|
|
<P>The <A HREF="rogers_example05f.c">example program</A> demonstrates how
|
|
to read an environmental variable and the two different methods of setting
|
|
an environmental variable. Run this program without TESTING being
|
|
set and then run `export TESTING=anything` and run the program again.
|
|
You will notice the difference between the two runs. Also notice
|
|
the order of the atexit() function calls and the order that they are actually
|
|
called when the program does exit. Copy one of the abort() calls
|
|
out before the exit and reexecute the program, when the abort is called
|
|
the atexit() functions are not called.
|
|
<P><B><FONT SIZE=+1>Random Numbers</FONT></B>
|
|
<UL><TT>#include <stdlib.h></TT>
|
|
<P><TT>int rand(void);</TT>
|
|
<BR><TT>void srand(unsigned int seed);</TT></UL>
|
|
<TT>void</TT>
|
|
<BR><TT>unsigned int seed</TT>
|
|
<P><TT>rand</TT> will return a random value between 0 and RAND_MAX.
|
|
<BR><TT>seed </TT>starts a new sequence of psuedo-random numbers.
|
|
<P>The rand function will set the seed to 1 the first time that you call
|
|
rand in your program unless you set it to something else. The sequence
|
|
of numbers that you get from rand will be in the same order if you set
|
|
seed to the same value each time. To get closer to truly random numbers
|
|
you should set the seed to something that won't repeat. time() is
|
|
what I use in the example.
|
|
<P><A HREF="rogers_example05c.c">The example</A> for this section has been
|
|
combined with the sorting and searching.
|
|
<P><B><FONT SIZE=+1>Multibyte Conversions</FONT></B>
|
|
<UL><TT>#include <stdlib.h></TT>
|
|
<BR><TT>int mblen(const char *s, size_t n);</TT>
|
|
<BR><TT>int mbtowc(wchar_t *pwc, const char *s, size_t n);</TT>
|
|
<BR><TT>int wctomb(char *s, wchar_t wchar);</TT>
|
|
<BR><TT>size_t mbstowcs(wchar_t *pwcs, const char *s, size_t n);</TT>
|
|
<BR><TT>size_t mbstowcs(char *s, wchar_t *pwcs, size_t n);</TT></UL>
|
|
This is that new fangled multilanguage character mapping stuff. I
|
|
don't think that I am qualified to write about it yet. I will revisit
|
|
it once I have covered everything else. Or maybe someone else could
|
|
tell us how to use these in everyday programming.
|
|
<P>
|
|
<HR>
|
|
<H4>
|
|
Bibliography:</H4>
|
|
<I>The ANSI C Programming Language, Second Edition</I>, Brian W. Kernighan,
|
|
Dennis M. Ritchie, Printice Hall Software Series, 1988
|
|
<P><I>The Standard C Library</I>, P. J. Plauger, Printice Hall P T R, 1992
|
|
<P><I>The Standard C Library, Parts 1, 2, and 3</I>, Chuck Allison, <I>C/C++
|
|
Users Journal</I>, January, February, March 1995
|
|
<P>STDLIB(3), BSD MANPAGE, <I>Linux Programmer's Manual</I>, 29 November
|
|
1993
|
|
<P> <HR><P>
|
|
<BR>
|
|
<CENTER>
|
|
<H4>
|
|
Previous "The Standard C Library for Linux" Articles</H4></CENTER>
|
|
<A HREF="http://www.linuxgazette.com/issue24/rogers.html"><I>The Standard
|
|
C Library for Linux, stdio.h</I>, James M. Rogers, January 1998</A>
|
|
<BR><A HREF="http://www.linuxgazette.com/issue31/rogers1.html"><I>The Standard
|
|
C Library for Linux, stdio.h</I>, James M. Rogers, July 1998</A>
|
|
<BR><A HREF="http://www.linuxgazette.com/issue32/rogers.html"><I>The Standard
|
|
C Library for Linux, stdio.h</I>, James M. Rogers, August 1998</A>
|
|
<BR><A HREF="http://www.linuxgazette.com/issue38/rogers.html"><I>The Standard
|
|
C Library for Linux, ctype.h</I>, James M. Rogers, March 1999</A>
|
|
|
|
|
|
<!--===================================================================-->
|
|
<P> <hr> <P>
|
|
<center><H5>Copyright © 1999, James M. Robers<BR>
|
|
Published in Issue 39 of <i>Linux Gazette</i>, April 1999</H5></center>
|
|
|
|
<!--===================================================================-->
|
|
<P> <hr> <P>
|
|
<A HREF="./index.html"><IMG ALIGN=BOTTOM SRC="../gx/indexnew.gif"
|
|
ALT="[ TABLE OF CONTENTS ]"></A>
|
|
<A HREF="../index.html"><IMG ALIGN=BOTTOM SRC="../gx/homenew.gif"
|
|
ALT="[ FRONT PAGE ]"></A>
|
|
<A HREF="./ayers2.html"><IMG SRC="../gx/back2.gif"
|
|
ALT=" Back "></A>
|
|
<A HREF="./telgarsky.html"><IMG SRC="../gx/fwd.gif" ALT=" Next "></A>
|
|
<P> <hr> <P>
|
|
<!--startcut ==========================================================-->
|
|
</BODY>
|
|
</HTML>
|
|
<!--endcut ============================================================-->
|