c++ - ejemplos - punteros en c
¿Para qué sirven los punteros const(a diferencia de los punteros para construir objetos)? (11)
A menudo he usado punteros para construir objetos, así que ...
const int *p;
Eso simplemente significa que no puede cambiar el entero al que p
está apuntando a través de p
. Pero también he visto referencias a punteros const, declarados así ...
int* const p;
Tal como lo entiendo, eso significa que la variable del puntero en sí es constante: puedes cambiar el número entero al que apunta todo el día, pero no puedes hacer que apunte a otra cosa.
¿Qué uso posible tendría eso?
Cuando diseña programas C para sistemas integrados o programas de propósito especial que necesitan referirse a la misma memoria (aplicaciones multiprocesador que comparten memoria), entonces necesita punteros constantes.
Por ejemplo, tengo un procesador MIP de 32 bits que tiene una pequeña pantalla LCD conectada. Tengo que escribir los datos de mi LCD en un puerto específico en la memoria, que luego se envía al controlador LCD.
Pude # definir ese número, pero también tengo que lanzarlo como un puntero, y el compilador de C no tiene tantas opciones cuando lo hago.
Además, podría necesitar que sea volátil, que también se puede transmitir, pero es más fácil y más claro utilizar la sintaxis proporcionada: un puntero constante a una ubicación de memoria volátil.
Para los programas de PC, un ejemplo sería: Si diseña juegos VGA DOS (hay tutoriales en línea que son divertidos de aprender para aprender los gráficos básicos de bajo nivel), entonces necesita escribir en la memoria VGA, que podría ser referenciada como un desplazamiento desde un puntero const.
-Adán
En cualquier función no const C ++ miembro, this
puntero es de tipo C * const
, donde C
es el tipo de clase - puede cambiar lo que señala (es decir, sus miembros), pero no puede cambiarlo para apuntar a una instancia diferente de una C
Para las funciones miembro de const
, this
es de tipo const C * const
. También hay (rara vez se encuentran) funciones const volatile
volatile
e const volatile
, para las que también tiene el calificador volatile
.
He visto un código OLE donde hay un objeto pasado desde fuera del código y para trabajar con él, tenía que acceder a la memoria específica que pasaba. Así que usamos punteros para asegurarse de que las funciones siempre manipularan los valores. que ingresó a través de la interfaz OLE.
Igual que "const int" ... si el compilador sabe que no va a cambiar, puede haber suposiciones de optimización basadas en eso.
struct MyClass
{
char* const ptr;
MyClass(char* str) :ptr(str) {}
void SomeFunc(MyOtherClass moc)
{
for(int i=0; i < 100; ++i)
{
printf("%c", ptr[i]);
moc.SomeOtherFunc(this);
}
}
}
Ahora, el compilador podría hacer bastante para optimizar ese bucle, siempre que sepa que SomeOtherFunc () no cambia el valor de ptr. Con la const, el compilador lo sabe y puede hacer suposiciones. Sin él, el compilador tiene que suponer que SomeOtherFunc cambiará ptr.
Le permite proteger el puntero de ser cambiado. Esto significa que puede proteger los supuestos que hace basándose en que el puntero nunca cambia o que no se modifique involuntariamente, por ejemplo:
int* const p = &i;
...
p++; /* Compiler error, oops you meant */
(*p)++; /* Increment the number */
Piense en type * y const type * como tipos en sí mismos. Entonces, puedes ver por qué querrías tener un const de esos tipos.
Se han dado varias buenas razones para responder a estas preguntas (dispositivos con memoria asignada y codificación defensiva antigua), pero estaría dispuesto a apostar a que la mayoría de los casos en que ve esto es en realidad un error y que la intención era tener al elemento sea un puntero-a-const.
Ciertamente no tengo datos para respaldar esta corazonada, pero aún así haré la apuesta.
Siempre los he usado cuando quería evitar modificaciones involuntarias en el puntero (como la aritmética del puntero o dentro de una función). También puede usarlos para patrones de Singleton.
''this'' es un puntero constante codificado.
Un uso es en código de bajo nivel (controlador de dispositivo o incrustado) donde necesita hacer referencia a una dirección específica asignada a un dispositivo de entrada / salida como un pin de hardware. Algunos idiomas le permiten vincular variables en direcciones específicas (por ejemplo, Ada tiene use at
). En C, la forma más idiomática de hacer esto es declarar un puntero constante. Tenga en cuenta que dichos usos también deben tener el calificador volatile
.
Otras veces es solo codificación defensiva. Si tiene un puntero que no debe cambiar, es aconsejable declararlo de manera que no pueda cambiar. Esto permitirá que el compilador (y las herramientas de pelusa) detecten intentos erróneos de modificarlo.
otro ejemplo: si sabe dónde se inicializó, puede evitar futuros controles NULL. El compilador le garantiza que el puntero nunca cambió (a NULL) ...
siempre piense en un puntero como un int. esto significa que
object* var;
en realidad se puede pensar como
int var;
entonces, un puntero de const simplemente significa que:
const object* var;
se convierte
const int var;
y por lo tanto, no puede cambiar la dirección que señala el puntero, y eso es todo. Para evitar el cambio de datos, debe convertirlo en un puntero a un objeto const.