¿Cómo utilizar punteros complejos en la programación integrada?

¿Cómo utilizar punteros complejos en la programación integrada?

1. Explique que
en la programación en lenguaje C, los punteros son los más propensos a errores, especialmente cuando aparecen muchos punteros al mismo tiempo, lo cual es deslumbrante. De uso fácil de puntero.

2. Punteros de función y funciones de puntero
En lenguaje C, las funciones tienen sus direcciones. Del mismo modo, las funciones tienen sus direcciones. Si asignamos la dirección de una función a un puntero de función, entonces podemos pasar el puntero de forma indirecta. Dirección de la función de llamada.

La definición del puntero de función es la siguiente:

Tipo de datos ( diversión) (lista de parámetros);
porque () tiene mayor prioridad
.

La definición de la función de puntero es la siguiente:

Tipo de datos divertido (lista de parámetros);
su valor de retorno es el tipo de datos
.

Ejemplo: llamar a un puntero de función a través de un puntero de función

Paso 1: definir el puntero de función

int ( pfun) (int , int );
aquí se llama a un puntero de función del tipo de datos int , donde los dos parámetros son dos int .

Paso 2: definir la función del puntero

int fun (int , int );
El valor de retorno de esta función es int
.

Paso 3: Implemente punteros de función

int fun (int a, int b)
{
int
ret = 0;
( ret) = ( a) + (* b);
return ret;
}
Paso 4: Asigne la dirección de la función al puntero de función

int main (int argc, char * argv)
{
int a = 3, b = 2, c = 0;
pfun = fun;
c =
(( pfun) (& a, & b));
rt_kprintf ("c es% d \ n ", c);
return0;
}
El más importante es la asignación y la llamada, pfun = fun; se usa para la asignación, y
((* pfun) (& a, & b)); se usa cuando se llama a la función indirectamente .

3. El problema de los punteros const modificados
Primero mire la siguiente declaración:

constint p;
intconst
q;
int const r;
constint
const x;
Cuando programe en lenguaje C, a menudo use const para modificar una variable, a fin de evitar que se cambie una variable.

Los dos primeros const int p; y int const q; tienen el mismo significado, tanto p como q se declaran como punteros de tipo const int. En otras palabras, los valores de py q no pueden modificarse en el programa . Para la conveniencia de la lectura, const generalmente se usa en frente.

int a = 3, b = 2;
constint p = & a;
p = & b;
p = 5; // err
rt_kprintf (" p es% d \ n", p);
donde el valor * p no se puede modificar, pero El valor de p puede ser modificado.

Para int * const r;

int const r = & a;
r = & b; // err
r = 6;
rt_kprintf ("r es% d \ n", * r);
donde r = & b está mal.

Combinando las operaciones anteriores, obtenemos const int * const x = & a;. Este es un valor que debe asignarse cuando se usa, y no se puede modificar, es decir

x = & b; // err
* x = 6; // err
Estas operaciones son incorrectas.

4. El problema del salto directo del puntero de función
En nuestro proceso de desarrollo de proyectos reales, es posible que necesitemos saltar directamente a una dirección de la función para ir al puntero.

void ( function_p) (void); // Definir el puntero de función function_p, sin valor de retorno, sin parámetros
function_p = my_func; // El puntero de función apunta a function function
(
function_p) (); // Ejecutar función con puntero de función
Esto es equivalente a llamada directa Función my_func, entonces, ¿qué significa esto?

De hecho, se propone una forma de pensar, es decir, puede saltar a la función de acuerdo con la dirección de la función. Por ejemplo, en el gestor de arranque, cuando el archivo binario se carga en la memoria, ¿cómo ejecutar el programa del núcleo? Eso es realizar un salto del gestor de arranque al kernel.

((nulo (*) ()) 0x80000) ();
Aquí significa que la dirección en 0x80000 es un tipo de función y no hay valor de retorno. Cuando nuestra dirección del núcleo es 0x80000, el programa salta y no regresa. Este es un ejemplo clásico.

5. Función de
devolución de llamada Se puede decir que la función de devolución de llamada es una aplicación avanzada del lenguaje C al puntero de la función. En resumen, una función de devolución de llamada es una función llamada a través de un puntero de función. En otras palabras, pasamos el puntero de la función a la función a través del parámetro de la función, luego podemos pensar que la función llamada es la función de devolución de llamada.

Analicemos un ejemplo específico en rt-thread para analizar la función mágica de la función de devolución de llamada.

Cualquiera que haya utilizado el sistema operativo rt-thread sabe que rt-thread utiliza un marco de controlador de dispositivo, es decir, la operación del sistema de archivos virtual se puede utilizar para operar el dispositivo controlador durante el proceso de desarrollo. Eche un vistazo a los contenidos de la estructura rt_device.

/ **

  • Estructura del dispositivo
    * /
    struct rt_device
    {
    struct rt_object parent; / * <heredar de rt_object /

    enum rt_device_class_type type; / <tipo de dispositivo * /
    rt_uint16_t flag; / * <indicador de dispositivo /
    rt_uint16_t open_flag; /
    <bandera de apertura del dispositivo * /

    rt_uint8_t ref_count; / * <número de referencia /
    rt_uint8_t device_id; / * <0-255 /

    / dispositivo de devolución de llamada /
    rt_err_t ( rx_indicate) (rt_device_t dev, rt_size_t size);
    rt_err_t (
    tx_complete) (rt_device_t dev, void * buffer);

#ifdef RT_USING_DEVICE_OPS
conststruct rt_device_ops ops;
#else
/
interfaz de dispositivo común /
rt_err_t (
init) (rt_device_t dev);
rt_err_t ( abierto) (rt_device_t dev, rt_uint16_t oflag);
rt_err_t (
cerrar) (rt_device_t dev);
rt_size_t ( leer) (rt_device_t dev, rt_off_t pos, void buffer, rt_size_t size);
rt_size_t ( escribir) (rt_device_t dev, rt_off_t pos, búfer constvoid, tamaño rt_size_t);
rt_err_t ( control) (rt_device_t dev, int cmd, void args);
#terminara si

#if definido (RT_USING_POSIX)
conststruct dfs_file_ops * fops;
struct rt_wqueue wait_queue;
#terminara si

void                     *user_data;                /**< device private data */

};
Donde nos centramos en analizar la interfaz de la función de devolución de llamada a continuación.

rt_err_t ( rx_indicate) (rt_device_t dev, rt_size_t size);
rt_err_t (
tx_complete) (rt_device_t dev, void * buffer); La
primera función significa que cuando el dispositivo subyacente recibe datos, puede llamar a esta función de devolución de llamada, la aplicación de capa superior implementa esta interfaz Si

La segunda interfaz también es un ejemplo en el que la interfaz inferior llama a la interfaz de la capa de aplicación superior.

Modelo de programación del dispositivo basado en hilo rt

Paso 1: encuentra el dispositivo

rt_device_find
devuelve un identificador de dispositivo de tipo rt_device_t.

Paso 2: Implemente la función rx_indicate

xxx_dev-> rx_indicate = xxx_rx_indicate;
donde xxx_rx_indicate es la función que necesitamos implementar, aquí podemos liberar el semáforo para informar a otros hilos que un mensaje está llegando.

El tercer paso: la interfaz de llamada subyacente

dev-> rx_indicate (dev, size);
esta interfaz se llama cuando llega un mensaje. Si la aplicación de capa superior implementa esta interfaz, ejecutará la función. Si no se implementa, se puede juzgar que dev-> rx_indicate está vacío y no se ejecuta.

De esta manera, la implementación del programa reduce el problema de las llamadas de acoplamiento. Si llamamos a la función directamente, el acoplamiento en la programación es demasiado fuerte. Este es también un ejemplo clásico de rt-thread que utiliza la función de devolución de llamada para reducir el acoplamiento.

6. Resumen Es
muy importante comprender el uso de punteros para la programación en lenguaje C. El afilador no corta los materiales por error. Solo cuando la base está bien colocada, la superestructura puede ser estable. Solo cuando los cimientos se acumulan y resumen continuamente, se puede mejorar el ámbito ideológico. La programación no se trata solo de habilidades orales, ni es un comienzo rápido de dos a tres meses para poder dominarlo. Se requieren días y meses para acumularse, sin pasos, miles de millas, sin flujo pequeño y sin río. Use esto para alentarse. Cooperación WeChat 17727800897

Supongo que te gusta

Origin blog.51cto.com/13258379/2488131
Recomendado
Clasificación