Aprendizaje de entrada de puntero de lenguaje C, clasificación de puntos de conocimiento (4)

El contenido de este artículo: los tres significados del asterisco puntero y la relación de transferencia variable entre el puntero y el parámetro real y el parámetro formal cuando se llama a la función, y cómo modificar el valor de la variable ordinaria de la función de llamada a través de la función llamada.

Portal:

Aprendizaje de entrada de puntero de lenguaje C, combinación de conceptos (1)

Aprendizaje de entrada de puntero de lenguaje C, combinación de conceptos (2)

Aprendizaje de entrada de puntero de lenguaje C, combinación de puntos de conocimiento (3)

Aprendizaje de entrada de puntero de lenguaje C, clasificación de puntos de conocimiento (4)


1. El significado del asterisco *:
  1. multiplicación
  2. Defina una variable de puntero: int * p; // Defina una variable de puntero llamada p, int * significa que p solo puede almacenar la dirección de una variable entera int
  3. Operador de puntero: colocado delante de la variable de puntero definida, si p es una variable de puntero definida, entonces p significa la variable int * p con el contenido de p como dirección
    ; el asterisco en
    P = 5 Los asteriscos no son lo mismo, el primero indica que p es una variable apuntadora, el segundo indica un operador de valor, *p es equivalente a 5

Convenciones en las variables del lenguaje C: use ijkl para números enteros, xyz para tipos de punto flotante y pqst para punteros

# include <stdio.h>

int main(void)
{
    
    
	int * p;   //该语句等价于 int *p;   也等价于int* p; 一般来说写法写int * p;
	int i = 5;
	char ch = 'A';    //单个字符必须用单括号,否则会被系统认成变量
	p = &i;           //正确,*p是以p的内容为地址的变量
	*p = 99;          //p接收了i的地址,所以*p就等同于i,即i的值为被赋值99
	printf("i = %d, *p = %d\n", i, *p);
	//p = &ch;        //error  类型不一致
	//p = ch;         //error  类型不一致
	//p = 5;          //error
	return 0;
}

---------------------------------------------------------------------------------------------------------------------------------
运行结果: i = 99, *p = 99;

A través del programa anterior, puede comprender claramente las funciones de las direcciones y los punteros, y prestar atención para distinguir p, *p, &i e int * p; estos son los conocimientos básicos para comprender los punteros, aprender los punteros y usar los punteros, que debe ser memorizado.


# include <stdio.h>

void swap_1(int a, int b);     //函数声明,此处还可以写成: void swap_1(int , int )

void swap_2(int * p, int * q)  //形参名字不是*p,*q而是p,q,接收实参数据, 函数结束后释放p,q,所以光调换p,q值不影响主函数中的a,b
{
    
                                  //C语言是值传递,此时p存放a的地址(如1000H),p也有自己的地址(如2000H),
    int * t;                   //*p表示的是a地址中的数据(3),修改*p就会修改变量a的值。      
    t = p; p = q; q = t;       //此处换的是p,q的地址,而没有换*p,*q,即主函数中a,b的地址和值都不变,所以输出结果还是a = 3, b = 5             
}
void swap_3(int * p, int * q)  //形参名字不是*p,*q而是指针变量p,q,接收实参数据(地址数据)
{
    
                                  //C语言是值传递,此时p存放a的地址(如1000H),p也有自己的地址(如2000H),
    int t;                     //*p,*q等同于a,b为int型,所以为保持类型一致,t也必须是整型int
    t = *p; *p = *q; *q = t;   //*p,*q虽然在子函数中,但通过地址可以直接修改主函数中a,b的值,输出结果为a = 5, b = 3          
}                              
int main(void)
{
    
    
	int a = 3;
	int b = 5;
	//swap_1(a, b);    //不报错,但无法修改主函数中a,b的值,不能完成交换
	//swap_2(a, b)    //error:错误,形参是指针变量p和q,p要接收的是整型地址而不是整型变量,应改为swap_2(&a, &b);
	//swap_2(&a, &b); //不报错,把a的地址传递给p,把b的地址传递给q。但是函数结束后主函数中a,b仍未完成交换
	swap_3(&a, &b);   //虽然调用函数结束后,形参指针变量p,q的值会被释放,但通过指针*p,*q,主函数中a,b的值已经被改写了,交换成功
	printf("a = %d, b = %d\n", a, b);
	return 0;
}

void swap_1(int i, int j)    //返回值为void,可以直接写return; 也可以不写return,每调用一次return只能返回一个值
{
    
                                
	int t;
	t = i; i = j; j = t;     //等号两边类型一致,不报错,但修改形参的值不影响主函数变量,无法完成交换
	//return;                //return有返回值,终值函数的作用
}


------------------------------------------------------------------------------------------------------------------------
三个函数中,只有swap_3()才能完成交换,输出: a = 5, b = 3
其余两个函数,输出结果都是: a = 3, b = 5 


Para resumirlo en una frase: dominar los conceptos de parámetros formales, parámetros reales, variables de puntero, direcciones y asteriscos, solo así no será fácil confundirse con varias variables en el programa.

1. Intercambio de parámetros formales, los parámetros formales p y q se liberan después de llamar a la función, por lo que no hay forma de afectar los parámetros reales a y b en la función principal principal, y el intercambio no se puede completar

2. Sin embargo, debido a las características de , al copiar las direcciones de los parámetros reales a y b para los parámetros formales p y q, puede usar *p y *q para modificar remotamente los valores de a y b en el función principal para completar el intercambio.

3. Los parámetros formales y los parámetros reales siempre son diferentes. Se les asignan diferentes espacios en diferentes funciones y pertenecen a diferentes variables. El valor pasado de la función principal a la función de llamada es equivalente a copiar el pasado y no afecta el valor real en la función principal Solo cuando la función de llamada tiene la dirección de la variable de función principal, puede controlar y modificar directamente la variable de parámetro real, y el puntero puede modificar de forma remota el valor de la variable en la función principal en la función de llamada a través de la dirección.


Inducción: ¿Cómo modificar el valor de la variable ordinaria de la función llamante a través de la función llamada?

  1. El parámetro real debe ser la dirección de la variable ordinaria, como: nombre de la función (&a,&b)
  2. El parámetro formal debe ser una variable de puntero, como int * p, int *q
  3. En la función llamada se puede modificar el valor de más de una variable relacionada de la función que llama mediante * nombre del parámetro formal = ...

(La capacidad es limitada, y el blog es solo para referencia y estudio de la mayoría de los internautas. Si hay alguna deficiencia, corríjame y progresemos juntos).

Supongo que te gusta

Origin blog.csdn.net/AII_IIA/article/details/131240733
Recomendado
Clasificación