Punteros avanzados: punteros de matriz, matrices de punteros, punteros de caracteres (explicación súper detallada, ¡Xiaobai puede entender de un vistazo!)

Tabla de contenido

I. Introducción

2. Cómo juzgar la matriz de punteros y el puntero de matriz

1. Tómalo literalmente

2. Comprender desde el aspecto de los símbolos 

3. Matriz de punteros

1. Aplicación de la matriz de punteros 

2. Entrada de matriz de puntero

 4. Puntero de matriz

Cinco, el puntero del personaje.

1. Uso del puntero de carácter

2. Puntos propensos a errores de los punteros de caracteres

Seis, aliento mutuo


I. Introducción

Cuando tenga una comprensión preliminar de los punteros, encontrará que en este momento, solo nos quedamos en los punteros que pueden comprender y escribir punteros básicos. El lugar donde los punteros se usan con mucha frecuencia es en realidad la aplicación de matrices de punteros, punteros de matriz y caracteres . punteros Debido a que estas cosas siguen apareciendo en la práctica habitual de aclarar preguntas y leer los códigos de los grandes, este conocimiento siempre me ha preocupado. Después de mi cuidadosa investigación, lo escribiré y lo compartiré con ustedes.

Si ha olvidado los conceptos básicos, puede echar un vistazo a mi comprensión previa de los punteros básicos:

(295 mensajes) Comprensión básica de punteros (simple, fácil de entender, súper detallado!!!)_blog de sunny-ll-blog de CSDN

2. Cómo juzgar la matriz de punteros y el puntero de matriz

1. Tómalo literalmente

"Puntero de matriz " y " matriz de punteros ", siempre que agregue la palabra " de " en el medio del sustantivo , sabrá el centro——

Puntero de matriz: es un puntero, ¿qué tipo de puntero es? Puntero a la matriz.

Matriz de punteros: es una matriz, ¿qué tipo de matriz es? Una matriz de punteros.

2. Comprender desde el aspecto de los símbolos 

Es necesario especificar un orden de prioridad: ()>[]>*, por lo que:

      (*p)[n]: De acuerdo con la prioridad, primero mire dentro de los corchetes, luego p es un puntero, este puntero apunta a una matriz unidimensional, la longitud de la matriz es n, este es el "puntero de matriz" , es decir, el puntero de matriz ;

     *p[n]: Según la prioridad, primero mire [], luego p es una matriz, y luego combinado con *, los elementos de esta matriz son tipos de puntero, con un total de n elementos. Esta es una "matriz de punteros", es decir, una matriz de punteros .

De acuerdo con los dos análisis anteriores, se puede ver que lo que es p, entonces lo que es la palabra central de la frase, es decir, la matriz "puntero" y el puntero "matriz".

3. Matriz de punteros

Si todos los elementos de una matriz contienen punteros, lo llamamos matriz de punteros. Su forma general es:

escriba * nombre del puntero [ ]

Es una matriz, y los elementos de la matriz son todos punteros. La cantidad de bytes que ocupa la matriz está determinada por el tamaño de la matriz en sí, y cada elemento es un puntero. 

Por ejemplo: char *arr[]={"Domingo", "Lunes"}, se almacenan dos punteros, el primer puntero apunta a la cadena "Domingo" y el segundo puntero apunta a la cadena "Lunes". 

El uso más importante de una matriz de punteros es realizar operaciones en varias cadenas, porque los punteros de caracteres son más rápidos y eficientes que las matrices bidimensionales.

 

1. Aplicación de la matriz de punteros 

Demostración de ejemplo de código:

#include <stdio.h>
int main()
{
    //定义三个整型数组
	int a[5] = { 1,2,3,4,5 };
	int b[5] = { 6,4,8,3,1 };
	int c[5] = { 2,5,8,6,1 };
    //定义一个存放指向整型变量的指针的数组arr
    int* arr[] = { a,b,c };
    //通过接引用打印出三个一维数组的元素
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 5; j++)
        {
		    printf("%d ", *(arr[i]+j));
	    }
        printf("\n");
    }
	return 0;
}

resultado:

1 2 3 4 5

 6 4 8 3 1

 2 5 8 6 1

Hay muchas formas de desreferenciar arr arriba, y todas son equivalentes. Pongamos un ejemplo: 

#include<stdio.h>
int main()
{
	int i = 0;
	int a[3][4] = { {1,2,3,4} ,{5,6,7,8} ,{9,10,11,12} };//定义一个二维数组
	int* pa[3];//定义一个指针数组
	for (i = 0; i < 3; i++)//给指针数组赋值
		pa[i] = a[i];
    printf("指针数组的内容为:\n");
	for (i = 0; i < 3; i++)//打印出指针数组的内容
	{
		int j;
		for (j = 0; j < 4; j++)
			printf("%d ", *(*(pa + i) + j));
		printf("\n");
	}
    //以下均为不同方式的解引用操作
    printf("不同解引用操作的结果为:\n");
	printf("%d,%d\n", a[1][1], *(pa[1] + 1));
	printf("%d,%d\n", a[1][1], *(*(pa+1) + 1));
	printf("%d,%d\n", a[1][1], (*(pa + 1))[1]);
	printf("%d,%d\n", a[1][1], pa[1][1]);
    return 0;
}

resultado:

El contenido de la matriz de punteros es:

1 2 3 4
5 6 7 8
9 10 11 12

Los resultados de las diferentes operaciones de desreferenciación son:

6,6
6,6
6,6
6,6

Se puede ver en los ejemplos anteriores que hay muchas formas de desreferenciar, y sus formas equivalentes son las siguientes: 

*( pa[i] + j ) //equivale a *( a[i] + j )

*( *(p+i) + j ) // 等了于 *( *(a+j) + j )

( *(p+i) )[ j ] // 等了于( *(a+i) )[ j ]

p[ i ][ j ] // 等了于 a[i][j]

Importante: las matrices de punteros también se pueden usar en combinación con matrices de cadenas , consulte el siguiente ejemplo: 

#include <stdio.h>
int main(){
    char *str[3] = {"lirendada","C语言","C Language"};
 
    printf("%s\n%s\n%s\n", str[0], str[1], str[2]);
    return 0;
}

tener una cita

lenguaje c

Lenguaje C

Nota: La primera dirección de la cadena se almacena en la matriz de caracteres str, no la cadena en sí. La cadena en sí está ubicada en otras áreas de memoria y está separada de la matriz de caracteres.

Solo cuando el tipo de cada elemento en la matriz de punteros es char *, se puede asignar a la matriz de punteros un valor como el anterior, y otros tipos no pueden.

2. Entrada de matriz de puntero

¿Cómo ingresar una cadena a una matriz de punteros?

1. El puntero se asigna durante la inicialización, como: char *p = "¡hola mundo!" o char *p[3]={"aa", "abc", "ggdd"}; 2. Durante la inicialización
Aplicar para el espacio, y luego apunte el puntero a un espacio de memoria inicializado;
debido a que un puntero que solo está definido pero no inicializado no apuntará a ningún espacio de memoria, no puede asignar un valor al lugar al que apunta el puntero. Por eso, si solo se definen punteros, use Xalloc o new para solicitar espacio para la inicialización.

solicitar espacio 

Use la función malloc para asignar espacio para una matriz de punteros:

malloc es un método de asignación dinámica y aleatoria de espacio de memoria, que se puede asignar a los programas según sea necesario.
Por ejemplo: (char*)malloc(sizeof(char)*20)
significa asignar espacio dinámicamente para 20 tamaños de datos de tipo char y convertir el tipo de puntero devuelto en un puntero de tipo char.

La operación de abrir un espacio se puede realizar mediante una sentencia de bucle, por ejemplo: for char *p[10]; se puede aplicar

for( i=0 ; i<10 ; i++ ) 
{
   p[i] = ( char *) malloc ( sizeof ( char ) * N ); //为每个指针申请开设N字符的存储空间
}

Use el lenguaje C para ingresar la matriz de punteros y la salida:

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    char* str[5] = {}; ///5为5个字符串,后面的大括号为初始化
    int i;
    for (i = 0; i < 5; i++)
    {///指针数组如果没有初始化赋值,则要申请空间,切记,否则会出错,这里的100为每个字符串的元素个数最多为100
        str[i] = (char*)malloc(100);
    }
    for (i = 0; i < 5; i++)
    {
        scanf("%s", str[i]); ///这里不用加& ,因为str本身是地址
        // gets(str[i]);
    }
    for (i = 0; i < 5; i++)
    {
        printf("%s ", str[i]);
        // puts(str[i]);
    }
    printf("\n");
    for (i = 0; i < 5; i++)
    {
        free(str[i]);///最后要free,逐个free
    }
    return 0;
}

 resultado de la operación:

Para el tema de la aplicación de la matriz de punteros, puede consultar este artículo:

(295 mensajes) Array of Pointers_Layne...'s Blog-CSDN Blog_Array of Pointers

 Resumen: De acuerdo con la explicación anterior, podemos encontrar claramente que la matriz de punteros se puede aplicar a: la creación de matrices bidimensionales, el almacenamiento de entrada de cadenas. En aplicaciones normales , en realidad se usa más para el almacenamiento de entrada de cadenas. Por ejemplo, el título requiere la entrada de 5 cadenas para comparar sus longitudes, la entrada continua de cadenas en orden lexicográfico y la clasificación de las cadenas. En este momento, ¡será muy conveniente para nosotros usar matrices de punteros! ! ! !

 4. Puntero de matriz

Los punteros de matriz, en la mayoría de los casos, se utilizan principalmente en la creación y aplicación de matrices bidimensionales. Su tipo es:

int(*p)[4] = a; 

Representa el puntero p que apunta a la matriz a, y cada fila de la matriz a tiene 4 elementos.

Los paréntesis *indican que p es un puntero a un arreglo de tipo , int [4]que es el tipo de cada arreglo unidimensional contenido en a.

[]La prioridad es más alta que la que se debe *agregar.Si ()se escribe desnudo int *p[4], entonces se debe entender que int *(p[4])p se convierte en una matriz de punteros, no en una matriz de punteros bidimensional.

¡El nombre de matriz a también se convertirá en un puntero equivalente a p en la expresión!

Exploremos cómo usar el puntero p para acceder a cada elemento en la matriz bidimensional. Según la definición anterior:

1)  pSeñale el comienzo de la matriz a, es decir, la fila 0; p+1avance una fila y señale la fila 1.

2)  *(p+1)Indica que se busquen los datos de la dirección, es decir, los datos completos de la primera fila. Tenga en cuenta que es una fila de datos, pero datos múltiples, no el elemento 0 en la fila 1. Comprensión del código:

#include <stdio.h>
int main(){
    int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
    int (*p)[4] = a;
    printf("%d\n", sizeof(*(p+1)));
    return 0;
}

   Resultado corriente: 16

   Indica: hay 4 enteros int en una fila, entonces 4*4=16 representa los datos de una fila

3) *(p+1)+1 representa la dirección del primer elemento en la primera fila. ¿Cómo entenderlo?

*(p+1) significa la primera fila de datos cuando se usa sola, y se convertirá en la primera dirección de la primera fila de datos cuando se coloque en la expresión, es decir, la dirección del elemento 0 de la primera fila, porque se usa toda la fila. Los datos no tienen un significado real y el compilador los convertirá en un puntero al elemento 0 de la fila cuando se encuentre con esta situación.

4)  *(*(p+1)+1)Indica el valor del primer elemento de la primera fila. Obviamente, agregar un * significa obtener los datos de la dirección.

De acuerdo con las conclusiones anteriores, se pueden deducir fácilmente las siguientes relaciones de equivalencia:

a+i == p+i
a[i] == p[i] == *(a+i) == *(p+i)
a[i][j] == p[i][j] == *(a[i]+j) == *(p[i]+j) == *(*(a+i)+j) == *(*(p+i)+j)

Aplicación de matriz bidimensional en puntero de matriz:

#include <stdio.h>
int main(){
    int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
    int(*p)[4];
    int i,j;
    p=a;
    for(i=0; i<3; i++){
        for(j=0; j<4; j++) printf("%2d  ",*(*(p+i)+j));
        printf("\n");
    }
    return 0;
}

 resultado de la operación:

0 1 2 3 
 4 5 6 
 7 8 9 10 11

Cinco, el puntero del personaje.

1. Uso del puntero de carácter

(1) Carácter único

 char  ch='w';
 char *p=&ch;
 //这里的p就是个字符指针 我们可以通过解引用p去改变ch中存的字符'w'。
 *p='s';

(2) cadena


   const char* pstr="hello bit.";//这里是把一个字符串放到pstr指针变量里了吗? 
   printf("%s\n", pstr);

Para (2)
en primer lugar, "hola bit", aquí hay una cadena constante, y char* aquí almacena la dirección del primer carácter de la cadena, que es la dirección de h.

Cadena constante: no se puede cambiar desreferenciando, por lo que debe usarse const para restringir que el puntero char* desreferencia y cambie el contenido.

Resumen: la dirección del primer carácter h de una cadena constante se almacena en la variable de puntero pstr.

2. Puntos propensos a errores de los punteros de caracteres

Ejemplo de código:

#include <stdio.h>
int main()
{
    char str1[] ="hello bit.";
    char str2[] ="hello bit.";
    
    const char* str3="hello bit.";    
    const char* str4="hello bit.";
    
    if(str1==str2)
       printf("str1 and str2 are same\n");    
    else
       printf("str1 and str2 are not same\n");   
           
    if(str3==str4)
       printf("str3 and str4 are same\n");    
    else
       printf("str3 and str4 are not same\n");       
    return 0;
}

¿Por qué str1 y str2 no son lo mismo, pero str3 y str4 son lo mismo?


En primer lugar, en el Ejemplo 1, las dos comparaciones if aquí son todas direcciones

La comparación entre str1 y str2 es la dirección del primer elemento de la matriz, porque la matriz abrirá un espacio en la memoria, por lo que las direcciones de str1 y str2 son diferentes.
str3 y str4 son punteros de caracteres y comparan la dirección del primer carácter de la cadena. El contenido almacenado en estos dos punteros es "hello bit". Son la misma cadena constante, y la misma cadena constante
en la memoria solo almacenarse Una copia, por lo que las direcciones de str3 y str4 son las mismas.

Seis, aliento mutuo

Lo siguiente es mi comprensión de los punteros de matriz, las matrices de punteros y los punteros de caracteres . Si hay amigos que no entienden o encuentran problemas, infórmeles en el área de comentarios. Al mismo tiempo, continuaré actualizando mi comprensión de la función qsort del puntero de devolución de llamada , continúe ¡Sígueme! ! ! ! !

 

 

Supongo que te gusta

Origin blog.csdn.net/weixin_45031801/article/details/127381406
Recomendado
Clasificación