cyuanyan指针

指针是C语言中一个重要的概念,也是C语言的一个重要特色。 正确而灵活地运用它,可以有效地表示复杂的数据结构; 能动态分配内存;能方便地使用字符串;有效而方便地使用数组。 掌握指针的应用,可以使程序简介,紧凑,高效。可以说,不掌握指针就是没有掌握C语言的精华。

什么是指针,数据在内存中如何存储,又是如何读取的

地址和内存的概念

  内存区的每一个字节有一个编号,这就是“地址”。如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。

直接访问和间接访问

打开一个A抽屉,有两种办法: 一种方法是 : 将A钥匙放在身上,需要时找到钥匙打开抽屉,取出东西 另一种方法:  将A钥匙放在抽屉B中锁起来。想要打开A钥匙则需要找到B钥匙打开B抽屉,拿出A钥匙,打开A抽屉。

直接访问:  a = 5;     系统在编译的时候,已经对变量分配了地址,例如,若变量的地址为2000, 则该语句的作用就是把常数 5 保存到地址为 2000 的单元。 间接访问如: scanf(“%d”,&a);    调用函数时,把变量a的地址传递给函数scanf,函数首先把该地址保存到一个单元中,然后把从键盘的数据通过所存储的地址保存到a变量中。

初始指针

在C语言中,指针是一种特殊的变量,他是存放地址的。假设我们定义了一个变量 int  *i_pointer用来存放整型变量 i 的地址。可以通过语句: i_pointer = &i ;    

将 i 的地址(2000)存放到 i_pointer中,这时 i_pointer的值就是(2000),即变量 i 所占用单元的起始地址。       要存取变量 i 的值,可以采用间接方式:先找到存放 “i 的地址”的变量 i_pointer,从中取出 i 的地址(2000),然后取出 i 的值3。             

 *:取值操作符  &:取地址操作符

如:           
int i = 2000;           
int *pointer;           
pointer = &I;           
printf(“%d\n”,*pointer); 

                        知道了一个变量的地址,就可以通过这个地址来访问这个变量,因此,又把这个变量的地址称为该变量的“指针”。        C语言中可以定义一类特殊的变量,这些变量专门用来存放变量的地址,称为指针变量。  注意: 指针变量的值(即指针变量中存放的值是地址(指针),请区分“指针”和“指针变量”这两个概念。

下面都是合法的定义:      float    *point_3 ;   //point_3 是指向float型变量的指针变量        char    *point_4 ;  // point_4 是指向字符型变量的指针变量    可以用赋值语句使一个指针变量得到另一个变量的地址,从而使它指向一个该变量。

1.指针变量前面的 “ * ”,表示该变量的类型为指针型变量,一般表示为: 类型说明符    * 变量名 ; 其中, * 表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示本指针变量所指向的变量的数据类型。    例如:  float    *point_1;    指针变量名 是  point_1 ,而不是 *point_1 ;

2.在定义指针变量时必须指定基类型。 特别需要注意的是,只有整型变量的地址才能放到指向整型变量的指针变量中,下面的赋值是错位的:   float  a;   int  *point_1;   point_1 = &a ; 将 float 型变量的地址放到指向整型变量的指针变量中,错误。

请牢记,指针变量中只能存放地址(指针),不要将一个整数赋给一个指针变量,否则编译器也会把该值当成一个地址来处理。 C语言中提供了地址运算符 & 来表示变量的地址,一般形式为: & 变量名; 如 & a  表示变量a的地址,&b 表示变量b的地址。当然,变量本身必须预先声明

Void main()
{
      int a,b;
      int  *point_1, *point_2 ;
      a = 100; b = 10;
      point_1 = & a;
      point_2 = & b;
      printf(“%d,%d\n”,a,b);
      printf(“%d,%d\n”,*point_1,*point_2);
}

如果有:          point_2 = & * point_1  ; 它的作用是将  &a(a的地址赋)赋给 point_2,如果 point_2 原来指向 b,经过重新赋值后它不再指向 b 了,而指向了a ;

. * & a 的含义是什么? 先进行 &a运算,得 a的地址,再进行 * 运算。即 &a 所指向的变量,也就是变量a. * & a 和 * point_1 的作用是一样的,它们都等价于变量 a,即 * & a  与 a 等价。

Void main()
{
     int *p1,*p2, *p ,a,b;
     scanf(“%d %d”,&a,&b);
     p1 = &a;
     p2 = &b;
     if(a < b)
    {
        p = p1; p1 = p2; p2 = p;  //此后, p1 指向 b,p2 指向 a 
    }    printf(“a = %d,b = %d \n”,a,b);  
         printf(“max = %d, min = %d\n”,*p1, * p2);
}

题目: 输入 a,b,c 三个整数,按大小 顺序输出,几次比较 ?

Void main()
{
    void exchange(int *q1,int *q2,int *q3);
    int a,b,c,*p1,*p2,*p3;
    scanf(“%d,%d,%d”,&a,&b,&c);
    p1 = &a;p2 =&b;p3=&c;
   exchange(p1,p2,p3);
   printf(“%d %d %d \n”,a,b,c);

}
Void exchange(int *p1,int*p2,int *p3)
{
   void swap(int *p1,int *p2);
      if(*p1 < *p2)
            {   swap(p1,p2); }
      if(*p1< *p3)
             {  swap(p1,p3); }
     if(*p2<*p3)
            {  swap(p2,p3);  } 
}

一个变量有地址,一个数组包含若干个元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。 指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中) 所谓数组元素的指针就是数组元素的地址。

定义一个指向数组元素的指针变量的方法,与之前介绍的指向变量的指针变量相同。 例如:           int a[10]; (定义a 为包含 10 个整型数据的数组) Int *p;    ( 定义p为指向整型变量的指针变量) 应当注意, 如果数组为 int 型,则指针变量的基类型亦应为 int 型

P  = & a[0]; 把 a[0]元素的地址赋给指针变量 p。 也就是使 p 指向 a 数组的第0 号元素

引用一个数组元素,可以用: 1.下标法, 如 a[i] 形式; 2.指针法, 如 *(a+i) 或 *(p+i)。 其中的 a是数组名, p是指向数组元素的指针变量,其初值 p = a; 注意: 数组名 即翻译成数组的第一个元素的地址。

输出数组中的全部元素,三种方法: 1.下标法,a[1],a[2],a[3]….. 2.通过数组名计算数组元素地址,找到元素的值 3.用指针变量指向数组元素

输出数组中的全部元素,第一种:下标法

Void main()
{
   int a[10];
   int I;
   for(i=0;i<10;i++)
   {    scanf(“%d”,&a[i]) ;    }
    printf(“\n”);
    for(i=0;i<10;i++)
    {  printf(“%d  “,a[i]) }
}
输出数组中的全部元素,第二种: 数组名

Void main()
{
   int a[10];
   int I;
   for(i=0;i<10;i++)
   {  scanf(“%d”,&a[i]) ;  }
    printf(“\n”);
    for(i=0;i<10;i++)
    {  printf(“%d  \n“,   *(a+i)  ) }
}
输出数组中的全部元素,第三种: 指针变量

Void main()
{
   int a[10], i ;
   int *p;
   for(i=0;i<10;i++)
    {    scanf(“%d”,&a[i]) ;  }
    printf(“\n”);
    for(p=a;  p < (a+10) ; p++)
     {    printf(“%d ”, *p ); }
}

用数组名作函数参数

f (int arr[] , int n) 但在编译时是将  arr 按指针变量处理的,相当于将函数 f 的首部写成  f (int *arr, int n) 以上两种写法等价。 C语言调用函数时虚实结合的方法都是采用 “值传递”方式,当用变量名作为函数参数时传递的都是变量的值 , 当用数组名作为函数参数时, 由于数组名代表的是数组首元素地址, 因此传递的值是 地址,所以要求形参为指针变量。

题: 将数组 a 中 n 个整数按相反顺序存放。(数组名版本)

Void reverse(int x[],int n);
Void main()
{
   int I,a[10]= {0,5,9,8,5,4,7,4,6,5,1};
   printf(“the original arry: \n”);
   for(i=0;i<10;i++)
   {    printf(“%d ”,a[i]);    }
   printf(“\n”);
   reverse(a,10);
   printf(“the array has been inverted :\n ”);
   for(i=0;i<10;i++)  
   { printf (“%d ”,a[i]) ;  }
}
Void reverse(int x[].int n)
{
    int temp , i,jm;
   m = (n- 1) / 2 ;
   for(i = 0 ;i<= m ;i++)
   {
       j = n-1-i;  //j 指向 对应的元素
       temp = x[i];
       x[i] = x[j];
       x[j] = temp;
   }   
}
题: 将数组 a 中 n 个整数按相反顺序存放。(指针版本)
Void reverse(int *x,int n);
Void main()
{
   int I,a[10]= {0,5,9,8,5,4,7,4,6,5};
   printf(“the original arry: \n”);
   for(i=0;i<10;i++)
   {    printf(“%d ”,a[i]);    }
   printf(“\n”);
   reverse(a,10);
   printf(“the array has been inverted :\n ”);
   for(i=0;i<10;i++)  
   { printf (“%d ”,a[i]) ;  }
Void reverse(int *x,int n)
{
  int *p,temp, *i,*j,m;
  m = (n-1)/2;
   i= x;   j = x+n -1;   p = x + m;
   for(i=x;i<= p ;i++, j--)
   {
         temp = * i;
         *i=*j;
         *j=temp;
   }   
}

  • 17
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值