Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Porque isso aconteceu?

Pessoal estou estudando C pra um concurso e queria que alguém me explicasse, pode ser comentando linha a linha o que acontece nesse código:

#include<stdio.h>

int main(){
    int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12};
        //aqui eu entendi que como ele omite o número nos primeiro parenteses o número seria 3 (3 linhas, 4 colunas)
    int i;
    for(i=0;i<3;++i){
        //For vai de 0 a 2... (0,1,2)
        printf("%d",*(a[i]+1));
        // Pelo resultado, entendi que a[0] seria equivalente a a[0][0]
        // e que que a[1] seria equivalente a a[1][0]
         // ele só omitiu o valor correspondente à coluna
        // e o +1 seria pra andar uma casa para a direita, gerando o resultado abaixo
        // mas gostaria de entender o conceito por trás disso
        // e se possível saber qual seria o equivalente a esse expressão
        // usando o nosso famoso a[1][0]~de outras linguagens
    }
}

O resultado é 2610

2 respostas
solução!

Oi Rafael.

Para tudo fazer sentido você precisa ter em mente que C é uma linguagem que utiliza aritmética de ponteiros. Ponteiros são nada mais do que endereços. Quando queremos acessar o endereço de uma variável usamos o prefixo & antes da mesma, um exemplo clássico está na função scanf, que recebe como parâmetro o endereço da variável que você deseja ler. Agora, quando queremos acessar o conteúdo de um endereço usamos o prefixo *, usado nesse código que você mandou por exemplo.

Sabendo disso, você precisa saber que em C, matrizes e vetores são internamente representados como endereços, por exemplo, se eu declaro um vetor

int v[3];

A linguagem guarda em v o endereço da primeira posição do vetor, sendo assim,

v[0] é equivalente a *(v)
 v[1] é equivalente a *(v + 1)
 v[2] é equivalente a *(v + 2)

Outra coisa importante é que o C guarda matrizes e vetores sequencialmente e por linha na memória, isso significa que se você tem uma matriz

1 2
3 4

O C armazenará na memória como 1 2 3 4, isso significa que se você tem o endereço da do primeiro elemento da primeira linha e se você somar 1 nesse endereço, você tem o segundo elemento da primeira linha, por isso que na primeira linha do seu código, a declaração foi feita como

int a[][4]

O número de linha pode ser omitido pois como expliquei acima o C não precisa dele para acessar determinado elemento, por exemplo, quando quero o primeiro elemento da terceira linha, o C pega o endereço da primeira e soma 3 vezes o número de colunas, e com isso estamos no primeiro elemento da linha 3, faz sentido? Perceba que não é possível fazer o contrário, declarar algo como int a[3][]; pois o C não saberia quantas colunas a matriz tem e como expliquei logo acima ele não conseguiria acessar os elementos da matriz.

Quanto ao for você está certo, ele itera 3 vezes, na linha dentro do for ele faz

printf("%d", *(a[i] + 1));

Agora que você sabe o que são ponteiros, a[i] é o ponteiro, ou seja, endereço da linha i, que aponta para o primeiro elemento da linha i, seguindo essa ideia, a[i] + 1 aponta para o segundo elemento da linha i, perceba que a[i] + 1 é o endereço da linha a[i] + 1, mas o valor impresso é *(a[i] + 1), ou seja, o conteúdo do segundo elemento da linha i.

Sendo assim quando:

i é 0 imprimimos o segundo elemento da linha 0 que é 2, quando i é 1 imprimimos o segundo elemento da linha 1 que é 6, quando i é 2 imprimimos o segundo elemento da linha 2 que é 10, resultando em 2610. Faz sentido?

Bom, eu não sei onde fica o emoticon das palmas, portanto fico sem ter como agradecer. VALEU MESMO!

Muito esclarecedor!!! OBRIGADO!