En C, el prototipo para la función de valor absoluto (que acepta un flotante) es
float fabsf( float );
¿Por qué este prototipo no acepta un valor constante, como este:
float fabsf( float const );
fabsf no cambiará el valor de la entrada, ¿verdad?
Si tengo una función que acepta una entrada y llama a fabsf, ¿me veo obligado a evitar especificar la entrada como constante?
¿Cuál es la forma apropiada de manejar la corrección constante en esta situación?
c
function
const
pass-by-value
user24205
fuente
fuente
const
es redundante aquí, ¿qué imaginas que está pasando?const
tiene sentido.float const x = -1.0; float y = fabsf(x);
me parece quefabsf
sí acepta entradas constantes. No hay forma de decir "puedes pasarme unfloat
por valor pero no puedes pasar unconst float
". (Y como vemos en las respuestas, C no proporciona una manera de exigir que la entrada a una función sea afloat const
.)Respuestas:
Editar
Como se ha comentado MM, en parámetros en prototipos el
const
se ignora. La fuente editada de la respuesta original (ver más abajo) muestra esto:No hay ningún mensaje de error.
De todos modos, dejaré el original en su lugar con la esperanza de que pueda ayudar.
Original
El
const
parámetro at a hace que este parámetro sea de solo lectura dentro de la función.Por ejemplo:
Esta fuente no se compilará sin un mensaje de error.
La función
correct()
leerá el valor dado, cambiará su signo y devolverá el valor negado.La función
erroneous()
parece hacer efectivamente lo mismo, excepto que hay una asignación al parámetro. Pero como el parámetro esconst
esto no está permitido.A continuación, la función
changer()
funcionará como las dos anteriores, pero no da errores.Veamos el sitio de la llamada:
La variable
f
dada como argumento se copiará en el parámetrovalue
. Nunca cambiará incluso sichanger()
se llamará.Es posible que desee ver los parámetros como algún tipo de variables locales. En realidad, se manejan principalmente de esta manera en el código de máquina generado.
Entonces, ¿por qué ves a
const
veces? Lo verá si un puntero se define como parámetro.Cuando no desea que se cambie el valor señalado , debe agregarlo
const
; pero hazlo en la posición correcta!fuente
float fabsf( float const );
no tiene nada que ver con la implementación de la función (que no tiene que repetirconst
), de hecho,const
se ignora por completo en el prototipoC utiliza pasar por valor. El valor para el parámetro de una función es una copia del argumento que da.
Está bien copiar flotadores const y no const, y el resultado es un flotador sin const.
Es similar a la asignación:
De hecho, el lenguaje especifica que el valor de una expresión nunca puede ser
const
, es decir, cuando se lee un valor de una variable, ese valor niconst
siquiera es si la variable lo fuera.fuente
Debido a que el lenguaje C usa la semántica de pasar por valor, cualquier argumento que le pase, aunque podría modificarse internamente, no afecta directamente el valor que pasa.
Esto significa que desde la perspectiva de la persona que llama,
float fabsf( float );
yfloat fabsf( const float );
son lo mismo. Entonces no tiene sentido hacer el parámetroconst
.Donde tiene sentido usar
const
es si el parámetro que pasa es un puntero, por ejemplo:Esta función, a pesar de lo que sugiere el nombre, puede desreferenciar el puntero dado y modificar lo que apunta, es decir
str[0] = 'x'
, para dar como resultado un cambio visible por la función de llamada. Si esta función se definiera así:La persona que llama tiene la seguridad de que la función no puede realizar modificaciones a los
str
puntos.fuente
((char*)str)[0] = 'f'
. Por lo tanto,const ... *
la lista de argumentos es solo una "declaración de intenciones".Para agregar una perspectiva de abogado de idiomas:
Eso significa que estos dos son compatibles:
Por lo tanto, puede escribir el prototipo con o sin
const
(lo que significa que sin tiene más sentido; menos para escribir / leer) y puede agregarconst
la definición de la función si desea evitar modificar accidentalmente el parámetro (copiado - ¡llamada por valor!) Dentro de las funciones cuerpo.fuente