Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Como passar uma matriz por referência e valor em linguagem de programação C?
como a estrutura do protótipo da função vai ficar?
Exemplo.:
Tenho uma matriz bidimensional para receber dados do tipo string como segue abaixo:
#include <stdio.h>
#include <stdlib.h>
//prototipos
int inclusao (char *produtos);
int main(){
char produtos[1000][100];
printf("DIGITE A DESCRICAO: \n");
scanf("%s",produto);
getchar();
inclusao(&produtos);
}
Obs.:
* Sei que a forma como estruturei está errada, porém, não encontrei muita coisa na web que especifique a forma como quero fazer.
* Sei que em passagem de vetores e matrizes por referência neste formato, somente o primeiro índice da matriz vai ser passado para a função de la o restante é tranquilo, mas, o problema em si é como realmente funciona a passagem por referência de uma matriz para dar sequencia nela e trabalhar com ela a partir de outras funções, sem ter que passagem por valor em que se copia todo o conteúdo da matriz e passa para a função?
Primeiramente agradeço muito a atenção e o post de forma rápida!
Certo, a compreensão do que é passagem por referência que em "C" é feita com ponteiros, que passa o endereço de memória de um objeto compreendi o conceito.
Acontece, que não consegui estender este conceito aplicando em matrizes, não sei como referenciar o endereço da memoria da matriz em uma função.
Teria algum exemplo pratico e simples que não mostre um sistema ou um algoritmo comprido o objetivo é só ver como referenciar o ponteiro da matriz em uma função e também se possível colocar um protótipo da função com ela referenciada, também, algo bem pratico.
Se for possível exemplificar num exemplo da passagem de uma matriz para uma função qualquer e se de preferência ela for do tipo char, vai ajudar bastante.
Quando se declara como array:
#include <stdio.h>
void multiplica(int m[][3], int a) {
for(int i = 0; i<3; i++) {
for(int j=0; j<3; j++) {
m[i][j] = m[i][j] * a;
}
}
}
void imprime(int m[][3]) {
for(int i=0; i<3; i++) {
for(int j=0; j<3; j++) {
printf("%d%c",m[i][j], (j==2)?'\n':' ');
}
}
}
int main(void) {
int m[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
imprime(m);
puts("");
multiplica(m, 2);
imprime(m);
return 0;
}
Se você tentar escrever as funções utilizando a sintaxe de ponteiros, vai se deparar com alguns warnings e erros:
isis@linux:~/src/imasters> gcc-5 -Wall -Wextra -std=c99 matriz.c
matriz.c: In function ‘main’:
matriz.c:19:10: warning: passing argument 1 of ‘imprime’ from incompatible pointer type [-Wincompatible-pointer-types]
imprime(m);
^
matriz.c:10:6: note: expected ‘int **’ but argument is of type ‘int (*)[3]’
void imprime(int ** m) {
^
matriz.c:21:13: warning: passing argument 1 of ‘multiplica’ from incompatible pointer type [-Wincompatible-pointer-types]
multiplica(m, 2);
^
matriz.c:2:6: note: expected ‘int **’ but argument is of type ‘int (*)[3]’
void multiplica(int ** m, int a) {
^
matriz.c:22:10: warning: passing argument 1 of ‘imprime’ from incompatible pointer type [-Wincompatible-pointer-types]
imprime(m);
^
matriz.c:10:6: note: expected ‘int **’ but argument is of type ‘int (*)[3]’
void imprime(int ** m) {
^
isis@linux:~/src/imasters> gcc-5 -Wall -Wextra -std=c99 matriz.c
matriz.c: In function ‘main’:
matriz.c:19:10: warning: passing argument 1 of ‘imprime’ from incompatible pointer type [-Wincompatible-pointer-types]
imprime(&m);
^
matriz.c:10:6: note: expected ‘int **’ but argument is of type ‘int (*)[3][3]’
void imprime(int ** m) {
^
matriz.c:21:13: warning: passing argument 1 of ‘multiplica’ from incompatible pointer type [-Wincompatible-pointer-types]
multiplica(&m, 2);
^
matriz.c:2:6: note: expected ‘int **’ but argument is of type ‘int (*)[3][3]’
void multiplica(int ** m, int a) {
^
matriz.c:22:10: warning: passing argument 1 of ‘imprime’ from incompatible pointer type [-Wincompatible-pointer-types]
imprime(&m);
^
matriz.c:10:6: note: expected ‘int **’ but argument is of type ‘int (*)[3][3]’
void imprime(int ** m) {
^
A coisa muda quando você utiliza alocação dinâmica (por praticidade não fiz as verificações dos retornos do malloc e nem liberei os ponteiros,mas na vida real você deve fazer essas coisas):
#include <stdio.h>
#include <stdlib.h>
void multiplica(int ** m, int a) {
for(int i = 0; i<3; i++) {
for(int j=0; j<3; j++) {
m[i][j] = m[i][j] * a;
}
}
}
void imprime(int ** m) {
for(int i=0; i<3; i++) {
for(int j=0; j<3; j++) {
printf("%d%c",m[i][j], (j==2)?'\n':' ');
}
}
}
int main(void) {
int ** m = malloc(sizeof(int *) * 3);
int i,j;
for(i=0; i<3; i++) {
m[i] = malloc(sizeof(int)*3);
for(j=0; j<3; j++) {
m[i][j] = (i+2)*(j+3);
}
}
imprime(m);
puts("");
multiplica(m, 2);
imprime(m);
return 0;
}
Entenda bem o conceito de ponteiro, porque a parte filé da coisa não é ficar fazendo lista ligada. É usar ponteiro p/ funções como callback e criar funções com lista de argumentos variáveis:
http://en.cppreference.com/w/c/language/pointer
http://en.cppreference.com/w/cpp/language/variadic_arguments
Boa Tarde _Isis_!
Novamente, muito obrigado pela atenção!
Estive estudando sobre ponteiros nos últimos dias, mas, a passagem de matrizes para funções ainda tem me assombrado, ainda estou com dificuldade de trabalhar com este tipo de conteúdo.
Tenho um código aqui estava desenvolvendo como exemplo e testando algumas situações.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void listar(char nomes[][10], int t);
int main(){
int j, i, k=1, l;
char nomes[10][10], capturaChar;
for(j=0;j<=10;j++){
for(i=0;i<=10;i++){
printf("Digite o nome %d: \n",k);
//EXEMPLO DE COLETA DE CARACTERES DO TECLADO
do {
capturaChar = getchar();
nomes[j][l] = capturaChar;
l++;
}while(capturaChar != '\n');
k++;
}
}
//TESTE COM PONTEIROS
/* char *ponteiroNomes[10][10];
ponteiroNomes = &nomes[0][0];*/
//PASSANDO ENDERECO DE MEMORIA E QUANTIDADE DE LINHAS
//listar(&nomes[0][0],10);
listar(nomes,10);
system("cls");
system("pause");
}
void listar(char nomes[][10], int t){
int i, j;
for(j=0;j<=10;j++){
for(i=0;i<=10;i++){
printf("%s",nomes[j][i]);
}
}
}
Como podes visualizar, estava testando algumas formas de passagem e métodos de captura de dados do usuário.
Então vamos as dúvidas:
* Em pesquisas vi algumas relações para passagem de matrizes bidimensionais:
protótipo para passagem de matriz bidimensional, no código desenvolvido acima está da seguinte maneira:
void listar(char nomes[][10], int t);
como ficaria o protótipo do mesmo, se utilizasse um ponteiro que indicaria a posição de memoria inicial da minha matriz bidimensional?
Pelo que pude entender das pesquisas, no protótipo da função, posso não indicar a quantidade de linhas como opção, e obrigatoriamente tenho que indicar o tamanho/quantidade de colunas, a variável do lado com o nome de "T" ficaria subentendida como sendo a quantidade de linhas que a mesma possui, isto seria uma passagem por valor, copiando a matriz inteira para a função.
Isto, pelo que entendi de alguns materiais pesquisas, seria assim mesmo?
* Passagem da matriz bidimensional para a função "listar":
No código desenvolvido tenho a passagem para a função da seguinte maneira:
listar(nomes,10);
pelo que entendi também poderia indicar a posição inicial da matriz com o seguinte código:
listar(&nomes[0][0],10);
sem a necessidade de alterar o protótipo, então Isis, como você teria feito esta passagem nos dois formatos, movendo a matriz inteira para a função listar e passando a penas o endereço de memória da mesma?
Novamente, agradeço muito a atenção, após entender bem o conceito, todos os problemas estarão resolvidos.
:D
http://en.cppreference.com/w/c/language/array
Procure por array to pointer conversion
A rigor, C não possui passagem por referência, apenas por valor.
O lance dos ponteiros como argumento é que é passado um endereço de memória por valor e vc utiliza ele p/ acessar o objeto real.