Puntero de lenguaje C avanzado (1)

Tabla de contenido

1. Puntero de carácter

2. Matriz de punteros

 Comprender las matrices de punteros por analogía

2.1 Forma general de matriz de punteros

2.2 Simulación de matriz de punteros para realizar una matriz bidimensional

3. Puntero de matriz

 Comprender los punteros de matriz por analogía

3.1 Forma general del puntero de matriz

3.2& Nombre de matriz VS Nombre de matriz

3.3 Uso de punteros de matriz

Cuatro, parámetros de matriz, parámetros de puntero

4.1 Paso de parámetros de matriz unidimensional

4.2 Paso de parámetros de matrices bidimensionales

4.3 Paso de parámetros de puntero de nivel 1 

4.4 Paso de parámetros de puntero de segundo nivel


Prefacio: En el puntero inicial, aprendimos sobre el concepto de punteros. Un puntero es una variable que se utiliza para almacenar una dirección. La dirección identifica de forma única un espacio de memoria. Al mismo tiempo, el puntero tiene un tipo. El tipo del puntero determina el tamaño de paso del entero + del puntero y la autoridad de la operación de desreferencia del puntero. A continuación, déjame guiarte para que comprendas varios tipos de punteros.

1. Puntero de carácter

La forma general de un puntero de carácter:

       char* nombre de la variable

 Uso general de punteros de caracteres

int main()
{
	char ch = 'w';
	char* pc = &ch;       //pc就是字符指针

    ch='a';
	*pc = 'a';

	return 0;
}

El valor de la variable ch se puede cambiar directamente, o el valor de la variable ch se puede cambiar a través de un puntero.

int main()
{
    char arr[]="abcdef";
    //创建一个数组,用字符串来初始化这个数组
    const char* p="abcdef";  //常量字符串
    //本质是将字符串首元素的地址赋给指针变量p
}

La esencia es asignar la dirección del primer elemento de la cadena a la variable de puntero p. Debido a que es una cadena constante, no se puede modificar, así que agregue const para evitar que *p modifique la cadena.

Verifique imprimiendo que la dirección del primer elemento de la cadena está almacenada en p

int main()
{
	const char* p = "abcedf";

	printf("%s\n", p);
	printf("%c\n", *p);
}

 Ejemplo de análisis:

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;
}

 str1 y str2 son dos matrices creadas, cada una con su propio espacio independiente.Aunque las dos matrices almacenan la misma cadena, sus direcciones son diferentes. str1 y str2 son nombres de matriz, y el nombre de la matriz representa la dirección del primer elemento, ¡así que str1! =str2

2. Matriz de punteros

 Comprender las matrices de punteros por analogía

Matriz de enteros -- una matriz que almacena números enteros

matriz de caracteres: un número para almacenar caracteres

matriz de punteros - una matriz de punteros

2.1 Forma general de matriz de punteros

        int* arr1[10]; // matriz de punteros enteros

        char* arr2[10]; //Array de punteros de caracteres

2.2 Simulación de matriz de punteros para realizar una matriz bidimensional

#include <stdio.h>
int main()
{
	int arr1[] = { 1,2,3,4,5 };		//arr1 - 数组名 - 首元素地址 int*
	int arr2[] = { 2,3,4,5,6 };		//arr2 - 数组名 - 首元素地址 int*
	int arr3[] = { 3,4,5,6,7 };		//arr3 - 数组名 - 首元素地址 int*

	int* arr[] = { arr1,arr2,arr3 };

	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

 

Las tres matrices creadas no son contiguas en el espacio de la memoria, por lo que en realidad no son matrices bidimensionales.

3. Puntero de matriz

 Comprender los punteros de matriz por analogía

Puntero entero: un puntero a una variable entera. Es decir, una variable puntero que almacena la dirección de una variable entera

Puntero de carácter -- Un puntero a una variable de carácter. Es decir, una variable puntero que almacena la dirección de una variable de carácter

Puntero de matriz: un puntero a una variable de matriz. Es decir, la variable de puntero que almacena la dirección de la variable de matriz

3.1 Forma general del puntero de matriz

        int(*p)[10]; 

Explicación: p primero se combina con *, lo que indica que p es una variable de puntero y luego apunta a una matriz de 10 enteros (el tipo señalado es int [10]). Entonces p es un puntero que apunta a una matriz, llamado puntero de matriz.

Nota: La prioridad de [] es mayor que la de *, por lo que se debe agregar () para garantizar que p se combine con * primero.

3.2& Nombre de matriz VS Nombre de matriz

El nombre de la matriz suele ser la dirección del primer elemento, con dos excepciones

1. sizeof(nombre de la matriz) El nombre de la matriz se coloca solo dentro de sizeof(), donde 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 El nombre de la matriz aquí también representa la matriz completa, y la dirección de la matriz completa se elimina

3.3 Uso de punteros de matriz

int main()
{
     int arr[10] = {1,2,3,4,5,6,7,8,9,0};
     int (*p)[10] = &arr;    //把数组arr的地址赋值给数组指针变量p
     return 0;
}

void Print(int(*arr)[5], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf("%d ", arr[i][j]);
            printf("%d ", *(*(arr+i)+j));
		}
		printf("\n");
	}
}

int main()
{
	int arr[3][5] = { 1,2,3,4,5,2,3,4,5,6,3,4,5,6,7 };
	Print(arr, 3, 5);
	return 0;
}

Interpretación del código:

printf("%d", *(*(arr+i)+j));

*&arr==arr dirección del primer elemento

*(arr+i)==arr+i es equivalente a la dirección del primer elemento de la fila i, +j salta j elementos  

Cada fila de una matriz bidimensional puede entenderse como un elemento de una matriz bidimensional, y cada fila es una matriz unidimensional. 

El nombre de la matriz arr indica la dirección del primer elemento. El primer elemento de la matriz bidimensional es la primera fila de la matriz bidimensional, por lo que la matriz que se pasa aquí es en realidad equivalente a la dirección de la primera fila, que es la dirección de la matriz unidimensional y puede ser recibida por el puntero de la matriz. .

Reponer:

Paso de parámetro de matriz unidimensional, la parte del parámetro formal puede ser una matriz o un puntero

void test1(int arr[5], int sz)
{}

void test2(int* arr, int sz)
{}

int main()
{
	int arr[5] = { 0 };
	test1(arr, 5);
	test2(arr, 5);
	return 0;
}

 Paso de parámetros de matriz bidimensional, la parte del parámetro formal puede ser una matriz o un puntero

void test1(int arr[3][5], int r,int c)
{}

void test2(int (*p)[5], int r,int c)
{}

int main()
{
	int arr[3][5] = { 0 };
	test1(arr,3, 5);
	test2(arr,3, 5);
	return 0;
}

Nota: Los parámetros formales están escritos en forma de matriz para que sea más fácil de entender, y son esencialmente punteros.

Cuatro, parámetros de matriz, parámetros de puntero

4.1 Paso de parámetros de matriz unidimensional

void test(int arr[10])//ok?
{}

void test(int *arr)//ok?
{}

int main()
{
     int arr[10] = {0};
     test(arr);
}

La primera es correcta, el array recibe el parámetro del array, pero la esencia del parámetro formal es un puntero. El número de elementos se puede omitir.

El segundo es correcto, el nombre de la matriz pasa la dirección del primer elemento, por lo que puede ser recibido por un puntero.

void test(int* arr[20])//ok?
{}

void test(int **arr)//ok?
{}

int main()
{
     int *arr2[20] = {0};
     test(arr2);
}

La primera es correcta, se puede recibir una matriz de punteros con una matriz de punteros.

La segunda es correcta, el tipo de la variable es una matriz de punteros, la dirección se almacena en la matriz, el tipo de cada elemento es int*, el nombre de la matriz es la dirección del primer elemento y la dirección real El parámetro es la dirección del puntero, así que use el segundo nivel. Se recibe el puntero.

4.2 Paso de parámetros de matrices bidimensionales

void test(int arr[3][5])//ok?
{}

void test(int arr[][])//ok?
{}

void test(int arr[][5])//ok?
{}

void test(int *arr)//ok?
{}

void test(int* arr[5])//ok?
{}

void test(int (*arr)[5])//ok?
{}

void test(int **arr)//ok?
{}

int main()
{
     int arr[3][5] = {0};
     test(arr);
}

 El primero es correcto, los parámetros de pase de matriz se reciben por números.

Nota: Para el paso de parámetros de matriz bidimensional, el diseño del parámetro de función solo puede omitir el primer número [].

Porque para una matriz bidimensional, no necesita saber cuántas filas hay, pero debe saber cuántos elementos hay en una fila.

 El cuarto es incorrecto.El nombre de la matriz de la matriz bidimensional es la dirección de una línea, y el tipo es int(*)[], que no puede ser recibido por int* arr.

El sexto es incorrecto, el puntero secundario no puede recibir la dirección de la variable entera.

4.3 Paso de parámetros de puntero de nivel 1 

       Cuando la parte del parámetro de una función es un puntero de primer nivel, los parámetros que puede pasar el parámetro real de la función

void test(int* p)
{}

int main()
{
	int n = 10;
	test(&n);

	int* p = &n;
	test(p);

	int arr[5] = { 0 };
	test(arr);
	return 0;
}

4.4 Paso de parámetros de puntero de segundo nivel

          Cuando la parte del parámetro de una función es un puntero secundario, los parámetros que puede pasar el parámetro real de la función

void test(int** p)
{}

int main()
{
	int n = 10;
    int* p=&n;
	test(&p);

	int** pp = &p;
	test(pp);

	int* arr[5] = { 0 };
	test(arr);
	return 0;
}

El contenido de este tiempo está aquí. Espero que puedan ganar algo después de leerlo, y gracias lectores por su apoyo. Si tiene alguna pregunta sobre el artículo, puede dejar un mensaje en el área de comentarios. El blogger debe revisarlo cuidadosamente y escribir mejores artículos en el futuro.  

Supongo que te gusta

Origin blog.csdn.net/2301_76207836/article/details/131613324
Recomendado
Clasificación