Модуль stdlib.h
Стандартные функции языка C
Модуль stdlib.h предоставляет стандартные функции языка C (функции прошивки) для работы с динамической памятью, преобразованием строк в числа, генерацией псевдослучайных чисел, математическими операциями, управлением завершением программы и поиском/сортировкой данных.
Для работы с модулем stdlib.h реализованы следующие функции:
// Управление динамической памятью
void *malloc(size_t size);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
void free(void *ptr);
// Преобразование строк в числа
int atoi(const char *nptr);
long atol(const char *nptr);
long long atoll(const char *nptr);
double atof(const char *nptr);
long strtol(const char *nptr, char **endptr, int base);
long long strtoll(const char *nptr, char **endptr, int base);
unsigned long strtoul(const char *nptr, char **endptr, int base);
unsigned long long strtoull(const char *nptr, char **endptr, int base);
float strtof(const char *nptr, char **endptr);
double strtod(const char *nptr, char **endptr);
long double strtold(const char *nptr, char **endptr);
// Генерация псевдослучайных чисел
int rand(void);
void srand(unsigned int seed);
// Математические операции
int abs(int x);
long labs(long x);
long long llabs(long long x);
div_t div(int numer, int denom);
ldiv_t ldiv(long numer, long denom);
lldiv_t lldiv(long long numer, long long denom);
// Управление завершением программы
void abort(void);
void exit(int status);
int atexit(void (*func)(void));
// Поиск и сортировка
void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
Особенности контроллера
Функции объявлены в заголовках компилятора сценариев, а выполняются в прошивке. Полной среды настольной ОС нет. Динамическая куча использует прежнюю область размером 8200 байт; служебные заголовки, выравнивание и фрагментация уменьшают доступный объём. Указатели malloc/calloc/realloc выровнены на 8 байт. Память между отдельными сценариями не сохраняет контракт выделения; старый указатель повторно использовать нельзя.
Выход за границы выделения, неверный указатель и повторный free не являются допустимым использованием API, даже если allocator отклоняет некоторые такие вызовы. У malloc нет гарантии обнуления. Правила начального обнуления глобальных и статических переменных описаны в особенностях C.
malloc
void *malloc(size_t size) выделяет size байт. При нуле или недопустимом размере, включая переполнение округления и размер больше кучи, возвращает NULL. При нехватке непрерывного свободного блока также возвращает NULL. Память не обнуляется.
#include <dev.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main(void) {
uint8_t *buffer = malloc(64);
if (buffer == NULL) {return 1;}
memset(buffer, 0, 64);
printf("Buffer: %u bytes\n", 64U);
free(buffer);
return 0;
}
calloc
void *calloc(size_t nmemb, size_t size) выделяет nmemb*size байт и обнуляет их. Проверяет переполнение произведения и размер до выделения. Возвращает NULL при нулевом общем размере, слишком большом запросе или нехватке памяти.
realloc
void *realloc(void *ptr, size_t size) меняет размер выделения. Данные сохраняются до меньшего из старого и нового размеров; добавленные байты не инициализированы. При уменьшении свободный хвост объединяется с соседним свободным блоком.
NULL в ptr означает malloc(size); size=0 освобождает ptr и возвращает NULL. При отказе с ненулевым size старое выделение сохраняется: сначала проверяйте временный указатель.
#include <dev.h>
#include <stdlib.h>
int main(void) {
uint8_t *buffer = malloc(32);
if (buffer == NULL) {return 1;}
uint8_t *larger = realloc(buffer, 64);
if (larger == NULL) {free(buffer); return 1;}
buffer = larger;
free(buffer);
return 0;
}
free
void free(void *ptr) освобождает выделение из кучи C-сценария и объединяет соседние свободные блоки. free(NULL) ничего не делает. Передавайте только адрес начала действующего выделения; после освобождения обращение через указатель недопустимо.
atoi
Функция int atoi(const char *nptr) преобразует строку nptr в целое число типа int.
Параметры:
nptr— указатель на строку.
Возвращаемые значения:
- Целое число или 0, если преобразование невозможно.
Примечание: Не сообщает об ошибках. Рекомендуется использовать strtol для большей надёжности.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *str = "123";
int num = atoi(str);
printf("Число: %d\n", num); // Ожидается: 123
return 0;
}
atol
Функция long atol(const char *nptr) преобразует строку nptr в целое число типа long.
Параметры:
nptr— указатель на строку.
Возвращаемые значения:
- Целое число или 0, если преобразование невозможно.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *str = "123456";
long num = atol(str);
printf("Число: %ld\n", num); // Ожидается: 123456
return 0;
}
atoll
Функция long long atoll(const char *nptr) преобразует строку nptr в целое число типа long long.
Параметры:
nptr— указатель на строку.
Возвращаемые значения:
- Целое число или 0, если преобразование невозможно.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *str = "123456789";
long long num = atoll(str);
printf("Число: %lld\n", num); // Ожидается: 123456789
return 0;
}
atof
Функция double atof(const char *nptr) преобразует строку nptr в число с плавающей точкой типа double.
Параметры:
nptr— указатель на строку.
Возвращаемые значения:
- Число с плавающей точкой или 0.0, если преобразование невозможно.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *str = "3.14159";
double num = atof(str);
printf("Число: %.5f\n", num); // Ожидается: 3.14159
return 0;
}
strtol
Функция long strtol(const char *nptr, char **endptr, int base) преобразует строку nptr в число типа long с указанием системы счисления base.
Параметры:
nptr— указатель на строку.endptr— указатель на указатель, куда записывается адрес первого непроанализированного символа (илиNULL).base— система счисления (2–36 или 0 для автоопределения).
Возвращаемые значения:
- Преобразованное число. Если цифр нет, возвращается 0 и endptr совпадает с началом строки. При переполнении возвращается граница типа, а не обязательно 0. Интерфейс errno сценариям не предоставлен: проверяйте endptr и прикладной диапазон.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *str = "123abc";
char *endptr;
long num = strtol(str, &endptr, 10);
printf("Число: %ld, остаток: %s\n", num, endptr); // Ожидается: Число: 123, остаток: abc
return 0;
}
strtoll
Функция long long strtoll(const char *nptr, char **endptr, int base) преобразует строку nptr в число типа long long.
Параметры:
- Аналогично
strtol.
Возвращаемые значения:
- Аналогично
strtol.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *str = "123456789abc";
char *endptr;
long long num = strtoll(str, &endptr, 10);
printf("Число: %lld, остаток: %s\n", num, endptr); // Ожидается: Число: 123456789, остаток: abc
return 0;
}
strtoul
Функция unsigned long strtoul(const char *nptr, char **endptr, int base) преобразует строку nptr в число типа unsigned long.
Параметры:
- Аналогично
strtol.
Возвращаемые значения:
- Аналогично
strtol.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *str = "0xFFabc";
char *endptr;
unsigned long num = strtoul(str, &endptr, 16);
printf("Число: %lu, остаток: %s\n", num, endptr); // Ожидается: Число: 255, остаток: abc
return 0;
}
strtoull
Функция unsigned long long strtoull(const char *nptr, char **endptr, int base) преобразует строку nptr в число типа unsigned long long.
Параметры:
- Аналогично
strtol.
Возвращаемые значения:
- Аналогично
strtol.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *str = "0xFFFFabc";
char *endptr;
unsigned long long num = strtoull(str, &endptr, 16);
printf("Число: %llu, остаток: %s\n", num, endptr); // Ожидается: Число: 65535, остаток: abc
return 0;
}
strtof
Функция float strtof(const char *nptr, char **endptr) преобразует строку nptr в число типа float.
Параметры:
nptr— указатель на строку.endptr— указатель на указатель, куда записывается адрес первого непроанализированного символа (илиNULL).
Возвращаемые значения:
- Преобразованное число; если преобразования нет, 0.0 и endptr указывает на начало строки. Переполнение может дать бесконечность, потеря значимости — ноль или субнормальное число. Не используйте один нулевой результат как единственный признак ошибки; API errno не предоставлен.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *str = "3.14159abc";
char *endptr;
float num = strtof(str, &endptr);
printf("Число: %.5f, остаток: %s\n", num, endptr); // Ожидается: Число: 3.14159, остаток: abc
return 0;
}
strtod
Функция double strtod(const char *nptr, char **endptr) преобразует строку nptr в число типа double.
Параметры:
- Аналогично
strtof.
Возвращаемые значения:
- Аналогично
strtof.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *str = "3.14159abc";
char *endptr;
double num = strtod(str, &endptr);
printf("Число: %.5f, остаток: %s\n", num, endptr); // Ожидается: Число: 3.14159, остаток: abc
return 0;
}
strtold
Функция long double strtold(const char *nptr, char **endptr) преобразует строку nptr в число типа long double.
Параметры:
- Аналогично
strtof.
Возвращаемые значения:
- Аналогично
strtof.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *str = "3.1415926535abc";
char *endptr;
long double num = strtold(str, &endptr);
printf("Число: %.10Lf, остаток: %s\n", num, endptr); // Ожидается: Число: 3.1415926535, остаток: abc
return 0;
}
rand
int rand(void) вызывает программный генератор Yasmarang с верхней исключённой границей 0x7fffffff. Текущая реализация возвращает 0..2147483646, хотя макрос RAND_MAX в поставляемом заголовке равен 32767. Это несоответствие заголовка и реализации: не нормируйте результат делением на RAND_MAX. Для заданного диапазона используйте random(start, stop) с start < stop.
srand
void srand(unsigned int seed) меняет только компонент yasmarang_dat общего состояния генератора. Другие компоненты не сбрасываются. В этой реализации повторный srand с тем же seed не гарантирует воспроизведения всей последовательности rand. Не используйте этот механизм для криптографии.
Для abs/labs/llabs аргумент не должен быть минимальным отрицательным числом своего типа: его положительное значение не представимо. Для div/ldiv/lldiv запрещены нулевой делитель и деление минимального отрицательного числа на -1.
abs
Функция int abs(int x) возвращает абсолютное значение числа типа int.
Параметры:
x— входное число.
Возвращаемые значения:
- Абсолютное значение
x.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int x = -42;
int res = abs(x);
printf("Абсолютное значение: %d\n", res); // Ожидается: 42
return 0;
}
labs
Функция long labs(long x) возвращает абсолютное значение числа типа long.
Параметры:
x— входное число.
Возвращаемые значения:
- Абсолютное значение
x.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
long x = -123456L;
long res = labs(x);
printf("Абсолютное значение: %ld\n", res); // Ожидается: 123456
return 0;
}
llabs
Функция long long llabs(long long x) возвращает абсолютное значение числа типа long long.
Параметры:
x— входное число.
Возвращаемые значения:
- Абсолютное значение
x.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
long long x = -123456789LL;
long long res = llabs(x);
printf("Абсолютное значение: %lld\n", res); // Ожидается: 123456789
return 0;
}
div
Функция div_t div(int numer, int denom) выполняет деление numer на denom и возвращает частное и остаток.
Параметры:
numer— числитель.denom— знаменатель.
Возвращаемые значения:
- Структура
div_tс полямиquot(частное) иrem(остаток).
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
div_t result = div(17, 5);
printf("Частное: %d, Остаток: %d\n", result.quot, result.rem); // Ожидается: Частное: 3, Остаток: 2
return 0;
}
ldiv
Функция ldiv_t ldiv(long numer, long denom) выполняет деление numer на denom для чисел типа long.
Параметры:
numer— числитель.denom— знаменатель.
Возвращаемые значения:
- Структура
ldiv_tс полямиquotиrem.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
ldiv_t result = ldiv(123456L, 100L);
printf("Частное: %ld, Остаток: %ld\n", result.quot, result.rem); // Ожидается: Частное: 1234, Остаток: 56
return 0;
}
lldiv
Функция lldiv_t lldiv(long long numer, long long denom) выполняет деление numer на denom для чисел типа long long.
Параметры:
numer— числитель.denom— знаменатель.
Возвращаемые значения:
- Структура
lldiv_tс полямиquotиrem.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
lldiv_t result = lldiv(123456789LL, 100LL);
printf("Частное: %lld, Остаток: %lld\n", result.quot, result.rem); // Ожидается: Частное: 1234567, Остаток: 89
return 0;
}
abort
void abort(void) немедленно завершает текущий C-сценарий с причиной «ошибка», пропуская atexit-обработчики. Функция не возвращается. Это штатное завершение задачи, а не перезагрузка контроллера и не генерация HardFault. Сообщение об abort сохраняется в /txt?log.
exit
void exit(int status) завершает текущий C-сценарий и вызывает atexit-обработчики в обратном порядке. Не возвращается. status=0 означает успех, ненулевой status — ошибку; ненулевой код записывается в /txt?log. Возврат значения из main имеет ту же семантику завершения. Файлового stdout и его сброса в этом API нет.
atexit
int atexit(void (*func)(void)) регистрирует до 32 обработчиков в существующей задаче сценария. Возвращает 0 при успехе, -1 для NULL, переполнения списка или вызова вне активного C-сценария. Одна функция может быть зарегистрирована несколько раз.
Обработчики вызываются при обычном return из main и exit, начиная с последнего. abort их пропускает. Внешняя принудительная остановка не гарантирует их вызова. В текущей реализации exit из обработчика продолжает завершение с оставшимися обработчиками; abort из обработчика прекращает их вызов. Зацикленный обработчик задерживает завершение.
#include <dev.h>
#include <stdio.h>
#include <stdlib.h>
static void finish(void) {
puts("Finished");
}
int main(void) {
if (atexit(finish) != 0) {return 1;}
puts("Started");
return 0;
}
bsearch
Функция void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) выполняет бинарный поиск в отсортированном массиве.
Параметры:
key— указатель на искомый элемент.base— указатель на массив.nmemb— количество элементов.size— размер каждого элемента.compar— функция сравнения, возвращающая отрицательное, нуль или положительное значение.
Возвращаемые значения:
- Указатель на найденный элемент или
NULL, если элемент не найден.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int compare(const void *a, const void *b) {
return (*(int *)a - *(int *)b);
}
int main(void) {
int arr[] = {1, 3, 5, 7, 9};
int key = 5;
int *result = bsearch(&key, arr, 5, sizeof(int), compare);
if (result) {
printf("Найден: %d\n", *result); // Ожидается: Найден: 5
} else {
printf("Не найден\n");
}
return 0;
}
qsort
Функция void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) сортирует массив методом быстрой сортировки.
Параметры:
base— указатель на массив.nmemb— количество элементов.size— размер каждого элемента.compar— функция сравнения, возвращающая отрицательное, нуль или положительное значение.
Возвращаемые значения:
- Нет.
Пример использования:
#include <stdio.h>
#include <stdlib.h>
int compare(const void *a, const void *b) {
return (*(int *)a - *(int *)b);
}
int main(void) {
int arr[] = {5, 2, 8, 1, 9};
qsort(arr, 5, sizeof(int), compare);
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]); // Ожидается: 1 2 5 8 9
}
return 0;
}