paulo1205
(usa Ubuntu)
Enviado em 14/06/2016 - 13:56h
listeiro_037 escreveu:
Não entendi qual pode ser o erro no site citado como exemplo.
Se puder explicar agradeceria.
A URL que eu coloquei realmente não foi a melhor. O C++ FAQ fala de quatro graves problemas com macros, o link que eu coloquei foi o do problema 2 (que foi o que apareceu primeiro no Google), e realmente não reflete os problemas na implementação que você propôs. Mas os links para os demais problemas estão ali.
Mas o que imaginei seria uma coisa bem assim:
#define NDX(I,J) I*N+J
O primeiro problema é que
N deveria ser passado também como argumento à macro. Você pode até assumir
N como global, mas isso seria um tiro do escuro -- qualquer função pode redeclarar
N localmente, ou usar outro nome (ou mesmo nome nenhum, preferindo constantes) na hora de fazer suas alocações.
Ou como meu professor ensinou, que macros possuem problemas de substituição de valores por extenso.
Devem ser colocados parêntesis na fórmula a ser inserida para não ocorrer erro na substituição.
Deixarei sem.
Pois é... Nesse caso, deveria usar parênteses (ou, no mínimo, espaços). Imagine que você percorre o array em loop, e usa algo com a seguinte forma:
matriz[NDX(N, i, ++j)]=algum_valor;
A expansão da macro vai resultar no seguinte:
matriz[i*N+++j]=algum_valor;
Responda rápido -- quem vai ser incrementado:
N ou
j?
Parou para pensar? Na verdade, o incremento será sobre
N, que certamente não era o que você queria. Esse é um dos motivos pelos quais eu coloquei o link para as postagens da C++ FAQ que dizem que “
macros are evil”.
Outra possibilidade seria função inline, onde o compilador pode ou não substituir o código localmente. Ou não.
O pensamento parece ser mais simples para não criar o varal de memórias alocadas.
Inclusive no caso de hipermatrizes. NxNxNx ... xN.
Pois é... De certo modo, como disse em minha mensagem, há vantagens em fazer como você sugeriu. Mas há também vantagens em fazer com múltiplos níveis de ponteiros. A mais óbvia é usar a mesma sintaxe para acesso a elementos em matrizes declaradas como tais (e.g. “
int matriz[10][20]”) e para matrizes emuladas através de ponteiro para ponteiro. Outra vantagem é poder apontar para uma linha inteira de uma só vez, permitindo passá-la como vetor para uma função que espere um vetor, referindo-se a ela simplesmente como “
matriz[i]” (em vez de “
matriz+N*i” ou “
&matriz[N*i]”, que sua solução requereria). Outra operação que seria facilitada pelo duplo nível de alocações é que a eventual remoção ou inserção de uma linha no meio da matriz feita com ponteiro de ponteiro seria uma operação O(n) (deslocamento do ponteiro para o início de cada linha a ser movida), ao passo que com um array linear obrigaria a uma operação O(n²) (deslocamento de todos os elementos afetados).