stdlib.h
stdlib.h
Type aliases and macros
stdlib.h defines the following type aliases.
- size_t: return type of sizeof.
- wchar_t: wide character type.
stdlib.h defines the following macros.
- NULL: null pointer.
- EXIT_SUCCESS: the exit status of the function when it runs successfully.
- EXIT_FAILURE: exit status of the function when it runs incorrectly.
- RAND_MAX: the maximum value that can be returned by the rand() function.
- MB_CUR_MAX: the maximum number of bytes occupied by multi-byte characters in the current language environment.
abs(), labs(), llabs()
These three functions are used to calculate the absolute value of an integer. abs()
is used for the int type, labs()
for the long int type and llabs()
for the long long int type.
int abs(int j);
long int labs(long int j);
long long int llabs(long long int j);
Here is an example of usage.
// output |-2| = 2
printf("|-2| = %d\n", abs(-2));
// output |4| = 4
printf("|4| = %d\n", abs(4));
ðŸ™'
## div(), ldiv(), lldiv()
These three functions are used to calculate the quotient and remainder of two arguments. `div()` is used for division by int types, `ldiv()` is used for division by long int types, and `lldiv()` is used for division by long long int types.
```c
div_t div(int numer, int denom);
ldiv_t ldiv(long int numer, long int denom);
lldiv_t lldiv(long long int numer, long long int denom);
These functions divide the 2nd argument (denominator) by the 1st argument (numerator) to produce a quotient and a remainder. These two values are returned via a data structure, div()
returns the div_t structure, ldiv()
returns the ldiv_t structure and lldiv()
returns the lldiv_t structure.
These structures all contain the following two fields.
int quot; // quotient
int rem; // remainder
They are fully defined as follows.
typedef struct {
int quot, rem;
} div_t;
typedef struct {
long int quot, rem;
} ldiv_t;
typedef struct {
long long int quot, rem;
} lldiv_t;
Here is an example.
div_t d = div(64, -7);
// output 64 / -7 = -9
printf("64 / -7 = %d\n", d.quot);
// output 64 % -7 = 1
printf("64 %% -7 = %d\n", d.rem);
Convert strings to values
a series of functions
stdlib.h
defines a series of functions that convert strings to numbers.
- atoi(): string to int type.
- atof(): string to double type.
- atol(): converts a string to a long int type.
- atoll(): string to long long int type.
Their prototypes are as follows.
int atoi(const char* nptr);
double atof(const char* nptr);
long int atol(const char* nptr);
long long int atoll(const char* nptr);
The arguments to the above functions are all pointers to a string. Spaces at the beginning of the string are ignored and the conversion stops at the first invalid character. The a
in the function name stands for ASCII, so atoi()
means "ASCII to int".
They return the converted value, or 0
if the string cannot be converted.
Here is an example of usage.
atoi("3490") // 3490
atof("3.141593") // 3.141593
If the argument is a string starting with a number, atoi()
will convert only the numeric part, e.g. atoi("42regular")
will return the integer 42
. If the first character is not a number, such as hello world
, then 0
will be returned.
str family of functions (floating point conversions)
stdlib.h
also defines some more powerful floating point conversion functions.
- strtof(): string to float type.
- strtod(): string to double type.
- strtold(): string to long double type.
Their prototypes are as follows.
float strtof(
const char* restrict nptr,
char** restrict endptr
);
double strtod(
const char* restrict nptr,
char** restrict endptr
);
long double strtold(
const char* restrict nptr,
char** restrict endptr
);
They both take two arguments, the first being the string to be converted, and the second a pointer to the part of the original string that cannot be converted.
nptr
: the string to be converted (whitespace characters at the beginning are ignored).endprt
: a pointer to the first character of the part that cannot be converted. If the string can be fully converted to a value, this pointer points to the terminator\0
at the end of the string. This parameter, if set to NULL, means that the remainder of the string does not need to be processed.
Their return value is the converted value. If the string cannot be converted, 0
is returned. If the result of the conversion overflows, errno is set to ERANGE. if the value is too large (either positive or negative), the function returns HUGE_VAL
; if the value is too small, the function returns zero.
char *inp = " 123.4567abdc";
char *badchar;
double val = strtod(inp, &badchar);
printf("%f\n", val); // 123.456700
printf("%s\n", badchar); // abdc
ðŸ˜'
In the case where the string can be fully converted, the second argument points to ``0``, so you can use the following writeup to determine if it is fully converted.
```c
if (*endptr == '\0') {
// complete conversion
} else {
// there is a character that cannot be converted
}
If you don't care about the unconverted part, you can set endptr to NULL.
These functions can also convert strings to the special values Infinity and NaN; if the string contains INF or INFINITY (either upper or lower case), it will be converted to Infinity; if the string contains NAN, it will return NaN.
The str family of functions (integer conversions)
The str family of functions also has an equivalent function for integer conversions.
- strtol(): converts a string to a long int type.
- strtoll(): string to long long int type.
- strtoul(): string to unsigned long int.
- strtoull(): string to unsigned long long int type.
Their prototypes are as follows.
long int strtol(
const char* restrict nptr,
char** restrict endptr,
int base
);
long long int strtoll(
const char* restrict nptr,
char** restrict endptr,
int base
);
unsigned long int strtoul(
const char* restrict nptr,
char** restrict endptr,
int base
);
unsigned long long int strtoull(
const char* restrict nptr,
char** restrict endptr, int base
);
They accept three arguments.
(1) nPtr
: the string to be converted (whitespace characters at the beginning are ignored).
(2) endPrt
: a pointer to the first character of the part that cannot be converted. If the string can be fully converted to a numeric value, this pointer points to the terminator \0
at the end of the string. If this parameter is set to NULL, it means that the remainder of the string does not need to be processed.
(3) base
: the binary of the integer to be converted. This value should be 2
to 36
between the integers, representing the corresponding binary, if it is a special value 0
, that allows the function to determine their own binary according to the prefix of the value, that is, if the number has the prefix 0
, it is octal, if the number has the prefix 0x
or 0X
, it is hexadecimal.
Their return value is the converted value, and 0
is returned if the conversion is unsuccessful.
Here is an example of converting a decimal integer.
char* s = "3490";
unsigned long int x = strtoul(u, NULL, 10);
printf("%lu\n", x); // 3490
Here is an example of converting a hexadecimal integer.
char* end;
long value = strtol("0xff", &end, 16);
printf("%ld\n", value); // 255
printf("%s\n", end); // no content
value = strtol("0xffxx", &end, 16);
printf("%ld\n", value); // 255
printf("%s\n", end); // xx
In the above example, strtol()
can specify that the string contains a hexadecimal integer. The parts that cannot be converted can be accessed using the pointer end
.
Here is an example of converting a binary integer.
char* s = "101010";
unsigned long int x = strtoul(s, NULL, 2);
printf("%lu\n", x); // 42
Here is an example of letting a function determine the integer binary by itself.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char* string = "-1234567abc";
char* remainderPtr;
long x = strtol(string, &remainderPtr, 0);
printf("%s\"%s\"\n%s%s%ld\n%s\"%s\"\n",
"The original string is ",
string,
"The converted value is ",
x,
"The remainder of the original string is ",
remainderPtr
);
}
The output of the above code is as follows.
The original string is "-1234567abc"
The converted value is -1234567
The remainder of the original string is "abc"
If the value being converted is too large, the strtol()
function stores the value ERANGE
in errno
and returns LONG_MIN
(the original value is negative) or LONG_MAX
(the original value is positive), and strtoul()
returns ULONG_MAX
.
rand()
The rand()
function is used to generate a random integer between 0 and RAND_MAX. RAND_MAX
is a macro defined inside stdlib.h
and is usually equal to INT_MAX.
// Prototype
int rand(void);
// Example
int x = rand();
If you wish to obtain a random number between integers N and M (including both N and M endpoint values), you can use the following writeup.
int x = rand() % (M - N + 1) + N;
For example, a random number between 1 and 6 would be written as follows.
int x = rand() % 6 + 1;
To get a random value for a floating point number, write the following.
// a random number between 0 and 0.999999
printf("0 to 0.99999: %f\n", rand() / ((float)RAND_MAX + 1));
// Random number between n and m.
// n + m * (rand() / (float)RAND_MAX)
printf("10.5 to 15.7: %f\n", 10.5 + 5.2 * rand() / (float)RAND_MAX);
In the above example, since rand()
and RAND_MAX
are both int types, use the displayed type conversion to convert to floating point numbers.
srand()
rand()
is a pseudo-random number function. To increase randomness, the seed value must be reset using the srand()
function before calling it.
The srand()
function accepts an unsigned integer (unsigned int) as the seed value and has no return value.
void srand(unsigned int seed);
The time(NULL)` function is usually used to return the number of seconds from the current time epoch as an argument to
srand()`.
#include <time.h>
srand((unsigned int) time(NULL));
In the above code, the prototype of time()
is defined inside the header file time.h
, and the type of the return value is the type alias time_t
, the exact type is system dependent, so force a bit of type conversion. The argument to time()
is a pointer to a specific time value of type time_t
, where the null pointer NULL
is passed as an argument, and since NULL is generally 0
, it can also be written as time(0)
.
abort()
abort()
is used to abnormally terminate an executing program. The main purpose of using this function is that it triggers a SIGABRT signal, for which the developer can set a handler in the program.
void abort(void);
This function has no arguments.
exit(), quick_exit(), _Exit()
These three functions are all used to exit the currently executing program.
void exit(int status);
void quick_exit(int status);
void _Exit(int status);
They both accept an integer indicating the exit status of the program, 0
being a normal exit and a non-zero value indicating that an error has occurred, and can use the macros EXIT_SUCCESS
and EXIT_FAILURE
as arguments. They have no return value of their own.
The difference between them is that the cleanup done on exit is different. exit()
is a normal exit, where the system does a complete cleanup, such as updating all file streams and deleting temporary files. quick_exit()
is a fast exit, where the system does slightly less cleanup. _Exit()
is an immediate exit, with no cleanup done.
Here are some examples of usage.
exit(EXIT_SUCCESS);
quick_exit(EXIT_FAILURE);
_Exit(2);
atexit(), at_quick_exit()
atexit()
is used to register other functions to be executed when the current program exits (by calling exit()
or main()
to exit normally).
at_quick_exit()
registers the other functions that will be executed when the current program exits using the quick_exit()
method.
exit()
can only trigger functions registered by atexit()
, and quick_exit()
can only trigger functions registered by at_quick_exit()
.
int atexit(void (*func)(void));
int at_quick_exit(void (*func)(void));
Their argument is the address of the function to be executed, i.e. the function name. They both return 0
on a successful call and a non-zero value on a failed call.
Here is an example.
void sign_off(void);
void too_bad(void);
int main(void) {
int n;
atexit(sign_off); /* register sign_off() function */
puts("Enter an integer:");
if (scanf("%d", &n) ! = 1) {
puts("That's no integer!");
atexit(too_bad); /* register too_bad() function */
exit(EXIT_FAILURE);
}
printf("%d is %s.\n", n, (n % 2 == 0) ? "even" : "odd");
return 0;
}
void sign_off(void) {
puts("sign_off");
}
void too_bad(void) {
puts("too bad");
}
In the above example, the sign_off()
and too_bad()
functions are called when the user input fails; but only sign_off()
will be called when the input succeeds. This is because the if
statement will only be entered to register too_bad()
if the input fails.
Also, if there are multiple atexit()
statements, the first one called when the function exits is the last function registered.
The functions registered by atexit()
(such as sign_off
and too_bad
in the above example) should take no arguments and have a return type of void
. Usually, these functions perform some cleanup tasks, such as deleting temporary files or resetting environment variables.
The same rule applies to at_quick_exit()
, an example of which is shown below.
void exit_handler_1(void) {
printf("1\n");
}
void exit_handler_2(void) {
printf("2\n");
}
int main(void) {
at_quick_exit(exit_handler_1);
at_quick_exit(exit_handler_2);
quick_exit(0);
}
Executing the above example, the command line will output 2 and then 1.
getenv()
getenv()
is used to get the value of an environment variable. Environment variables are some environmental parameters outside the program provided by the operating system.
char* getenv(const char* name);
Its argument is a string indicating the name of the environment variable. The return value is also a string, indicating the value of the environment variable. If the specified environment variable does not exist, NULL is returned.
The following is an example of outputting the value of the environment variable $PATH
.
printf("PATH is %s\n", getenv("PATH"));
system()
The system()
function is used to execute external programs. It will pass its argument string to the operating system for the operating system's command processor to execute.
void system( char const * command );
The return value of this function varies from compiler to compiler. However, the standard specifies that if NULL is passed as an argument, it means that the operating system is asked if there is a command processor available, and if so, a non-zero value is returned, otherwise zero is returned.
The following is an example of executing the ls
command.
system("ls -l");
Memory management functions
stdlib.h provides a number of memory manipulation functions. The following functions are detailed in the chapter on Memory Management, the rest are described in this section.
- malloc(): allocates a memory region
- calloc(): allocates a region of memory.
- realloc(): adjusts the size of the memory area.
- free(): frees a memory area.
aligned_alloc()
Many systems have memory alignment requirements, i.e. the size of a block of memory must be a multiple of some value (e.g. 64 bytes) to facilitate faster processing. `aligned_alloc()
is then used to allocate blocks of memory that meet the memory alignment requirement, and it has the following prototype.
void* aligned_alloc(size_t alignment, size_t size);
It accepts two arguments.
- alignment: an integer indicating the unit size of the memory alignment, typically an integer power of 2 (2, 4, 8, 16 ......).
- size: integer, indicating the size of the memory block.
On successful allocation, it returns an untyped pointer to the newly allocated block of memory. On a failed allocation, it returns NULL.
char* p = aligned_alloc(64, 256);
In the above example, aligned_alloc()
allocates a block of memory with a unit size of 64 bytes, and the number of bytes to be allocated is 256 bytes.
qsort()
qsort()
is used to quickly sort an array. It has no requirements on the type of array members, any type of array can be sorted with this function.
void qsort(
void *base,
size_t nmemb,
size_t size,
int (*compar)(const void *, const void *)
);
This function takes four arguments.
- base: a pointer to the start position of the array to be sorted.
- nmemb: the number of members of the array.
- size: the length of the bytes occupied by each member of the array.
- compare: a function pointer to a function that compares two members.
The compare function compar
takes as an argument a pointer to two members of the array and compares the two members. The function should return a negative value if the first argument is smaller than the second, 0
if the two functions are equal, or a positive number if the first argument is larger than the second.
Here is an example usage.
#include <stdio.h>
#include <stdlib.h>
int compar(const void* elem0, const void* elem1) {
const int* x = elem0;
const int* y = elem1;
return *x - *y;
}
int main(void) {
int a[9] = {14, 2, 3, 17, 10, 8, 6, 1, 13};
qsort(a, 9, sizeof(int), compar);
for (int i = 0; i < 9; i++)
printf("%d ", a[i]);
putchar('\n');
}
The above example will output the sorted array "1 2 3 6 8 10 13 14 17".
bsearch()
bsearch()
uses a dichotomous search to search for a value in an array. It has no requirements on the type of the array members, and any type of array can be searched for values with this function.
Note that this method is only valid for arrays that are already sorted.
void *bsearch(
const void* key,
const void* base,
size_t nmemb,
size_t size,
int (*compar)(const void *, const void *)
);
This function accepts 5 arguments.
- key: a pointer to the value to be found.
- base: a pointer to the start of the array, which must already be sorted.
- nmemb: the number of members of the array.
- size: the length of the bytes occupied by each member of the array.
- compar: a pointer to a function that compares the value to be found with other values.
The compare function compar
takes the value to be found as the first argument and the value to be compared as the second argument. If the first argument is less than the second, the function should return a negative value; if the two arguments are equal, 0
; if the first argument is greater than the second, a positive value.
If the value to be found, bsearch()
returns a pointer to the value, or NULL if it cannot be found.
Here is an example usage.
#include <stdio.h>
#include <stdlib.h>
int compar(const void *key, const void *value) {
const int* k = key;
const int* v = value;
return *k - *v;
}
int main(void) {
int a[9] = {2, 6, 9, 12, 13, 18, 20, 32, 47};
int* r;
int key;
key = 12; // included in the array
r = bsearch(&key, a, 9, sizeof(int), compar);
printf("Found %d\n", *r);
key = 30; // not included in the array
r = bsearch(&key, a, 9, sizeof(int), compar);
if (r == NULL)
printf("Didn't find 30\n");
return 0;
}
Executing the above example will output the following result.
Found 12
Didn't find 30
Multibyte character functions
stdlib.h provides the following functions to manipulate multibyte characters, see the chapter on Multibyte Characters for details.
- mblen(): the byte length of a multibyte character.
- mbtowc(): converts multibyte characters to wide characters.
- wctomb(): converts wide characters to multibyte characters.
- mbstowcs(): converts multibyte strings to wide strings.
- wcstombs(): converts wide strings to multi-byte strings.