#include // Para int64_t
#include
#include // Para malloc e free
/**
* @brief Calcula o quadrado de números pares em um intervalo e os armazena em um array alocado dinamicamente.
*
* Esta função aloca dinamicamente a memória para o array de resultados.
* O chamador (caller) é responsável por liberar a memória alocada com free()
* após o uso para evitar vazamentos de memória (memory leak).
*
* Otimizações e Boas Práticas:
* 1. Usa int64_t (de ) para 'number', 'x', e os resultados para lidar com
* números grandes (até 700.000.000 e seus quadrados).
* 2. Calcula o tamanho exato necessário para o array antes da alocação.
* - Apenas números pares são incluídos, o que reduz o tamanho pela metade (aproximadamente).
* 3. Retorna o array por meio de um ponteiro e usa um ponteiro adicional (result_size)
* para retornar o tamanho real do array alocado.
* 4. Verifica a alocação de memória (malloc).
*
* @param number O limite superior inclusivo do intervalo (começando em 1).
* @param result_size Ponteiro para armazenar o tamanho real do array de retorno.
* @return Um ponteiro para o array int64_t alocado dinamicamente contendo os quadrados,
* ou NULL em caso de falha na alocação.
*/
int64_t *square(int64_t number, int64_t *result_size) {
// 1. Otimização: Calcular o tamanho exato do array.
// O loop itera de 1 a 'number'.
// A cada 2 números, 1 é par (2, 4, 6...).
// O número de pares é floor(number / 2).
int64_t count = number / 2;
if (count < 0) { // Garante que o número de elementos não é negativo se 'number' fosse negativo
count = 0;
}
// Armazena o tamanho real do array no ponteiro de saída.
*result_size = count;
// Se não houver elementos (count == 0), retorna NULL imediatamente (boa prática)
if (count == 0) {
return NULL;
}
// 2. Alocação Dinâmica de Memória (Heap).
// Aloca 'count' elementos do tamanho de int64_t (8 bytes)
int64_t *list_squared = (int64_t *)malloc(count * sizeof(int64_t));
// 3. Verificação de Falha na Alocação (Boa Prática).
if (list_squared == NULL) {
perror("Falha na alocacao de memoria"); // Imprime uma mensagem de erro
*result_size = 0; // Garante que o tamanho retornado é 0
return NULL;
}
// 4. Preenchimento do Array.
// Não precisamos de 'if (x % 2 == 0)' dentro do loop, pois sabemos que:
// O primeiro par é 2. O k-ésimo par é 2 * (k + 1), onde k começa em 0.
// Simplificando: O par é 2 * (i), onde i começa em 1.
// O loop interno fará 'count' iterações.
// 'i' será o índice do array, de 0 a count-1.
// 'x' será o valor par a ser elevado ao quadrado: 2 * (i + 1).
for (int64_t i = 0; i < count; i++) {
int64_t x = 2 * (i + 1);
list_squared[i] = x * x;
}
return list_squared;
}
// Função main (equivalente ao print(square(...)) do Python)
int main() {
// Usamos um literal long long (sufixo LL) para garantir 64 bits para o valor de entrada
const int64_t INPUT_NUMBER = 1000000000LL;
int64_t size = 0;
// Chama a função e passa o endereço da variável 'size' para receber o tamanho.
int64_t *result_array = square(INPUT_NUMBER, &size);
// Verifica se a função retornou um array válido (não NULL).
if (result_array != NULL) {
// Exemplo: Imprime apenas o primeiro e o último elemento.
// O array completo é muito grande para imprimir.
printf("Chamando square(%lld)\n", INPUT_NUMBER);
printf("Tamanho do array de retorno: %lld\n", size);
if (size > 0) {
printf("Primeiro elemento (quadrado de 2): %lld\n", result_array[0]);
// O último valor par é 2 * floor(700.000.000 / 2) = 700.000.000
// O último índice é size - 1
printf("Ultimo elemento (quadrado de %lld): %lld\n", (size * 2), result_array[size - 1]);
}
// 5. Liberação de Memória (Boa Prática de C).
// É crucial liberar a memória que foi alocada por malloc dentro da função 'square'.
free(result_array);
result_array = NULL; // Boa prática: evitar ponteiros pendentes (dangling pointers)
} else {
printf("A funcao square(%lld) retornou um array vazio ou falhou na alocacao de memoria.\n", INPUT_NUMBER);
}
return 0;
}