The <stdlib.h> header file
This header file contains the following functions:
abort abs alloca atexit
atof atoi atol bsearch
calloc div exit fabs
free labs ldiv malloc
max min qsort rand
random randomize realloc srand
strtol strtoul
and the following constants and predefined types:
atexit_t div_t ldiv_t NULL
RAND_MAX size_t
Functions
Absolute value of a number.
abs returns the absolute value of a numeric argument x, which may be either an integer
or a floating point value. The returned value is of the same type as the argument.
See also labs and fabs.
NOTE: abs is a smart macro which compiles to an open code, which depends of the type of the
argument.
Absolute value of a long integer number.
labs returns the absolute value of (long) integer argument x. See also abs
and fabs.
NOTE: labs is built-in function in GCC compiler itself, and it compiles to the open code instead of
function call.
Absolute value of a floating point number.
fabs returns the absolute value of floating point argument x. See also abs
and labs.
Minimum of two integer values.
min is an inline function (implemented using GNU C smart macros) which returns the smaller of
a and b. They may be any numeric values, either integer or floating point
numbers, and they also may be pointers to the same base type. The result has the type of the
argument which has greater range of possible values (e.g. if one is float and second one is
long int, the result is of float type).
Maximum of two integer numbers.
max is an inline function (implemented using GNU C smart macros) which returns the greater of
a and b.
They may be any numeric values, either integer or floating point
numbers, and they also may be pointers to the same base type. The result has the type of the
argument which has greater range of possible values (e.g. if one is float and second one is
long int, the result is of float type).
div_t div (short numer, short denom);
Divides two short integers, and returns quotient and remainder.
div divides two integers and returns both the quotient and the remainder as
a div_t type. numer and denom are the numerator and the
denominator, respectively. div returns a structure whose elements are quot (the
quotient) and rem (the remainder).
NOTE: div is an inline function, implemented using GNU C smart macros.
ldiv_t ldiv (long n, long d);
Divides two long integers, and returns quotient and remainder.
ldiv divides two long integers and returns both the quotient and the remainder as
a ldiv_t type. numer and denom are the numerator and the
denominator, respectively. div returns a structure whose elements are quot (the
quotient) and rem (the remainder).
NOTE: ldiv is an inline function, implemented using GNU C smart macros.
Converts a string to a short integer.
atoi converts the string pointed to by str to integer. atoi recognizes (in the
following order):
- an optional string of spaces [ws];
- an optional sign ('+', '-', or special "small" minus used in TI-Basic) [sn];
- a string of digits [ddd].
The characters must match this generic format:
[ws] [sn] [ddd]
In atoi, the first unrecognized character ends the conversion. There are no provisions for
overflow in atoi (results are wrong in a case of overflow). atoi returns the converted value
of the input string. If the string cannot be converted, the return value is 0. See
strtol and strtoul for conversions which
allow much greater flexibility.
Converts a string to a long integer.
atol is similar like atoi, but converts the string to a long integer.
float atof (const char *s);
Converts a string to a floating point.
atof converts a string pointed to by s to floating point value. It recognizes
the character representation of a floating point number, made up of the following:
- an optional string of spaces;
- an optional minus sign;
- a string of ditits and an optional decimal point (the digits can be on both
sides of the decimal point);
- an optional exponent followed by a (optionally signed) integer.
It is important to say that this implementation of atof requires that an optional
minus sign and an optional exponent must be TI Basic characters for minus sign and exponent,
(characters with codes 0xAD and 0x95 instead of ordinary
'-' and 'e' or 'E' characters).
This limitation is caused by using some TIOS calls which needs such number format. Anyway,
it is very easy to "preprocess" any string to satisfy this convention before calling to
atof by routine like the following (assuming that c is a char variable, and i
is an integer variable):
for (i = 0; c = s[i]; i++) // Yes, the second '=' is really '=', not '=='...
{
if (c == '-') s[i] = 0xAD;
if ((c|32) == 'e') s[i] = 0x95;
}
atof returns the converted value of the input string. It returns NAN if the
input string cannot be converted (i.e. if it is not in a correct format). This is not the same
as in ANSI C: atof in ANSI C returns 0 if the conversion was not successful. I decided to
return NAN instead, so the user can check whether the conversion was
successful (which is not possible with ANSI atof). See is_nan for a good
method to check whether the result is NAN.
Converts a string to a long integer using a given radix, with detection of overflows and errors.
strtol converts a character string str to a long integer value. str is a
sequence of characters that can be interpreted as a long value. The characters must match this
generic format:
[ws] [sn] [0] [x] [ddd]
where
- [ws] is an optional string of spaces;
- [sn] is an optional sign ('+', '-', or special "small" minus used in TI-Basic);
- [0] is an optional zero (0);
- [x] is an optional 'x' or 'X';
- [ddd] is an optional string of digits.
strtol stops reading the string at the first character it doesn't recognize.
- If radix is between 2 and 36, the long integer is expressed in base radix.
- If radix is 0, the first few characters of str determine the base of the value
being converted.
First character | Second character | String interpreted as |
0 0 1 - 9 |
1 - 7 x or X |
Octal Hexadecimal Decimal |
- If radix is 1, less than 0 or greater than 36, it is considered to be an invalid value.
The characters are interpreted in according to the following table:
Value in str meant to be interpreted as |
Resulting Character Recognition |
Octal |
Any character other than 0 to 7 will be unrecognized. |
Decimal |
Any character other than 0 to 9 will be unrecognized. |
A number in any other base |
Only the numerals and letters used to represent numbers in that base will be
recognized (for example, if radix equals 5, only 0 to 4 will be recognized; if
radix equals 20, only 0 to 9 and A to J will be recognized).
|
If endptr is not NULL, strtol sets the pointer variable pointed
to by endptr to point to the character that stopped the scan (i.e. *endptr = &stopper).
strtol returns the value of the converted string, or 0 on error. In a case of overflow,
strtol returns LONG_MAX or
LONG_MIN, depending of the sign.
NOTE: strtol is much more flexible than atol (or atoi),
but as it is not built-in in the TIOS, usage of it makes the total size of the program much
greater.
Converts a string to an unsigned long integer using a given radix, with detection of overflows and errors.
strtoul operates the same as strtol, except that it converts a string
str to an unsigned long value (where strtol converts to a long).
See strtol for more information. In a case of overflow, strtoul
returns ULONG_MAX.
Random number generator.
rand uses a linear congruential random number generator to return successive pseudorandom
numbers in the range from 0 to RAND_MAX (i.e. from 0 to 32767).
It returns the generated pseudorandom number.
Generates a random integer in a given range.
random is a macro which uses rand to return a random number
between 0 and (num-1).
Initializes random number generator.
The random number generator is reinitialized by calling srand with an argument value of 1.
It can be set to a new starting point by calling srand with a given seed number (if
an argument is set to seed).
Initializes random number generator with a random value.
randomize initializes the random number generator with a random value
(picked from the timer).
Allocates a memory.
malloc allocates a block of Size bytes from the memory heap.
It allows a program to allocate memory explicitly as it's needed, and in
the exact amounts needed. The heap is used for dynamic allocation of
variable-sized blocks of memory. Many data structures, such as trees and
lists, naturally employ heap memory allocation. On success, malloc returns
a pointer to the newly allocated block of memory. If not enough space
exists for the new block, it returns NULL. The contents
of the block are left unchanged. If the argument Size is zero
malloc also returns NULL.
malloc is in fact an ANSI C alias for a TIOS routine originally called
HeapAllocPtr (see description of it for more
system info).
NOTE: As TIOS memory manager assigns a handle to each allocated block, and
as the total number of handles is limited, malloc is not good for algorithms
where you need to allocate a large number of small blocks (as in implementations
of linked lists which are usually seen in various C language books and tutorials).
The same is true for all other TIOS memory management routines.
Allocates a memory for a given number of items.
calloc allocates a block of NoOfItems x SizeOfItems
bytes from the memory heap. On success, calloc returns a pointer to the newly allocated
block of memory. If not enough space exists for the new block, it returns
NULL. The allocated block will be cleared to zero content.
NOTE: In releases of TIGCCLIB prior to 2.0, calloc was implemented here as a macro,
Now, it is a function. It first calls malloc
with NoOfItems x SizeOfItems as the argument, then calls
memset if first call was successful.
Reallocates allocated memory.
realloc attempts to shrink or expand the previously allocated block to NewSize
bytes. The Ptr argument points to a memory block previously obtained by calling
malloc, calloc, or realloc.
In opposite to ANSI C implementation, Ptr should not be NULL
(anyway, nobody calls realloc with NULL as the argument: ANSI C proposes
that realloc should work just like malloc in this case).
realloc adjusts the size of the allocated block to size, copying the contents to a new location
if necessary (note that the block will not stay in the high memory after the reallocation, but
it will still remain locked; see alloc.h header file for more info).
realloc returns the address of the reallocated block, which can be different than the address
of the original block. If the block cannot be reallocated, realloc returns NULL.
NOTE: realloc is introduced to increase compatibility with ANSI C. It is better to use
TIOS official function HeapRealloc and other functions
from alloc.h header file which use system of handles to memory blocks.
Frees allocated blocks.
free deallocates a memory block allocated by a previous call to
malloc or calloc.
NOTE: free is in fact an ANSI C alias for a TIOS routine originally called
HeapFreePtr.
Allocates a memory on a local storage space.
alloca is function which is not included in ANSI C standard, but it exists in many C dialects
(including TIGCC). It allocates a block of Size bytes on the CPU stack (local
storage space), in opposite to malloc which allocates memory on the
memory heap. The space allocated with alloca exists until the containing function returns
(i.e. it will be automatically deallocated at the end of the function). Be aware of the
fact that the size of the hardware stack on TI calculators is limited to 16 kilobytes, so
do not use alloca for allocating large blocks.
alloca is usually used for simulating automatic variable-sized one-dimensional arrays, which will be automatically
deallocated when the function ends (like all automatic variables), so it is sometimes more
preferable than malloc. For example, to simulate
int a[n];
where 'n'
is not known in advance, you can use
int *a = alloca (n);
Note, however, that GNU C extensions allows variable-length
arrays, which are more elegant than usage of alloca, and which may also be with more than
one dimension (which is not possible with alloca).
NOTE: alloca is a builtin (open-coded) function in GNU C, which is translated to a single
instruction which simply adjust the stack. Some compiler command options (like
'-ansi') prevent alloca to be an open-codes function. In this implementation
of TIGCC, you can not use alloca with such options (however, it is very unlikely that you will
ever have such problems).
Sorts an area of items.
qsort sorts the entries in a table by repeatedly calling the user-defined
comparison function pointed to by cmp_func. BasePtr points to the base
(0-th element) of the table to be sorted. NoOfElement is the number of
entries in the table. Width is the size of each entry in the table, in
bytes. cmp_func, the comparison function, accepts two arguments,
elem1 and elem2, each a pointer to an entry in the table.
The comparison function compares each of the pointed-to items (*elem1 and
*elem2), and returns a long integer based on the result of the comparison:
- If *elem1 < *elem2, cmp_func should return an integer < 0.
- If *elem1 == *elem2, cmp_func should return 0.
- If *elem1 > *elem2, cmp_func should return an integer > 0.
In the comparison, the less-than symbol (<) means the left element should
appear before the right element in the final, sorted sequence. Similarly, the
greater-than symbol (>) means the left element should appear after the right element
in the final, sorted sequence.
Here is a complete example of usage (somewhat shorted, without necessary "includes"):
long cmpfunc(void *a, void *b) // comparison function
{
return *(int*)a - *(int*)b; // Note that typecasts are necessary
}
void _main(void)
{
LCD_BUFFER buffer;
int i;
int array[10] = {2, 9, 3, 6, 4, 2, 3, 3, 1, 5};
LCD_save (buffer);
qsort (array, 10, sizeof (int), cmpfunc);
clrscr ();
for (i = 0; i < 10; i++) printf ("%d ", array[i]);
ngetchx ();
LCD_restore( buffer);
}
Note that function strcmp seems ideal for string comparisons.
However, its parameters are not void pointers. This may be solved using a typecast like
qsort (StringArray, NoOfStrings, LenOfEachString, (long(*)(void*,void*))strcmp);
Binary search.
bsearch searches a table (array) of NoOfElements elements in memory, and returns
the address of the first entry in the table that matches the search key. Because this is a
binary search, the first matching entry is not necessarily the first entry in the table.
If no match is found, bsearch returns NULL.
NoOfElements gives the number of elements in the table.
Width specifies the number of bytes in each table entry.
BasePtr points to the base (0-th element) of the table to be sorted.
Key is a pointer to the search key.
cmp_func, the comparison function, accepts two arguments,
elem1 and elem2, each a pointer to an entry in the table.
The comparison function compares each of the pointed-to items (*elem1 and
*elem2), and returns a long integer based on the result of the comparison:
- If *elem1 < *elem2, cmp_func should return an integer < 0.
- If *elem1 == *elem2, cmp_func should return 0.
- If *elem1 > *elem2, cmp_func should return an integer > 0.
See also qsort.
Forced termination of the program.
exit terminates the program (it may be called from any nesting level). Before termination, any
registered "exit functions" (posted with atexit) are called. ANSI proposes
that exit also closes all open files. Such behaviour is not implemented here, you need to do
it manually if necessary.
code is the exit status. Value of 0 is used to indicate a normal exit. If code
is nonzero, an error message dialog which corresponds with code code will be displayed
before exiting. Note that this is not the same as throwing error code using
ER_throwVar. Throwing an error is much more "barbaric"
method for exiting from the program. Among others, by throwing an error, no registered "exit
functions" will be called.
NOTE: The implementation of this function assumes that all functions have stack
frames which are linked in a linked list, so the usage of this function is not recommended
if you used '-fomit-frame-pointer' command line option during the compilation.
Abnormal termination of a process.
abort writes a termination message ("ABNORMAL PROGRAM TERMINATION") in the status line,
then aborts the program by a call to exit (passing 0 to it).
short atexit (atexit_t func);
Registers termination function.
atexit registers the function pointed to by func as an exit function.
Upon normal termination of the program (including termination using
exit function), func is called just before
returning to the TIOS. Each call to atexit registers another exit function.
The number of function which can be registered depends of the current number
of free handles. All registered termination functions are executed on a last-in,
first-out basis (the last function registered is the first to be executed).
atexit returns 0 on success and nonzero on failure (no space left to register
the function).
NOTE: termination functions are not called on abnormal termination of the
program (i.e. if an error is thrown from the program). Also, the
implementation of this function assumes that all functions have stack
frames which are linked in a linked list, so the usage of this function is not recommended
if you used '-fomit-frame-pointer' option during the compilation.
Constants and predefined types
RAND_MAX is a constant (here with value 32767) which is usually defined in stdlib.h.
Its meaning is "the largest number returned by rand".
size_t is a type proposed in ANSI C for defining size of strings and
memory blocks. It is defined here as
typedef unsigned long size_t;
atexit_t is a type proposed in ANSI C for defining type of exit function
passed to atexit. It is defined here as
typedef void (*atexit_t) (void);
NULL is a null-pointer value, defined as (void *) 0.
div_t type is an integer division return type used in div function. It is a
structure of integers defined as
typedef struct
{
short quot, rem;
} div_t;
div_t type is a long integer division return type used in ldiv function. It is a
structure of long integers defined as
typedef struct
{
long quot, rem;
} ldiv_t;