Foros del Web » Programación para mayores de 30 ;) » C/C++ »

problemas con el calificador de tipo "Const"

Estas en el tema de problemas con el calificador de tipo "Const" en el foro de C/C++ en Foros del Web. Tengo un par de dudas con este identificador y para no extenderme demasiado esta es la primera y la que mas urge saber: Lo que ...
  #1 (permalink)  
Antiguo 09/08/2015, 02:31
 
Fecha de Ingreso: febrero-2015
Mensajes: 20
Antigüedad: 9 años, 2 meses
Puntos: 0
Pregunta problemas con el calificador de tipo "Const"

Tengo un par de dudas con este identificador y para no extenderme demasiado esta es la primera y la que mas urge saber:

Lo que pasa es que estoy iniciándome en el tema de los arreglos bidimencionales de el libro de deitel y ahorita estoy viendo solo ejemplos y no he hecho muchos ejercicios aun, pero todos los ejemplos que veo los hago tambien ya que aprendo mas escribiendolos...
y sucede por ejemplo que el prototipo y definición de una función cualquiera especifica que va a recibir como parámetro un arreglo bidimensional de la forma const int a[][3]
ejemplo:
Código:
#include <stdio.h>

void despliegaArreglo(const int a[][3]);    //despliega los elementos del arreglo

int main()
{
    int arreglo1[2][3] = {{1,2,3},{4,5,6}};
    int arreglo2[2][3]= {1,2,3,4,5};
    int arreglo3[2][3]= {{1,2},{4}};
	
	despliegaArreglo(arreglo1);
	despliegaArreglo(arreglo2);
	despliegaArreglo(arreglo3);
	
	return 0;
}

void despliegaArreglo(const int a[][3])
{
	int i;
	int j;
	
	for(i = 0; i < 2; i++){
		
		for(j = 0; j < 3; j++){
			printf("%d ", a[i][j]);
		}
		printf("\n");
    }
}
El programa se ejecuta pero el compilador marca algunos errores como por ejemplo:

[Warning] passing argument 1 of 'despliegaArreglo' from incompatible pointer type [enabled by default]
[Note] expected 'const int (*)[3]' but argument is of type 'int (*)[3]'

Esto lo solucione precediendo los arreglos locales de main con const, no se si el error es por culpa del compilador o si es error mio pero el ejemplo esta así en el libro...
Otro detalle es que solo me pasa con arreglos bidimencionales...

Hasta el momento solo se que const se usa solo para hacer constante el arreglo y evitar que una función la modifique, tampoco se profundizo mucho en el concepto por lo que necesito aclararme un poco mas esto, ya que no comprendo por que sucede esto con los arreglos bidimencionales y con los de un subindice no.

la otra duda que tengo la explicare de manera de resumen;

int arreglo[2][3] = {1,2,3,4,5,6}; //declaro un arreglo en main
la paso a una función que especifica en el parámetro que a arreglo la precederá un "const"
Código:
void funcion(const int a[][3])
//en esta funcion se llama a otra función que recibe el mismo parámetro pero sin "const"
Código:
ordenamBurbuja(a);
El programa se ejecuta pero el compilador marca el siguiente error:
[Warning] passing argument 1 of 'ordenamBurbuja' discards 'const' qualifier from pointer target type [enabled by default]

por lo que supongo (en ambos casos)que es incorrecto hacer esto aunque el programa corra bien...

les agradecería que me pudieran ayudar un poco ya que no encuentro lo que busco en internet
  #2 (permalink)  
Antiguo 09/08/2015, 05:37
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: problemas con el calificador de tipo "Const"

Bueno, ante todo una cosa.
Hay que diferenciar entre errores y avisos(warnings).
Lo que te manda el compilador son avisos que si bien te dejan ejecutar el programa te están advirtiendo de fallos que te pueden ocasionar problemas más adelante.

Respecto a la primera duda, efectivamente, el tipo del parámetro es const int y tú le estás enviando un int.
El compilador te lo acepta EN ESTE CASO, porque efectivamente tu función no está modificando el contenido del array. Así que le hace un casting a const int y ejecuta la función.

Sin embargo prueba a meter dentro de la función una sentencia que sí modifique el array, algo tipo:
Código C++:
Ver original
  1. a[1][1]=3;

El warning se convierte en error y directamente no te dejará compilar, ya que const está protegiendo al array de modificaciones dentro de la función.

Y sobre el segundo warning igual....sólo que en este caso te debería dar error directamente, ya que la función ordenaBurbuja(int [][]) espera encontrarse con un int y tu le envías un const int
__________________
Mi calculadora en Qt
  #3 (permalink)  
Antiguo 10/08/2015, 00:22
 
Fecha de Ingreso: febrero-2015
Mensajes: 20
Antigüedad: 9 años, 2 meses
Puntos: 0
Respuesta: problemas con el calificador de tipo "Const"

Cita:
Iniciado por dehm Ver Mensaje
Bueno, ante todo una cosa.
Hay que diferenciar entre errores y avisos(warnings).
Lo que te manda el compilador son avisos que si bien te dejan ejecutar el programa te están advirtiendo de fallos que te pueden ocasionar problemas más adelante.

Respecto a la primera duda, efectivamente, el tipo del parámetro es const int y tú le estás enviando un int.
El compilador te lo acepta EN ESTE CASO, porque efectivamente tu función no está modificando el contenido del array. Así que le hace un casting a const int y ejecuta la función.

Sin embargo prueba a meter dentro de la función una sentencia que sí modifique el array, algo tipo:
Código C++:
Ver original
  1. a[1][1]=3;

El warning se convierte en error y directamente no te dejará compilar, ya que const está protegiendo al array de modificaciones dentro de la función.

Y sobre el segundo warning igual....sólo que en este caso te debería dar error directamente, ya que la función ordenaBurbuja(int [][]) espera encontrarse con un int y tu le envías un const int
Gracias ya entiendo un poco mejor, aunque con los arreglos de un subindice no me da estos avisos y pues creí que el arreglo bidimensional tenia algo que ver...

En fin, solo tengo otra duda general solo para que me quede un poco mas claro...
¿Se puede decir que esta bien pasar un arreglo de tipo int a una función que la convierte en const int siempre y cuando la función no trate de modificar el array, pero esta mal pasar un arreglo const int a una funcion que recibe como parámetro al arreglo de tipo int?
Es decir ¿Se puede hacer un casting de int a const int pero es incorrecto hacerlo viceversa? eso es lo que entendi
  #4 (permalink)  
Antiguo 10/08/2015, 02:48
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 7 meses
Puntos: 38
Respuesta: problemas con el calificador de tipo "Const"

cuando nosotros creamos una función que recibe un const es que sabemos que en ningún momento el dato que le pasamos será modificado, es una especie de "seguro", tu como programador al ver que la función recibe const debe saber que lo que le vas a pasar no se verá afectado, se pasa a modo de simple consulta. Sin embargo, si la función espera un simples int y tu le pasas un const no tiene mucha lógica. ¿¿¿Tendría lógica hacer int n = (const)x;(por poner un ejemplo, lo más probable es que falle XD)???

Cuanto a si está bien o mal, digamos que no esta mal pasar int a una función que espere const, pero lo mejor es que la aplicación al compilar no emita ni warnings ni erros, si con poner un foo((const)loquesea); hace que el programa no emita avisos, ni erros, es buena practica, y también quiere decir que dominas la el problema. ;)
  #5 (permalink)  
Antiguo 11/08/2015, 00:41
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: problemas con el calificador de tipo "Const"

Cita:
Es decir ¿Se puede hacer un casting de int a const int pero es incorrecto hacerlo viceversa? eso es lo que entendi
Bueno, realmente te dije que se hacía un casting de int a const int y no sé si es muy correcta esa lectura.
Veo mejor limitarse a pensar que con la cláusula const en una función me aseguro de que el contenido del array que mando como parámetro no será modificado. Puede no parecer muy útil cuando tú estás diseñando tu función y ésta no es muy complicada. En ese caso tú sabes mejor que nadie lo que ha de hacer la función y cómo ha de hacerlo. Pero puede ser que le mandes el prototipo a otra persona para que lo desarrolle, o tú mismo en el futuro quieres cambiar ese contenido. Con la cláusula const ya sabes que el contenido del array será siempre no modificable.

Sobre la inversa, si el parámetro se pasa por referencia, como es un array, te saltará el error porque es un cambio de tipo no permitido.
Si se pasa el objeto o variable por valor, y puesto que la copia local no modifica al parámetro, sí se podría.

Código C++:
Ver original
  1. void Leer (int num)
  2. {
  3.     num++;
  4.     cout<<"A en la función: "<<num<<endl;
  5. }
  6.  
  7. int main()
  8. {
  9.     const int a=6;
  10.     Leer (a);
  11.     cout<<"A en main: "<<a<<endl;
  12.     return 0;
  13. }

En este caso uso el parámetro para obtener un valor, cuya modificación dentro de la función no afecta al objeto o variable que uso como parámetro, luego es suficiente con que los dos sean del tipo int.
Sin embargo así:
Código C++:
Ver original
  1. void Leer (int& num)
  2. {
  3.     cout<<"A en la función: "<<num<<endl;
  4. }
  5.  
  6. int main()
  7. {
  8.     const int a=6;
  9.     Leer (a);
  10.     cout<<"A en main: "<<a<<endl;
  11.     return 0;
  12. }

Puesto que lo que quiero pasar como parámetro es la propia variable, ésta ha de tener el mismo tipo, aunque no sea modificada.

Mira aquí que te enterarás seguro que mucho mejor que con mi explicación.
http://c.conclase.net/curso/index.ph...025#VARV_CONST
__________________
Mi calculadora en Qt

Etiquetas: arreglos, funcion, int, programa, tipo
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 21:26.