Puntero de aprendizaje de lenguaje C (8)


El alma del lenguaje C, el eslabón más importante.

1. Puntero


1.1 ¿Qué es un puntero?

Fundamentalmente, un puntero es una variable (u objeto de datos) cuyo valor es una dirección de memoria. Así como una variable de tipo char es un carácter, una variable de tipo int es un número entero y el valor de una variable de puntero es una dirección.

En pocas palabras, un puntero es una variable, pero almacena la dirección de la variable.

El tamaño del puntero es de 4 bytes en plataformas de 32 bits y de 8 bytes en plataformas de 64 bits.

# include <stdio.h>

int main(void){
    
    

	// 声明一个变量
	int a = 10;	
	// 声明一个int类型的指针p,该指针存放的值为a变量在内存中的地址。
	int* p = &a;
	// 打印a变量的地址,也就是p的值。
	printf("%p", p);	// 结果为:000000000061FE14
	
	return 0;
}

En el ejemplo anterior, "%p" es el carácter de control de la variable de tipo de puntero de salida, consulte formato de entrada/salida para obtener más información .

" * " es el operador de desreferencia. & es un carácter de dirección. Puede leer el artículo del operador, que explica los operadores en detalle.


1.2 Definición de puntero

La definición del puntero se ha visto en el ejemplo anterior. La estructura es la siguiente:

数据类型 *指针变量名
// 定义一个char类型指针变量,char_p为指针变量名。等号后面为char_p的值。
char* char_p = &a;
// 定义一个int类型指针变量,int_p为指针变量名。等号后面为int_p的值。
int* int_p = &b;
// 定义一个short类型指针变量,short_p为指针变量名。等号后面为short_p的值。
short* short_p = &c;
// 定义一个float类型指针变量,float_p为指针变量名。等号后面为float_p的值。
float* float_p = &d;
// 定义一个double类型指针变量,double_p为指针变量名。等号后面为double_p的值。
double* double_p = &e;

1.3 Tipos de punteros

En 1.2, declaramos variables de puntero de tipo int, char, etc. A través del ejemplo anterior, vimos que los punteros también tienen tipos, y los tipos de punteros son:

type *	// type指的是数据类型。例如 int,char等等

// 示例
int* p = &a;	// int*表示指针类型为int*,p为指针变量的名称。&a为指针变量的值。

El tipo del puntero determina el tamaño del espacio al que puede acceder el puntero durante la operación de desreferenciación (cuántos bytes se pueden manipular). Por ejemplo: la desreferencia de puntero char * solo puede acceder a un byte, y la desreferencia de puntero int * puede acceder a 4 bytes.

# include <stdio.h>

int main(void){
    
    

int a = 10;
char* ch = &a;
int* p = &a;

// 打印a的地址
printf("%p\n", &a);	// 000000000061FE0C
// char类型的指针只能访问一个字节,当char类型的指针+1时,
// 只能后移一个字节,则ch+1的地址就是a的地址+1。0C+1 = 0D
printf("%p\n", ch+1);	// 000000000061FE0D
// int类型的指针只能访问4个字节,当int类型的指针+1时,
// 后移4个字节,则p+1的地址就是a的地址+4。0C+4 = 10 
printf("%p\n", p+1);	// 000000000061FE10
	return 0;
}

El tamaño de una variable de puntero es de 4 bytes en una máquina de 32 bits y de 8 bytes en una máquina de 64 bits .


Dos, puntero salvaje

2.1 ¿Qué es un puntero salvaje?

El puntero salvaje es la dirección a la que apunta el puntero es desconocida (incierta, aleatoria)


2.2 Por qué se generan punteros salvajes

1、指针未初始化。
2、指针数组越界。
3、指针指向的空间释放
# include <stdio.h>

int main(void){
    
    

	int *p;	// 指针未初始化,随机值
	*p = 10;

	return 0;
}
# include <stdio.h>

int main(void){
    
    

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

	int *p = arr;
	for (int i = 0; i < 6; i++)
	{
    
    
		// 当超出数组时,指针就是野指针
		*(p++) = i;
	}

	return 0;
}

2.3 Cómo evitar los punteros salvajes

1、指针记得初始化。
2、不要使指针数组越界。
3、指针指向空间释放后置指针为NULL。
4、避免返回局部变量的地址。
5、指针使用前检查有效性。

3. Aritmética de punteros

3.1 Cesión

Asignación significa que puede asignar una dirección a un puntero. Pero tenga en cuenta que el tipo de la dirección debe ser el mismo que el del puntero, por ejemplo: no puede asignar una dirección de tipo char a un puntero de tipo int.

# include <stdio.h>

int main(void){
    
    

	// 定义一个char类型的变量
	char a = 10;
	// 定义一个char类型的指针并将char类型变量的地址赋值给char类型的指针
	char *p = &a;

	return 0;
}
// 将char类型的变量不能赋值给int类型的指针
int *tp = &a;

3.2 Desreferencia

El operador * da un puntero al valor almacenado en la dirección. *p tiene un valor de 10, que se almacena en la dirección.


3.3 Adición de enteros de puntero

Puede agregar punteros con el operador + o números enteros con punteros. En cualquier caso, el número entero se multiplica por el tamaño (en bytes) del tipo al que apunta el puntero y el resultado se suma al valor inicial. Hay ejemplos en Tipos de punteros 1.3.


3.4 Puntero menos un entero

Se puede restar un número entero de un puntero usando el operador -. Un puntero debe ser el primer operando y un entero es el segundo operando. Este entero se multiplicará por el tamaño del tipo apuntado por el puntero en bytes, y el producto se restará de la dirección inicial.

Si el resultado de la resta excede el rango de la matriz a la que apunta el puntero inicial, la parte sobrante es un puntero salvaje. C garantiza que el puntero es válido a menos que esté justo más allá de la primera posición más allá del final de la matriz.


3.5 Punteros de incremento y decremento

Incremento y decremento también funcionan con punteros, incrementando un puntero a un elemento de matriz mueve ese puntero al siguiente elemento de la matriz.

# include <stdio.h>

int main(void){
    
    

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

	int *p = arr;
	for (int i = 0; i < 5; i++)
	{
    
    
		// 通过指针的递增来遍历数组
		*(p++) = i;
	}

	return 0;
}

3.6 Diferencia de puntero

Se puede calcular la diferencia entre dos punteros. Por lo general, los dos punteros de diferencia apuntan a diferentes elementos de la misma matriz, y la distancia entre los dos elementos se calcula y divide. Las unidades de la diferencia son las mismas que las unidades del tipo de datos.

# include <stdio.h>

int main(void){
    
    

	int arr[]={
    
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	
	// 取数组首元素的地址
	int *first = &arr[0];
	// 取数组尾元素的地址
	int *last = &arr[9];
	// 两个指针相减,为数组的长度
	int ret = *last - *first;
	printf("arr[0]为:%d\n", arr[0]);	// 结果为:0
	printf("arr[9]为:%d\n", arr[9]);	// 结果为:9
	printf("数组长度为:%d\n", ret);	// 结果为:9

	return 0;
}

3.7 Comparación de punteros

Utilice operadores relacionales para comparar los valores de dos punteros, siempre que ambos punteros apunten a objetos del mismo tipo.

# include <stdio.h>

int main(void){
    
    

	int arr[]={
    
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

	int *first = &arr[0];
	int *last = &arr[9];
	// 两个相同类型的指针比较,因为last大于first,所以输出的结果为0
	int ret = *last < *first;

	printf("ret结果为:%d\n", ret);	// 结果为:0

	return 0;
}

Cuarto, el puntero secundario

Como se mencionó anteriormente, una variable de puntero también es una variable, una variable tiene una dirección y el puntero que almacena la dirección de la variable de puntero es un puntero secundario

# include <stdio.h>

int main(void){
    
    

	// 定义int类型的变量
	int a = 10;
	// 定义int类型的指针变量并赋值为a的地址
	int *pta = &a; 
	// 定义一个二级指针变量指向*pta的地址
	int **ppta = &pta;

	return 0;
}

La dirección de a se almacena en pta, la dirección de pta se almacena en ppta, pta es un puntero de primer nivel y ppta es un puntero de segundo nivel.

# include <stdio.h>

int main(void){
    
    

	// 定义int类型的变量
	int a = 10;
	// 定义int类型的指针变量并赋值为a的地址
	int *pta = &a; 
	// 定义一个二级指针变量指向*pta的地址
	int **ppta = &pta;

	printf("a的地址为:%p\n", a);	// 000000000000000A
	printf("*pta的地址为:%p\n", *pta);	// *pta的地址为:000000000061FE14
	printf("**ppta的地址为:%p\n", **ppta); // **ppta的地址为:000000000061FE08
	return 0;
}

Cinco, la matriz de punteros

La esencia de una matriz de punteros sigue siendo una matriz. Sin embargo, los punteros se almacenan en la matriz.

# include <stdio.h>

int main(void){
    
    

	// arr是一个数组,里面有6个元素,每个元素都是一个整型指针。其他类型的指针数组同理。
	int *arr[6];

	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_46292926/article/details/127568865
Recomendado
Clasificación