2010-09-25 19 views

Respuesta

8

int * pi

pi es un puntero a un entero

int ** ppi

ppi es un puntero a un puntero a un entero.

EDITAR:

que necesita para leer un buen libro sobre los punteros. Recomiendo Pointers on C by Kenneth Reek.

23

puntero a un valor entero

int* i 


Puntero a un puntero a un valor entero

int** i 

(Es decir, en el segundo caso se requerirá dos dereferrences para acceder a la valor entero)

7
  • int* i: i es un puntero a un objeto de tipo int
  • int** i: i es un puntero a un puntero a un objeto de tipo int
  • int*** i: i es un puntero a un puntero a un puntero a objeto de tipo int
  • int**** i: i es un puntero a un puntero a un puntero a un puntero a objeto de tipo int
  • ...
+3

* "... puntero a una variable ..." * No necesariamente una variable. La palabra "variable" en este contexto probablemente oscurece el significado un poco, de hecho. –

+0

@ T.J. Crowder: incluso una variable const es una variable. Puede obtener un valor diferente cada vez que se crea. –

+4

@Nathan No está en 'new int'. No hay ninguna variable aquí. Reemplazar 'variable' por' objeto' sería apropiado. –

6

No creo que esto sea específico de opencv.

int *i declara un puntero a un int. Entonces i almacena una dirección de memoria, y C espera que el contenido de esa dirección de memoria contenga un int.

int **i está declarando un puntero a ... un puntero. A una int. Entonces i contiene una dirección, y en esa dirección de memoria, C espera ver otro puntero. Se espera que esa segunda dirección de memoria contenga un int.

Tenga en cuenta que, mientras está declarando un puntero a un int, el int real no está asignado. Por lo tanto, es válido decir int *i = 23, que dice "Tengo una variable y quiero que apunte a la dirección de memoria 23 que contendrá un int". Pero si intenta leer o escribir realmente en la dirección de memoria 23, probablemente segfault, ya que su programa no "posee" ese trozo de RAM. *i = 100 segfault. (La solución es usar malloc().O puede hacer que apunte a una variable existente, como en int j = 5; int *i = &j)

2

Digamos que usted es profesor y tiene que dar notas a uno de sus alumnos.

int note; 

Bueno ... significaba toda la clase

int *class_note; /* class_note[0]: note for Adam; class_note[1]: note for Brian; ... */ 

Bueno ... no se olvide que tiene varias clases

int **classes_notes; /* classes_notes[0][2]: note for Charles in class 0; ... */ 

Y, también da clases en varias instituciones

int ***intitute_note; /* institute_note[1][1][1]: note for David in class 1 of institute 1 */ 

etc, etc ...

+1

Los punteros no siempre apuntan a las matrices. – luiscubal

+0

@luiscubal: ¿dónde hay una matriz en mi código (no en los comentarios)? – pmg

+0

Precisamente en los comentarios. – luiscubal

1

Tampoco es una declaración. La sintaxis de la declaración no permite () en toda la declaración. ¿Qué están haciendo estos () allí? Si se supone que esto es parte de la declaración de la función, incluya la cosa de la declaración de la función completa en su pregunta, ya que, en general, el significado real de una declaración podría depender de eso. (No en este caso).

En cuanto a la diferencia ... Hay uno * en el primero y hay dos * s en el segundo. ¿Ayuda? Probablemente no. El primero declara i como un puntero a int. El segundo declara i como un puntero a int *. ¿Esto ayuda? Probablemente tampoco mucho. Sin una pregunta más específica, es difícil proporcionar una respuesta más significativa.

Proporcione más contexto, por favor. O bien, si esto es realmente lo más específico que puede obtener, lea su libro favorito C o C++ sobre punteros. Tales preguntas generales genéricas no son algo que pidas en la red.

+2

No es exactamente la respuesta que esperaría de usted. No es mi dv tho. –

+1

@John no es mi dv tampoco, pero exactamente la respuesta que esperaría de @AndreyT :) –

+0

Hm ... Estoy siendo gruñón después de otra batalla 'size_t' ... – AnT

3

Imagine que tiene un par de amigos, uno de ellos tiene que darle algo (un tesoro ... :-) , que Juan tiene el tesoro

int treasure = 10000; // in USD, EUR or even better, in SO rep points 

Si le preguntas directamente John

int john = treasure; 
int you = john; 

Si no puede unirse a John, pero Gill sabe cómo contactar con él,

int john = treasure; 
int *gill = &john; 
int you = *gill; 

Si no se pueden combi t incluso unirse a las branquias, pero tienen que ponerse en contacto primero Jake que puede ponerse en contacto con las branquias

int john = treasure; 
int *gill = &john; 
int **jake = &gill; 
int you = **jake; 

etc ... Los punteros son sólo indirecciones.

Esa fue mi última historia para hoy antes de ir a la cama :-)

3

profundamente Creo que una imagen vale más que mil palabras. Tomemos el ejemplo siguiente

// Finds the first integer "I" in the sequence of N integers pointed to by "A" . 
// If an integer is found, the pointer pointed to by P is set to point to 
// that integer. 
void f(int N, int *A, int I, int **P) { 
    for(int i = 0; i < N; i++) 
    if(A[i] == I) { 
     // Set the pointer pointed to by P to point to the ith integer. 
     *P = &A[i]; 
     return; 
    } 
} 

Así que en el anterior, A apunta al primer número entero en la secuencia de N números enteros. Y P apunta a un puntero que la persona que llama tendrá el puntero al entero encontrado en.

int Is[] = { 1, 2, 3 }; 

int *P; 
f(3, &Is[0], 2, &P); 
assert(*P == 2); 

&P se utiliza para pasar la dirección de P a la función. Esta dirección tiene el tipo int **, porque es la dirección de un puntero a int.

0

Tenga en cuenta que

int *i 

no es totalmente intercambiable con

int i[] 

Esto se puede ver en que el siguiente será compilar:

int *i = new int[5]; 

si bien esto no:

int i[] = new int[5]; 

Para la segunda, hay que darle una lista constructor:

int i[] = {5,2,1,6,3}; 

También puede obtener algunas comprobaciones con la forma []:

int *i = new int[5]; 
    int *j = &(i[1]); 
    delete j; 

compila advertencia libre, mientras que:

int i[] = {0,1,2,3,4}; 
    int j[] = {i[1]}; 
    delete j; 

dará las advertencias:

advertencia C4156: eliminación de una expresión de matriz sin utilizar la forma de matriz de 'eliminar'; forma de matriz sustituida advertencia C4154: eliminación de una expresión de matriz; conversión al puntero proporcionado

Ambos dos últimos ejemplos bloquearán la aplicación, pero la segunda versión (con el tipo de declaración []) dará una advertencia de que se está disparando en el pie.

(proyecto ++, Visual Studio 2010 Win32 consola C)

1

int * i es la dirección de una posición de memoria de un entero
int ** es la dirección de una posición de memoria de una dirección de una posición de memoria de un número entero

0

La sustitución de texto es útil aquí, pero tenga cuidado de usarlo a ciegas, ya que puede inducir a error (como en el ejemplo avanzado a continuación).

T var; // var has type T 
T* var; // var has type "pointer to T" 

Esto funciona sin importar lo que T es:

int* var; // pointer to int 
char* var; // pointer to char 
double* var; // pointer to double 

// advanced (and not pure textual substitution): 
typedef int int3[3]; // confusing: int3 has type "array (of size 3) of ints" 
        // also known as "int[3]" 
int3* var; // pointer to "array (of size 3) of ints" 
      // aka "pointer to int[3]" 

int (*var)[3]; // same as above, note how the array type from the typedef 
       // gets "unwrapped" around the declaration, using parens 
       // because [] has higher precedence than * 
       // ("int* var[3];" is an array (size 3) of pointers to int) 

Esto funciona cuando T es en sí mismo un tipo de puntero:

typedef int* T; // T is a synonym for "pointer to int" 
T* var; // pointer to T 
     // which means pointer to pointer to int 
// same as: 
int** var; 
0

int * i; // i es un puntero a entero. Puede contener la dirección de una variable entera.

int ** i; // i es un puntero a puntero a entero. Puede contener la dirección de una variable de puntero entero.

Cuestiones relacionadas