指针

文档属性

名称 指针
格式 zip
文件大小 56.5KB
资源类型 教案
版本资源 通用版
科目 信息技术(信息科技)
更新时间 2010-09-16 19:31:00

图片预览

文档简介

(共34张PPT)
第7章 指针
本章要点
7.1 变量的地址和指针
7.2 指针变量的定义和指针变量的基类型
7.3 给指针变量赋值
7.4 对指针变量的操作
7.5 函数之间地址值的传递
8.1 变量的地址和指针
1.变量及其地址
在C的程序中要定义许多变量,用来保存程序中用到的数据,包括输入的原始数据、加工的中间结果及最终数据。
C编译系统会根据定义中变量的类型,为其分配一定字节数的内存空间(如字符型占1个字节,整型占2字节,实型占4字节,双精度型占8字节等),此后这个变量的地址也就确定了。
程序中: int i;
float k;
计算机的内存是以字节为单位的一片连续的存储空间,每个字节有一个编号-----地址
…...
…...
2000
2001
2002
2005
内存
0
2003
i
k
编译或函数调用时为其分配内存单元
变量是对程序中数据
存储空间的抽象,每个变量的地址是指该变量所占存储单元的第一个字节的地址
地址的概念
变量的地址起到了寻找变量的作用,好象是一个指针指向了变量,所以常把变量的地址称为“指针”。
2.指针变量
若一个变量专用于存放另一个变量的地址(指针),则该变量称为指针变量。
指针的对象:当把变量的地址存入指针变量后, 我们就可以说这个指针指向了该变量。
变量的存取方法:直接存取和间接存取。
直接存取:直接根据变量名存取数据。
间接存取:通过指针变量存取相应变量的数据。
直接存取与间接存取
直接存取:按变量地址存取变量值
间接存取:通过存放变量地址的变量去访问变量
例 i=3; -----直接存取
指针变量
…...
…...
2000
2004
2006
2005
整型变量i
10
变量i_pointer
2001
2002
2003
2000
3
例 *i_pointer=20; -----间接存取
20
指针变量
…...
…...
2000
2004
2006
2005
整型变量i
10
变量i_pointer
2001
2002
2003
2000
整型变量k
例 k=i; --直接存取
k=*i_pointer; --间接存取
10
例 k=i;
k=*i_pointer;
在C程序中,变量的地址可以通过运算符“&”来得到,该运算符称为“取地址”运算符,它的运算对象是变量或数组元素,得到的结果是变量或数组元素的地址。
  例如:int a,b[10];
  &a: 得到的是变量a的地址
  &b[5]: 得到的是数组元素b[5]的地址
在C语言中,指针被广泛应用,它和数组、字符串、函数间数据的传递等有着密不可分的联系。
7.2 指针变量
7.2.1 指针变量的定义
7.2.2 给指针变量赋地址值
7.2.3 给指针变量赋“空”值
合法标识符
指针的目标变量的数据类型
表示定义指针变量
不是‘*’运算符
例 int *p1,*p2;
float *q ;
static char *name;
注意:
1、int *p1, *p2; 与 int *p1, p2;
2、指针变量名是p1,p2 ,不是*p1,*p2
3、指针变量只能指向定义时所规定类型的变量
4、指针变量定义后,变量值不确定,应用前必须先赋值
7.2.1 指针变量的定义
指针变量:专门存放地址的变量叫指针变量,指针即是指针变量的简称。
一般形式: 类型名 *指针变量名1,*指针变量名2,……;
…...
…...
2000
2004
2006
2005
整型变量i
10
变量i_pointer
2001
2002
2003
2000
指针
指针变量
变量的内容
变量的地址
指针变量
变量
变量地址(指针)
变量值
指向
地址存入
指针变量
指针变量与其所指向的变量之间的关系
指向指针的指针变量
int **p,*s,k=20;
s=&k;
p=&s;
9521
2012
4567
9521
2012
2013
p
s
k
一个指针变量可以通过以下三种方式获得一个确定的地址,从而指向一个具体的对象。
(1)通过求地址运算(&)获得地址值
一般形式:数据类型 *指针名=初始地址值;
赋给指针变量,
不是赋给目标变量
例 int i;
int *p=&i;
变量必须已说明过
类型应一致
例 int *p=&i;
int i;
例 int i;
int *p=&i;
int *q=p;
用已初始化指针变量作初值
7.2.2 给指针变量赋地址值
(2)通过指针变量获得地址值
  可以通过赋值运算,把一个指针变量中的地址值赋给另一个指针变量,从而使这两个指针变量指向同一地址。例如,若有以上定义,则语句:
  p=q;
 使指针变量p中也存放了变量k的地址,也就是说指针变量p和q都指向了变量k。
 注意:在赋值号两边指针变量的基类型必须相同。
(3)通过标准函数获得地址值
  可以通过调用库函数malloc和calloc在内存中开辟动态存储单元,并把所开辟的动态存储单元的地址赋给指针变量。
例 main( )
{ int i=10;
int *p;
*p=i;
printf(“%d”,*p);
}
危险!
例 main( )
{ int i=10,k;
int *p;
p=&k;
*p=i;
printf(“%d”,*p);
}
指针变量必须先赋值,再使用
…...
…...
2000
2004
2006
2005
整型变量i
10
指针变量p
2001
2002
2003
随机
零指针与空类型指针
零指针:(空指针)
定义:指针变量值为零
表示: int * p=0;
p指向地址为0的单元,
系统保证该单元不作它用
表示指针变量值没有意义
#define NULL 0
int *p=NULL:
p=NULL与未对p赋值不同
用途:
避免指针变量的非法引用
在程序中常作为状态比较
例 int *p;
......
while(p!=NULL)
{ ...…
}
void *类型指针
表示: void *p;
使用时要进行强制类型转换
例 char *p1;
void *p2;
p1=(char *)p2;
p2=(void *)p1;
表示不指定p是指向哪一种
类型数据的指针变量
7.2.3 给指针变量赋“空”值
2、使用 指针访问变量(所指的)
main()
{ int a;
int *pa=&a;
a=10;
printf("a:%d\n",a);
printf("*pa:%d\n",*pa);
printf("&a:%x(hex)\n",&a);
printf("pa:%x(hex)\n",pa);
printf("&pa:%x(hex)\n",&pa);
}
运行结果:
a:10
*pa:10
&a:f86(hex)
pa:f86(hex)
&pa:f88(hex)
…...
…...
f86
f8a
f8c
f8b
整型变量a
10
指针变量pa
f87
f88
f89
f86
例:
例: 输入两个数,并使其从大到小输出
main()
{ int *p1,*p2,*p,a,b;
scanf("%d,%d",&a,&b);
p1=&a; p2=&b;
if(a{ p=p1; p1=p2; p2=p;}
printf("a=%d,b=%d\n",a,b);
printf("max=%d,min=%d\n",*p1,*p2);
}
运行结果:a=5,b=9
max=9,min=5
…...
…...
指针变量p1
指针变量p
2000
2008
2002
2004
2006
指针变量p2
整型变量b
整型变量a
5
2006
9
2008
2006
2008
2006
7.3 对指针的操作
7.3.1 引用存储单元
7.3.2 移动指针
7.3.3 指针比较
7.3.1 引用存储单元
两个与指针变量有关的运算符:
&:取地址运算符。为取地址运算符,其作用是返回操作对象(变量或数组元素)的地址。
例如,“&x;”返回变量x的地址,“&a[5];”返回的是数组元素a[5]的地址。
*:指针运算符,其作用是返回以操作对象的值作为地址的变量(或内存单元)的内容。
C语言中提供了地址运算符&来表示变量的地址。
其一般形式为:
&变量名;
如&a表示变量a的地址,&b表示变量b的地址。变量本身必须预先说明。
&与*运算符
含义
含义: 取变量的地址
单目运算符
优先级: 2
结合性:自右向左
含义: 取指针所指向变量的内容
单目运算符
优先级: 2
结合性:自右向左
两者关系:互为逆运算
理解
i_pointer-----指针变量,它的内容是地址量
*i_pointer----指针的目标变量,它的内容是数据
&i_pointer---指针变量占用内存的地址
2000
10
i_pointer
*i_pointer
&i_pointer
i
i_pointer &i &(*i_pointer)
i *i_pointer *(&i)
i_pointer = &i = &(*i_pointer)
i = *i_pointer = *(&i)
…...
…...
2000
2004
2006
2005
整型变量i
10
变量i_pointer
2001
2002
2003
2000
指针变量
&、 *运算符的关系及比较
3
变量i
2000
i_pointer
*i_pointer
i
*i_pointer
&i
i_pointer
i=3;
*i_pointer=3
3
变量i
2000
i_pointer
*i_pointer
i
*i_pointer
&i
i_pointer
i=3;
*i_pointer=3
例:有以下语句:
int a=8,b,*p;
p=&a;
则赋值语句:b=*p;的含义是把指针变量p所指向的变量a的值赋给变量b。这里*P意味着取指针变量所指向变量的内容。
若将指针变量所指向的变量a中存放的数据加1之后赋给变量b,以下语句都可以表示:
①b=a+1;;②b=*p+1;;③b=*(&a)+1;;④b=*p+=1;;⑤b=++*p;。
例: main()
{ int a=7,b=8,*p,*q,*r;
p=&a;q=&b;
r=p;p=q;q=r;
printf(“%d,%d,%d,%d\n”,*p,*q,a,b);
}
输出结果:8,7,7,8
  它们都是单目运算符,优先级高于所有的双目运算符,它们的结合性均是自右向左。在使用这两个运算符需要注意以下几点:
(1)如果已经执行了“p=&a;”语句,若有 &*p
  由于“&”和“*”两个运算符的优先级别相同,但按自右向左方向结合,因此先运算*p,它就是变量a,再执行&运算。因此它等同于&a。
(2)*&a的含义是a。因为先进行&a运算,得到a的地址,再进行*运算,即&a所向的变量,因此*&a等价于a。
(3)(*p)++相当于a++。注意括号是必要的,如果没有括号,就成为*(p++),这时使指针变量本身增1,并不是使p所指的存储单元的值增1。
通过指针引用存储单元
 例如: int *p, k=4, q;
p=&i;
 则赋值语句
 q=*p;
  就是把p所指存储单元(k)的内容(整数4)赋予变量q,这里的*p代表p所指向的变量i。因此,上面的语句等价于
 q=k;
  间接访问运算符必须出现在运算对象的左边,其运算对象是地址或者是存放地址的指针变量。即*号右边也可以是地址值,如
  q=*(&k);
  表达式&i求出变量i的地址,以上赋值语句表示取地址&k中的内容赋给q。由于*和&的优先级相同,且自右向左结合,因此表达式中的括号可以省略,即
  q=*&k;
  下面的语句取指针变量p所指向的存储单元中的内容加1后赋给变量q。
  q=*p+1;
7.3.2 移动指针
移动指针就是通过赋值运算,对指针变量加上或减去一个整数,使指针变量指向相邻的存储单元。因此,只有指针变量指向一片连续的存储单元时,指针的移动才有意义。
移动指针时,系统会根据指针的基类型自动地确定移动的字节数。
…...
…...
2000
2002
2004
2006
P
…...
…...
2000
2002
2004
2006
P
p=p+1
7.3.3 指针比较
指针的比较是通过关系运算符来实现的。设p、q是指向同一数据集合的指针变量,如果p>q表达式的结果为“真”,则表明:p指针变量所指向的元素在q指针变量所指向的元素之后。
…...
…...
2000
2002
2004
2006
P
q
7.4 指针与函数
7.4.1 “传值”与“传址”
7.4.2 函数返回地址
7.4.1 “传值”与“传址”
形参为指针变量时,实参与形参之间的数据传递
若在定义函数时,函数的形参为指针变量,则调用该函数时,对应的实参必须是与形参基类型相同的地址值或已指向某个存储单元的指针变量。
例: int f(int *a,int *b)
{ int s;
s=*a+*b;
return s;
}
main()
{ int x=2,y=4,s;
s=f(&x,&y);
printf(“%d\n”,s)
}
输出结果:6
通过传送地址值,在被调用函数中直接改变调用函数中的变量值
通过传送地址,在被调用函数中对调用函数中的变量进行引用,使得通过形参改变对应实参的值有了可能,可把两个或两个以上的数据从被调函数返回到调用函数。
例: void swap(int *a,int *b)
{ int t;
t=*a; *a=*b; *b=t;
}
main()
{ int x=10,y=20;
printf(“(1)x=%d y=%d\n”,x,y)
swap(&x,&y);
printf(“(2)x=%d y=%d\n”,x,y)
}
输出结果:
(1)x=10 y=20
(2)x=20 y=10
例: void f(int y,int *x)
{ y=y+*x; *x=*x+y; }
main()
{ int x=2,y=4;
f(y,&x);
printf(“%d %d\n”,x,y)
}
8 4
7.4.2 函数返回地址
函数值的类型不仅可以是简单的数据类型,而且还可以是指针类型。其一般形式为:
  类型名 *函数名(形式参数说明列表)
 以下是几点说明:
(1)存储类型有两种,static和extern,默认为extern.
(2)“*函数名”不能写成“(*函数名)”,否则就成了指向函数的指针。
(3)此类函数的调用形式通常是:p=函数名(实际参数列表),其中p通常是调用函数中定义的一个指针变量。
例:以下函数把两个整数形参中较小的那个数的地址作为函数值传回。
int *fun(int *,int *)
main()
{ int a,b,*p;
scanf(“%d%d”,&a,&b);
p=fun(&a,&b);
printf(“a=%d,b=%d,*p=%d\n”,a,b,*p);
}
int *fun(int *x,int *y)
{ if(*x<*y) return x;
returny;
}
同课章节目录