Como o comprimento de uma matriz em C é determinado?


Melhor resposta

Não está claro o que você está perguntando, mas presumo que a questão seja dada uma matriz , como você determina seu comprimento.

C tem vários tipos de arrays: arrays de tamanho desconhecido, arrays de tamanho constante conhecido e arrays de comprimento variável.

Para um array de tamanho constante, o tamanho é parte de seu tipo: o comprimento de uma matriz cujo tipo é int[10] é exatamente 10. C não tem mecanismo para extrair isso diretamente do tipo (ao contrário de C ++ ), mas você pode fazer isso indiretamente por meio de sizeof:

int a[] = {1,2,3,4,5,6,7,8,9,0};

size\_t sz = sizeof a / sizeof *a; // or .../sizeof a[0], same thing

printf("size = \%zu\n", sz);

O tamanho de uma matriz de comprimento variável também pode ser calculado com sizeof, com código idêntico. Nesse caso, ele é executado em tempo de execução:

scanf("\%d", &x);

int a[x];

size\_t sz = sizeof a / sizeof *a;

printf("size = \%zu\n", sz);

Finalmente, os arrays de limite desconhecido têm, por definição, tamanho desconhecido. Você teria que obtê-lo por meio da lógica do programa

extern int a[];

size\_t sz = something\_from\_the\_module\_that\_defines\_a();

Uma ressalva, é claro, arrays nus em C não podem ser passados ​​para funções e, portanto, os tamanhos devem ser calculados no lado do chamador e passados ​​separadamente:

void f(int *a, size\_t sz);

int a[] = {1,2,3,4,5,6,7,8,9,0};

f(a, sizeof a / sizeof *a);

matrizes de membros podem ser passadas para funções por valor:

struct a10 {int a[10];};

void f(struct a10 s) {

size\_t sz = sizeof s.a / sizeof *s.a;

}

Resposta

A principal questão é: você pesquisará várias vezes. Em caso afirmativo, crie uma tabela hash ou outro índice uma vez para encontrar as coisas rapidamente. Uma tabela hash pode ser gerada ao mesmo tempo em que os dados são lidos do disco (se for de onde eles vêm).

Se isso acontecer uma única vez e os dados forem carregados do disco, faça a pesquisa se sobrepôs ao IO. Podem ser usados ​​2 ou mais buffers.

Outra pergunta é se você está apenas interessado em saber se algo está presente ou se há dados associados que deseja recuperar? Se você apenas deseja saber se um número está presente, uma matriz de bits pode ser usada para uma representação mais compacta.

Além disso, o código C embutido usando a comparação mais rápida é melhor; Use todas as opções de otimização que o compilador oferece. Alguns compiladores podem gerar o mesmo código rápido, independentemente de você usar ponteiros, contadores ou indexação:

int * first = ..., * last = ...;

for ( ; first <= last; ++first ) if ( *first == target ) ...

ou

int * first = ..., count = ...;

for ( ; count-- > 0; ++first ) if ( *first == target ) ...

ou

int * first = ..., count = ..., index = ...;

for ( ; index < count; ++index ) if ( first[index] == target ) ...

Você pode considerar uma trapaça pedir ao compilador para gerar a fonte do assembler para ter uma idéia do que está fazendo, mas os compiladores menores podem exigir isso se você estiver realmente preocupado com o desempenho - apenas para ver que forma de código C gera o melhor resultado.

Então, há outras coisas que você pode fazer, como usar vários threads: Se você tiver 8 núcleos disponíveis, poderá dividir o array em 8 seções e lançar um thread para cada seção. Mas o custo de iniciar os threads pode ser muito alto se o custo de comparação for baixo.

O array pode ser grande, então a troca de memória virtual pode retardar as coisas. Usar seu próprio backup de arquivo mapeado de memória pode permitir que você controle o mapeamento e desmapeamento para manter baixo o uso de memória física. Você pode remover o mapeamento de uma seção que acabou de pesquisar, para que a memória possa ser usada em seções posteriores.

Apenas algumas idéias. Boa sorte.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *