<stdlib.h>

No cabeçalho <stdlib.h> estão localizadas as funções responsáveis pela manipulação da alocação (e desalocação) dinâmica de memória, bem como funções para converter strings em valores numéricos (como double ou int). Além disso, a biblioteca fornece utilitários gerais como geração de números pseudoaleatórios, controle do fluxo do programa e algoritmos padrão de busca e ordenação.

Variáveis e Tipos

  • size_t: Tem por finalidade indicar o tamanho, em bytes, que uma variável ou objeto ocupa na memória. É um tipo inteiro sem sinal.
  • wchar_t: Tem por finalidade representar caracteres com codificação ampla (wide characters), ou seja, caracteres com códigos maiores que aqueles que o tipo char tradicional suporta.
  • div_t: Estrutura (struct) que contém dois campos do tipo int (quot e rem); armazena o quociente e o resto da divisão entre dois números.
  • ldiv_t: Estrutura (struct) que contém dois campos do tipo long int (quot e rem); armazena o quociente e o resto da divisão entre dois números.

Macros

  • NULL: Macro utilizado para indicar que um ponteiro não aponta para um endereço de memória válido.
  • EXIT_FAILURE: Macro utilizado para indicar (via função exit) que um programa foi finalizado de forma inesperada ou com erro.
  • EXIT_SUCCESS: Macro utilizado para indicar que um programa foi finalizado corretamente e com sucesso.
  • RAND_MAX: Macro que indica o valor máximo absoluto que pode ser retornado pela função rand().
  • MB_CUR_MAX: Valor máximo (em bytes) que um caractere multibyte pode ocupar no locale atual.

Funções

double atof(const char *stringNum)

Converte uma string (cadeia de caracteres) para um valor de ponto flutuante (double).

Recebe: Uma variável que seja um array de caracteres representando um número.

Retorna: O número presente na string convertido para o tipo double.

Exemplo

// EXEMPLO ATOF()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    char *exemplo = "42\0";
    double resposta = atof(exemplo);

    printf("%.0lf é a resposta!!!\n", resposta);

    return 0; 
}

Saída esperada

>./main 
42 é a resposta!!!

int atoi(const char *stringNum)

Converte uma string (cadeia de caracteres) para um valor inteiro (int).

Recebe: Uma string na qual um número esteja sendo representado.

Retorna: O número presente na string convertido para o tipo int.

Exemplo

// EXEMPLO ATOI()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    char *exemplo = "42\0";
    int resposta = atoi(exemplo);

    printf("%d é a resposta!!!\n", resposta);

    return 0; 
}

Saída esperada

>./main 
42 é a resposta!!!

long atol(const char *stringNum)

Converte uma string (cadeia de caracteres) para um valor inteiro longo (long).

Recebe: Uma string na qual um número esteja sendo representado.

Retorna: O número presente na string convertido para o tipo long.

Exemplo

// EXEMPLO ATOL()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    char *exemplo = "42\0";
    long int resposta = atol(exemplo);

    printf("%ld é a resposta!!!\n", resposta);

    return 0; 
}

Saída esperada

>./main 
42 é a resposta!!!

double strtod(const char *stringComNum, char **resto)

Lê um número de ponto flutuante de uma string e armazena o restante não numérico em um ponteiro.

Recebe: Uma string inicializada com um número e um ponteiro para ponteiro que guardará o restante da string não convertida.

Retorna: O número no início da string convertido para double.

Exemplo

// EXEMPLO STRTOD()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    char *exemplo = "42 é a resposta!!!\0";
    double resposta = strtod(exemplo, NULL);

    printf("%.0lf!!!\n", resposta);

    return 0; 
}

Saída esperada

>./main 
42!!!

long int strtol(const char *stringComNum, char **resto, int base)

Converte o prefixo de uma string para um número do tipo long int baseado numa base numérica (ex: 10, 16).

Recebe: A string com o número, o ponteiro de sobra e a base numérica da conversão.

Retorna: O número convertido para long int na base indicada.

Exemplo

// EXEMPLO STRTOL()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    char *exemplo = "42 é a resposta!!!\0";
    long int resposta = strtol(exemplo, NULL, 10);

    printf("%ld!!!\n", resposta);

    return 0; 
}

Saída esperada

>./main 
42!!!

unsigned long int strtoul(const char *stringComNum, char **resto, int base)

Similar ao strtol, mas converte para um unsigned long int.

Recebe: A string original, o ponteiro para o texto que sobra e a base.

Retorna: O número convertido para unsigned long na base indicada.

Exemplo

// EXEMPLO STRTOUL()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    char *exemplo = "42 é a resposta!!!\0";
    unsigned long int resposta = strtoul(exemplo, NULL, 10);

    printf("%lu!!!\n", resposta);

    return 0; 
}

Saída esperada

>./main 
42!!!

int rand()

Gera números inteiros pseudoaleatórios dentro do limite de 0 até RAND_MAX.

Recebe: Não recebe parâmetros.

Retorna: Um número inteiro, não negativo, "aleatório".

Exemplo

// EXEMPLO RAND()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    // Número randômico entre 0 e 9
    int randomico = rand() % 10;
    printf("%d.\n", randomico);

    // Número randômico entre 0 e 41
    randomico = rand() % 42;
    printf("%d não é a resposta...\n", randomico);

    return 0; 
}

Saída esperada

>./main 
3. 
3 não é a resposta...

void srand(unsigned int semente)

Configura o valor inicial ("semente") para a geração dos números da função rand().

Recebe: Uma semente numérica (geralmente usamos o tempo atual via time(NULL)).

Retorna: void. Sem retorno, altera o estado interno do gerador aleatório.

Exemplo

// EXEMPLO SRAND()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    // Ao definir a mesma semente, rand gerará sempre a mesma sequência
    srand(42); 

    int randomico = rand() % 10;
    printf("%d.\n", randomico);

    return 0; 
}

Saída esperada

>./main 
6.

void *calloc(size_t quantidadeElementos, size_t tamanhoDoTipo)

Aloca dinamicamente um bloco de memória para um array de elementos e os inicializa com zero.

Recebe: A quantidade de blocos a serem alocados e o tamanho em bytes do tipo.

Retorna: O ponteiro para o início da memória alocada, ou NULL em caso de falha.

Exemplo

// EXEMPLO CALLOC()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    int *numero = (int *)calloc(1, sizeof(int));
    
    // Como foi usado calloc, o valor inicializa como zero.
    printf("%d não é a resposta...\n", *numero);

    *numero = 42;
    printf("%d é a resposta em uma variável dinamicamente alocada!\n", *numero);

    free(numero);
    return 0; 
}

Saída esperada

>./main 
0 não é a resposta... 
42 é a resposta em uma variável dinamicamente alocada!

void *malloc(size_t tamanhoDoTipo)

Aloca dinamicamente um bloco de memória, mas diferentemente do calloc, o conteúdo não é inicializado (pode conter "lixo" de memória).

Recebe: A quantidade exata de memória a ser alocada (comumente usando sizeof).

Retorna: O ponteiro para o endereço inicial do espaço alocado.

Exemplo

// EXEMPLO MALLOC()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    int *numero = (int *)malloc(sizeof(int));

    // Valor será lixo (imprevisível), vamos sobrescrevê-lo:
    *numero = 42;
    printf("%d é a resposta em uma variável dinamicamente alocada!\n", *numero);

    free(numero);
    return 0; 
}

Saída esperada

>./main 
42 é a resposta em uma variável dinamicamente alocada!

void *realloc(void *ponteiro, size_t tamanhoDoTipo)

Redimensiona (aumenta ou diminui) o tamanho de um bloco de memória que foi previamente alocado.

Recebe: O ponteiro da memória antiga e o novo tamanho em bytes.

Retorna: O ponteiro do novo bloco alocado.

Exemplo

// EXEMPLO REALLOC()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    int *numero = (int *)malloc(sizeof(int));
    *numero = 42;

    printf("%d é a resposta!\n", *numero);

    // Expande a memória para suportar 10 inteiros
    numero = (int *)realloc(numero, 10 * sizeof(int));

    for (int i = 0; i < 10; i++) {
        numero[i] = 42;
    }

    for (int i = 0; i < 10; i++) {
        printf("%d ", numero[i]);
    }
    putchar('\n');

    free(numero);
    return 0; 
}

Saída esperada

>./main 
42 é a resposta! 
42 42 42 42 42 42 42 42 42 42

void free(void *ponteiro)

Libera manualmente o espaço de memória que foi previamente alocado (evitando memory leaks).

Recebe: O ponteiro que aponta para a variável dinamicamente alocada.

Retorna: void.

Exemplo

// EXEMPLO FREE()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    int *numero = (int *)malloc(sizeof(int));
    *numero = 42;

    free(numero); 
    printf("Ponteiro liberado!\n");

    return 0; 
}

Saída esperada

>./main 
Ponteiro liberado!

void abort()

Interrompe forçadamente o programa gerando um sinal SIGABRT.

Recebe: Não recebe parâmetros.

Retorna: void; interrompe e aborta o programa imediatamente.

Exemplo

// EXEMPLO ABORT()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    printf("Essa mensagem será mostrada na saída padrão.\n");

    abort();

    printf("Essa mensagem não será mostrada...\n");
    return 0; 
}

Saída esperada

>./main 
Essa mensagem será mostrada na saída padrão. 
Aborted (core dumped)

void exit(int status)

Termina a execução do programa e retorna o código de status ao sistema operacional (0 = sucesso).

Recebe: O código de status (int).

Retorna: O status do término e finaliza no ponto chamado.

Exemplo

// EXEMPLO EXIT()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    int numero = 422;

    if (numero != 42) { 
        printf("Saindo com erro...\n");
        exit(EXIT_FAILURE); 
    } 
    return EXIT_SUCCESS; 
}

Saída esperada

>./main 
Saindo com erro...

int atexit(void (*funcao)(void))

Registra uma função específica para ser chamada logo antes de o programa terminar com sucesso.

Recebe: Um ponteiro para a função desejada.

Retorna: Um inteiro não nulo caso haja falha, 0 se registrado com sucesso.

Exemplo

// EXEMPLO ATEXIT()
#include <stdio.h>
#include <stdlib.h>

void respostaFinal() { 
    printf("42 é a resposta!\n"); 
}

int main() { 
    atexit(respostaFinal);

    printf("Mensagem qualquer antes de finalizar o programa...\n");

    return 0; 
}

Saída esperada

>./main 
Mensagem qualquer antes de finalizar o programa... 
42 é a resposta!

int system(const char *comandoSO)

Passa um comando como string para o processador de comandos hospedeiro (shell/terminal).

Recebe: O comando a ser executado.

Retorna: O status do shell (específico da implementação do SO).

Exemplo

// EXEMPLO SYSTEM()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    system("echo \"42 é a resposta!\"");

    return 0; 
}

Saída esperada

>./main 
42 é a resposta!

char *getenv(const char *nomeVariavel)

Acessa uma variável de ambiente do sistema operacional.

Recebe: O nome da variável de ambiente procurada.

Retorna: A string com o valor apontado ou NULL se a variável não existir.

Exemplo

// EXEMPLO GETENV()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    char *path = getenv("HOME"); // ou "USERPROFILE" no Windows

    if(path != NULL) {
        printf("%s\n", path);
    }
    return 0; 
}

Saída esperada

>./main 
/home/user

void *bsearch(const void *chave, const void *array, size_t tamanhoDoArray, size_t tamanhoDoTipo, int (*compara)(const void *, const void *))

Realiza uma busca binária em um array ordenado em busca de um elemento.

Recebe: O valor chave (referência), o array alvo, o número de elementos, o tamanho em bytes de um único item e o ponteiro da função de comparação.

Retorna: O ponteiro indicando o endereço em que a chave foi encontrada ou NULL se não estiver no array.

Exemplo

// EXEMPLO BSEARCH()
#include <stdio.h>
#include <stdlib.h>

int compara(const void *a, const void *b) { 
    return (*((int *)a) - *((int *)b)); 
}

int main() { 
    int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int chave = 9;
    int *achou;

    achou = bsearch(&chave, array, 10, sizeof(int), compara);

    if (achou == NULL) {
        printf("O número informado não está no array.\n"); 
    } else {
        printf("O número %d está no array!\n", *achou);
    }

    return 0; 
}

Saída esperada

>./main 
O número 9 está no array!

void qsort(void *array, size_t tamanhoDoArray, size_t tamanhoDoTipo, int (*compara)(const void *, const void *))

Ordena um array (usualmente utilizando o algoritmo Quick Sort) utilizando uma função de avaliação externa.

Recebe: O array que será ordenado, sua quantidade de elementos, o tamanho de cada elemento e a função de comparação que orienta a ordem crescente.

Retorna: void; organiza os dados localmente no próprio array.

Exemplo

// EXEMPLO QSORT()
#include <stdio.h>
#include <stdlib.h>

int compara(const void *a, const void *b) { 
    return (*((int *)a) - *((int *)b)); 
}

int main() { 
    int array[10] = {7, 8, 3, 5, 9, 1, 4, 6, 10, 2};

    printf("Array antes:\n"); 
    for (int i = 0; i < 10; i++) printf("%d ", array[i]); 
    putchar('\n');

    qsort(array, 10, sizeof(int), compara);

    printf("Array após:\n"); 
    for (int i = 0; i < 10; i++) printf("%d ", array[i]); 
    putchar('\n');

    return 0; 
}

Saída esperada

>./main 
Array antes: 
7 8 3 5 9 1 4 6 10 2 
Array após: 
1 2 3 4 5 6 7 8 9 10

int abs(int numero)

Retorna o valor absoluto de um número inteiro.

Recebe: O número inteiro que se deseja obter o módulo.

Retorna: O módulo (valor positivo correspondente) do parâmetro passado.

Exemplo

// EXEMPLO ABS()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    int valor = -42;

    printf("Número informado: %d\n", valor);
    printf("Módulo: %d\n", abs(valor));

    return 0; 
}

Saída esperada

>./main 
Número informado: -42 
Módulo: 42

long int labs(long int numero)

Retorna o valor absoluto de um número inteiro longo.

Recebe: O número do tipo long int para módulo.

Retorna: O módulo positivo correspondente.

Exemplo

// EXEMPLO LABS()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    long int valor = -42;

    printf("Número informado: %ld\n", valor);
    printf("Módulo: %ld\n", labs(valor));

    return 0; 
}

Saída esperada

>./main 
Número informado: -42 
Módulo: 42

div_t div(int numerador, int denominador)

Retorna simultaneamente o quociente e o resto de uma divisão entre dois inteiros.

Recebe: Os dois inteiros envolvidos.

Retorna: Um struct do tipo div_t contendo o resultado (quot) e o resto (rem).

Exemplo

// EXEMPLO DIV()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    int numerador = 9; 
    int denominador = 3;

    div_t divisao = div(numerador, denominador);

    printf("A divisão de %d por %d resulta em: %d\n", numerador, denominador, divisao.quot);
    printf("O resto da divisão é: %d\n", divisao.rem);

    return 0; 
}

Saída esperada

>./main 
A divisão de 9 por 3 resulta em: 3 
O resto da divisão é: 0

ldiv_t ldiv(long int numerador, long int denominador)

Similar à função div(), mas lidando com números inteiros longos.

Recebe: Os dois inteiros longos envolvidos.

Retorna: Um struct do tipo ldiv_t com quociente e resto.

Exemplo

// EXEMPLO LDIV()
#include <stdio.h>
#include <stdlib.h>

int main() { 
    long int numerador = 9; 
    long int denominador = 3;

    ldiv_t divisao = ldiv(numerador, denominador);

    printf("A divisão de %ld por %ld resulta em: %ld\n", numerador, denominador, divisao.quot);
    printf("O resto da divisão é: %ld\n", divisao.rem);

    return 0; 
}

Saída esperada

>./main 
A divisão de 9 por 3 resulta em: 3 
O resto da divisão é: 0