第 15讲 指针定义和引用一、指针和地址的概念
1,内存与地址
2,指针和指针变量
3,对内存单元的访问方式二、指针的运算
1.指针变量的定义
2.指针运算符
3.指针变量的初始化
4.指针的运算三、指针变量作为函数参数
1,内存与地址
存储单元:存放一个字节数据的存储器。
存储单元的内容:存储单元内的数据。
内存地址:存储单元的编号。
一、指针和地址的概念
···
···
2007
2003
2002
2000
x = 10 ;
y =?a? ;
z = 9.8 ;
2字节
1字节
4字节
a
10
9.8
int x ;
char y ;
float z ;
例:
2,指针和指针变量
指针,就是变量的内存地址,是一个常量。
指针变量,就是存放变量内存地址的变量。
变量的指针,变量的地址。
当把某个变量 x的地址存入指针变量 p后,
我们就说这个指针变量 p的指针指向该变量 x。
指针变量 p
指向
2000
2000
变量 x
10
3.对内存单元的访问方式:
直接访问方式:
通过变量名访问。
间接访问方式:
通过变量的指针访问。
1.指针变量的定义
格式,
类型说明符 *指针变量名 1,··· ;
例,int *p1,*p2;
说明:
1)指针变量的名是 p1和 p2
若写成,int *p1,p2;
则 p2被定义为整型变量而非整型指针变量。
二、指针的运算
格式,
类型说明符 *指针变量名 1,···;
例,int *p1,*p2;
说明:
2)指针变量的类型是定义时所规定的指向变量的类型,如 p1,p2只能指向整型变量,不能指向实型和字符型变量。
格式,
类型说明符 *指针变量名 1,···;
例,int *p1,*p2;
说明:
3) 指针变量的值表示的是它所指向变量的地址 。 若一个指针变量为 0 (NULL),表示该指针为空,说明它没有指向任何变量 ( 存储单元 ) 。
2.指针运算符
取地址运算符 ──,&”
指针运算符 ──,*”
取地址运算符 ──,&”
作用,取变量的地址。
例,int i,*p1 ;
p1=&i ;
注意,不能对常量、表达式进行,&”运算 。
例,下列运算为非法的。
p2=&68;
p3=&( i + 1 );
&运算符返回操作对象的内存地址。指针变量通过 &的赋值语句,指向该操作对象。
例:
p1 = & i ; /* 将 i的地址赋给指针变量 p1*/
p2 = & chr ; /* 将 chr的地址赋给指针变量 p2*/
p1
p2 chr
i
赋值之后指针 P2指向了字符型变量 chr
赋值之后指针 P1指向了整型变量 i
指针运算符 ──,*”
作用:取指针所指向的地址空间的内容,即取指针所指向的变量的值。
例:
int i=100,*p1;
p1=&i;
printf(“%d\n”,*p1);
*运算符间接地存取指针变量所指向的变量的值例,p1 = & i ; /*将 i的地址赋给指针变量 pi*/
*p1 = 10 ; /*把 10存入 p1所指的地址( &i) 中 */
等同于语句,i = 10 ;
ip1
* p1
10& i
例 指针运算符的使用
main( )
{
int a=50,*p;
/* 声明整型指针变量 p */
p=&a;
printf("*p=%d,p=%x\n",*p,p );
/* 取指针 p所指地址的值 */
*p=100;
printf("a=%d,&a=%x\n",a,&a );
}
程序运行结果:
*p=50,p=ffe
a=100,a=ffe
例 指针运算符的使用
main( )
{
int *p1,*p2,x1,x2 ;
scanf( "%d%d",&x1,&x2 );
p1 = &x1;
p2 = &x2;
printf("*p1=%d,*p2=%d\n",*p1,*p2 );
p2 = p1 ;
printf("*p1=%d,*p2=%d\n",*p1,*p2 );
}
输入:
1 2
输出:
*p1=1,*p2=2
*p1=1,*p2=1
例 &和 *的混合运用
&和 *两个运算符的优先级相同,当混合使用时,
按自右而左的顺序进行运算定义,int a,b;
int *p1,*p2;
有,p1 = & a ;
p2 = & b;
p2 = & *p1 ;
P1
&a
P2
&b
a
b
&a
3.指针变量的初始化
格式类型说明符 *指针变量名 1=初始地址值,···;
注意:
指针变量在使用前必须要有确定的值,即指向一个变量。
例,int i,*ptr1=&i;
float *f1=0,*f2=NULL;
4.指针的运算
实质:地址的运算。
类型:
指针赋值运算:赋地址运算。
指针算术运算:
指针加 (减 )一个整数运算。
两个指针相减运算。
指针关系运算,两个指针比较运算。
I,指针 赋值运算,赋地址运算例 交换两个指针所指向变量的值。
main( )
{
int *p1,*p2,x1=10,x2=20,t;
p1=&x1; p2=&x2;
printf("*p1=%d,*p2=%d\n",*p1,*p2 );
t=x1; x1=x2; x2=t;
printf("*p1=%d,*p2=%d\n",*p1,*p2 );
printf(" x1=%d,x2=%d\n",x1,x2 );
}
程序运行结果:
*p1=10,*p2=20
*p1=20,*p2=10
x1=20,x2=10
例 两个指针变量交换指向。
main( )
{
int *p1,*p2,*s;
int x1=10,x2=20;
p1=&x1; p2=&x2;
printf("*p1=%d,*p2=%d\n",*p1,*p2 );
s=p2; p2=p1; p1=s;
printf("*p1=%d,*p2=%d\n",*p1,*p2 );
}
程序运行结果:
*p1=10,*p2=20
*p1=20,*p2=10
II,算术运算,移动指针
移动指针:对指针变量进行加上或减去一个整数、或通过赋值运算,使指针变量指向相邻的存储单元。
指针移动是以它指向的数据类型所占的字节数为移动单位。
只有当指针指向一串连续的存储单元时,指针的移动才有意义。才可以将 一个指针变量与一个整数 n做加减运算。
例,
main( )
{
int a[10]={0,1,2,3,4,5,6,7,8,9};
int n=6,*p1,*p2;
p1=p2=a;
printf(“1) *p1=%d,*p2=%d\n",*p1,*p2 );
p1=p1+n;
p2++;
printf(“2) *p1=%d,*p2=%d\n",*p1,*p2 );
程序运行结果:
1) *p1=0,*p2=0
2) *p1=6,*p2=1
--p1;
p1=p1-4;
n=p1-p2;
printf(“3) *p1=%d,*p2=%d,n=%d\n",
*p1,*p2,n);
}
程序运行结果:
3) *p1=1,*p2=1,n=0
III.两个指针的 比较运算两个指针的比较运算经常用于数组,以判断两个指针所指数组元素位置的先后。
例:
若 pi<pj,则 pi所指的地址在 pj所指的地址之前。
若 pi>pj,则 pi所指的地址在 pj所指的地址之后。
若 pi==pj,则 pi所指的地址与 pj所指的地址相同。
若 pi!=pj,则 pi所指的地址与 pj所指的地址不同。
三、指针变量作为函数参数
在 C语言中,函数参数可以是指针类型。
当指针变量作函数参数,其作用是将一个变量的地址传送到另一个函数中。
过程为:形参从实参获得了变量的地址,即形参和实参指向同一个变量,当形参指向的变量发生变化时,实参指向的变量也随之变化。
指针作为函数参数举例,
swap( int *x,int *y )
{ int temp;
temp=*y; *y=*x; *x=temp;
/* 改变形参所指向变量的值 */
}
main()
{ int a=10,b=20;
printf("1) a=%d,b=%d\n",a,b);
swap(&a,&b);
printf("2) a=%d,b=%d\n",a,b);
}
程序运行结果:
1) a=10,b=20
2) a=20,b=10
说明如下:
1)主函数:定义变量 a,b。
并初始化
2) 主函数:调用 swap( ),
将实参的值 ( 地址 ) 传递给形参,使得形参 x,y分别指向实参 a,b。
3) swap() 函数:交换形参 *x,*y的值。即 a,b的值。
a b
10 20
&ax y&b
temp
*y=b*x=a
20
1020
例 交换两个元素的值
swap( int *x,int *y )
{ int *p;
p = x; x = y; y = p;
/* 改变形参的值 */
}
main()
{ int a=10,b=20;
int *p1=&a,*p2=&b;
printf("1) a=%d,b=%d\n",a,b);
swap( p1,p2 );
printf("2) a=%d,b=%d\n",a,b);
}
程序运行结果:
1) a=10,b=20
2) a=10,b=20
说明如下:
a b
10 20
p1 p2
&a &b
yx
&a &b
&a
b a
1) 主函数:定义变量 a、
b,并初始化 。
2) 主函数:定义指针变量 p1,p2,并初始化 。
使得 p1,p2分别指向 a,
b。
3) 主函数,调用 swap( ),
将实参的值 ( 地址 ) 传递给形参,使得形参 x,y分别指向变量 a,b。
4) swap( ) 函数:交换形参 x,y的值 —地址 。 使得 x,y的指向发生改变,
由于实参对形参是单向传递,因此,形参的变化对实参没有影响 。
例 交换两个元素的值。
swap( int *x,int *y )
{ int *p;
*p=*x; /* 指针 p未赋值 */
*x=*y; *y=*p;
}
main()
{ int a = 10,b = 20;
swap( &a,&b);
printf("a=%d,b=%d\n",a,b);
}
例 用选择法将任意 10个整数按从大到小顺序排序。
main( )
{ int *p,i,a[10];
for (i=0;i<10;i++)
scanf("%d",a+i);
p=a;
sort(p,10);
for(i=0;i<10;i++)
printf("%d ",*p++);
printf("\n");
}
sort( int x[ ],int n )
{int i,j,k,temp;
for ( i=0; i<n-1; i++ )
{ k=i ;
for (j=i+1; j<n; j++)
if (x[j]>x[k]) k=j;
if ( k != i )
{ temp=x[i];
x[i]=x[k];
x[k]=temp; } }
}