第9章 第1课

本课主题: 变量的指针与指向变量的指针变量

教学目的: 掌握指针的基本概念,掌握特殊类型的变量:指针变量的特殊性。掌握指针变量作函数参数的特殊作用。

教学重点: 指针的概念。指针变量的作用。

教学难点: 指针的概念。值传递与地址传递的区别。

授课内容:

一、什么是指针?

  计算机存储数据都是按先后顺序存储在存储器中的。程序运行时,数据存储在内存中,内存划分为若干字节,相当于电影院内有若干座位,为了便于存取数据,我们把内存编上号,每个字节为一个单元,这就是内存地址,它可以唯一的确定内存中的字节。就象电影院中的座位号,每个座位号对应一个座位,根据座位号我们可以确定对应的座位在电影院中的位置。

  一个内存单元的地址和内存单元的内容是两个不同的概念。就象3排2号是一个座位的地址,而上面座的是一位23岁的男同志。下面第2000字节是内存单元的地址,里面存放的内容是字符'a'。(注意:不同类型的数据占用的内存单元数不同。)

内存地址 内存用户数据区
...
2000 a 变量char c
2001 (两字节) 3 变量int i
2003 (两字节) 6 变量int j
...
3010 (两字节) 2000 变量int* cp (指针变量)
..

  指针即是地址。它能确定数据在内存中的存储位置。

二、指针的作用

  前面我们学习的存取数据的方法都是通过变量进行的,例如我们为了存储一个班级的学生人数,要定义一个变量,然后向该变量赋值。当需要这个值时,再通过这个变量的名称取出数据:

main()
{
    int stunum;
    stunum=54;
    printf("%d this class has %d students.",stunum);
}

  我们存取内存中的数据,除了上面的通过变量名称直接存取的方式外,还可以通过指针间接存取:

/*e09-01.c*/
main()
{
  char d,e,f;
  *((char *)0xFFCE)='z'; 
           /*这里我们选用的地址在数据区偏后的位置,它可能是某个变量的存储空间*/
  d=*((char *)0xFFCE); 
          /*如果这个地址刚好是代码区,对该地址的赋值可能造成系统的崩溃,
本例只是演示直接存取的方法,请不要用于其它目的*/
  printf("%c ",d);
}
/*----------
result:
z
*/

三、什么是变量的指针?

  变量的指针就是变量的地址。我们可以先取得变量的地址,然后用该地址直接存取该变量的内容。

  如何取得变量的地址呢?通过&(取地址运算符)即可。

  取到该变量的地址后,如何通过指针存取该变量的内容呢?通过*(指针运算符)即可。见下例:

/e09-02.c/
main()
{ int a;
int p_a;
p_a=&a; /
这样做就取得了a变量的存储地址了,现在变量p_a中放的就是a变量的地址/
p_a=3; /注意:''号是指针运算符,或称间接访问运算符,这个语句把3这个数据存放到p_a变量所指示的地址中,即存放到了变量a中。现在变量a的值为3/
printf(“%d",a); /
请运行这个程序查看结果*/
}

四、用指针变量来存储变量的指针

  指针变量是专门存储地址值的变量,因为不同类型的变量占用的存储空间大小(字节数)不同,因此为区别所存储的地址是何种类型的数据,通过定义指针变量的类型来达到此目的。不论何种类型的指针变量,其自身占用的存储空间是相同的。

main()
{
    int i;
    float f;
    int *p_i; /*定义指针变量的形式:在变量名前加'*'号 */
    float *p_f;
    p_i=&i;
    p_f=&f;
}

五、用指针变量来引用其它变量

/*e09-03.c*/
main()
{
  int a,b;
  int *p_1,*p_2;
  a=100;b=10;
  p_1=&a;
  p_2=&b;
  printf("%d,%d\n",a,b);
  printf("%d,%d\n",*p_1,*p_2);
}
/*----------
result:
100,10
100,10
*/

六、我来试一试

  改动上例,通过指针变量p_1,p_2来交换变量a,b的值,交换后a的值为10,b的值为100。

七、要注意的问题

  1、指针与地址的概念

  2、指针变量与变通变量的区别与联系。

八、函数参数的作用

  复习一下函数的形参与实参,回忆形参与实参的对应关系。

  函数参数的主要作用是通过形参与实参的对应关系,在程序运行中通过把实参的值传递给形参在函数内部根据形参值做相应的处理,并把处理结果通过函数返回值带回。

九、传值与传地址

  普通变量作函数实参,只能将变量的值传递给形参,形参接受的是实参变量的值。形参作为局部变量,自身的值在函数内部的变动不会影响对应的实参,也就是说进入函数内部后,实参变量不会受函数内部代码的影响。这就是参数传递的方式之一:值传递。C语言采用的参数传递方式就是值传递。其它有些语言则不是。

  简单地说,C语言中,只是把实参的值传递给形参,两者之间没有固定的联系。

  下面举个例子说明:

  假设我们想写一个函数用来交换两个变量的值如下:

  在swap函数中交换了两个形参变量的值。没有问题。

  在主函数中把x,y作为实参,想用swap函数改变它们的值。并没有达到目的。因为调用时系统只是把实参的值传递给形参,进入被调函数后不再保持它们之间的联系了。

chapter09-01.gif

  那我们的想法能不能实现呢?请向下看。

十、指针变量做参数传的是值还是地址?

  如果我们能把实参的地址传递给被调函数,在被调函数中利用形参接收的实参地址进行间接存取就可以达到目的了。

chapter09-02.gif

  要注意这里的参数传递方式仍是值传递方式,只不过实参的值是其它变量的地址而已。不能说C语言的参数传递也有地址传递方式。倒可以说上面的参数传递 传的是地址。

十一、传地址的意义何在?

  我们看到上例中通过传递变量的地址就可以在被调函数中改变主调函数中的局部变量值了。这样我们就多了一种在主、被调函数之间进行通讯的一种方法。

  如果想通过被调函数传回更多的操作结果,当然可以用上面的方法啦。

十二、我来试一试

  写一个函数,能将主调函数中的三个局部整型变量的值分别加上1,2,3。

十三、要注意的问题

  1、指针变量作函数参数的重要意义

  2、值传递与地址传递的区别

十四、作业

标签: C程序设计, C语言, 指针

评论已关闭