Página 1 de 2

Duda con bucle "for" en C

Publicado: 30 May 2014, 00:27
por Baal_30
Hola, estoy siguiendo unos tutoriales, y en uno de ellos, se usa esta función :

void comparar(int filas, int columnas, int **m1, int **m2){
int i,j,aux=0;

for(i=0;i<filas && aux == 0;i++){
for(j=0;j<columnas && aux == 0;j++){
if (m1[j] != m2[j]){
aux = 1;

}
}
}
if (aux == 0){
printf("Ambas matrices son iguales.\n");
}
else{
printf("Ambas matrices no son iguales.\n");
}
}

Y al quedarme mirándola... No entiendo cuando se dará el caso del segundo "if", ya que si aux es == 0, el blucle for no dejaría de repetirse nunca, y para que dejara de repetirse, aux tendría que ser != 0, y en ese caso se iría al "else" de abajo, ¿no? Estoy bastante mareado, no se si es porque estoy cansado, pero eso que tenía más o menos claro, ahora no se ni por donde cogerlo. Espero haberme explicado con claridad.

Gracias de antemano y buenas noches :)

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 00:38
por Blau
Fíjate en el if del segundo for.

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 09:25
por Baal_30
Si, si m1[j] != m2[j] entonces aux es 1, y ahí se saldría y se iría directamente al "else" ¿no? Porque mientras siga siendo m1 igual a m2, aux será siempre 0, y con ello seguirá el bucle, o eso es lo que entiendo yo.

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 09:46
por NvK
cambie void por bool en la funcion... realmente no comprendo en su totalidad sobre que código quiere comparar o lo que quiere hacer.
¿Podria ser mas especifico?, e idente por favor asi entendemos todos...
for(i=0;i<filas && aux == 0;i++){
  for(j=0;j<columnas && aux == 0;j++){
    if (m1[i][j] != m2[i][j]){
      //printf("Ambas matrices son iguales.\n");
      return 1;
    }
  }
}
return 0
Edito: si compara el numero de filas podria hacer m1[j] != m2[j] en vez de (m1[j] != m2[j])

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 14:45
por Baal_30
Si el código que he compartido está correcto y funciona, lo que no entiendo es el por qué.

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 15:36
por NvK
Todavía no comprendo del todo sobre que es aplicable así que tratare de ser lo más "analitico" posible:
imaginemos que tenemos 3 filas y 4 columnas(sistema 3x4) el primer bucle i++ correra el numero de filas(es decir 3) al caer en el segundo bucle j++(que correra 4 columnas * fila) el primer valor del array bidimensional m1[j] (supongamos que hay un valor de 0x30) comparara el valor del segundo array bidimensional es decir m2[j] que tendra las mismas filas y columnas en ese momento, también hay que mensionar que al ser de dos dimensiones guarda 2 tipos de datos simultaneamente lo que es muy útil en video juegos(por ejemplo) para crear matrizes de niveles, al ser !=(distinto que) decimos que lo que buscara es que si alguna no es igual(o ambos arreglos) la función de por terminado su trabajo...
en pocas palabras:
m1[0][0]= 0x1;
m1[1][0]= 0x2;
m1[0][1]= 0x3;

m2[0][0]= 0x1;
m2[1][0]= 0x2;
m2[0][1]= 0x4; // Aqui se terminaria la funcion dentro de los bucles, es distinto a m1
recuerda también que los arrays de más de una dimension no son de memoria contigua, dime si he sido claro.

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 17:06
por Baal_30
No se si me explico bien.

El "if" ese, dice que si m1 y m2 son diferentes, aux es igual a 1, entonces se saldría se saldría del bucle y se iría directamente al "else". ¿Cierto?
Hasta ahí todo bien, pero si da que m1 y m2 son iguales, aux será SIEMPRE 0 ¿Si o no? Entonces, mientras aux sea 0, el bucle "for" no dejará nunca de correr. ¿No?

//Edito : Ah, a ver, en el caso de que sea m1 y m2 iguales, el bucle "for", no dejará de correr hasta que "i" o "j" llegue al número de "filas" o "columnas" ¿Verdad? Entonces ahí automáticamente se saldrá del bucle, y el aux se mantendría en 0, así que dará el mensaje de que son iguales. Si es así, creo que ya lo he entendido...

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 17:28
por NvK
Baal_30 escribió:No se si me explico bien.

El "if" ese, dice que si m1 y m2 son diferentes, aux es igual a 1, entonces se saldría se saldría del bucle y se iría directamente al "else". ¿Cierto?
Hasta ahí todo bien, pero si da que m1 y m2 son iguales, aux será SIEMPRE 0 ¿Si o no? Entonces, mientras aux sea 0, el bucle "for" no dejará nunca de correr. ¿No?

//Edito : Ah, a ver, en el caso de que sea m1 y m2 iguales, el bucle "for", no dejará de correr hasta que "i" o "j" llegue al número de "filas" o "columnas" ¿Verdad? Entonces ahí automáticamente se saldrá del bucle, y el aux se mantendría en 0, así que dará el mensaje de que son iguales. Si es así, creo que ya lo he entendido...
Por supuesto que no. En el código original no hay break o return que garantize que si el array es muy grande haya optimizacion(osea que se salga del bucle), de lo contrario recorrera todo y si en un futuro trabajas con punteros hacer eso daria consecuencias catastroficas...
El bucle correra siempre, no es optimo ni mucho menos seguro.

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 17:49
por Baal_30
Entonces, es una mala forma de hacer eso, ¿no?, Mira, te pego el código entero del ejercicio por si quieres ver para que era esa función. Lo he hecho como lo explican, no se si será la mejor forma para hacerlo. El ejercicio era para explicar las funciones y memoria dinámicas... Gracias.

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

int reservar(int filas, int columnas);
void introduce(int filas, int columnas, int **mat);
void comparar(int filas, int columnas, int **m1, int **m2);

int main(){
	
	int filas, columnas;
	int **m1;
	int **m2;
	
	printf("Introduce el numero de filas: ");
	scanf("%i",&filas);
	printf("Introduce el numero de columnas: ");
	scanf("%i",&columnas);
	
	m1 = reservar(filas,columnas);
	m2 = reservar(filas,columnas);
	
	introduce(filas,columnas,m1);
	introduce(filas,columnas,m2);
	
	comparar(filas,columnas,m1,m2);
	
	system("pause");
	return 0;
}

int reservar(int filas, int columnas){
	
	int i;
	int **mat;
	mat = (int**)malloc(filas*sizeof(int));
	if( mat == NULL ){
		printf("No se ha podido reservar memoria.\n");
		exit(1);
	}
	
	for(i=0;i<filas;i++){
		mat[i] = (int*)malloc(columnas*sizeof(int));
		if(mat[i] == NULL){
			printf("No se ha podido reservar memoria. \n");
			exit(1);
		}
	}
	
	return mat;
	
}

void introduce(int filas, int columnas, int **mat){
	int i,j;
	
	for(i=0;i<filas;i++){
		for(j=0;j<columnas;j++){
			printf("Introduce un valor para el elemento [%i][%i]: ",i,j);
			scanf("%i",&mat[i][j]);
		}
	}
}

void comparar(int filas, int columnas, int **m1, int **m2){
	int i,j,aux=0;
	
	for(i=0;i<filas && aux == 0;i++){
		for(j=0;j<columnas && aux == 0;j++){
			if (m1[i][j] != m2[i][j]){
				aux = 1;
				
			}
		}
	}
	if (aux == 0){
		printf("Ambas matrices son iguales.\n");
	}
	else{
		printf("Ambas matrices no son iguales.\n");
	}
}

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 18:00
por NvK
Hasta reservar vamos bien(aun que bien podria haber retorna el total de bloques y no el bloque en si, eso se pudo hacer desde el main..).
Introduce y Comparar estan mal, definitivamente...
Usa scanf lo que es muuuy peligroso(de hecho esta obsoleto) ya que se podria producir un desbordamiento, para evitar todo esto usa: fgets(mat[j], TAM_DEL_BUFFER, stdin); entonces
lo "agarra" de la entrada estandar y con un tamaño de buffer limitado.
Y comparar no es para nada optima ni segura haz esto:
bool comparar(int filas, int columnas, int **m1, int **m2){
    int i,j;
     
    for(i=0;i<filas;i++){
        for(j=0;j<columnas;j++){
            if (m1[i][j] != m2[i][j]){
                //printf("Ambas matrices no son iguales.\n");
                return 1;
            }
        }
    }
    //printf("Ambas matrices son iguales.\n");
    return 0;
}

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 18:17
por Baal_30
Joder pues vaya del tío que estoy aprendiendo, porque él lo hace todo así :/

Gracias por la ayuda NvK. Lo que ahora no entiendo es que tipo de función es "bool" (aún no la he aprendido) y tampoco se como funcionan los return :(

Y, puede que esté equivocado, pero, ¿no te falta un "else" para meter el return 0; ?

Gracias!

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 18:24
por Pino1952
Hola a todos.-
recuerda también que los arrays de más de una dimension no son de memoria contigua...
NvK me queda una duda con respecto a esta frase, entonces la imagen que pongo a continuación es incorrecta o te réferis a otra cosa.-

Imagen


Saludos.-
Daniel

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 18:28
por NvK
jeje tranquilo todos empezemos desde 0. Mira las funciones en que en C que dicen void son las que no retornan ningun valor, en terminos menos formales, una vez que una funcion termina la aplicacion continua(hasta que termina el programa obviamente), si esa funcion retorna un valor puedes guardarlo en una variable o usarlo con algun fin...
entonces al declarar una funcion bool(verdadero o falso), al terminar puedes hacer algo así:
if ( comparar(filas,columnas,m1,m2) == 1 )
 printf("Ambas matrices no son iguales.\n");
else
 printf("Ambas matrices son iguales.\n");
osea aqui comparar retorna y en el caso de que sea 1 imprime el primer printf y si no el segundo.

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 18:29
por NvK
Pino1952 escribió:Hola a todos.-
recuerda también que los arrays de más de una dimension no son de memoria contigua...
NvK me queda una duda con respecto a esta frase, entonces la imagen que pongo a continuación es incorrecta o te réferis a otra cosa.-

Imagen


Saludos.-
Daniel
Saludos daniel, mira los array bidimensionales trabajando con punteros no son de memoria contigua

EDITO: Es decir jamas pueden ser de memoria contigua por que dentro del modelo de memoria todo se separa en el heap, pero no sucede lo mismo con los arrays de 1 dimension.

Re: Duda con bucle "for" en C

Publicado: 30 May 2014, 18:54
por NvK
Perdon que haga doble post es que quería aclarar algo...
Un array bidimensional estatico si es de memoria contigua, pero uno que se declara dinamicamente no lo es.
Ejemplo:
char **p;
p= (char **)malloc(3 * sizeof(char *)); // un array de 3 indices de forma dinamica
//char *p[3] de forma estatica
p[0]= malloc(TAM_VALOR); /* ahora si ya se reserva memoria para el indice del array en si
con el tamaño deseado */
p[1]= malloc(TAM_VALOR);
p[2]= malloc(TAM_VALOR);
... // etc..
Lo pude hacer con un bucle pero para efectos de prueba así es mas entendible
y al hacerlo de forma dinamica la ventaja es que en un futuro lo puedes reagrandar con realloc.
Esto es una ventaja si tu aplicacion trabaja constatemente con valores impredecibles y que debes recalcular, pero recuerda siempre liberarar memoria si no las consecuencias en el sistema operativo podrían ser desastrosas...