Categorías
C/C++ Top 10

Las 5 preguntas principales sobre punteros C / C ++

Este artículo resume las principales preguntas formuladas sobre los punteros de C / C ++ en stackoverflow.com. Los punteros son la parte más confusa de C / C ++, esas preguntas utilizan ejemplos simples para explicar conceptos clave de punteros.

1. Cuente de 1 a 1000 sin usar bucles

#include <stdio.h>
#include <stdlib.h>
 
void main(int j) {
  printf("%dn", j);
  (&main + (&exit - &main)*(j/1000))(j+1);
}

El único otro método para contar del 1 al 1000 es la recursividad. Según el lenguaje C, j tiene ‘1’ como su valor al principio. Cuando 1 <= j <1000, & main + (& exit - & main) * (j / 1000) siempre se evalúa como & main, que es la dirección de memoria de main. (& main) (j + 1) es la siguiente iteración que queremos obtener, que imprimiría '2' en la pantalla, etc. La condición de parada de esta recursividad es que cuando j llega a 1000, & main + (& exit - & main) * (j / 1000) evalúa a & exit, que saldrá elegantemente de este proceso y tiene el código de error 1001 devuelto al sistema operativo.

2. ¿Por qué un[5] == 5[a]?

a[b] significa * (a + b) según el estándar C. a es la dirección base, b es un desplazamiento a partir de a. a[b] es el valor en la dirección de a + b.

Por tanto, a + 5 y 5 + a es la misma dirección de memoria. Su valor * (a + 5) y * (5 + a) es el mismo. Entonces un[5] == 5[a]

3. ¿Cuántos niveles de punteros podemos tener?

Tanto como un humano pueda manejar. Cualquier compilador de c / c ++ definitivamente admite más que eso.

  Las 10 preguntas principales sobre las colecciones de Java

4. C puntero a matriz / matriz de desambiguación de punteros

¿Cuál es la diferencia entre las siguientes declaraciones?

int* arr1[8];
int (*arr2)[8];
int *(arr3[8]);

Por tabla de precedencia C, matriz [], la función return () tiene mayor prioridad sobre el puntero *.

Para int * arr1[8]
arr1 ante todo es una matriz sin importar el tipo de elemento. Después de aplicar el puntero *, sabemos que arr1 es una matriz de punteros int.

Para int (* arr2)[8]
Por regla de anulación de corchetes, el puntero * tiene mayor prioridad sobre la matriz [] en este caso. Entonces arr2 es ante todo un puntero sin importar a qué esté apuntando. Después de aplicar la matriz [], sabemos que arr2 es un puntero a una matriz de int.

Para int * (arr3[8])
El corchete en este caso no cambia ninguna precedencia predeterminada, por lo que es lo mismo que int * arr1[8]

5. ¿Qué sentido tienen los punteros constantes?

(1) void foo (int * const ptr);
(2) void foo (int * ptr);

Para el llamador de foo, el valor de ptr se copia en foo tanto en (1) como en (2).

(1) y (2) marcan la diferencia solo para el implementador de foo, no para el cliente de foo.

En (2), el implementador puede cambiar accidentalmente el valor de ptr, lo que potencialmente puede introducir errores.

(1) es como el implementador le dice al compilador antes de escribir el cuerpo de foo, «oye, no quiero valorar ptr, si se cambia de alguna manera oscura, haz que la compilación falle, déjame verificar eso»

Por Programación.Click

Más de 20 años programando en diferentes lenguajes de programación. Apasionado del code clean y el terminar lo que se empieza. ¿Programamos de verdad?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *