Erratas en lenguaje C --- puntero

Este artículo presenta principalmente los errores que ocurren fácilmente en el uso de punteros.

Tabla de contenido

Este artículo presenta principalmente los errores que ocurren fácilmente en el uso de punteros.

1. Puntero de carácter (se asigna una cadena constante al puntero)

2. El uso de matrices de punteros (matriz de punteros)

3. Puntero de matriz (puntero a matriz)

4. Puntero de función

5. Matriz de punteros de función

6. Función de devolución de llamada

7. Pasando parámetros


Comprender sustantivos:

Una dirección hexadecimal ocupa un byte

p [0] = * (p + 0)

char * p (puntero de carácter) - int * p (puntero de entero) - int p [10] (matriz de entero) 

int * p [10] (Matriz de punteros: hay 10 elementos en la matriz y cada tipo de elemento es int *)

int (* p) [10] (Puntero de matriz: * p es un puntero que apunta a una matriz, hay 10 elementos en la matriz y cada tipo de elemento es int) 

int * p () (función de puntero)

int (* p) (int, int) (puntero de función)

int (* p [10]) (int) (matriz de punteros de función)

int (* p [10]) [5] (una matriz, hay 10 elementos en la matriz, cada tipo de elemento es un puntero de matriz, el puntero de matriz apunta a 5 elementos, cada tipo de elemento es int) Para este tipo de datos , Primero encuentra el sujeto --- número ------ sácalo ----- el resto int (* p) [5] ----- puntero de matriz

void *: puede aceptar cualquier tipo de dirección, no puede desreferenciar, no puede realizar ++ - y otras operaciones, si desea desreferenciar, necesita realizar una coerción (como * (int *) p)

1. Puntero de carácter (se asigna una cadena constante al puntero)

(1) Primero mira el siguiente código

#include<stdio.h>
int main(int argv,char *argc[])
{
	
	char *p = "abcdef";
	printf("%s\n",p);
	printf("%c\n",*p);

	*p = 'A';

    return 0;
}

Resultado de salida

Los resultados anteriores muestran que el puntero almacena la primera dirección del elemento de cadena, no la cadena completa (el puntero ocupa 4/8 bytes en un sistema de 32 bits / 64)

                        ¿Por qué hay un error de segmentación? Eso se debe a que "abcdef" es una cadena constante y no se puede cambiar.

(2) Mire el siguiente código nuevamente

#include<stdio.h>
int main(int argv,char *argc[])
{
	char arr1[] = "abcdef";
	char arr2[] = "abcdef";
	char *p = "abcdef";
	char *n = "abcdef";

	if(arr1 == arr2){
		printf("arr1 == arr2\n");
	}
	else{
		printf("arr1 != arr2\n");
	}
	if(p == n){
		printf("p == n\n");
	}
	else{
		printf("p != n\n");
	}

    return 0;
}

Resultado de salida

Los resultados anteriores muestran que la cadena asignada por el puntero es una cadena constante En nuestro sistema operativo, para ahorrar memoria, la cadena constante solo se guardará una vez. Es decir, el puntero p y el puntero n apuntan a a (la primera dirección del elemento de cadena)

                         La matriz de cadenas se puede abrir varias veces.

2. El uso de matrices de punteros (matriz de punteros)

int * arr [10] (según la prioridad, arr se combina primero con [10], arr [10] almacena int *)

#include<stdio.h>
int main(int argv,char *argc[])
{
	char arr1[] = {1,2,3,4};
	char arr2[] = {5,6,7,8};
	char arr3[] = {9,10,11,12};

	char *p[3] = {arr1,arr2,arr3};

	for(int i = 0;i < 3;i ++)
	{
		for(int j = 0;j < 4;j ++)
		{
			printf("%d",*(p[i]+j));
		}
		printf("\n");
	}
//	printf("%d\n",*(p[0]+1));

    return 0;
}

3. Puntero de matriz (puntero a matriz)

int (* arr) [10] (según la prioridad, arr se combina primero con *, y el puntero * arr apunta a int [10])

Suponga una matriz de un bit int arr [10]

Entonces int * p = arr; luego arr [i] == p [i] == * (p + i) == * (arr + i) 

Suponiendo una matriz bidimensional int arr [3] [5]

Entonces int arr [3] [5] = int (* p) [5] luego ----> arr [i] [j] == p [i] [j] == * (* (p + i) + j) == * (p [i] + j)

4. Puntero de función

Compare los punteros de matriz para comprender los punteros de función

int (* p) (int a, int b)

int add(int a,int b)
{
    return a+b;
}
int main()
{
    int a = 10;
    int b =20;
    
                                //数组指针int (*p)[10]
    int (*p)(int,int) = add;    //函数指针 指针p指向add,*p相当于调用
    printf("sum = %d\n",(*p)(2,3));
    printf("sum = %d\n",p(2,3));  //*没有实际意义
}

1) Mira el siguiente segmento de código (* (void (*) ()) 0) (); equivalente a una llamada de función

(* (xxx) xxx) () significa llamada

2)

la señal es una declaración de función

El tipo de retorno de la función es un puntero de función , el puntero de función apunta al parámetro int y el tipo de retorno es nulo

El primer parámetro de la función es , el tipo del segundo parámetro es un puntero de función , el puntero de función apunta a int y el tipo de retorno es nulo

Nota: cambie el nombre de los punteros de función con typedef

void (*signal(int, void(*)(int)))(int);

typedef void (*function)(int);
function signal(int,function);

5. Matriz de punteros de función

La matriz de punteros se usa para almacenar punteros y la matriz de punteros de función se usa para almacenar punteros de función. Hay una diferencia entre los dos

Representación de matriz de puntero de función: void (* p [4]) (int, int) / void (* p [4]) () ........

inicialización 

//void(*p[4])(int,int);
void SUM(int,int)
{}
void SUB(int,int)
{}
void MUL(int,int)
{}
void DIV(int,int)
{}

int main(int,int)
{
    void(*p[4])(int,int) = {SUM,SUB,MUL,DIV};
}

Ejemplo de uso:

                    1.char * (* pf) (char *, const char *)

                    2.char * (* pf [4]) (char *, const char *)

Se utiliza para escenarios donde la calculadora suma, resta, multiplica y divide los mismos parámetros y diferentes funciones ( tabla de transferencia )

6. Función de devolución de llamada

  Una función de devolución de llamada es una función llamada a través de un puntero de función. Si pasa un puntero de función (dirección) como parámetro a otra función, cuando este puntero se usa para llamar a la función apuntada, decimos que se trata de una función de devolución de llamada. La función de devolución de llamada no es llamada directamente por el implementador de la función, pero es llamada por otra parte cuando ocurre un evento o condición específica, y se usa para responder al evento o condición. ( No llamar a esta función directa-indirectamente )

 
#include <stdio.h>
//回调函数
int ADD(int (*callback)(int,int), int a, int b){
	return (*callback)(a,b);//此处回调add函数...
}
//普通函数
int add(int a, int b){
	return a + b;
}
 
int main(void){
	printf("%d\n",add(1,2));
	printf("%d\n",ADD(add,1,2));
	return 0;
}

7. Pasando parámetros

Transferencia de parámetros de matriz bidimensional ----- Si el nombre de matriz de una matriz bidimensional representa el primer elemento, es la primera fila de la matriz

void test(int arr[5][10])
{}
void test1(int arr[][10])
{}
void test3(int arr[5][])  //error
{}
void test4(int arr[][])  //error
{}
void test5(int **arr)  //error  二级指针用来存放一级指针的变量的地址,arr对于二维数组来说就是第一行数组的地址,数组的地址不能存放在二级指针里边
{}
void test6(int (*arr)[10])//指向数组的指针,可以用来存贮一位数组
{}
int main()
{
    int arr[5][10] = {0};
    test(arr);
    test1(arr);
    test6(arr);
}

Transferencia de puntero de segundo nivel

void test(char **p)
{
    printf("%c\n",**p);
}

int main()
{
    char a = 'b';
    char *p = &a;
    char **pp = &p;
    char *buff[32] = {p};
    test(pp); //用二级指针传参
    test(&p); //用一级指针的地址传参
    test(buff);//用指针数组传参
}

Puntero de función pasando parámetros (puntero a función, utilizado para almacenar la dirección de la función)

int add(int a,int b)
{
    return a+b;
}
int main()
{
    int a = 10;
    int b =20;
    
                                //数组指针int (*p)[10]
    int (*p)(int,int) = add;    //函数指针 指针p指向add,*p相当于调用
    printf("sum = %d\n",(*p)(2,3));
    printf("sum = %d\n",(p)(2,3)); //*其实没有实际意义
}

 

 

Supongo que te gusta

Origin blog.csdn.net/qq_45604814/article/details/112844269
Recomendado
Clasificación