Punteros del lenguaje C [Explicación súper detallada que lo llevará a comprender los punteros capa por capa]

Tabla de contenido

1. Acerca de los consejos

2. Tipo de puntero

1. Descripción de los derechos de acceso de punteros enteros:

2. Descripción de los derechos de acceso del puntero de carácter:

3. El tipo de puntero determina qué tan lejos está un paso hacia adelante o hacia atrás.

3. Conocimiento sobre los punteros salvajes.

1. La causa del puntero salvaje

① El puntero no está inicializado

② Acceso fuera de límites del puntero

③Se libera el espacio señalado por el puntero.

2. Cómo evitar sugerencias descabelladas

① Es necesario inicializar el puntero

②Preste atención al problema de que el puntero cruza el límite

③El espacio señalado por el puntero se establece en NULL en el tiempo

④ Evite devolver la dirección de una variable local

⑤ Verifique la validez del puntero antes de usarlo

4. Punteros constantes y constantes de puntero.

1. puntero constante

2. Constante de puntero

Cinco, el funcionamiento del puntero. 

1. Puntero + - entero

2. Puntero-puntero

3. Operaciones relacionales sobre punteros.

6. Puntero de carácter

Cadena constante (conocimiento relacionado)

Siete, matriz de punteros

El significado del nombre de la matriz.

8. Puntero de matriz

Nueve, parámetros de matriz, parámetros de puntero

1. Paso de parámetros de matriz unidimensional

2. Paso de parámetros de matriz bidimensional

3. Paso de parámetros de puntero de primer nivel

4. Paso de parámetro de puntero secundario

10. Puntero de función

cambio de nombre del puntero de función 

11. Matriz de punteros de función


​​​​​​​

1. Acerca de los consejos

Primero, la memoria se dividirá en pequeñas unidades de memoria, y cada unidad de memoria tiene un número, que se llama dirección . También llamamos dirección puntero , como se muestra en la siguiente figura:


Nota: Los punteros se refieren a direcciones, pero en nuestro idioma hablado los punteros generalmente se refieren a variables de puntero.

Una variable de puntero es una variable utilizada para almacenar una dirección.

Podemos modificar el valor original modificando el valor de la variable puntero, de la siguiente manera:

El valor original de a es 5, a través de la variable de puntero pa, la desreferenciación también puede cambiar el valor de a


Con respecto al tamaño del puntero: el tamaño es de 4 bytes en la plataforma de 32 bits y de 8 bytes en la plataforma de 64 bits , ¡y no cambiará debido al cambio del tipo de puntero! La siguiente es una demostración en el entorno de plataforma de 32 bits de VS2019:

 De la observación se puede ver que ya sea un puntero de número entero o un puntero de carácter, el tamaño de la memoria es de 4 bytes en la plataforma de 32 bits.

Nota: La plataforma de 32 bits se compone de 32 bits, por lo que 32 bits = 4 bytes , por lo que el puntero en la plataforma de 32 bits tiene un tamaño de 4 bytes y lo mismo ocurre con la plataforma de 64 bits.


2. Tipo de puntero

El tipo de puntero determina los permisos de acceso del puntero cuando se le quita la referencia, por ejemplo:

Desreferenciar un puntero entero accede a 4 bytes

La desreferencia del puntero Char accede a 1 byte.

Probemos específicamente los derechos de acceso de estos dos tipos de punteros:

1. Descripción de los derechos de acceso de punteros enteros:

a es 0x11223344 en hexadecimal, observe en la página de monitoreo que a es igual a *pa, ambos son valores ; &a es igual a pa, ambas son direcciones

 Observe el almacenamiento de a en la memoria en este momento.

Ingrese la dirección de a y descubra que la memoria está almacenada como 44 33 22 11. Esto implica el almacenamiento endian grande y pequeño que mencionamos anteriormente. Los amigos que no lo sepan pueden ir al blog "Almacenamiento de datos en lenguaje C" para aprender

Nuestro VS usa almacenamiento little-endian , por lo que es 44 33 22 11, y luego de ejecutar hasta *pa=0, podemos observar la memoria:

El valor de a se ha cambiado a 00 00 00 00 y se han cambiado los valores de 4 bytes 

2. Descripción de los derechos de acceso del puntero de carácter:

En el mismo orden que antes, como se muestra en la siguiente figura:

El resto del código permanece sin cambios, solo se cambia el tipo de puntero.

 El monitoreo es el mismo que la sección de memoria.

Cuando el código se ejecuta *pa=0

Descubrimos que para el tipo de puntero de carácter, la desreferenciación solo puede cambiar 2 dígitos hexadecimales , es decir, 8 bits , es decir, 1 byte.

Los dos ejemplos anteriores demuestran que los diferentes derechos de acceso al puntero son diferentes

3. El tipo de puntero determina qué tan lejos está un paso hacia adelante o hacia atrás.

El significado específico es que la variable de puntero se suma o resta en uno y su dirección cambia de la siguiente manera:

La variable de puntero entero pa y la variable de puntero de carácter pb están definidas respectivamente ,  y %p se utiliza para imprimir la dirección respectivamente. La observación de los resultados de ejecución muestra que:

Las direcciones de pa y pb son las mismas, porque tanto pa como pb apuntan a la dirección de un

Sin embargo, pa+1 y pb+1 son bastante diferentes. Pa+1 suma 4 a pa, mientras que pb+1 solo suma 1 a pb. En este ejemplo, se puede ver que el tipo de puntero también está determinado y el El puntero señala cuánta distancia se puede recorrer dando un paso hacia adelante o hacia atrás.


3. Conocimiento sobre los punteros salvajes.

¡El puntero salvaje es que el puntero apunta a una posición desconocida !

1. La causa del puntero salvaje

① El puntero no está inicializado

Este tipo de problema es muy común; consulte el siguiente código para obtener más detalles;

Este error también se mostrará después de ejecutar

 El código int* p no está inicializado , por lo que la dirección almacenada en la variable p no apunta al espacio de nuestro programa actual, sino a un espacio aleatorio en la memoria , por lo que debe ser incorrecto acceder a este espacio de memoria con *p !

Aquí p es el puntero salvaje.

② Acceso fuera de límites del puntero

Se puede decir que este problema es muy común y, si no prestamos atención, generalmente encontramos este tipo de problemas al atravesar matrices:

Configuramos la matriz arr y hacemos que la variable puntero p sea igual a la dirección del primer elemento de la matriz. La matriz en sí tiene 5 elementos , pero se repite 6 veces en el bucle for , i son 0 1 2 3 4 5, y i en sí es 0 ~ 4 Sí, hay un 5 adicional en el bucle, lo que conduce a un acceso ilegal a la memoria , por lo que el sexto número se imprime como un número aleatorio, y esto también es un problema de punteros salvajes. 

③Se libera el espacio señalado por el puntero.

Este problema también se produce con frecuencia; consulte el siguiente ejemplo para obtener más detalles:

El valor de retorno de la función de prueba es la dirección de x. En la función principal, la variable de puntero p se usa para recibir la dirección de x, pero la variable x ingresa a la función de prueba para crearla y . En este momento, cambie el valor de *p, es decir, use la dirección x, es ilegal acceder a la memoria y también causará el problema de los punteros salvajes.

2. Cómo evitar sugerencias descabelladas

① Es necesario inicializar el puntero

Por ejemplo, en el ejemplo anterior, int* p no se puede usar directamente, debe inicializarse, int a = 10; int* p = &a; para evitar el problema del puntero salvaje

②Preste atención al problema de que el puntero cruza el límite

Cuando usamos matrices, debemos prestar atención a la cantidad de elementos en la matriz y la cantidad de veces que realizamos un bucle , para evitar el acceso descuidado y fuera de los límites.

③El espacio señalado por el puntero se establece en NULL en el tiempo

Cuando no usamos la variable de puntero p , int* p = NULL; déjala vacía , y cuando queramos usar p a continuación, usa la declaración if:

si(p!= NULL) ......

Bien puede evitar consejos salvajes

④ Evite devolver la dirección de una variable local

Al igual que en el tercer ejemplo anterior de la causa del puntero comodín, evite devolver la dirección de la variable local.

⑤ Verifique la validez del puntero antes de usarlo

como si(p != NULL)  ...está comprobando la validez del puntero


4. Punteros constantes y constantes de puntero.

Hay muchos punteros constantes y constantes de puntero encontrados en el tema. Todos están relacionados con la palabra clave const . Aquí hay tres ejemplos para ver si puede distinguir la diferencia:

constante int *pa = &a;

int const *pa = &a;

int *const pa = &a;

1. puntero constante

El concepto de puntero constante es: el valor del espacio señalado por el puntero no se puede cambiar , y el valor del espacio señalado por el puntero no se puede modificar eliminando la referencia al puntero, pero se puede cambiar la orientación del puntero.

2. Constante de puntero

El concepto de constante del puntero es: el puntero en sí es una constante, es decir, el punto del puntero no se puede cambiar , pero se puede cambiar el valor del espacio al que apunta el puntero y el valor del espacio al que apunta el puntero se puede cambiar eliminando la referencia


¿Cómo entenderlo mejor?

Primero veamos el nombre del puntero constante, que termina con un puntero , por lo que tiene la naturaleza de un puntero, por lo que se puede cambiar, y como es un puntero constante, el valor señalado es constante, es decir, no se puede cambiar

Mire el nombre de la constante del puntero, que termina con una constante y debe tener algunas propiedades de una constante, por lo que, naturalmente, la orientación del puntero no se puede cambiar, solo se puede modificar el valor señalado por el puntero.

Entonces, ¿en qué parte del código se agrega const para que se le llame puntero constante y dónde se agrega para que se le llame puntero constante?

Decir un pequeño truco puede ayudar a que todos recuerden rápidamente:

Si const está a la izquierda de *, es un puntero constante

Si const está en el lado derecho de *, es una constante de puntero

En cuanto a por qué quieres recordarlo así, puedes pensarlo, * tiene la función de desreferenciar en el puntero, luego const está a la izquierda de *, que puede entenderse como modificación constante * , es decir, el valor El espacio señalado por el puntero no se puede modificar, pero el punto del puntero es ilimitado.

Entonces const está en el lado derecho de * y se modifica como una variable de puntero , es decir, la variable de puntero no puede cambiar su punto, pero el valor del espacio al que apunta el puntero no está limitado

Entonces, los tres ejemplos anteriores obviamente tienen la respuesta, solo necesito ver si la modificación constante es * o una variable de puntero

Puntero constante: const int *pa = &a;, int const *pa = &a;

Constante del puntero: int *const pa = &a;


Cinco, el funcionamiento del puntero. 

1. Puntero + - entero

Dé un ejemplo para ilustrar brevemente la situación de sumar y restar números enteros mediante punteros:

 La variable puntero p es la dirección del primer elemento de la matriz. Utilice el bucle for para imprimir cada elemento de la matriz. La prioridad de * es mayor que ++ . Por lo tanto, después de cada ejecución de *p imprime los elementos de la matriz. matriz, p++ apunta al siguiente elemento de la matriz . Por lo tanto, realiza un bucle 5 veces para imprimir 5 elementos en la matriz.

2. Puntero-puntero

 La operación puntero-puntero obtiene el número de elementos entre el puntero y el puntero . Por supuesto, la premisa es que los dos punteros deben apuntar al mismo espacio . Consulte el ejemplo a continuación;

El dibujo específico se explica a continuación:

Como se muestra en la figura anterior, representa el almacenamiento de cinco elementos en la matriz en la memoria, donde p1 apunta a la dirección del primer elemento y p2 representa la dirección del quinto elemento . Usar p2-p1 en el código significa que está entre dos punteros El número de elementos entre ellos, está claro que hay 4 elementos , por lo que el resultado impreso es 4

3. Operaciones relacionales sobre punteros.

La operación relacional de los punteros es comparar el tamaño de los punteros para lograr ciertas funciones, como por ejemplo:

 El círculo es la operación relacional del puntero. La imagen dibujada a continuación se puede explicar claramente:

 p es la dirección del primer elemento de la matriz al principio, luego, a través de la comparación de p < &arr [5] , si se cumple, se imprimirá el elemento debajo de la dirección, y luego p ++, la siguiente ronda de comparación se realizará hasta que p<&arr[5] no se cumpla

Puede que haya amigos aquí que quieran preguntar. ¿No dice lo anterior que no se puede cruzar el límite? La matriz tiene solo 5 elementos y el subíndice máximo es 4. ¿Cómo se puede usar arr [5]? , No hay límites aquí. Se usa lo anterior La dirección fuera de los límites ya ha accedido ilegalmente a la memoria, y esta dirección solo se escribe aquí, y la variable de puntero p se usa para operaciones relacionales, y esta dirección no usado, por lo que no hay problema de punteros salvajes , tenga la seguridad ♪(^∇^*)

Regulaciones: se permite comparar un puntero a un elemento de la matriz con un puntero a la ubicación de memoria después del último elemento de la matriz (como en el ejemplo anterior), pero no a un puntero a una ubicación de memoria antes del primer elemento.


6. Puntero de carácter

El puntero de carácter es la dirección del carácter almacenado, es decir, la dirección de la variable de carácter se coloca en el puntero de carácter , por ejemplo de la siguiente manera:

Defina la variable de puntero pa para almacenar la dirección de a, cambie el valor de *pa y a cambiará en consecuencia 

Cadena constante (conocimiento relacionado)

Si existe tal código: char* pa = "abcde"; "abcde" aquí es una cadena constante , "abcde" se almacena en el área constante y pa apunta a la dirección de un

La cadena constante no se puede modificar. Si alguien quiere escribir un código similar a *pa='w', el programa fallará, por lo que podemos agregar const delante para protección y escribirlo como const char * pa = " abcde " ( aquí está el tipo de puntero constante)

Y este código no almacena "abcde" en pa, sino que almacena la dirección de a en la variable de puntero pa. El siguiente ejemplo puede explicar este conocimiento más claramente:

  

 Desreferencia pa, imprima y descubra que de hecho es el carácter a, luego pa+1, debe apuntar al carácter b, desreferencia e imprima es de hecho el valor del carácter b, si desea imprimir la cadena completa, entonces use % s directamente, pa se puede imprimir

Aquí hay un ejemplo muy clásico: puedes pensar si p1 y p2, p3 y p4 son iguales.

La respuesta es: p1 y p2 son iguales, p3 y p4 no son iguales

 Del contenido anterior, podemos ver que "abcde" es una cadena constante, que se almacena en el área constante, por lo que tanto p1 como p2 apuntan a esta cadena constante y ambos almacenan la dirección de a, por lo que p1 y p2 son iguales.

Y p3 y p4 son la inicialización de dos matrices respectivamente , por lo que p3 y p4 representan respectivamente las direcciones de los primeros elementos de las dos matrices, por lo que p3 y p4 son diferentes


Siete, matriz de punteros

Cuando se trata de matrices de punteros, es posible que escuche menos, pero cuando se trata de vocabulario como matrices de enteros y matrices de caracteres, es posible que escuche más, entonces, ¿qué es exactamente una matriz de punteros?

Primero hable sobre matrices de enteros y matrices de caracteres.

Matriz de enteros : se puede ver desde el significado literal que una matriz de enteros es una matriz que almacena números enteros , como int arr [5] = {1,2,3,4,5}, la matriz arr es una matriz de enteros, y el array tiene 5 elementos, el tipo de cada elemento del array es int

Las matrices de caracteres también son lo mismo que las matrices de enteros, y así sucesivamente.

Entonces, cuando se trata de esto, la definición de matriz de punteros es muy simple, es una matriz que almacena punteros , por ejemplo int* arr[3]={&a,&b,&c}, la matriz tiene 3 elementos y cada elemento en la matriz es Puntero, el tipo de cada elemento es int* , dicha matriz se llama matriz de puntero

A continuación se muestra un caso que le ayudará a comprender mejor la aplicación práctica de las matrices de punteros:

Primero creamos 3 matrices de enteros arr1, arr2, arr3, y luego creamos una matriz de puntero arr para almacenar la dirección del primer elemento de las tres matrices de enteros (porque el nombre de la matriz es la dirección del primer elemento de la matriz ), voluntad 3 entero La dirección del primer elemento de la matriz de tipo se almacena en la matriz de puntero arr, por lo que cuando desee representar los elementos en la matriz de enteros, es equivalente a crear una matriz bidimensional, que se puede mostrar claramente. en la siguiente figura:

Cada elemento en la matriz arr es de tipo int*, entonces arr[i] es el elemento en la matriz arr , es decir, la dirección del primer elemento de las 3 matrices de enteros en la matriz arr, y arr[i][ j] es 3 El elemento entero con subíndice j en una matriz de enteros , por lo que la aplicación de esta matriz de punteros es equivalente a una matriz bidimensional

Otro método de representación es *(arr[i]+j), arr[i] significa los elementos en la matriz arr , es decir, la dirección del primer elemento de las 3 matrices de enteros, y +j significa hacia atrás desde la dirección de el primer elemento Mueva la dirección de j elementos y luego elimine la referencia e imprímalos, que también es un elemento de una matriz de números enteros

Demos un ejemplo de la matriz arr1, todos quedarán más claros.

Esta es la explicación de los dos métodos de impresión en el código. ¡Creo que todos entienden el motivo!

El significado del nombre de la matriz.

Hablando de matrices, entonces tenemos que hablar sobre el significado del nombre de la matriz.

En términos generales, el nombre de la matriz es la dirección del primer elemento de la matriz.

Pero también hay 2 excepciones:

1.sizeof (nombre de la matriz) , en este caso, el nombre de la matriz no es la dirección del primer elemento de la matriz. En este momento, el nombre de la matriz representa la matriz completa y el cálculo es el tamaño de la matriz completa.

2. & nombre de la matriz , en este caso, el nombre de la matriz no es la dirección del primer elemento, sino también la dirección de toda la matriz, y se extrae la dirección de toda la matriz

Haz un dibujo a continuación para ayudarte a comprender

 Se puede ver en la figura que los valores de &arr[0], arr y &arr son las direcciones del primer elemento de la matriz, pero los significados que representan son diferentes, si &arr[0] y arr son + 1, se omite un número entero . tipo elemento , apunta a la dirección del siguiente elemento entero, y si &arr es +1, omite una matriz y apunta a la dirección de la siguiente posición del elemento 8

 A través del código, se puede observar claramente la conclusión que se acaba de sacar.

 Los anteriores son los puntos de conocimiento que se deben agregar sobre el significado del nombre de la matriz ♪(^∇^*)


8. Puntero de matriz

Después de hablar sobre la matriz de punteros, ahora hablemos sobre la matriz de punteros. La matriz de punteros es una matriz, por lo que el puntero de la matriz es un puntero.

Hemos aprendido acerca de los punteros a números enteros antes, int* p=&a, es un puntero a un número entero, que almacena la dirección de una variable entera; y un puntero a carácter es un puntero a un carácter, que almacena la dirección de una variable de carácter; entonces el El puntero de matriz apunta naturalmente a la matriz en la que se encuentra el puntero.

Luego da un ejemplo:

entero* p1[3];

entero (*p2)[3];

De los dos ejemplos anteriores, ¿cuál es un puntero de matriz y cuál es una matriz de punteros?

Primero puede observar p1 y p2, que son los nombres de matriz que aprendimos antes, primero mire el primer int *p1[3]; debido a que [] tiene una prioridad más alta que *p1, cuando encuentre corchetes, primero coincidirá con corchetes Los corchetes se combinan , por lo que esta es una matriz con 3 elementos , y observando el int* delante de p1, puedes saber que el tipo de cada elemento en esta matriz es int* , por lo que esta es una matriz de punteros

Mirando el segundo int(*p2)[3]; p2 se combina primero con *, p2 es una variable de puntero, por lo que es un puntero a una matriz de tamaño 3, y cada elemento es de tipo int, por lo que este es un puntero de matriz

Primero, para punteros enteros, int a = 5; int* pa = &a, dada una variable entera a, toma la dirección de a y colócala en el puntero entero pa, donde la variable puntero pa es de tipo int*, que puede ser considerado Es int* pa Después de eliminar el nombre de la variable pa, el resto es el tipo de este puntero

De la misma manera, int arr[3]={0}; int (*parr) [3] = &arr ;Dada una matriz de números enteros arr con 3 elementos, entonces la dirección de la matriz debe colocarse en la matriz Dentro del puntero parr, entonces la pregunta es, ¿ cuál es el tipo de puntero de matriz parr ? Es muy simple y se puede obtener eliminando el nombre de la variable puntero de int (*parr) [3], es decir, int (*) [3], que se puede obtener según el tipo . El puntero apunta a una matriz, y la matriz tiene 3 elementos. Cada elemento de tipo int

Aquí hay un ejemplo para ilustrar:

De acuerdo con lo anterior, pa es la dirección de la variable a, y su tipo es int*, por lo que al imprimir la dirección, la dirección de pa+1 se incrementa de 00A8FB54 a 00A8FB58, lo que aumenta el tamaño de 4 bytes (el tamaño de un número entero), mientras que parr es la dirección de la matriz de almacenamiento arr y el tipo es int (*) [3], por lo que, por supuesto, la dirección de parr+1 se cambia de 00A8FB34 a 00A8FB40 en comparación con la dirección de parr , lo que aumenta el tamaño de 12 bytes (tres enteros Tamaño) Debido a que la matriz a la que apunta esta variable de puntero tiene tres elementos y cada elemento es de tipo int, parr+1 omite las direcciones de 3 variables enteras.


Nueve, parámetros de matriz, parámetros de puntero

En el código, debe pasar matrices y punteros a funciones, lo que implica el concepto de parámetros de matriz y parámetros de puntero.

1. Paso de parámetros de matriz unidimensional

Hay matrices unidimensionales arr1 y arr2, y los parámetros se pasan a test1 y test2, entonces, ¿cómo se deben escribir los parámetros formales de la prueba?

Debido a que pasar el nombre de la matriz equivale a pasar la dirección del primer elemento del grupo, el parámetro formal se puede escribir en forma de matriz o en forma de puntero.

Paso de parámetro de matriz Arr1:

La forma de la matriz: void test1(int arr1[]) o void test1(int arr1[5])

Cada tipo de elemento es int, por lo que el puntero es int*

La forma del puntero: void test1(int* p1)

Paso de parámetro de matriz Arr2:

La forma de la matriz: void test2(int* arr2[]) o void test2(int* arr2[15])

Cada tipo de elemento es int*, por lo que el puntero es int**

La forma del puntero: void test2(int** p2)

2. Paso de parámetros de matriz bidimensional

La base del paso de parámetros de una matriz unidimensional, existen dos formas de paso de parámetros de una matriz bidimensional

Preste atención a los parámetros de la matriz bidimensional, las filas se pueden omitir y las columnas no, porque si se omiten las columnas, no sabrá el número específico de cada columna, lo que causará problemas en la disposición de la memoria. , porque la memoria es la primera fila y la segunda fila se almacena continuamente

Formato de matriz: prueba nula (int arr[][3]) o prueba nula (int arr[2][3])

El nombre de la matriz es la dirección del primer elemento de la matriz, y la dirección del primer elemento de la matriz bidimensional es la dirección de la primera fila de la matriz unidimensional, por lo que la dirección de la primera fila de la matriz matriz es un puntero de matriz: int(*)[3], el parámetro formal debe ser Puntero de matriz p: int(*p)[3]

La forma del puntero: void test(int(*p)[3])

3. Paso de parámetros de puntero de primer nivel

Los punteros de primer nivel pasan parámetros, pasan punteros de primer nivel y luego usan punteros de primer nivel para recibir

También se puede revertir. Si el parámetro de prueba es int* ptr, entonces la función puede recibir los siguientes tres parámetros

①test(arr)②test(p)③Hay un int a = 0; la dirección de a se puede pasar a test(&a)

4. Paso de parámetro de puntero secundario

El puntero de segundo nivel se pasa como parámetro y el puntero de segundo nivel se pasa, luego el puntero de segundo nivel se usa para recibir

De manera similar, si el parámetro de prueba es int** ptr, entonces la función puede recibir los siguientes tres parámetros

Uno y dos son fáciles de entender. Mire el tercero. La matriz arr tiene 5 elementos y cada elemento es de tipo int*. Pasar arr equivale a pasar la dirección del primer elemento de la matriz, y el El tipo del primer elemento es int*, luego la dirección de int* es int**, que también cumple con los requisitos. 


10. Puntero de función

Un puntero de función es un puntero a una función. A continuación se muestra un ejemplo de un puntero de función.

Aquí p es el puntero de función.

Primero, p y * se combinan entre paréntesis, lo que indica que p es un puntero y los tipos de parámetros de la función son int e int entre paréntesis. 

Lo mismo aquí, p es un puntero de función, pero aquí está imprimir en lugar de & imprimir, porque los significados de estas dos formas son los mismos. 

Al llamar, ambos de los anteriores se pueden transferir a la función.

cambio de nombre del puntero de función 

Si el tipo de puntero de función es int (*)(int,char) y es demasiado largo y complicado, puede usar typedef para cambiarle el nombre, pero el cambio de nombre aquí es diferente del formato de nombre anterior y el nombre debe ser colocado en * Este último, a saber: typedef int (*p)(int,char), el significado del código es cambiar el nombre del puntero de función tipo int (*)(int,char) a p


11. Matriz de punteros de función

La matriz de punteros de función es una matriz y los punteros de función se almacenan en la matriz de la siguiente manera:

int(*ptr[3])(int, int) es el uso de la matriz de puntero de función, ptr es la matriz de puntero de función, elimina el nombre de la matriz ptr y [3], podemos ver que cada elemento de la matriz es int (*)(int, int) punteros de función, por lo que se denomina matriz de punteros de función


Se trata de sugerencias, si está interesado, puede investigar más. O(∩_∩)O

Supongo que te gusta

Origin blog.csdn.net/m0_64411530/article/details/125584522
Recomendado
Clasificación