para que sirve const int en c++




¿Cuál es la diferencia entre const int*, const int*const y int const*? (10)

Siempre arruino la forma de usar const int* , const int * const y int const * correctamente. ¿Hay un conjunto de reglas que definen lo que puedes y no puedes hacer?

Quiero saber todo lo que se debe y lo que no se debe hacer en términos de tareas, pases a las funciones, etc.


  1. Referencia constante:

    Una referencia a una variable (aquí int), que es constante. Pasamos la variable como referencia principalmente, porque las referencias son más pequeñas en tamaño que el valor real, pero hay un efecto secundario y es porque es como un alias de la variable real. Podemos cambiar accidentalmente la variable principal a través de nuestro acceso completo al alias, por lo que lo hacemos constante para evitar este efecto secundario.

    int var0 = 0;
    const int &ptr1 = var0;
    ptr1 = 8; // Error
    var0 = 6; // OK
    
  2. Punteros constantes

    Una vez que un puntero constante apunta a una variable, entonces no puede apuntar a ninguna otra variable.

    int var1 = 1;
    int var2 = 0;
    
    int *const ptr2 = &var1;
    ptr2 = &var2; // Error
    
  3. Puntero a constante

    Un puntero a través del cual no se puede cambiar el valor de una variable que señala se conoce como un puntero a constante.

    int const * ptr3 = &var2;
    *ptr3 = 4; // Error
    
  4. Puntero constante a una constante

    Un puntero constante a una constante es un puntero que no puede cambiar la dirección a la que apunta y tampoco puede cambiar el valor guardado en esa dirección.

    int var3 = 0;
    int var4 = 0;
    const int * const ptr4 = &var3;
    *ptr4 = 1;     // Error
     ptr4 = &var4; // Error
    

Como casi todo el mundo señaló:

¿Cuál es la diferencia entre const X* p , X* const p y const X* const p ?

Tienes que leer las declaraciones de puntero de derecha a izquierda.

  • const X* p significa "p apunta a una X que es const": el objeto X no se puede cambiar a través de p.

  • X* const p significa "p es un puntero de const a una X que no es constante": no puede cambiar el puntero p en sí, pero puede cambiar el objeto X a través de p.

  • const X* const p significa "p es un puntero de const a una X que es const": no se puede cambiar el puntero p, ni se puede cambiar el objeto X a través de p.


Es simple pero complicado. Tenga en cuenta que podemos intercambiar el calificador const con cualquier tipo de datos ( int , char , float , etc.).

Veamos los siguientes ejemplos.

const int *p ==> *p es de solo lectura [ p es un puntero a un entero constante]

int const *p ==> *p es de solo lectura [ p es un puntero a un entero constante]

int *p const ==> Declaración errónea . El compilador lanza un error de sintaxis.

int *const p ==> p es de solo lectura [ p es un puntero constante a un entero]. Como el puntero p es de solo lectura, la declaración y la definición deben estar en el mismo lugar.

const int *p const ==> Declaración errónea . El compilador lanza un error de sintaxis.

const int const *p ==> *p es de solo lectura

const int *const p1 ==> *p y p son de solo lectura [ p es un puntero constante a un entero constante]. Como el puntero p es de solo lectura, la declaración y la definición deben estar en el mismo lugar.

int const *p const ==> Declaración errónea . El compilador lanza un error de sintaxis.

int const int *p ==> Declaración errónea . El compilador lanza un error de sintaxis.

int const const *p ==> *p es de solo lectura y es equivalente a int const *p

int const *const p ==> *p y p son de solo lectura [ p es un puntero constante a un entero constante]. Como el puntero p es de solo lectura, la declaración y la definición deben estar en el mismo lugar.


Esta pregunta muestra precisamente por qué me gusta hacer las cosas de la manera que mencioné en mi pregunta: ¿ se acepta const después de que sea id tipo?

En resumen, la forma más fácil de recordar la regla es que la "const" va después de lo que se aplica. En su pregunta, "int const *" significa que int es constante, mientras que "int * const" significa que el puntero es constante.

Si alguien decide ponerlo en el frente (por ejemplo: "const int *"), como excepción especial, en ese caso, se aplica a la cosa que está detrás de él.

A muchas personas les gusta usar esa excepción especial porque piensan que se ve mejor. No me gusta, porque es una excepción, y por lo tanto confunde las cosas.


Hay muchos otros puntos sutiles que rodean la corrección constante en C ++. Supongo que la pregunta aquí ha sido simplemente sobre C, pero daré algunos ejemplos relacionados ya que la etiqueta es C ++:

  • A menudo se pasan grandes argumentos como cadenas como TYPE const & que impiden que el objeto sea modificado o copiado. Ejemplo:

    TYPE& TYPE::operator=(const TYPE &rhs) { ... return *this; }

    Pero TYPE & const tiene sentido porque las referencias son siempre const.

  • Siempre debe etiquetar los métodos de clase que no modifican la clase como const , de lo contrario no puede llamar al método desde una TYPE const & reference. Ejemplo:

    bool TYPE::operator==(const TYPE &rhs) const { ... }

  • Hay situaciones comunes en las que tanto el valor de retorno como el método deben ser const. Ejemplo:

    const TYPE TYPE::operator+(const TYPE &rhs) const { ... }

    De hecho, los métodos const no deben devolver datos de clase internos como una referencia a no const.

  • Como resultado, a menudo se debe crear tanto un método const como un método non-const utilizando la sobrecarga const. Por ejemplo, si define T const& operator[] (unsigned i) const; , entonces probablemente también querrás la versión no constante dada por:

    inline T& operator[] (unsigned i) { return const_cast<char&>( static_cast<const TYPE&>(*this)[](i) ); }

Afaik, no hay funciones const en C, las funciones que no son miembros no pueden ser const en C ++, los métodos const pueden tener efectos secundarios y el compilador no puede usar las funciones const para evitar llamadas a funciones duplicadas. De hecho, incluso un simple int const & reference podría ser testigo de que el valor al que se refiere se cambie en otra parte.


Léalo al revés (según lo indicado por Clockwise / Spiral Rule ):

  • int* - puntero a int
  • int const * - puntero a const int
  • int * const - const point to int
  • int const * const - const puntero a const int

Ahora la primera const puede estar en cualquier lado del tipo, así que:

  • const int * == int const *
  • const int * const == int const * const

Si quieres volverte realmente loco puedes hacer cosas como esta:

  • int ** - puntero a puntero a int
  • int ** const - un puntero constante a un puntero a un int
  • int * const * - un puntero a un const puntero a un int
  • int const ** - un puntero a un puntero a un const int
  • int * const * const - un puntero const a un puntero const a un int
  • ...

Y para asegurarnos de que tenemos claro el significado de const

const int* foo;
int *const bar; //note, you actually need to set the pointer 
                //here because you can't change it later ;)

foo es un puntero variable a un entero constante. Esto le permite cambiar lo que apunta pero no el valor al que apunta. La mayoría de las veces, esto se ve con cadenas de estilo C, donde tiene un puntero a un const char . Puede cambiar a qué cadena apunta pero no puede cambiar el contenido de estas cadenas. Esto es importante cuando la cadena está en el segmento de datos de un programa y no debe cambiarse.

bar es un puntero constante o fijo a un valor que se puede cambiar. Esto es como una referencia sin el azúcar sintáctico adicional. Debido a este hecho, normalmente usaría una referencia donde usaría un puntero T* const menos que necesite permitir punteros NULL .


La regla general es que la palabra clave const aplica a lo que la precede inmediatamente. Excepción, una const partida se aplica a lo que sigue.

  • const int* es lo mismo que int const* y significa "puntero a constante int" .
  • const int* const es lo mismo que int const* const y significa "puntero constante a constante int" .

Edit: Para el hacer y no hacer, si esta respuesta no es suficiente, ¿podría ser más preciso sobre lo que quiere?


La sintaxis de declaración de C y C ++ ha sido descrita repetidamente como un experimento fallido, por los diseñadores originales.

En su lugar, vamos a nombrar el tipo "puntero a Type "; Lo llamaré Ptr_ :

template< class Type >
using Ptr_ = Type*;

Ahora Ptr_<char> es un puntero a char .

Ptr_<const char> es un puntero a const char .

Y const Ptr_<const char> es un puntero de const char para const char .

Ahí.


Tenía la misma duda que tú hasta que encontré este book del C ++ Guru Scott Meyers. Refiera el tercer artículo en este libro donde habla en detalles sobre el uso de const .

Solo sigue este consejo

  1. Si la palabra const aparece a la izquierda del asterisco, lo que apunta es constante
  2. Si la palabra const aparece a la derecha del asterisco, el puntero es constante
  3. Si aparece const en ambos lados, ambos son constantes.

Uso simple de 'const'

El uso más simple es declarar una constante nombrada. Para hacer esto, uno declara una constante como si fuera una variable pero agrega 'const' antes de ella. Uno tiene que inicializarlo inmediatamente en el constructor porque, por supuesto, uno no puede establecer el valor más adelante, ya que eso lo alteraría. Por ejemplo,

const int Constant1=96; 

creará una constante entera, unimaginativamente llamada 'Constant1', con el valor 96.

Estas constantes son útiles para los parámetros que se utilizan en el programa, pero no es necesario cambiarlos después de compilar el programa. Tiene una ventaja para los programadores sobre el comando '#define' del preprocesador en que es comprendido y usado por el compilador, no solo sustituido por el preprocesador en el texto del programa antes de llegar al compilador principal, así que los mensajes de error son mucho más útiles .

También funciona con punteros, pero uno tiene que tener cuidado donde "const" para determinar si el puntero o lo que apunta es constante o ambos. Por ejemplo,

const int * Constant2 

declara que Constant2 es un puntero variable a un entero constante y

int const * Constant2

Es una sintaxis alternativa que hace lo mismo, mientras que

int * const Constant3

declara que Constant3 es un puntero constante a un entero variable y

int const * const Constant4

declara que Constant4 es un puntero constante a un entero constante. Básicamente, 'const' se aplica a lo que está a su izquierda inmediata (excepto si no hay nada en ese caso, se aplica a lo que está a su derecha inmediata).

ref: http://duramecho.com/ComputerInformation/WhyHowCppConst.html





const