Base de puntero de lenguaje C

Si desea obtener más información sobre los puntos de conocimiento de los punteros, puede ver otro blog mío.

Puntero avanzado: https://blog.csdn.net/qq_46485161/article/details/115037692

El concepto de direcciones y punteros.

Para aclarar qué es un puntero, es necesario averiguar cómo se almacenan los datos en la memoria y cómo se leen.

Cada byte del área de memoria tiene un número, que es la "dirección". Si se define una variable en el programa, el sistema asignará una unidad de memoria a esta variable cuando se compile el programa.

1. El método para acceder a los valores de las variables según las direcciones de las variables se denomina "acceso directo", por ejemplo:

printf(%d″,i);
scanf(%d″,&i);
k=i+j;

2. Otra forma de acceder a los valores de las variables se llama "acceso indirecto". Es decir, almacene la dirección de la variable i en otra variable.

En lenguaje C, la variable de puntero es una variable especial, que almacena la dirección. Supongamos que definimos una variable de puntero i_pointer para almacenar la dirección de una variable entera, y se le asignan dos bytes con las direcciones (3010) y (3011). Puede utilizar la instrucción: i_pointer = & i;
almacenar la dirección de i (2000) en i_pointer. En este momento, el valor de i_pointer es (2000), que es la dirección inicial de la unidad ocupada por la variable i. Para acceder al valor de la variable i, puede usar un método indirecto: primero busque la variable i_pointer que almacena la "dirección de i", saque la dirección de i de ella (2000), y luego saque el valor de i para 2000 y 2001

Punteros y variables de puntero

Definición de punteros y variables de puntero :
La dirección de una variable se denomina "puntero" de la variable.
Por ejemplo, la dirección 2000 es un puntero a la variable i.
Si hay una variable dedicada a almacenar la dirección de otra variable (es decir, un puntero), se denomina "variable de puntero".
El i_pointer anterior es una variable de puntero.

El valor de la variable de puntero (es decir, el valor almacenado en la variable de puntero) es la dirección (es decir, el puntero).
Distinga los dos conceptos de "puntero" y "variable de puntero".

El puntero a la variable y la variable puntero a la variable
1. Defina una
variable de puntero La forma general de definir una variable de puntero es
tipo base * nombre de variable de puntero;
int * ptr;

Explicación
El tipo de variable de puntero: Indica el tipo de datos almacenados en el espacio de memoria al que apunta el puntero.
El " " en la definición significa que la variable definida es una variable de puntero. El nombre de la variable es ptr, no ptr.

Nota: Solo la dirección (puntero) se puede almacenar en la variable de puntero, no asigne un número entero (o cualquier otro tipo de datos que no sean de dirección) a una variable de puntero

Asignar puntero

1. Asigne un valor al puntero a través del operador &, por ejemplo:
ptr_var = & var;
2. Asigne un valor al puntero a través de otra variable de puntero que apunte al mismo tipo de elemento de datos, por ejemplo:
ptr_var2 = ptr_var;
3. Asigne una constante simbólica NULL a la variable de puntero
Por ejemplo: float * ptr_var3 = NULL;
Descripción: NULL es un puntero nulo, lo que significa que el valor de la variable de puntero no tiene sentido. El propósito es evitar referencias ilegales a variables de puntero que no se han inicializado. La definición de NULL está en "stdio.h".
4. Asigne valores a las variables mediante punteros.
Por ejemplo:

	int *ptr_var = NULL;
	int var = 100;
	ptr_var = &var;
	*ptr_var = 10;	/*等价于var = 10;*/
	/*如果ptr_var指向var,则把10赋给var*/

Operador de puntero

& Es un operador unario, devuelve la dirección de memoria del operando.
Por ejemplo:

int var=12,*ptr;
ptr = &var;

* Es el operador inverso de &, también es un operador unario, que devuelve el valor en la ubicación de memoria apuntada por el puntero.
Por ejemplo:

int var=12,*ptr=&var;
int temp = *ptr;	//等价于temp=var;

Explicación
de los operadores "&" y " ": ( Los niveles de precedencia de "&" y " " son los mismos, pero se combinan de derecha a izquierda)

Si se ha ejecutado la instrucción pointer_1 = & a; pointer_2 = & a;;
(1) pointer_2 = & * pointer_1?
Primero realice la operación de * pointer_1, que es la variable a, y luego realice la operación &. & * pointer_1 es lo mismo que & a, es decir, la dirección de la variable a, es para asignar & a (la dirección de a) a pointer_2

(2) y una? & a ?
Realice & una operación primero, obtenga la dirección de a, y luego realice la
operación. Es decir, la variable apuntada por & a, que es la variable a.
Las funciones de & a y pointer_1 son las mismas, son equivalentes a la variable a. Es decir, & a es equivalente a a.

(3) ( pointer_1) ++ y pointer_1 ++
pointer_1 ++: ++ suma tiene la misma prioridad, y la dirección de la combinación es de derecha a izquierda, por lo que es equivalente a
(pointer_1 ++). Dado que ++ está en el lado derecho de pointer_1, es "post-agregado", por lo que el valor original de pointer_1 se opera primero para
obtener el valor de a, y luego el valor de pointer_1 se cambia para que pointer_1 ya no apunte a una.
(* Pointer_1) ++: * pointer_1 es equivalente a a, por lo que toda la expresión es equivalente a a ++

Operaciones aritméticas de puntero

Dos formas: puntero ± entero o puntero-puntero
Nota: ① El resultado de la suma y resta de puntero y valor entero es un puntero, lo que significa que el puntero apunta a la memoria después de que el puntero se mueve hacia abajo o hacia arriba por el número de almacenamiento unidades (valor entero) dirección. El tamaño de la unidad de almacenamiento es el tamaño de memoria requerido por el tipo de datos del puntero.
② La operación de sustracción de punteros y punteros requiere que los dos punteros que se resten sean del mismo tipo y el resultado sea un número entero, que representa el número de datos entre los dos punteros.
P.ej:

//假定var存储在地址1000中,因为整数的长度是 4 个字,ptr_var节的值将是1004
int var, *ptr_var;
ptr_var = &var;
ptr_var ++;	

Cuando se incrementa el puntero, apuntará a la ubicación de memoria del siguiente elemento de su tipo y viceversa.
Inserte la descripción de la imagen aquí

Comparación de punteros

Premisa: Ambos punteros apuntan al mismo tipo de variable.
Suponga que ptr_a y ptr_b apuntan a ayb respectivamente.
Inserte la descripción de la imagen aquí

El puntero se pasa por dirección

El puntero se puede utilizar como parámetro
. La dirección del parámetro actual se pasa al parámetro formal, lo que
permite que la función acceda a la ubicación de la memoria. La
función llamada puede modificar el valor del parámetro del programa de llamada principal.
Ejemplo:

#include <stdio.h>
void swap(int *pi1, int *pi2)
{
    
    
int temp;
temp = *pi1;
*pi1 = *pi2;
*pi2 = temp;
}

void main()
{
    
    
int iNum1, iNum2;
iNum1 = 10;
iNum2 = 20;
swap(&iNum1, &iNum2);
printf(“iNum1=%d,iNum2=%d” ,iNum1,iNum2);
}

Punteros y matrices unidimensionales

Una matriz contiene varios elementos y cada elemento de la matriz ocupa una unidad de almacenamiento en la memoria y todos tienen direcciones correspondientes. Dado que las variables de puntero pueden apuntar a variables, también pueden apuntar a matrices y elementos de matriz.

El llamado puntero de matriz (el nombre de la matriz) es la dirección inicial del grupo de índice, es decir, la dirección del primer elemento. El puntero a la matriz es un puntero constante

La dirección de un elemento de la matriz se puede expresar de dos formas:
①Añadir un signo "&" delante del elemento de la matriz, por ejemplo: & ary [2]
②Nombre de la matriz + subíndice, por ejemplo: ary + 2

Ejemplo:

#include <stdio.h>

int main()
{
    
    
	static int ary[10] = {
    
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	int i;
	int *p=NULL;
  	for (i = 0; i < 10; i ++)
	{
    
    
		printf("\ni=%d,ary[i]=%d,*(ary+i)=%d  ",i,ary[i],*(ary + i));
		printf("  &ary[i]= %X,ary+i=%X",&ary[i],ary+i);
	}
	for (p = ary; p < ary+10 ; p++)
	{
    
    	/*能否使用ary++?*/
		printf("\naddress:%x,value:%d",p,*p);
	}
	return 0;
}

Matriz como paso de parámetro

Cuando se pasan elementos de matriz unidimensionales como parámetros, pasar por valor

Cuando se pasa la matriz completa (nombre de la matriz) como parámetro, se pasa por dirección. Hay tres formas equivalentes de escritura:

void TestArray(char ary[ ]);
void TestArray(char ary[LEN]);
void TestArray(char *ary);

Matriz de enteros como valor de retorno

En resumen, si hay un grupo de parámetros real y desea cambiar el valor de los elementos de esta matriz en la función, la relación correspondiente del parámetro real tiene las siguientes 4 situaciones:
① Tanto el parámetro formal como el parámetro real use el nombre de la matriz, como:

void f(int x[],int n)
{
    
     ····
}
void main()
{
    
    
	int a[10];
	·····
	f(a,10)
}

② Utilice nombres de matriz para parámetros reales y variables de puntero para parámetros formales. Tal como:

void f(int *x,int n)
{
    
     ····
}
void main()
{
    
    
	int a[10];
	·····
	f(a,10)
}

③ Los parámetros reales y los parámetros formales son todas variables de puntero. P.ej:

void f(int *x,int n)
{
    
     ····
}
void main()
{
    
    
	int a[10]*p=a;
	·····
	f(a,10)
}

④ El parámetro real es una variable de puntero y el parámetro formal es un nombre de matriz. Tal como:

void f(int x[],int n)
{
    
     ····
}
void main()
{
    
    
	int a[10]*p=a;
	·····
	f(a,10)
}

Puntero de carácter a una constante de cadena

Puede declarar que el puntero de carácter apunta directamente a la constante de cadena, por ejemplo, char * pStr = "Bienvenido"; el puntero de carácter pStr apuntará a la constante de carácter "Bienvenido". "Bienvenido" es una constante de cadena, por lo que su valor no se puede modificar.

Puede usar punteros de caracteres para almacenar y acceder a cadenas.
Declare la sintaxis de puntero de caracteres: char * pStr;
declare string: char str [10] = "hola";
use punteros de caracteres para señalar cadenas: pStr = str;
puede usar punteros de caracteres para acceder a los caracteres String, como pStr [0] = 'a'; Este código cambia el primer carácter a'a '

void main()
{
    
    
	char* pStr;
	char str[10]="hello";
	pStr=str;
	pStr[0]='a';
	printf("pStr = %s\n",pStr);
}  ==>pStr = aello

La diferencia entre la matriz de caracteres y el puntero de caracteres

Inserte la descripción de la imagen aquí

Matriz de caracteres como valor de retorno

#include <stdio.h>
char *print()
{
    
    
	char acStr[]="hello world";
	return acStr;>返回整个数组(数组首地址)
}
void main()
{
    
    
	char *pcStr;
    pcStr = print();
    puts(pcStr);
	return;
}

Resultado:
Inserte la descripción de la imagen aquí
No se puede imprimir hola mundo. Razón:
La matriz de la función es una variable local y el sistema la borra automáticamente cuando finaliza la función. Si se devuelve una dirección en este momento, se puede acceder a los datos asignados al sistema la próxima vez, y si
se modifica la ubicación , también puede causar un gran error.

Aquí puedes ponerchar acStr[]="hello world"; 改为char *acStr="hello world";

Supongo que te gusta

Origin blog.csdn.net/qq_46485161/article/details/115035600
Recomendado
Clasificación