Ir para o conteúdo
B. Inácio

Arrays multidimensionais

Mensagens Recomendadas

B. Inácio

Olá, pessoal.

Estou com uma dúvida aqui com relação a arrays multidimensionais...

Na verdade, não é algo que eu pretendo usar normalmente, sei que não se enquadraria nas boas práticas de programação, é só uma dúvida mesmo de como a linguagem funciona.

Por exemplo, um vetor funciona como um ponteiro que aponta para o primeiro elemento da array e a partir dai, somamos o índice à posição de memória do primeiro valor, portanto, podemos acessar um vetor como: *(vetor + índice). Para isso, as variáveis precisam ficar em sequência à partir da primeira. Ok.

Minha dúvida é se isso também acontece nas arrays multidimensionais ou se elas são apenas uma espécie de "vetor de ponteiros", em que os locais apontados não precisam estar em sequencia.

Não sei se me expressei muito bem, então vou dar um exemplo: para acessar uma array bidimensional

int i[2][2];

Eu poderia acessar i[1][1] para pegar o quarto elemento ou utilizar *(*(i + 1) + 1). Nesse caso, eu poderia conseguir acessar essa mesma posição com um i[0][3] ou um *(*i+3)?

Eu fiz o teste aqui e resultou nos valores corretos, mas não sei se foi apenas uma coincidência ou algo que ocorre no meu compilador mas que não é padrão da linguagem, então resolvi tirar a dúvida aqui.

Desculpem os erros de Português g.g

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

Sugiro-te uma leitura da seccao 6 do FAQ do comp.lang.c (e, uma vez que la vais, das outras seccoes).

O que se passa é que, com i[0][3] ou *(*i + 3) estas a misturar alhos com bugalhos (mas praticamente ninguem nota a diferenca por isso funciona)

i[0] representa um array com dois elementos; i[0][3] é um acesso ilegal a um elemento que nao existe.

em *(*i + 3), o i "decai" para um ponteiro para um array com 2 ints. Depois O *i + 3, ilegalmente, aponta para fora do array.


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
B. Inácio

pmg, um pouco antes de ver a sua resposta, encontrei um site que converte códigos em C para assambly e fiz o teste. Ele me retornou exatamente:


#include <stdio.h>

int main(void) {
int t[2][2] = {
{1, 2},
{3, 4}
};
printf("%d", t[1][0]);
printf("%d", t[0][2]);
return 0;
}

resulta em:


.LC0:
.string "%d"
main:
subq $8, %rsp
movl $3, %edx
movl $.LC0, %esi
movl $1, %edi
xorl %eax, %eax
call __printf_chk
movl $3, %edx
movl $.LC0, %esi
movl $1, %edi
xorl %eax, %eax
call __printf_chk
xorl %eax, %eax
addq $8, %rsp
ret

Pelo que eu entendi, seria o mesmo código.

Eu entendo que não é uma coisa muito "certa" de se fazer e nem pretendo usar isso em um código. É mais para entender mesmo como funciona. Na verdade, eu só estou postando isso agora porque eu estava lendo alguns livros na internet encontrei um exemplo com este código:

{
int i,M[10][10];
int *p; // o sinal * indica que a variável é do tipo ponteiro
p=&M[0][0]; // atribui o endereço do primeiro elemento de M
for (i=0; i <100; i++)
*(p+i)=0; // preenche a matriz M com o valor zero
}

Eu até entendi essa parte de uma array não ser exatamente a mesma coisa que um ponteiro, apesar de ter muita relação. Vendo o link que você me enviou, encontrei:

http://c-faq.com/aryptr/ary2dfunc2.html

que diz:

void f2(int *aryp, int nrows, int ncolumns)
{ ... array[i][j] is accessed as aryp[i * ncolumns + j] ... }

isso não seria o mesmo que o que eu disse como i[0][3]?

Editado por B. Inácio

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

O valor de &array[0] e o valor de &array[0][0] sao o mesmo (embora sejam de tipos diferentes).

Se conseguires fazer o compilador aceitar uma atribuicao de um valor do primeiro tipo a uma variavel do segundo tipo (que é uma coisa ilegal, mas com um cast o compilador nao se queixa) podes fazer os acessos como sugeres.

Isto porque a propria linguagem diz que os varios elementos de um array estao contiguos sem espaco extra a separa-los; e porque um array multidimensional é apenas uma forma facilitada de pensar para nos humanos, para o compilador um array multidimensional é pura e simplesmente um array em que os elementos sao arrays.


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
B. Inácio

Ok, agora eu entendi.

Uma última questão, que me veio a dúvida agora. Na maioria dos exemplos e livros que eu vi, davam apenas a passagem de array para ponteiro usando um ponteiro comum e não um ponteiro para array. É melhor mesmo usar sempre apenas ponteiros, ou tem algum caso específico que seja melhor utilizar o ponteiro para array?

Pelo que eu vi até agora, até mesmo no c-faq, os ponteiros para array fariam a mesma coisa e não parecem ter um beneficio sobre os ponteiros comuns, além de serem mais trabalhosos.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

Basicamente ... geralmente é mais cómodo (embora vá contra a "pequena" type-safety do C) usar ponteiros simples.

Usar ponteiros para arrays, além da sintaxe "esquisita", limita o programa para arrays com o tamanho especificado. Se for isso que precisas (por exemplo não é de prever que o número de cartas num baralho se altere para qualquer coisa diferente de 52, ou que um ano passe a ter 10 meses, ...), é melhor usar ponteiros para arrays.


What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.