Discussion:
Matrices
(demasiado antiguo para responder)
Olaf "El Blanco"
2005-12-21 13:53:28 UTC
Permalink
Porque no funciona lo siguiente?

void crear_tabla (int *tabla)
{
int f, c;
for (c=0; c<MAX; c++)
for (f=0; f<MAX; f++)
&tabla[f][c] = 3;
}

Porque si funciona lo siguiente?

void imprime_matriz(float matriz[fila][columna])
{
int f, c;
for (c=0; c<columna; c++) {
for (f=0; f<fila; f++)
printf ("%2.2f ", matriz[f][c]);
printf ("\n");
}

****En este 2do ejemplo es correcto en la cabecera del procedimiento
aclararle la cantidad
de filas y columnas?
****No entiendo porque funciona el primer printf, ¿que es matriz[f][c]?
Creia haber entendido que para imprimir el contenido de una dirección de
memoria a la que apunta un puntero, hacia falta poner un &.

De antemano Gracias.




*****************************************************
"...Winds and storms, embrace us now,
Lay waste the light of day.
Open gates to darker lands...
We spread our wings and fly away..."
*****************************************************
Oscar Garcia
2005-12-21 14:48:39 UTC
Permalink
El Wed, 21 Dec 2005 14:53:28 +0100, "Olaf \"El Blanco\""
Post by Olaf "El Blanco"
Porque no funciona lo siguiente?
Veamos.
Post by Olaf "El Blanco"
void crear_tabla (int *tabla)
{
int f, c;
for (c=0; c<MAX; c++)
for (f=0; f<MAX; f++)
&tabla[f][c] = 3;
Veamos... te recuerdo que & obtiene la dirección de memoria donde se
aloja una variable o dato.

Por supuesto a un resultado no le puedes asignar un valor. Sería
equivalente a hacer (por ejemplo) lo siguiente:

75 = 3;
Post by Olaf "El Blanco"
}
Porque si funciona lo siguiente?
Veamos.
Post by Olaf "El Blanco"
void imprime_matriz(float matriz[fila][columna])
{
int f, c;
for (c=0; c<columna; c++) {
for (f=0; f<fila; f++)
printf ("%2.2f ", matriz[f][c]);
Estás leyendo el elemento de una matriz de tamaño estático. ¿Porqué no
debería funcionar?
Post by Olaf "El Blanco"
printf ("\n");
}
****En este 2do ejemplo es correcto en la cabecera del procedimiento
aclararle la cantidad
de filas y columnas?
Sí, es completamente correcto.
Post by Olaf "El Blanco"
****No entiendo porque funciona el primer printf, ¿que es matriz[f][c]?
Creia haber entendido que para imprimir el contenido de una dirección de
memoria a la que apunta un puntero, hacia falta poner un &.
No, & obtiene la dirección de memoria donde está alojado un dato...
pero para acceder a una dirección y meter allí un dato se usa su
operador complementario, asterisco (*).
Post by Olaf "El Blanco"
De antemano Gracias.
De nada.
Oscar Garcia
2005-12-21 14:54:37 UTC
Permalink
El Wed, 21 Dec 2005 14:53:28 +0100, "Olaf \"El Blanco\""
Post by Olaf "El Blanco"
void imprime_matriz(float matriz[fila][columna])
{
[...]
}
****En este 2do ejemplo es correcto en la cabecera del procedimiento
aclararle la cantidad
de filas y columnas?
A ver, creo que te estás confundiendo.

Posiblemente fila y columna sean variables predefinidas con un
#define. Si no fuera así te dará un error de compilación.

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
Olaf "El Blanco"
2005-12-21 16:02:37 UTC
Permalink
Gracias Oscar...
Se me han aclarado varias cosas, pero me falta algún concepto.
Mira ésto, le he agregado los comentarios en el mail...


#include <stdio.h>
#define MAX 5 // Maximo tamaño de columna y fila
// Recibe como parámetro un puntero, no recibe la tabla en si,
// recibe una direccion de memoria
void crear_tabla (int *tabla[MAX][MAX])
{
int f, c;
for (c=0; c<MAX; c++)
for (f=0; f<MAX; f++)
// Accedemos a la direccion de memoria de la tabla
// Específicamente en esa fila y columna
// Y le cambiamos el valor.
*tabla[f][c] = f + c;

void imprimir_tabla (int *tabla[MAX][MAX])
{
int f, c;
for (c=0; c<MAX; c++) {
for (f=0; f<MAX; f++)
printf ("%3d");
printf ("\n");
}
}

void main()
{
// Reservo memoria para una matriz de MAX x MAX enteros...
int matrix[MAX][MAX];
// En teoría esa direccion la puedo ver asi: printf ("%d",&matrix) ???
// Le doy el entero direccion de memoria donde "comienza" la tabla en la RAM
crear_tabla(&matrix);
// Le doy el entero direccion de memoria donde "comienza" la tabla en la RAM
imprimir_tabla(&matrix);
// Todo esto sirve para no copiar la tabla entera mas de una vez, para
ahorrar memoria.
getch();
}


Obviamente no funciona.
Julián Albo
2005-12-21 16:14:39 UTC
Permalink
Post by Olaf "El Blanco"
// Específicamente en esa fila y columna
// Y le cambiamos el valor.
*tabla[f][c] = f + c;
Hay que tener en cuenta la prioridad de los operadores:

* tabla [f] [c] es equivalente a: tabla [f][c][0]

Cuando lo que quieres imagino que es:

tabla [0][f][c]

Por claridad sería prferible ponerlo con *, claro, pero para hacerlo
necesitas paréntesis:

(* tabla) [f][c]
--
Salu2
Olaf "El Blanco"
2005-12-21 16:19:16 UTC
Permalink
Post by Julián Albo
* tabla [f] [c] es equivalente a: tabla [f][c][0]
¿Ese 0 que significa?
Post by Julián Albo
Post by Olaf "El Blanco"
// Específicamente en esa fila y columna
// Y le cambiamos el valor.
*tabla[f][c] = f + c;
* tabla [f] [c] es equivalente a: tabla [f][c][0]
tabla [0][f][c]
Por claridad sería prferible ponerlo con *, claro, pero para hacerlo
(* tabla) [f][c]
--
Salu2
Oscar Garcia
2005-12-21 16:34:23 UTC
Permalink
El Wed, 21 Dec 2005 17:19:16 +0100, "Olaf \"El Blanco\""
Post by Olaf "El Blanco"
Post by Julián Albo
* tabla [f] [c] es equivalente a: tabla [f][c][0]
¿Ese 0 que significa?
Cuando se trata de un puntero a punteros, el resultado final es un
puntero a un elemento único o bien a un array de elementos, entonces
se usa * para acceder al elemento en sí o bien [i] para acceder al
elemento i-ésimo.

Al ser una matriz estática no debes preocuparte por ese último índice.

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
Oscar Garcia
2005-12-21 16:42:08 UTC
Permalink
El Wed, 21 Dec 2005 17:02:37 +0100, "Olaf \"El Blanco\""
Post by Olaf "El Blanco"
Gracias Oscar...
Se me han aclarado varias cosas, pero me falta algún concepto.
Mira ésto, le he agregado los comentarios en el mail...
Umm, ahora yo tengo otras dudillas.. Ejem... ¿tú no serás por
casualidad alumno de la Escuela Politécnica Superior de Linares?

Si es así entonces decirte que soy posiblemente compañero de facultad
y paisano :)

Lo presupongo porque ya he enseñado a varias personas de Peritos a
realizar dichas prácticas y me parece extraño que coincida con que lo
preguntes tú también aquí.
Post by Olaf "El Blanco"
#include <stdio.h>
#define MAX 5 // Maximo tamaño de columna y fila
// Recibe como parámetro un puntero, no recibe la tabla en si,
// recibe una direccion de memoria
void crear_tabla (int *tabla[MAX][MAX])
{
int f, c;
for (c=0; c<MAX; c++)
for (f=0; f<MAX; f++)
// Accedemos a la direccion de memoria de la tabla
// Específicamente en esa fila y columna
// Y le cambiamos el valor.
*tabla[f][c] = f + c;
Para no tener confusiones deberías poner (*tabla)[f][c]. El compilador
lo entenderá tal y como yo te he puesto, pero se lee y entiende mejor
como te lo he puesto.
Post by Olaf "El Blanco"
void imprimir_tabla (int *tabla[MAX][MAX])
{
int f, c;
for (c=0; c<MAX; c++) {
for (f=0; f<MAX; f++)
printf ("%3d");
Con esto no imprimes nada porque no has pasado nada como segundo
parámetro al printf.
Post by Olaf "El Blanco"
printf ("\n");
}
}
void main()
{
// Reservo memoria para una matriz de MAX x MAX enteros...
int matrix[MAX][MAX];
// En teoría esa direccion la puedo ver asi: printf ("%d",&matrix) ???
Ni de coña. "matrix" es una matriz de elementos y no puede ser
visualizada directamente mediante un printf (es un "arreglo" de
elementos como se han traducido en muchos textos).
Post by Olaf "El Blanco"
// Le doy el entero direccion de memoria donde "comienza" la tabla en la RAM
crear_tabla(&matrix);
Realmente para C matrix es un puntero que apunta al inicio de los
elementos, de modo que puedes poner el paso del parámetro sólo como:

crear_tabla(matrix);
Post by Olaf "El Blanco"
// Le doy el entero direccion de memoria donde "comienza" la tabla en la RAM
imprimir_tabla(&matrix);
Idem.
Post by Olaf "El Blanco"
// Todo esto sirve para no copiar la tabla entera mas de una vez, para
ahorrar memoria.
getch();
¡Ojo! ¡¡getch es una función de curses.h y no de stdio.h!! Ten cuidado
porque la gente que programa bajo Windows olvida que getch es una
función de control del terminal de datos y no de la corriente de
entrada / salida.
Post by Olaf "El Blanco"
}
Obviamente no funciona.
Date cuenta que te faltal algunos cierres de corchetes entre otras
cosas :P

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
Olaf "El Blanco"
2005-12-21 20:58:32 UTC
Permalink
Vez primera que no se me aclaran las dudas! :)

En resumen: No puedo llamar a este procedimiento.

void crear_tabla (int (*tabla)[MAX][MAX])
{
int f, c;
for (c=0; c<MAX; c++)
for (f=0; f<MAX; f++)
*tabla[f][c] = f + c;
}


void main()
{
int matrix[MAX][MAX];
crear_tabla(matrix); <--- me da error aqui,
imprimir_tabla(matrix); <----- me da error aqui
getch(); //Cual es el equivalente en ANSI C getchar()?
}
Post by Oscar Garcia
El Wed, 21 Dec 2005 17:02:37 +0100, "Olaf \"El Blanco\""
Post by Olaf "El Blanco"
Gracias Oscar...
Se me han aclarado varias cosas, pero me falta algún concepto.
Mira ésto, le he agregado los comentarios en el mail...
Umm, ahora yo tengo otras dudillas.. Ejem... ¿tú no serás por
casualidad alumno de la Escuela Politécnica Superior de Linares?
Si es así entonces decirte que soy posiblemente compañero de facultad
y paisano :)
Lo presupongo porque ya he enseñado a varias personas de Peritos a
realizar dichas prácticas y me parece extraño que coincida con que lo
preguntes tú también aquí.
Post by Olaf "El Blanco"
#include <stdio.h>
#define MAX 5 // Maximo tamaño de columna y fila
// Recibe como parámetro un puntero, no recibe la tabla en si,
// recibe una direccion de memoria
void crear_tabla (int *tabla[MAX][MAX])
{
int f, c;
for (c=0; c<MAX; c++)
for (f=0; f<MAX; f++)
// Accedemos a la direccion de memoria de la tabla
// Específicamente en esa fila y columna
// Y le cambiamos el valor.
*tabla[f][c] = f + c;
Para no tener confusiones deberías poner (*tabla)[f][c]. El compilador
lo entenderá tal y como yo te he puesto, pero se lee y entiende mejor
como te lo he puesto.
Post by Olaf "El Blanco"
void imprimir_tabla (int *tabla[MAX][MAX])
{
int f, c;
for (c=0; c<MAX; c++) {
for (f=0; f<MAX; f++)
printf ("%3d");
Con esto no imprimes nada porque no has pasado nada como segundo
parámetro al printf.
Post by Olaf "El Blanco"
printf ("\n");
}
}
void main()
{
// Reservo memoria para una matriz de MAX x MAX enteros...
int matrix[MAX][MAX];
// En teoría esa direccion la puedo ver asi: printf ("%d",&matrix) ???
Ni de coña. "matrix" es una matriz de elementos y no puede ser
visualizada directamente mediante un printf (es un "arreglo" de
elementos como se han traducido en muchos textos).
Post by Olaf "El Blanco"
// Le doy el entero direccion de memoria donde "comienza" la tabla en la RAM
crear_tabla(&matrix);
Realmente para C matrix es un puntero que apunta al inicio de los
crear_tabla(matrix);
Post by Olaf "El Blanco"
// Le doy el entero direccion de memoria donde "comienza" la tabla en la RAM
imprimir_tabla(&matrix);
Idem.
Post by Olaf "El Blanco"
// Todo esto sirve para no copiar la tabla entera mas de una vez, para
ahorrar memoria.
getch();
¡Ojo! ¡¡getch es una función de curses.h y no de stdio.h!! Ten cuidado
porque la gente que programa bajo Windows olvida que getch es una
función de control del terminal de datos y no de la corriente de
entrada / salida.
Post by Olaf "El Blanco"
}
Obviamente no funciona.
Date cuenta que te faltal algunos cierres de corchetes entre otras
cosas :P
Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
Oscar Garcia
2005-12-21 22:49:30 UTC
Permalink
El Wed, 21 Dec 2005 21:58:32 +0100, "Olaf \"El Blanco\""
Post by Olaf "El Blanco"
Vez primera que no se me aclaran las dudas! :)
En resumen: No puedo llamar a este procedimiento.
void main()
{
int matrix[MAX][MAX];
crear_tabla(matrix); <--- me da error aqui,
imprimir_tabla(matrix); <----- me da error aqui
getch(); //Cual es el equivalente en ANSI C getchar()?
}
Si miras el código que te puse hay que poner:
crear_tabla(&matrix);
imprimir_tabla(&matrix);

En este caso no se puede usar matrix a secas para hacer referencia al
arreglo completo de datos.

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
Olaf "El Blanco"
2005-12-22 09:21:15 UTC
Permalink
Post by Olaf "El Blanco"
crear_tabla(&matrix);
imprimir_tabla(&matrix);
Tampoco va. Eso fue lo primero que intente.
Uso el DEV CPP
Oscar Garcia
2005-12-22 09:42:00 UTC
Permalink
El Thu, 22 Dec 2005 10:21:15 +0100, "Olaf \"El Blanco\""
Post by Olaf "El Blanco"
Post by Olaf "El Blanco"
crear_tabla(&matrix);
imprimir_tabla(&matrix);
Tampoco va. Eso fue lo primero que intente.
Uso el DEV CPP
El compilador debería ser indiferente.

Yo he usado el gcc de linux (en primera instancia) y posteriormente
usé el djgpp de windows y en ambos me funcionó perfectamente:

***@redstar:~/pruebas$ cc -Wall -o olaf olaf.c
***@redstar:~/pruebas$ ./olaf
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8

El parámetro -Wall te muestra TODOS los warnings posibles (incluso las
advertencias más tontas) y como puedes ver no dice nada (y funcionar,
funciona correctamente).

Aunque tengo una licencia del MS Visual Studio 97 no me he manejado lo
suficiente con VC como para poder compilarlo, y del Borland C++
Builder no tengo ni licencia ni lo he manejado nunca ;(

Nota: ¿El DEV CPP qué compilador es?
¿Podrías pegar de nuevo el código completo?

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
Olaf "El Blanco"
2005-12-22 10:42:56 UTC
Permalink
Es increible! El DEV CPP es GCC!
Seguro que no le has cambiado nada?
Bueno, de todas manera... ya funciona.
Pregunta: ¿Siempre que usemos matrices y vectores conviene usar punteros? Es
una buena costumbre de programacion?



Mira este codigo. Lo hice ANTES de saber lo que era un puntero. Pero tengo
dudas al respecto.
¿Usa punteros? En teoria siempre las matrices y vectores se pasan por
referencia, (la direccion del primer elelemnto) Que he hecho aqui? El fuente
funciona. Pero me acuerdo que hubo mucho de prueba y error. ¿HE malgastado
memoria? Aunque no se note en un programa tan tonto quiero aprender eso de
no derrochar y que los ejecutables sean rápidos.



#include <stdio.h>
#define fila 3
#define columna 4

void carga_matriz(float matriz[fila][columna])
{
int f, c;
for (f=0; f<fila; f++)
for (c=0; c<columna; c++) {
printf ("\nIngrese dato [COLUMNA/FILA][%d,%d] -> ", c+1, f+1);
scanf ("%f", &matriz[f][c]);
}
}

void imprime_matriz(float matriz[fila][columna])
{
int f, c;
for (c=0; c<columna; c++) {
for (f=0; f<fila; f++)
printf ("%2.2f ", matriz[f][c]);
printf ("\n");
}
}

void multiplica(float matriz[fila][columna])
{
int f, c;
for (c=0; c<columna; c++)
for (f=0; f<fila; f++)
matriz[f][c] = matriz[f][f] * matriz[2][2];
}


#include <stdlib.h>

int main()
{
float matriz[fila][columna];
carga_matriz(matriz);
imprime_matriz(matriz);
getch();
printf ("\n\n\n");
multiplica(matriz);
imprime_matriz(matriz);
return 0;
}
Post by Oscar Garcia
El Thu, 22 Dec 2005 10:21:15 +0100, "Olaf \"El Blanco\""
Post by Olaf "El Blanco"
Post by Olaf "El Blanco"
crear_tabla(&matrix);
imprimir_tabla(&matrix);
Tampoco va. Eso fue lo primero que intente.
Uso el DEV CPP
El compilador debería ser indiferente.
Yo he usado el gcc de linux (en primera instancia) y posteriormente
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
El parámetro -Wall te muestra TODOS los warnings posibles (incluso las
advertencias más tontas) y como puedes ver no dice nada (y funcionar,
funciona correctamente).
Aunque tengo una licencia del MS Visual Studio 97 no me he manejado lo
suficiente con VC como para poder compilarlo, y del Borland C++
Builder no tengo ni licencia ni lo he manejado nunca ;(
Nota: ¿El DEV CPP qué compilador es?
¿Podrías pegar de nuevo el código completo?
Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
Oscar Garcia
2005-12-22 13:55:29 UTC
Permalink
El Thu, 22 Dec 2005 11:42:56 +0100, "Olaf \"El Blanco\""
Post by Olaf "El Blanco"
Es increible! El DEV CPP es GCC!
Seguro que no le has cambiado nada?
Bueno, de todas manera... ya funciona.
Pregunta: ¿Siempre que usemos matrices y vectores conviene usar punteros? Es
una buena costumbre de programacion?
No me respondiste a mi pregunta acerca de dónde estás estudiando :P

Si pasas un valor por valor se mete en la pila el contenido de la
variable y si modificas ese parámetro lo estarás modificando en el
espacio donde se guardó en la pila. Al volver de la función la
variable original mantiene su valor intacto porque hemos modificado
una copia que se envió a través de la pila.

Si pasas un valor por referencia (usando un puntero) estás enviando la
zona de memoria donde se aloja, de modo que si modificas algo estás
modificando los valores en la zona de memoria donde se alojan los
valores originales. Cuando vuelves de la función dichos valores se
mantienen cambiados.
Post by Olaf "El Blanco"
Mira este codigo. Lo hice ANTES de saber lo que era un puntero. Pero tengo
dudas al respecto.
¿Usa punteros? En teoria siempre las matrices y vectores se pasan por
referencia, (la direccion del primer elelemnto) Que he hecho aqui? El fuente
funciona. Pero me acuerdo que hubo mucho de prueba y error. ¿HE malgastado
memoria? Aunque no se note en un programa tan tonto quiero aprender eso de
no derrochar y que los ejecutables sean rápidos.
void carga_matriz(float matriz[fila][columna])
Estás poniendo en la pila fila * columna valores float. Y si los
modificas se modifican en la pila, y no en la variable que usaste para
pasar el parámetro.

Acerca del uso de memoria.. estás gastando CPU en mover datos a la
pila, estás usando memoria de la pila y posteriormente no podrás
modificar dichos valores para que el programa llamante mantenga dichos
cambios realizados.
Post by Olaf "El Blanco"
void carga_matriz(float matriz[fila][columna])
{
int f, c;
for (f=0; f<fila; f++)
for (c=0; c<columna; c++) {
printf ("\nIngrese dato [COLUMNA/FILA][%d,%d] -> ", c+1, f+1);
scanf ("%f", &matriz[f][c]);
}
}
carga_matriz(matriz);
Enviarás una copia de la matriz a la pila (valores no inicializados) y
todas las entradas de teclado se almacenarán en la zona de la pila, de
modo que al volver el control al programa principal la variable matriz
sigue valiendo lo mismo.
Post by Olaf "El Blanco"
void imprime_matriz(float matriz[fila][columna])
{
int f, c;
for (c=0; c<columna; c++) {
for (f=0; f<fila; f++)
printf ("%2.2f ", matriz[f][c]);
printf ("\n");
}
}
Esto estaría bien, pero claro, malgastaría CPU y memoria copiando los
datos y almacenándolos en la pila innecesariamente.
Post by Olaf "El Blanco"
void multiplica(float matriz[fila][columna])
{
int f, c;
for (c=0; c<columna; c++)
for (f=0; f<fila; f++)
matriz[f][c] = matriz[f][f] * matriz[2][2];
}
Hombre, yo creo que "multiplica" necesitaría dos parámetros y un valor
de retorno (o un tercer parámetro pasado por referencia para almacenar
el resultado).

Como regla general recuerda que si debes modificar los valores de una
variable debes pasarlos por referencia y si los valores que quieres
pasar a la función son únicamente para realizar unos cálculos y no
serán modificados puedes pasarlos por valor.

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
Olaf "El Blanco"
2005-12-22 16:06:51 UTC
Permalink
Post by Oscar Garcia
No me respondiste a mi pregunta acerca de dónde estás estudiando :P
Jajaja, es que no, no estudio ahí. :(

Estuve viendo tu CV.
¿Que opinas de las FP?
Has terminado la FP de electrónica y has seguido estudiando?
¿Siempre te ha gustado la programación?

Como optimizarías este programa que pretende ser un strlen: (Teniendo en
cuanta mi tan bajo nivel)
#include <cstdlib>
#include <iostream>
int longitud (char *cadena)
{
int suma = 0;
while (*cadena != '\0') {
suma++;
cadena++;
}
return(suma);
}
int main()
{
char cadena[]="I am learning C";
printf ("Cadena: %s\n",cadena);
printf ("Llamando a la funcion %d",longitud(cadena)); (*)
getchar();
return EXIT_SUCCESS;
}

¿Estoy usando las llaves al estilo de Dennis Ritchie?
(*) Porque en esa línea no le puedo pasar cadena de la siguiente forma:
printf ("Llamando a la función %d",longitud(&cadena));
En los libros dice que si creo una función con el parámetro formal
*blablabla
el parámetro actual, o la forma de llamar a dicha función debe ser siempre
una dirección de memoria, por lo tanto &blablabla

No sabes lo que me estas ayudando!
Oscar Garcia
2005-12-22 17:11:07 UTC
Permalink
El Thu, 22 Dec 2005 17:06:51 +0100, "Olaf \"El Blanco\""
Post by Olaf "El Blanco"
Post by Oscar Garcia
No me respondiste a mi pregunta acerca de dónde estás estudiando :P
Jajaja, es que no, no estudio ahí. :(
Es que lo que preguntas es igual a una práctica de la ingeniería de
Mecánica :)
Post by Olaf "El Blanco"
Estuve viendo tu CV.
¿Que opinas de las FP?
Pues que el futuro es preparar fomentando las dotes de una persona y
no metiendote una carrera de letras "porque son para inteligentes y
las de ciencias para torpes".
Post by Olaf "El Blanco"
Has terminado la FP de electrónica y has seguido estudiando?
Sí, aunque tengo un poco abandonados los estudios de la ingeniería
desde el 98.
Post by Olaf "El Blanco"
¿Siempre te ha gustado la programación?
Más o menos desde los 8 o 9 años. Aunque no programé un ordenador real
hasta los 10 años (tenia que inventarme los programas en papel y
creerme todo lo que decían en los libros de la biblioteca de mi ciudad
:).
Post by Olaf "El Blanco"
Como optimizarías este programa que pretende ser un strlen: (Teniendo en
cuanta mi tan bajo nivel)
#include <cstdlib>
#include <iostream>
Mira que te gusta mezclar C++ con C, ¿eh?
Post by Olaf "El Blanco"
int longitud (char *cadena)
{
int suma = 0;
while (*cadena != '\0') {
suma++;
cadena++;
}
return(suma);
}
Habría muchas formas:

int longitud (char *cadena) {
char *b = cadena;
while (*b) b++;
return b - cadena;
}

int longitud (char *cadena) {
int i = 0;
while (cadena[i]) i++;
return i;
}

Etc...
Post by Olaf "El Blanco"
¿Estoy usando las llaves al estilo de Dennis Ritchie?
Ni idea, no tengo el placer de conocer a ese señor.
Post by Olaf "El Blanco"
printf ("Llamando a la función %d",longitud(&cadena));
Porque en sí cadena ya es un puntero que apunta al comienzo de la
cadena de caracteres (apunta al primer carácter). Cadena no es en sí
un tipo de dato "compacto" si no que siempre se trata de un puntero
que apunta a la zona de memoria donde se guarda la cadena.
Post by Olaf "El Blanco"
En los libros dice que si creo una función con el parámetro formal
*blablabla
el parámetro actual, o la forma de llamar a dicha función debe ser siempre
una dirección de memoria, por lo tanto &blablabla
Si una variable es ya el tipo de dato que debes entregar a una función
no necesitas reconvertirlo (o rizar el rizo).

a ver...
int i;
funcion (i);

Entonces funcion recibe un int.

int i;
funcion (&i);

Entonces función recibe un int * (un puntero a un entero).

int *i;
funcion (i);

Entonces función recibe de nuevo un int *.

int *i;
funcion (&i);

Ahora recibe un int ** (un puntero que apunta a la dirección de
memoria donde se guarda un puntero que apunta a un entero).
Post by Olaf "El Blanco"
No sabes lo que me estas ayudando!
Un placer.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
heltena
2005-12-22 17:22:05 UTC
Permalink
Lo que has escrito:

int longitud (char *cadena)
{
int suma = 0;
while (*cadena != '\0') {
suma++;
cadena++;
}
return(suma);
}

Lo suelen escribir como:

int longitud(char *cadena) {
int suma = 0;
while (*cadena++)
suma++;
return suma;
}

Que parece más compacto, pero hace exáctamente lo mismo.

Por otro lado, estás usando librerías de C++ (cstdlib y iostream) y,
si estás programando en C, mejor usar las librerías de C (stdlib.h y
stdio.h) y la stdlib.h no sé si la necesitarás. Si usas cstdlib
porque el compilador se queja será porque el fichero de tu programa
tiene extensión .cpp y no .c

Por otro lado, no puedes poner &cadena por lo siguiente:
cadena es de tipo puntero a caracter (char *)
&cadena es de tipo puntero a puntero a caracter (char **)
y la función "longitud" está esperando un "char *" y no un "char **".
Lo que dicen "los libros" son recetitas que sirven para perder el miedo
al lenguaje, pero después no hacen más que liarte como el rabillo de
un cerdo.
A ver, una explicación detallada y simple (espero). Esto es como la
suma, que no puedes sumar peras con manzanas. Pues lo mismo, si una
función espera una pera no le puedes pasar una manzana. Ahora
cambiamos peras y manzanas por char y char*.
Miremos el operator &:

int a; /* a es de tipo int */
char p[] = "hola"; /* p es de tipo char * (puntero a char) y además se
reserva 5 caracteres en memoria (los cuatro de hola y el centinela del
final) */
int *b; /* b es de tipo int * */

entonces:
&a es de tipo int *
&p es de tipo char **
&b es de tipo int **
*b es de tipo int
*p es de tipo char
p[3] es de tipo char (y p[0] es equivalente a *p)

y se pueden hacer cosas como:
b = &a;
a = *b;
p[2] = 'L';
*p = 'H';
*b = p[2]; /* bueno, a un int se le puede asignar un char */

y si te fijas, es posible porque estamos igualando peras con peras y
manzanas con manzanas.

y si en vez de una asignación lo piensas con un paso de parámetros,
pues tienes lo mismo y, espero, te aclara un poco tu pregunta
(&cadena).

Saludos y felices fiestas!!!

heltena
2005-12-22 08:32:21 UTC
Permalink
¿por qué quieres llamar al getch?

No pongas nada, al ejecutarlo hazlo desde una ventanita del msdios o,
si usas VisualC, pulsa Ctrl+F5.
Oscar Garcia
2005-12-21 16:50:37 UTC
Permalink
El Wed, 21 Dec 2005 17:02:37 +0100, "Olaf \"El Blanco\""
Post by Olaf "El Blanco"
Gracias Oscar...
Se me han aclarado varias cosas, pero me falta algún concepto.
Mira ésto, le he agregado los comentarios en el mail...
Mira al final del mensaje que tengo algo para tí.
Post by Olaf "El Blanco"
#include <stdio.h>
#define MAX 5 // Maximo tamaño de columna y fila
// Recibe como parámetro un puntero, no recibe la tabla en si,
// recibe una direccion de memoria
void crear_tabla (int *tabla[MAX][MAX])
{
int f, c;
for (c=0; c<MAX; c++)
for (f=0; f<MAX; f++)
// Accedemos a la direccion de memoria de la tabla
// Específicamente en esa fila y columna
// Y le cambiamos el valor.
*tabla[f][c] = f + c;
void imprimir_tabla (int *tabla[MAX][MAX])
{
int f, c;
for (c=0; c<MAX; c++) {
for (f=0; f<MAX; f++)
printf ("%3d");
printf ("\n");
}
}
void main()
{
// Reservo memoria para una matriz de MAX x MAX enteros...
int matrix[MAX][MAX];
// En teoría esa direccion la puedo ver asi: printf ("%d",&matrix) ???
// Le doy el entero direccion de memoria donde "comienza" la tabla en la RAM
crear_tabla(&matrix);
// Le doy el entero direccion de memoria donde "comienza" la tabla en la RAM
imprimir_tabla(&matrix);
// Todo esto sirve para no copiar la tabla entera mas de una vez, para
ahorrar memoria.
getch();
}
Obviamente no funciona.
Mira como ahora sí funciona (si se hace correctamente):

#include <stdio.h>
#define MAX 5 // Maximo tamaño de columna y fila
// Recibe como parámetro un puntero, no recibe la tabla en si,
// recibe una direccion de memoria
void crear_tabla (int (*tabla)[MAX][MAX])
{
int f, c;
for (c=0; c<MAX; c++)
for (f=0; f<MAX; f++)
// Accedemos a la direccion de memoria de la
tabla
// Específicamente en esa fila y columna
// Y le cambiamos el valor.
(*tabla)[f][c] = f + c;
}

void imprimir_tabla (int (*tabla)[MAX][MAX])
{
int f, c;
for (c=0; c<MAX; c++) {
for (f=0; f<MAX; f++)
printf ("%3d", (*tabla)[f][c]);
printf ("\n");
}
}

int main()
{
// Reservo memoria para una matriz de MAX x MAX enteros...
int matrix[MAX][MAX];
// En teoría esa direccion la puedo ver asi: printf
("%d",&matrix) ???
// Le doy el entero direccion de memoria donde "comienza" la
tabla en la RAM
crear_tabla(&matrix);
// Le doy el entero direccion de memoria donde "comienza" la
tabla en la RAM
imprimir_tabla(&matrix);
// Todo esto sirve para no copiar la tabla entera mas de una
vez, para
// ahorrar memoria.
return 0;
}

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
Olaf "El Blanco"
2005-12-21 21:58:59 UTC
Permalink
Resumiendo:

Porque el programa1 SI funciona y el programa2 NO funciona.

Programa1
**************************************************************************************
#include <stdio.h>
#define MAX 15 // Maximo tamaño de columna y fila
int main()
{
int tabla[MAX][MAX];
int f, c;
for (c=0; c<MAX; c++)
for (f=0; f<MAX; f++)
tabla[f][c] = f+c;
for (c=0; c<MAX; c++) {
for (f=0; f<MAX; f++)
printf ("%4d ",tabla[c][f]);
printf ("\n");
}
getch();
return 0;
}

Programa2
**************************************************************************************
#include <stdio.h>
#define MAX 5 // Maximo tamaño de columna y fila
void crear_tabla (int (*tabla)[MAX][MAX])
{
int f, c;
for (c=0; c<MAX; c++)
for (f=0; f<MAX; f++)
(*tabla)[f][c] = f+c;
}
void imprimir_tabla (int (*tabla)[MAX][MAX])
{
int f, c;
for (c=0; c<MAX; c++) {
for (f=0; f<MAX; f++)
printf ("%d ! ",*tabla[c][f]);
printf ("\n");
}
}
int main()
{
int matrix[MAX][MAX];
crear_tabla(&matrix[MAX][MAX]);
imprimir_tabla(&matrix[MAX][MAX]);
getch();
return 0;
}
Oscar Garcia
2005-12-21 22:45:53 UTC
Permalink
El Wed, 21 Dec 2005 22:58:59 +0100, "Olaf \"El Blanco\""
Post by Olaf "El Blanco"
Porque el programa1 SI funciona y el programa2 NO funciona.
Mira que eres cabezón (en el buen sentido :). Mira que te gusta añadir
cosas nuevas sin ton ni son.
Post by Olaf "El Blanco"
int main()
{
int matrix[MAX][MAX];
crear_tabla(&matrix[MAX][MAX]);
imprimir_tabla(&matrix[MAX][MAX]);
getch();
return 0;
}
¿Para qué pones las dimensiones al pasar como parámetro la matriz?

¿No viste mi código?

Pon _SOLO_:

crear_tabla(&matrix);
imprimir_tabla(&matrix);

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
Loading...