• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

djthyrax

Passar matriz para função

11 mensagens neste tópico

Preciso de fazer uma função para manipular uma matriz[ x][y].

Tenho no main() int matriz[2][2] = {{0, 0}, {0, 0}}; e preciso de manipular a matriz numa função myfunc.

Se isto fosse apenas int x = 0;, sei que faria:

void myfunc(int *a){
    *a = 1;
}
int main(){
    int x = 0;
    myfunc(&x);
    printf("%i\n", x);
    return 0;
}

E mostrava-me o 1. Agora, como faço isto para a matriz?

Thx in advance.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

void myfunc(int rows, int cols, int **matriz)
{
int i,j;

for (i=0; i<rows; i++)
	for (j=0; j<cols; j++)
		matriz[i][j] = (i+j)*(i+j);
}

int** create_matrix(int rows, int cols)
{
int i,**matrix;
matrix = malloc(sizeof(int)*rows);
for (i=0; i<cols; i++)
	matrix[i] = malloc(sizeof(int)*cols);
return matrix;
}

int main (int argc, char const *argv[])
{
int **matriz = create_matrix(2,2);

myfunc(2, 2, matriz);
printf("%d %d\n%d %d\n", matriz[0][0], matriz[0][1], matriz[1][0], matriz[1][1]);
return 0;
}

It's not pretty, but works.

Ao invés desta treta toda para criar uma matriz, podes passar a matriz como argumento desta forma int (*matriz)[2].

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Grande confusão...

O objectivo é usar a matriz [ x][y] como eu a declarei, e manipulá-la na função. Just that. É mesmo preciso recorrer ao malloc para isso?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Depois de uma leitura iluminante dos exemplos do Ling. C do Damas (não dos textos sobre apontadores, que estão uma treta...), aprendi qualquer coisa sobre ponteiros e passei a perceber.

Neste momento estou a usar:

#include <stdio.h>
#define TAMANHO 36 // fazer matriz 36x36, com margem de segurança

void changeDirection(int a[TAMANHO][TAMANHO]){
printf("%i\n", a[1][1]);

a[1][1] = 2;
}

int main(){
int start[2] = {17, 17}, //posição do 1
	end, //nr pedido
	x = start[0], y = start[1], //coordenadas actuais
	matriz[TAMANHO][TAMANHO] = {
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	};

	changeDirection(matriz);
	printf("%i\n", matriz[1][1]);
	//scanf("%d\n", &end);



return 0;
}

Output:

[djthyrax@dawn ~]$ gcc -o j j.c && ./j

j.c: In function ‘changeDirection’:

j.c:7: warning: assignment makes pointer from integer without a cast

j.c: In function ‘main’:

j.c:53: warning: passing argument 1 of ‘changeDirection’ from incompatible pointer type

1

2

Dá warning mas já funciona... Se alguém souber como tirar dali os warnings, ficava agradecido. :P

EDIT: Fixed, editei o código em cima.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Essa declaração da matriz está um bocado estranha :S Pq é que não te limitas a declarar a matriz e a usar um ciclo for para a preencher?

#include <stdio.h>
#define TAMANHO 36 


void change_direction(int a[TAMANHO][TAMANHO],int col,int lin) {
    printf("%i\n",a[col][lin]);
    a[col][lin]=2;
}

int main() {
    int i,j;
    int matriz[TAMANHO][TAMANHO];
    for(i=0;i<TAMANHO;i++) {
        for(j=0;j<TAMANHO;j++) {
            matriz[i][j]=0;
        }
    }
    matriz[16][16]=1;
    change_direction(matriz,0,0);
    printf("%i\n",matriz[0][0]);
    return 0;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Essa declaração da matriz está um bocado estranha :S Pq é que não te limitas a declarar a matriz e a usar um ciclo for para a preencher?

Na altura achei mais fácil, mas também já estava todo queimado...

Ou um ciclo for ou o memset.

Ainda não sei usar as mem*() nem o malloc().
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

tal como podes ver aqui,

memset( void * s , int c, size_t n )

significa que vais inicializar n bytes começados no endereço de memória s com o valor c.

Caso não saibas, ao definires uma matriz como fizeste ou um array, as posições da matriz ficam todas seguidas na memória coluna a coluna. Ou seja, ao acederes à posição matriz[2][5] , estás a aceder à posição 2 * TAMANHO + 5.

Além disso, "matriz" contem o endereço da primeira posição de memoria da matriz.

No teu caso podias fazer

memset( matriz , 0 , sizeof( matriz ) ); 

Com isto vais inicializar todos os bytes da matriz (valor do sizeof) com o valor 0. Como estás a inicializar bytes, o valor c tem de estar entre 0 e 255.

Um "int" são 4 bytes, por isso é preciso ter cuidado ao usar o memset com int's. Funciona bem com os valores 0 e -1. Com outros valores não. Para explicar porquê era preciso tar a falar de binário...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Um "int" são 4 bytes, por isso é preciso ter cuidado ao usar o memset com int's. Funciona bem com os valores 0 e -1. Com outros valores não. Para explicar porquê era preciso tar a falar de binário...

Até agora percebi, por isso podes continuar :P
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Penso que ele esteja a falar do high/low endian. Ou seja, ao passares um int de 4 bytes, o memset só vai aproveitar um dos bytes (para ter um valor 0-255). Acontece que o byte que vai ser aproveitado depende da máquina. Se tiveres um int com o valor 64, tens 4 bytes seguidos, imaginando que está em big-endianness:

|0|0|0|64|, ou seja, os primeiros três bytes estão a zero. Se o memset for buscar o primeiro byte do int, vai buscar 0, logo não vai ser o que tu queres.

Se quiseres 0 não há problema porque os bytes estão todos a zero. Se quiseres -1, a representação é a seguinte:

|255|255|255|255|, ou seja, anda 'um para trás' em relação ao zero. Quando o memset vai buscar o valor encontra 255, que é a representação de -1 num byte.

Espero não ter dito muitos disparates...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Sorry, só hoje voltei ao forum...

Espero não ter dito muitos disparates...

Disseste alguns :( Mas vou aproveitar a tua explicação.

O problema é que se quiseres inicializar um 'int' com 64 com o memset não consegues. O memset trata a região de memória byte a byte, independentemente dos dados que lá se encontrem. Assim, o memset atribui o byte c a cada byte da memória - ficavamos com o número:

|64|64|64|64|  ( 01000000010000000100000001000000 em binário ) que em décimal é igual a  64 + 64 * 256 + 64 * 256*256 + 64 * 256*256*256 = 1.077.952.576

Com -1 funciona porque a representação de -1 é "1111" em 4 bits , "11111111" em 8 bits , etc. Assim, o memset coloca todos os bits a 1 e um 'int' com os 32bits (4bytes) a 1 representa -1 em décimal.

Nota: "11111111" = -1 num inteiro com sinal ou 255 num inteiro sem sinal, assim, de facto temos  |255|255|255|255| como o pedrosorio referiu.

0

Partilhar esta mensagem


Link 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