Lenguaje C: Ensayo 5 - puntero 1

Aunque los punteros son un concepto importante, no son nada complicados. Pero él es de hecho la esencia del lenguaje C.

Usarlo de manera correcta y flexible puede expresar de manera efectiva estructuras de datos complejas; asignar memoria dinámicamente; usar cadenas de manera conveniente y usar matrices de manera efectiva y conveniente.

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

Comencemos con una hermosa historia. . . .

Por ejemplo, cuando Xiao A fue a la biblioteca a pedir prestado un libro "Soy una belleza", accidentalmente se encontró con un chico guapo en el camino, y luego Xiao A se apresuró valientemente y sacó su teléfono móvil. El chico guapo agrega el número de teléfono y la dirección, y luego el chico guapo piensa que el pequeño A realmente parece que no diría el número de teléfono de su casa. Solo dijo la dirección de su casa. Vive en la habitación 102 de un apartamento de soltero, por lo que el pequeño A lo haría Puedes acudir a él, jaja, porque el Pequeño A ya conoce la dirección de su casa, entonces esta está ligada a nuestra memoria. Sabemos que la memoria tiene dos atributos. La primera memoria es un espacio de almacenamiento lineal con dos Uno de los atributos es la dirección y el otro son los datos almacenados en la dirección. Bien, la memoria se usa para almacenar datos, al igual que nuestra dirección, cada número de casa tiene una casa y habrá muchachos guapos en la casa, que es lo mismo. Podemos indexar a una determinada memoria que queremos indexar a través de la dirección. Si no sabemos su dirección y número de casa, ¿cómo deberíamos encontrarlo y no podemos llamar a la puerta uno por uno? Por tanto, nuestra memoria tiene una dirección programada, siempre que tenga los datos correspondientes en una dirección fija. Almacenamos datos por esta dirección para indexarlos, luego sé dónde se almacenan mis cosas y sé dónde conseguir mis cosas.

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á automáticamente una unidad de memoria a esta variable cuando se compile el programa. Esto se llama variable local.

En lenguaje C, hay dos formas de acceder a las variables, acceso directo y acceso indirecto.

Un ejemplo es:

Para abrir un cajón A, existen dos métodos:

(1) Un método es llevarse la llave A y, cuando sea necesario, encontrar la llave para abrir el cajón y sacar las cosas que necesita. ----- entrevista directa

Acceso directo como: a = 5;

Cuando el sistema está compilando, a la variable se le ha asignado una dirección. Por ejemplo, si la dirección asignada de la variable a es 2000, la función de esta declaración es guardar la constante 5 en la unidad con la dirección 2000. (Dijimos que hay dos atributos en la memoria, uno es la dirección, y luego los datos almacenados en el espacio correspondiente a la dirección, luego los datos almacenados en la dirección de 2000 son 5, y esta variable se llama a.)

(2) Otro método es: por seguridad, coloque la llave A en otro cajón B y ciérrelo. Si necesita abrir el cajón A, debe encontrar la llave B, abrir el cajón B, sacar la llave A, luego abrir el cajón A y sacar el contenido del cajón A. ----- Acceso indirecto

Acceso indirecto como: scanf ("% d", & a); // La función de esta función lee una variable entera y asigna su valor a una

Cuando llamamos a esta función, pasamos la dirección de la variable a a la función scanf. La función primero guarda la dirección en una unidad y luego guarda los datos recibidos del teclado en la variable a a través de la dirección almacenada.

1. Conociendo el puntero

En lenguaje C, el puntero es una variable especial, que almacena la dirección (generalmente, la variable almacena el valor, por ejemplo, a = 5, la variable a almacena 5; pero nuestro puntero es una variable especial. Almacena direcciones, llamadas variables de puntero). Supongamos que definimos una variable de puntero, int * i_pointer se usa para almacenar la dirección de la variable entera i. Puede usar la instrucción i_pointer = & i; (obtenga la dirección de i y asígnela a la variable de puntero i_pointer)

Como se muestra en la figura anterior: Suponga que las direcciones de la variable i, la variable j y la variable k son 2000, 2002, 2004; los datos almacenados en ella son 3, 6 y 9 respectivamente; y la variable de puntero que definimos está almacenada en ella. Dirección, aquí usamos esta oración i_pointer = & i para almacenar la dirección de la variable i en B, por lo que la dirección de i se almacena en B. Las variables de puntero también son variables y las variables de matriz también son variables. Es lo mismo que las variables, excepto La variable de puntero almacena una dirección y nuestra variable ordinaria almacena un valor. Solo necesitamos usar su aplicación flexible para ser muy NB.

Almacene la dirección de i (2000) en i_point. En este momento, el valor de i_pointer es (2000), que es la dirección inicial de la unidad ocupada por la variable i. (Porque los diferentes tipos ocupan diferentes bytes en la memoria)

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", tome la dirección de i de ella (2000), y luego tome el valor de i 3. Vea la figura siguiente: si es directo, i = 3 directamente; simplemente sáquelo.

*: llamado operador de valor;

&: Se llama operador de toma de direcciones; (analizaré en detalle cómo usar estas dos operaciones más adelante, es solo el método de uso básico en la actualidad)

int i=2000;//i的值为2000
int *pointer;//我们声明一个指针pointer//此处的*号并不是取值操作符,这个是申明它为指针的一个特征
pointer=&i;//在这里取出i的地址,比如说他的地址是1000,就把他的地址给了变量pointer//这个是取址
printf("%d\n",*pointer)//那我通过这个*号,取出指向这个地址的里边的值,也就是打印出来的值应该是2000//这个才是取值操作

Conociendo la dirección de una variable, puede acceder a la variable a través de esta dirección, por lo que la dirección de la variable se llama "puntero" de la variable. El puntero apunta a una dirección. En cuanto a las variables de puntero, se define un tipo especial de variable en el lenguaje C. Estas variables se utilizan para almacenar la dirección de la variable y se denominan variables de puntero. (Entonces, las direcciones y las variables son cosas completamente diferentes).

Nota: 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)) debe distinguirse de los dos conceptos de "puntero (es una dirección)" y "variable de puntero (es una variable)".

//定义一个指针变量
float *pointer_3;//pointer_3是指向float型变量的指针变量//pomiter_3是变量名而不是*pointer_3//*号只是起到表明它是指针
//*表示定义,*可以表示声明定义一个指针,如果不在声明的情况下,它是取值操作符

// La siguiente instrucción de asignación puede usarse para hacer que una variable de puntero obtenga la dirección de otra variable, de modo que apunte a una variable. Como:

En primer lugar, nuestro pointer_1 almacena la dirección de i, por lo que apunta a la variable i; pointer_2 almacena la dirección de j, por lo que apunta a la variable j. Entonces, si existe la siguiente declaración:

pointer_1 = pointer_2; // Sirve para almacenar el contenido en la variable pointer_2 sobre el contenido en pointer_1. Entonces, en este momento, lo que se almacena en pointer_1 ya no es la dirección de i, sino la dirección de j. En este momento, pointer_1 apunta a j. Por supuesto, el puntero_2 sigue apuntando a j sin ningún cambio; es decir, ahora i está abandonado y ambos van directamente a j.

El * delante de la variable de puntero indica que el tipo de cambio es una variable de puntero. Especificador de tipo * nombre de variable;

Al definir una variable de puntero, se debe especificar el tipo base. Se presta especial atención a lo siguiente: solo la dirección de una variable entera se puede colocar en una variable de puntero que apunta a una variable entera.

Tenga en cuenta que solo las direcciones (punteros) se pueden almacenar en las variables de puntero. No asigne un número entero (o cualquier otro dato que no sea de tipo de dirección) a una variable de puntero, de lo contrario el compilador tratará el valor como una dirección.

&变量名;//地址运算符&来表示变量的地址。

2. Puntero como parámetro de función

Ingrese dos números enteros, a y b, y emita en orden de magnitud

#include<stdio.h>
//交换a,b的值
void swap(int *p1,int *p2);//行参定义的指向整数型的指针变量

void main()
{
   int a,b;
   int *pointer_1, *pointer_2;
   scanf("%d %d",&a,&b);
   pointer_1=&a;//pointer_1该指针变量指向的是a。
   pointer_2=&b;
   if(a<b)
   {
       swap(pointer_1,pointer_2);//所以实参需要传入的是????指针呢?还是指针变量。pointer_1叫做指针变量
   }
   printf("\n%d > %d\n",a,b);    
}
void swap(int *p1,int *p2)
{
   int temp;
   printf("I'm swap....\n");
   temp=*p1;
   *p1=*p2;
   *p2=temp;
}

Ingrese tres números enteros a, b, cy emita en orden de magnitud

#include<stdio.h>
//交换a,b的值
void exchange(int *q1,int *q2,int q3);//使得a>b>c。

void main()
{
   int a,b,c;
   int *p1, *p2,*p3;
   scanf("%d %d %d",&a,&b,&c);
   p1=&a;//p1指针指向a的地址
   p2=&b;
   p3=&c;
   exchange(p1,p2,p3);//与上边定义相比,是做了int *q1=p1;这个操作。(行参和实参的一个交换就相当于一个赋值操作,他们是通过栈来完成的)
   printf("%d %d %d\n",a,b,c);    
}
void exchange(int *q1,int *q2,int *q3)
{
   void swap(int *pt1,int *pt2);//用于交换
   if(*q1<*q2)//p1和q1都是指向a变量的//即如果a<b的话交换
   { 
      swap(q1,q2);
   }
   if(*q1<*q3)//a如果小于c的话c,交换
   { 
      swap(q1,q3);
   }
   if(*q2<*q3)//b如果小于c的话再交换
   { 
      swap(q2,q3);
   }

}
void swap(int *pt1,int *pt2)
{
   int temp;
   temp=*pt1;
   *pt1=*pt2;
   *pt2=temp;
}

3. Matrices y punteros

(Debido a que las matrices y los punteros apuntan a una dirección, las matrices son relativamente estables y los punteros se pueden cambiar en cualquier momento; las matrices ocupan espacio cuando se definen y los punteros son variables, y el espacio del puntero se puede eliminar en cualquier momento, y Array no puede)

Una variable tiene una dirección y un arreglo contiene varios elementos, cada elemento del arreglo ocupa una unidad de almacenamiento en la memoria (y son continuos) y todos tienen direcciones correspondientes.

La variable de puntero (la dirección de la variable almacenada en el interior) puede apuntar a la variable, por supuesto, también puede apuntar al elemento de la matriz (poner la dirección de un elemento en una variable de puntero)

El puntero al llamado elemento de matriz es la dirección del elemento de matriz.

El método para definir una variable de puntero que apunta a un elemento de matriz es el mismo que el de la variable de puntero que apunta a una variable introducida previamente.

int a[10];//定义a为包含10个整型数据的数组
int *p;//定义p为指向整型变量的指针变量 
//应当注意,如果数组为int型,则指针变量的基类型也应为int型
p=&a[2];//指针指向数组的第三个元素;把a[2]元素的地址赋给指针变量p,也就是说把p指向a数组的第2号元素。
p++;//表示

Consulte los elementos de la matriz, puede usar el método de subíndice o el método de puntero:

(1) Método de subíndice: la forma de una [i];

(2) Método de puntero: * (a + 1) o * (p + i); // Como a es la dirección del primer elemento, la adición de i significa que apunta al i-ésimo elemento, no a la dirección más i , Porque depende de qué tipo.

Donde a es el nombre de la matriz, p es una variable de puntero que apunta al elemento de la matriz, y su valor inicial p = a es p = & a [0];

Nota: El nombre de la matriz (compilado en una dirección en el compilador) es "la dirección del primer elemento de la matriz compilada" (esta es la similitud mencionada anteriormente).

Use nombres de matriz como parámetros de función --------

Como:

void f(int arr[],int n)
{
    ......
}
void main()
{
   int arr[10];
   ... ...
   f(arr,10);//数组名相当于该数组的首地址
}

En lo anterior, f (int arr [], int n), arr se procesa como una variable de puntero en tiempo de compilación, lo que equivale a escribir la primera parte de la función f como f (int * arr, int n) por lo que los dos métodos de escritura anteriores Son equivalentes.

Cabe señalar que el método de combinar virtual y real cuando se llama a una función en lenguaje C usa la transferencia de valor. Cuando se usa un nombre de variable como parámetro de función, se pasa el valor de la variable; cuando se usa un nombre de matriz como parámetro de función, debido al nombre de matriz Representa la dirección del primer elemento de la matriz, por lo que el valor que se pasa es la dirección, por lo que se requiere que el parámetro formal sea una variable de puntero.

Ejemplo: Almacene n enteros en la matriz a en orden inverso.

#include<stdio.h>
void reverse(int x[],int n)//形参x是数组名
void main()
{
   int i, a[10]={3,5,7,8,1,0,2,6,9,4};
   printf(" The original array:\n");
   for(i=0,i<10,i++)
   {
       printf("%d",a[i]);
   }
   printf("\n");
   reverse(a,10);
   printf("The Array has been inverted:\n");
}
void reverse(int x[],int n)
{
   int temp,i,j,m;
   m=(n-1)/2;
   for(i=0;i<=m;i++)
   {
      j=n-1-i;
      temp=x[i];
      x[i]=x[j];
      x[j]=temp;
   }
}

Cambie el parámetro de una función con un puntero:

#include<stdio.h>
void reverse(int *x,int n)//形参x为指针变量
void main()
{
   int i, a[10]={3,5,7,8,1,0,2,6,9,4};
   printf(" The original array:\n");
   for(i=0,i<10,i++)
   {
       printf("%d",a[i]);
   }
   printf("\n");
   reverse(a,10);
   printf("The Array has been inverted:\n");
}
void reverse(int *x,int n)//形参x为指针变量
{
   int *p,temp,*i,*j,m;
   m=(n-1)/2;//中间序号
   i=x;//前边的序号//i指向数组的第一个元素
   j=x-1+n;//后边的序号//j指向数组的最后一个元素
   p=x+m;//指向中间配对
   for(;i<=p;i++,j--)
   {
      
      temp=*i;
      *i=*j;
      *j=temp;
   }
}

Utilice punteros como parámetros ------

Ejemplo: Encuentre los valores máximo y mínimo de 10 números.

#include<stdio.h>
int max,min;//全局变量
void max_min_values(int array[],int n);
void main()
{
   int i,number[10];
   printf("Enter 10 integer numbers:\n");
   for(i=0;i<10;i++)
   {
       scanf("%d",&number[i]);
   }
   max_min_values(number,10);
   printf("\nmax=%d,min=%d\n,"max,min);
}
void max_min_values(int array[],int n)
{
   int *p,*array_end;
   array_end=array+n;
   max=min=*array;
   for(p=array+1;p<array_end;p++)
   {
      if(*p>max)
      {
          max=*p;
      }
      else if(*p<min)
      {
          min=*p;
      }
   }

}

Resumen: si hay una matriz y desea cambiar el valor de los elementos de esta matriz en una función (subrutina), existen cuatro tipos de relaciones correspondientes que realmente participan en los parámetros formales:

(1) Tanto los parámetros formales como los reales utilizan nombres de matriz:

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

(2) El parámetro real usa el nombre de la matriz y el parámetro formal usa la variable de puntero. Como:

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

(3) Tanto los parámetros reales como los parámetros de línea utilizan variables de puntero. Como:

void main()
{
   int a[10];
   int *p=a;//指针变量p指向数组的首地址
   f(p,10);//传指针相当于传a数组的地址
}
void f(int *x,int n)//int *x指针相当于指向a的地址,相当于传值的时侯x=p,p指向a那么x也指向a
{
   ......
}

(4) El parámetro real es una variable de puntero y el parámetro de fila es un nombre de matriz. Como:

void main()
{
   int a[10];
   int *p=a;
   f(p,10);//1这里把数组的首地址当作实参传过去,
}
void f(int x[],int n)//2定义数组来接收首地址,说明位置起始点一样指向了同一组数组。
{
   ......
}

Ejemplo: organice los elementos en una matriz en orden descendente.

#include<stdio.h>
int max,min;//全局变量
void sort(int array[],int n);
void main()
{
   int *p,i,a[10]={3,7,4,9,2,0,5,8,1,6};
   printf("The origial array:\n");
   for(i=0;i<10;i++)
   {  
         printf("%d",a[i]);
   }
   printf("\n");
   p=a;
   sort(p,10);
   printf("The result is:\n");
   for(p=a;i=0;i<10;i++)
   {
       printf("%d",*p);
       p++;
   }
   printf("\n");
}
void sort(int x[],int n)
{
   int i,j,k,t;
   for(i=0;i<n-1;i++)
   {
      k=i;//假设第一个是最大的,如果接着的那个比他大那就把他调过来
      for(j=i+1;j<n;j++)
      {
         if(x[j]>x[k])
            {
                t=x[j];
                x[j]=x[k];
                x[k]=t;
            }
      }
   }

}

 

Supongo que te gusta

Origin blog.csdn.net/m0_37957160/article/details/108512339
Recomendado
Clasificación