一;学习目标如下

1.学习角度

  • 指针是什么
  • 为什么要学习指针
  • 如何使用指针

2.本章重难点

      指针的使用与理解

  • 本节要点
  1. 指针是地址,指向某一变量单元(在进行程序编译时根据定义的变量类型为变量分配的内存单元(每个字节单元都有一个编号))

   注意:C中的地址包括位置信息(内存编号,或称为纯地址)和它所指向的数据的类型信息

对变量的访问都是通过地址访问的访问方式:

       (1)直接访问(通过变量名进行访问)

       (2)间接访问(通过变量的地址进行访问)

  1. 为什么要使用指针(有哪些优点)?

   (1)指针的使用使得不同区域的代码可以轻易的共享内存数据

当然也可以通过数据的复制达到相同的效果,但是这样往往效率不太好。指针节省 内存主要体现在参数传递上,比如传递一个结构体指针变量和传递一个结构体变 量,结构体占用内存越大,传递指针变量越节省内存的,也就是可以减少不必要的 数据复制

(2)C语言中一些复杂的数据结构往往需要使用指针来构建,如链表、二叉树等

(3)有些操作必须使用指针完成
①如:操作申请的堆内存。
②又如:C语言中的一切函数调用中,值传递都是“按值传递”的。如果要在函数 中修改被传递过来的对象,就必须通过这个对象的指针来完成。(如对一个函数传 入一个x一个y,交换两者的值,如果只是按值传递,那在函数内交换并不影响函 数外的x和y,而指针则可以做到)

(4)动态分配内存
大多数情况下,可以看到程序使用的内存是通过显式声明分配给变量的内存(也就 是静态内存分配)。这一点对于节省计算机内存是有帮助的,因为计算机可以提前 为需要的变量分配内存。但是在很多应用场合中,可能程序运行时不清楚到底需要 多少内存,这时候可以使用指针,让程序在运行时获得新的内存空间(实际上应该 就是动态内存分配),并让指针指向这一内存更为方便。

(5)函数多个返回值
可以用指针(或者结构体?)

(6)指针和数组的效率问题(不太清楚缘由)
需要遍历数组或频繁引用其元素时, 这样效率比使用下标高.

  1. 如何使用指针?
  • 指针变量:仅存放地址的变量,可用来指向其他对象(如变量、数组、函数等)

           I.定义格式: 类型名(基类型) *变量名

      II.说明变量类型:指向某(基类型)数据的指针变量

III.如何使用:

(1)指针指向变量时

赋值(将某一变量的地址赋值给指针变量)

                int a;       

               int *p1;     

                p1 =  &a; 

引用指针变量指向的变量(按某一种格式输出或者改变其值)

     int a;                   

    scanf_s("%d",&a);

    int *p1;                

    p1 = &a;             

    printf("%d",p1);  

    *p1=2;                

注意:(1)两个重要的运算符

  1. &:取地址运算符。如&a:变量a的地址
  2. *:指针运算符。(也被称为解引用操作)如:*p

补充:二者的运算优先级是一样的,所以说在组合运算时是按照从右向左的方向进行结合的

例子:&*p(最终取的为地址);  *&a(最终取得为a的值)

实际应用实例:

用指针来实现两个数的大小比较并按照从大到小顺序输出

方法一:可以通过函数(用指针)来实现两个数值的互换

方法二:也可以通过交换指针的指向(如果3个数,可以考虑用方法一)

 #include<stdio.h>               

  int main(void)                      

  {                                           

    int a,b;                               

    scanf_s("%d",&a,&b);       

    int *p1,*p2,*p3;                 //定义了三个指针变量

    int t;                                  

    p1 = &a;                           

    p2 = &b;                        

  if(*p2>*p1)/                  /方法一:通过交换指针变量指向的地址来实现两个数的互换,变量内容不变

    {                                  

     p3=p2;                     

     p2=p1;                     

     p1=p3;                     

    }                                 

printf("%d%d",*p1,*p2);

   if(*p1<*p2)                    方法二:通过交换指针变量指向变量的内容来实现 也可以设计一个函数来实现此功能

   {                                    

     t=*p1;                        

     *p1=*p2;                    

     *p2=t;                         

   }                                    

   printf("%d%d",*p1,*p2);

       return 0;                    

补充:如果是在交换值的情况下,不能够用第三个定义的指针变量,因为不知它指向谁(无确定的值)有可能其中存储着有用的数据,如果改变,可能会影响系统的正常工作状态                       

  • 指针指向数组时
  1. 引用数组元素的方法:下标法(如s[2])  和  指针法

                                           如*(p+i)和*(s+i)

  1. 指针法的优点:目标程序效率高(占用内存少、运行速度快)

    下标法的优点:更加直观,能直接知道是第几个元素

注意:数组名和指针的值均是指向首元素的地址,并非指向所有的数组元素地址

  1. 指针的算术运算

      当指针指向数组元素时并且指针变量的基类型和数组元素一样时,指针加一或指针减一,会根据定义的指针变量的基类型进行移动,在读取数据时也是根据其基类型进行的

    #include<stdio.h>                

    int main(void)                        

    {                                              

       int s[10];                              

       int i;                                     

       int *p1;                                

       p1 = s;                                

      *(p1+5)<=>*(s+5)<=>s[5]  

       return 0;                             

    }                                             

补充:[]为变址运算符,即将s[i]按照s+i计算地址,然后找出地址中的值,地址相加无意义

格外注意:(1)数组名虽代表地址,但其为指针型常量,其值固定不变,不可对其进行自增和自减操作

                  (2)在编写程序时,一定要注意指针的当前指向

  1.    * 与++与--的用法如下:

   * 、++、--三者的优先级一致,运算方向为从右向左,一定要注意

使用说明:(1)行地址前加*变为列地址 如*(a+i),其指向的是a[i][0]的地址

              列地址前加&变为行地址 如&a[0],a[0]等价于*a,其前加个取地址符,变为列地址

(2)a[i]与*(a+i)等价(二维数组中)在一维数组a[i]代表的是第i+1个元素的值

  • *(p++)与*(++p)二者的作用不同,前者先取*p值然后再使p加1;后者则是先使p+1,然后再取其内容  ++(*p)先取*p指向的内容,后使内容加1;
  • *(p++)<==>a[++i]   *(--p)<==>a[--i]
  • 在二维数组中,*(a+i)、a[i]、a[i]+0 均指向第一行0列地址

(3)用数组名作为函数参数

     数组名实际上就是数组首元素的地址,而指针指向的也是地址,故二者可以互换使用,有四种组合方式,如下:

      实参    数组名  指针变量  数组名   指针变量

     形参    数组名  指针变量  指针变量    数组名

注意:如果指针变量作实参,必须先使指针变量有确定值,指向一个已定义的对象