Ajuda com matriz e ponteiros em C

1. Ajuda com matriz e ponteiros em C

Larissa Fiorini
larissaf

(usa Linux Mint)

Enviado em 28/06/2014 - 17:25h

Olá, como posso fazer para passar uma matriz bidimensional para um procedimento e no procedimento alterar a matriz e ela voltar alterada para o main principal? Sei que preciso usar ponteiros, mas como ela é do tipo char(pois é composta de letras), nao sei como utilizar o ponteiro.. Vocês poderiam me ajudar com algum exemplo ou dica???
Eu preciso muitoo de ajuda, obrigada!!


  


2. Re: Ajuda com matriz e ponteiros em C

???
gokernel

(usa Linux Mint)

Enviado em 29/06/2014 - 09:56h


Mostre o seu código... ajudamos ... não fazemos o dever de casa ... ;)

T+.



3. Re: Ajuda com matriz e ponteiros em C

Luis R. C. Silva
luisrcs

(usa Linux Mint)

Enviado em 29/06/2014 - 10:47h

Passagem por referência geralmente é:

funcao(char *matriz){
}

Para chamá-la:

função(&matriz);


Na função utiliza-se o * (asterisco) para informar que ele recebe um ponteiro de char; e na chamada utiliza o & (e comercial) para passar o endereço da matriz.


4. Re: Ajuda com matriz e ponteiros em C

Paulo
paulo1205

(usa Ubuntu)

Enviado em 30/06/2014 - 03:17h

luisrcs escreveu:

[...]

e na chamada utiliza o & (e comercial) para passar o endereço da matriz.


Cuidado aí! Se é uma matriz, quer estática (array), quer dinamicamente alocada através de ponteiros, você provavelmente não vai querer usar o operador &, pois o próprio identificador da matriz, se não vier acompanhado de nenhum índice entre colchetes, já é um endereço (do primeiro elemento, no caso de arrays, ou da primeira linha, no caso de ponteiro para ponteiro).

O que você sugeriu pode até funcionar para arrays estáticos (globais ou declarados dentro de funções com o modificador static) e automáticos (alocados na pilha, quando declarados dentro do corpo da função sem o modifcador static), mas, ainda que o uso com ou sem o & apontem para o mesmo endereço, o tipo do dado deixa de ser ponteiro para char e passa a ser ponteiro para array de char, e isso pode causar problemas caso se esteja compilando em C++ ou com diretivas do compilador C que reforcem verificação de tipos.

Particularmente, eu acho esse comportamento inadequado. O operador & serve para obter o endereço de um lvalue, mas arrays em C só são lvalues quando declarados como argumentos de função (quando são, na verdade, convertidos para ponteiros). Nunca li o padrão para ver se existe alguma justificativa, mas imagino que os comissários tenham optado pela uniformidade sintática (“se pode para arrays declarados como argumentos, deve poder para qualquer array”), inventando um comportamento ad hoc para quando o operando não é um lvalue, em lugar de criticar o operando e manter uniformidade funcional (que seria a minha escolha, se eu fosse um dos membros do comitê).


5. Re: Ajuda com matriz e ponteiros em C

Paulo
paulo1205

(usa Ubuntu)

Enviado em 30/06/2014 - 04:55h

larissaf escreveu:

Olá, como posso fazer para passar uma matriz bidimensional para um procedimento e no procedimento alterar a matriz e ela voltar alterada para o main principal? Sei que preciso usar ponteiros, mas como ela é do tipo char(pois é composta de letras), nao sei como utilizar o ponteiro.. Vocês poderiam me ajudar com algum exemplo ou dica???
Eu preciso muitoo de ajuda, obrigada!!


Antes de responder diretamente sua pergunta, quero esclarecer uns equívocos.

Você deve tomar cuidado para não confundir os tipos dos elementos da matriz com o tipo da própria matriz. char pode ser o tipo dos elementos de uma matriz de caracteres, mas pode haver diversos tipos de matrizes de caracteres diferentes e incompatíveis entre si, pois as dimensões (i.e. quantidade de linhas e colunas) fazem parte do tipo da matriz. No código abaixo, por exemplo, temos quatro tipos incompatíveis de matrizes cujos elementos são do tipo char, todas elas contendo vinte elementos.

char m1[2][10];  /* 2 linhas de 10 colunas */
char m2[4][5]; /* 4 linhas de 5 colunas */
char m3[5][4]; /* 5 linhas de 4 colunas */
char m4[10][2]; /* 10 linhas de 2 colunas */


Ainda um outro detalhe: muita gente inexperiente em C costuma confundir cadeias de caracteres (strings), que normalmente são representados por meio de arrays (também chamados de vetores) de char, com o próprio tipo char (uma variação do mesmo problema de nomenclatura que eu indiquei acima). Se o que você quer é uma matriz de strings, pode ter de apelar para arrays de char de três dimensões, como no exemplo abaixo.

char str_matrix[10][20][81]; /* matriz com 10 linhas de 20 colunas de strings com até 80 caracteres */ 


----

Agora, sua dúvida.

Se, no seu programa, você trabalha com matrizes de tamanho fixo, pode usar na declaração dos parâmetros das suas funções as mesmas dimensões que usou na declaração das matrizes que serão passadas como argumentos. Aliás, o compilador até facilita a sua vida, permitindo que você omita na declaração do argumento da função o tamanho da dimensão mais à esquerda (na verdade, ele o ignora). No exemplo abaixo, as funções f(), g() e h() aceitam sem problema como argumento a matriz m1, declarada dentro de main().

void f(char m[2][10]){
/* Acesso aos elementos na forma “m[lin][col]”. */
}

void g(char m[][10], int n_rows){
/* Acesso aos elementos na forma “m[lin][col]”. */
}

void h(char m[123456789][10]){
/* Acesso aos elementos na forma “m[lin][col]”. */
}


int main(void){
char m1[2][10];
f(m1); /* OK. */
g(m1, 2); /* OK. Informar explicitamente o número de linhas é sempre bom. */
h(m1); /* Surpreendente, mas OK! Tomara que h() não passe da segunda linha! */
/*
Na verdade, todas as funções ignoram a dimensão mais à esquerda do primeiro
parâmetro. Na prática, todas entendem o tipo do parâmetro como sendo,
literalmente, de acordo com o padrão da linguagem, “char (*)[10]”.
*/
return 0;
}


Se você trabalhar com matrizes de tamanhos diferentes e quiser que a mesma função processe todos elas, terá de fazer algo como abaixo.

void f(int *mat, int n_rows, int n_cols){
int i, j;
/* ... */
/* Acede ao elemento da j-ésima coluna da i-ésima linha. */
mat[n_cols*i+j]=some_int_value;
}


int main(void){
int m1[10][20];
int m2[3][4];

f((char *)m1, 10, 20); /* Necessário converter o tipo para “char *”. */
f((char *)m2, 3, 4); /* Necessário converter o tipo para “char *”. */

return 0;
}


Se você estiver trabalhando com alocação dinâmica, pode ser que suas matrizes sejam ponteiros de ponteiros, sendo responsabilidade sua guardar os endereços dos ponteiros e as dimensões de cada matriz dinamicamente alocada. Uma função que manipule seus elementos teria a seguinte forma.

void f(char **mat, int n_rows, int n_cols){
/* Use n_rows e n_cols para não exceder as dimensões da matriz. */
/* Acesso aos elementos na forma “mat[lin][col]”. */
}







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts