Uso avanzado del lenguaje C_(11)_Pointers

Tabla de contenido

1 Conceptos básicos de punteros. 

2 puntero secundario 

3 operaciones aritméticas sobre punteros

4 punteros vacíos

5 punteros constantes

6 matrices de punteros y punteros de matriz

1 conjunto de punteros

2 punteros de matriz

7 La relación entre punteros y matrices.

 1 La relación entre punteros y matrices unidimensionales.

 2 La relación entre punteros y matrices bidimensionales.

 3 formas de acceder a elementos de matriz


1 Conceptos básicos de punteros. 

1 dirección: el número utilizado para distinguir diferentes bytes en la memoria

2 puntero: la dirección es el puntero, el puntero es la dirección

Variable de 3 punteros: una variable que almacena una dirección

4 &: este símbolo se utiliza para obtener la primera dirección de una variable en el espacio de memoria y para actualizar el tipo de expresión. Por ejemplo tipo int--->>tipo int*.

5 *: Si este símbolo está en el lado derecho de la expresión =, significa tomar el valor del espacio al que apunta el puntero (el tamaño del espacio obtenido depende del tipo de puntero). Si está a la izquierda de la expresión =, significa que el valor de la derecha se coloca en el espacio señalado por el puntero. También tiene el efecto de degradar el tipo de expresión. Por ejemplo int* tipo--->>int tipo.

Como se muestra en la figura siguiente, se utilizan cuatro bytes para almacenar el número entero 100 y ocho bytes para almacenar el puntero a la primera dirección de la variable entera.

2 puntero secundario 

Llamamos puntero a una variable que almacena la dirección de una variable, pero ¿qué pasa con los punteros a los que queremos almacenar punteros? Luego use el puntero secundario.

número entero = 0;

int *pnúm = #

int **ppnum = &pnum;                                                                                                               

Aquí tienes un programa para explicarlo.

#include <stdio.h>

int main(int argc, char const *argv[])
{
          int num = 100;
          int *pnum = &num;
          int **ppnum = &pnum;

          printf("num = %d\n",num);
          printf("*pnum = %d\n",*pnum);
          printf("**ppnum = %d\n",**ppnum);
          printf("&num = %p\n",&num);
          printf("pnum = %p\n",pnum);
          printf("*ppnum = %p\n",*ppnum);
          printf("&pnum = %p\n",&pnum);
          printf("ppnum = %p\n",ppnum); 
        
          return 0;
}

 

Sin embargo, los punteros secundarios se utilizan en dos lugares en C:

 1 Cuando el cuerpo de la función quiere modificar el valor de la variable de puntero fuera del cuerpo de la función, la dirección de la variable de puntero es el puntero de segundo nivel.

 2 Al pasar parámetros a una matriz de puntero, el nombre de la matriz es un puntero al primer elemento de puntero de la matriz.

3 operaciones aritméticas sobre punteros

+-++--

El desplazamiento del puntero es el tamaño del espacio de bytes del tipo de datos señalado.

entero* :4

carácter* :1

doble* :8

entero** :8

4 punteros vacíos

vacío *p;

A menudo se usa para señalar una dirección de memoria de almacenamiento y no tiene ningún significado para señalar el tamaño del espacio.

Los punteros de tipo void* no deben usarse para operaciones relacionadas con la obtención de * o ++ --.

La conversión entre puntero de tipo void * y otros tipos de punteros no requiere conversión de tipo obligatoria.

usar

Se utiliza como parámetro de función o valor de retorno de función para representar un puntero compatible con todos los tipos.

1 memcpy (void *dest, const void *src, size_t n); definición de parámetros de la función de copia de memoria

2 memcmp(const void *s1,const void *s2,size_t n);

Una pregunta de ejemplo: asigne un número entero 100 al espacio cuya dirección de memoria es 0x2000 (0x2000 es una dirección de tipo void *)

           (*(int *)((void*)0x2000)) = 100 o (* (int *)0x2000) = 100;

5 punteros constantes

1. constanteint *p;

2.int constante *p;

3.int *const p;

4. constante int *const p;

5. int const *const p;

1 y 2 son equivalentes, const se modifica con * p y el espacio al que apunta p no se puede cambiar (solo lectura), pero p se puede modificar. (como el parámetro const char *src de la función strcpy, y no podemos modificar la fuente). Se puede utilizar pero no se puede cambiar.

En 3, la constante es modificada por p, y p no se puede cambiar, pero * p se puede cambiar, por lo que debe inicializarse, porque en el programa, p solo puede apuntar al espacio en el momento de la inicialización y no puede apuntar a otros espacios, pero el puntero se puede utilizar para modificar el espacio al que apunta el valor p. (Por ejemplo, el nombre de la matriz siempre apunta a la primera dirección del primer elemento y podemos modificar el valor del primer elemento).

4 y 5 son equivalentes, const se modifica con p y *p, y la dirección y el espacio señalado por el puntero no se pueden cambiar. Debe inicializarse.

6 matrices de punteros y punteros de matriz

1 conjunto de punteros

Matriz de punteros:

Una matriz de punteros es una matriz, es decir, una matriz de punteros, y cada elemento de esta matriz es un puntero.

entero *p[5];

Por ejemplo, arriba, se define una matriz p y hay cinco elementos en la matriz, cada elemento tiene 8 bytes, un total de 40 bytes y cada elemento es un puntero a una variable entera.

Las matrices de punteros de enteros generalmente se usan menos y las matrices de punteros de caracteres (char *pstr[5]) generalmente se usan en lenguaje C.

código para entender

#include <stdio.h>

int main(int argc, char const *argv[])
{
          char *pstr[5] = {"hello","world","how","are","you",};
          for(int i = 0;i < 5;i++)
          {
                    printf("str[%d] = %s\n",i,pstr[i]);
          }
          return 0;
}

En general, se utiliza una matriz bidimensional para almacenar cadenas y una matriz de punteros para manipular cadenas.

Por ejemplo, utilizamos la clasificación por burbujas para ordenar una matriz de cadenas, donde se intercambian direcciones en lugar de cadenas.

Como se muestra en el código de ejemplo a continuación

in(int argc, char const *argv[])
{
          char *pstr[5] = {"hello","world","how","are","you",};
          int i = 0;
          int j = 0;
          char *ptmp = NULL;
          for(i = 0;i < 5 -1;i++)
          {
                    for(j = 0;j < 5 -1 - i;j ++)
                    {
                              if(strcmp(pstr[j],pstr[j + 1]) > 0)
                              {
                                        ptmp = pstr[j];
                                        pstr[j] = pstr[j + 1];
                                        pstr[j +1] = ptmp;
                              }
                    }
          }

          for(i = 0; i < 5; i++)
          {
                    printf("%s\n",pstr[i]);
          }
          return 0;
}

2 punteros de matriz

 El puntero de la matriz es un puntero, el puntero apunta a la matriz y el puntero ocupa ocho bytes.

int(*a)[5];

int un[5];

&a:int (*)[5]

1 Para la operación y el nombre de la matriz unidimensional, el tipo de valor invariante se actualiza a un puntero de matriz.

2 Para la operación * en el puntero de la matriz, el tipo de valor invariante se degrada a un puntero al primer elemento de la matriz.

Explica el código

#include <stdio.h>

int main(int argc, char const *argv[])
{
          int (*p)[5] = NULL;
          int a[5] = {1,2,3,4,5,};
          p = &a;

          printf("a = %p\n",a);
          printf("&a = %p\n",&a);
          printf("*a = %d\n",*a); 
          printf("*&a = %p\n",*&a);
          printf("========================\n");
          printf("p = %p\n",p);
          printf("p + 1 = %p\n", p+1);
          printf("*p = %p\n",*p);
          printf("*p + 1 = %p\n", *p+1); 
          return 0;
}

 7 La relación entre punteros y matrices.

 1 La relación entre punteros y matrices unidimensionales.

 int un[5] = {1,2,3,4,5};

El nombre de la matriz de una matriz es un puntero al primer elemento de la matriz.

a = &a[0]

La forma de acceder a los elementos de la matriz: a[n] = *(a + n) 

 2 La relación entre punteros y matrices bidimensionales.

El nombre de la matriz a de la matriz bidimensional es un puntero de matriz que apunta a los elementos de la primera fila de la matriz.

#include <stdio.h>

int main(int argc, char const *argv[])
{
          int a[2][3] = {1,2,3,4,5,6};

          printf("================================\n");
          printf("&a[0][0] = %p\n",&a[0][0]);
          printf("&a[0][1] = %p\n",&a[0][1]);
          printf("&a[0][2] = %p\n",&a[0][2]);
          printf("&a[1][0] = %p\n",&a[1][0]);
          printf("&a[1][1] = %p\n",&a[1][1]);
          printf("&a[1][2] = %p\n",&a[1][2]);
          printf("================================\n");
          printf("a = %p\n",a);
          printf("a + 1 = %p\n",a + 1);
          printf("================================\n");
          printf("a[0] = %p\n",a[0]);
          printf("a[0] + 1 = %p\n",a[0] + 1);
          printf("a[1] = %p\n",a[1]);
          printf("a[1] + 1 = %p\n",a[1] + 1);
          printf("================================\n");
          printf("*a[0] = %d\n",*a[0]);
          printf("*(a[0] + 1)= %d\n",*(a[0] + 1));
          printf("*a[1] = %d\n",*a[1]);
          printf("*(a[1] + 1) = %d\n",*(a[1] + 1));
          printf("================================\n");
          printf("*a = %p\n",*a);
          printf("*(a + 1) = %p\n",*(a + 1));
          return 0;
}

 

 3 formas de acceder a elementos de matriz

a[m][n] = *(a[m] + n) = *(*(a + m) + n)

*(p + m * N + n)

Supongo que te gusta

Origin blog.csdn.net/m0_58193842/article/details/128369481
Recomendado
Clasificación