第8章指针

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

}
order(int *a , int *b ) { if (*a>*b) swap( a , b ) ; } main( ) { int x, y ; printf(“Enter x y : “ ) ; scanf(“%d%d”, &x, &y ) ; printf(“x=%d y=%d “ , x, y ) ; order(&x , &y ) ; printf(“x=%d y=%d\n” , x , y ) ; } 执行程序
指针是地址常量,但千万不要将一整型常量赋给一个指针变量。
如:p=1101
是错误的。
8.4 对指针变量的操作
8.4.1 通过指针来引用一个存储单元
间接访问运算符(指针运算符):* int *p , I=10 , j ; ( *p 代表 I ) ( 或 j=I ; 或 j=*( &I ) ; 或 j=*&I ; ) * 是单目运算符
8.3.2 给指针变量赋“空”值
#include ︰ int *p ; p=NULL ; ( 或 p=„\0‟ ; 或 p=0 ; ) ∵NULL的代码值为0 “stdio.h” NULL是在stdio.h头文件中定义的预 定义符,∴要有此命令
注意:p称为空指针;
指针p并不是指向地址为0的存储单元,而是具有一个确定的值---“空”
8.5 函数之间地址值的传递
8.5.1 形式参数为变量指针时,实参和形参之间的数据传递
例 8.2 编写函数myadd ( int *a , int *b ) ,函数中把指针变量a和b所的 存储单元中的两个值相加,然后将和值作为函数返回值。 myadd ( int *a , int *b ) { int sum ; sum=*a+*b ; return sum ; } main( ) { int x , y , z ; printf ( “Enter x , y :” ) ; scanf (“%d%d”,&x,&y) ; z=myadd(&x,&y) ; printf ( “%d + %d = %d \n”,x,y,z ) ; } 执行程序
指针变量的定义和指针变量的基本类型
定义指针变量的一般形式如下:
类型名
*指针变量名1,*指针变量名2,… ①*:是说明符,用来说明该变 量是指针变量。
如:
int
*p1 , *p2 ;
②p1 、p2是两个指向整型变量的 指针,也就是说,变量p1 量 p2中只能存放int类型变 的地址。 指针类型(*)
double
*p3 ; 定义指针变量有两个类型:
char
*p4 ;
基类型
int
**p , * s , k=20 ;
s = &k ; p = &s ;
指针变量 p:( 即指向指针的指针变量)内 部只能存放基类型为int 类型的指 针变量的地址。 指针变量 s:内部只能存放某整型变量的地址。
s 指向存储单元k k=88 ; 等价
2、通过指针变量获得地址值
int *p , *q , k=22 ; q=&k ; p=q ; ( 把一个指针变量中的地址值赋给另一个指针变量, p与q 都指向变量k)
注意:当进行赋值运算时,赋值号两边的指针变量的基类型必 须相同。
3、通过标准函数获得地址值 (第13章介绍) 通过调用库函数malloc和calloc在内存中开辟动态存 储单元,并把所开辟的动态存储单元的地址赋给指针变 量。
p=p+3 ;
printf((“%d “ , p-a ) ; 结果: 3 ( 不是 3 ×2 ) ( 是合法的)
8.4.3 指针比较
if ( p<q ) printf ( “ p points to lower memory than q.\n”);
if ( p==„\0‟ )
printf (“
“) ;
t=*a ; *a=*b ; *b= t ; printf ( “③a=%d b=%d\n”,*a,*b) ;
}
执行程序
例 8.4 编写函数order(int *a , int *b ) , 使调用函数中的第一个实参总是 存放两个数中的最小数。第二个参数存放两个数中较大的数。 swap ( int *x1 , int *x2 ) { int t ; t=*x1 ; *x1=*x2 ; *x2=t ;
8.5.2 通过传送地址值,在被调用函数中直接改变调用函数中的变量的值。 例 8.3 调用swap函数,交换主函数中x和y中的数据。
main( ) {int x=30 , y=20 ; printf(“①x=%d y=%d \n”,x,y) ; swap(&x,&y) ; printf(“④x=%d } swap (int *a , int *b ) { int t ; printf ( “②a=%d b=%d\n”, *a , *b ) ; y=%d\n”,x , y ) ;
55
a[5]
66
(q指向33 ) (q指向44 ) ( q指向55 ) (q指向44 )
增1:使指针指向地址值大的方向移动一 个单元 指针的基类型是int : 自动移 2字节 存储单元 指针的基类型是float :自动移4字 节 指针的基类型是double :自动移 8
当指针指向一串连续的存储单元时,可以对指针变量进行加上或减 去一个整数的运算,也可以只对同一串连续存储单元的两个指针进行相 减的运算,除此之外,不可对指针进行任何其它的算术运算。 int a[6]={1,3,6,8,9} , *p=a ;

p
1012 2002
a
1012
1013
指 针 :将一个变量的地址称为该变量的指针。如:变量a的地址是:1012 (指针是地址的形象化名称) 变量a的指针是:1012
指针变量:用来存放指针(即地址)的变量就称为“指针变量”。如p就 是 指针变量。 变量p指向变量a 指针变量p中存放变量a的地址
8.2
(*p)++ :括号不可少,使 p所指存储单元中的值增1。
*(p++):该表达式的值是p所指存储单元中的值(大小并 没有变化,在此为100),然 后使p本身增1(p 所指存储 单元中的值没有变化)。
例 8.1 用指针指向两个变量,通过指针运算选出值小的哪个数。
main ( ) { int a , b , min ; int *pa , *pb ,*pmin ; pa=&a ; pb=&b ; pmin=&min ; scanf ( “%d%d” , pa,pb) ; printf (“a=%d b=%d \n” , a , b ) ; *pmin=*pa ; if ( *pa>*pb ) *pmin =*pb ; printf(“min=%d\n” ,min ) ; }
第八章 指 针
8.1 变量的地址和指针
内存地址: 计算机的内存是以字节为单位的一片连续的存储空间, 每一个字节都有一个编号,这个编号就称为内存地址。内存的存储空间是 连续的,内存中的地址也是连续的,并且用二进制数来表示,为了直观起 见,在这里我们将用十进制数进行描述。 若在程序中定义了一个变量,C编译系统就会根据定义中变量的类型, 为其分配一定字节数的内存空间: int a;
执行程序
8.4.2 移动指针
移动指针:对指针变量进行加上或减去一个整数、或通过赋值运算, 使Fra Baidu bibliotek针变量指向相邻的存储单元。因此。只有当指针指向一串连续的存 储单元时,指针的移动才有意义。
a[0]
11 p q=p+2 ; q++ ; q++ ; q-- ;
a[1]
22
a[2]
33 q
a[3]
44
a[4]
p=&I ; j=*p ;
*的运算对象是存放地址的指针变量
*的运算对象是地址
注意:运算符*和&的优先级相同,“右结合性”,因此 *(&I ) 等价 *&I 也即 *&I 等价 I
X=X ;
(x 出现在赋值号左边和右边所代表的含义是不同的)
int *p ,k=100 ;
p=&k ;
*p=*p+1 ; k=101 在赋值号左右两边的*p,其含义也是不同的:取指针变 量p所指向的存储单元中的值,加1后再放入p所指向的 存储单元中。 等价 *p+=1 ; 或 ++*p ;或 (*p)++ ;
printf(“I=%d , j=%d , *p=%d\n” , I,j, *p) ;
}
int *fun(int *a , int *b ) { if (*a>*b) return a ; return b ; } 执行程序
( *s 代表存储单元k ) *s=88 ;
P 指向存储单元 s (*p 代表存储单元 s ) ( **p代表单元 k ) p s k
2000
1000
3000
2000 3000 3001
8.3 给指针变量赋值
8.3.1 给指针变量赋地址值 (一旦获得一个确定的地址值,该指针变量就指向一个具体的对象) 1、通过求地址运算(&)获得地址值 int k=1 , *q , *p ; &;取变量地址运算符
8.5.3 函数返回地址值
例 8.5 以下函数把两个整形参数中较大的哪个数的地址作为函数值传回。 int *fun(int * , int * ) ; main( )
{int *p , I , j ;
printf(“Enter tow number: “) ; scanf(“%d%d”,&I,&j); p=fun(&I,&j) ;
q=&k ;
*:指针变量运算符
①把变量k的地址赋予了q(即q指向了变量k ) ; ②求地址运算符&只能应用于变量和数组元素,不可用于表达式、常 量 或被说明为register的变量(第12章介绍);∴ q=&(k+1)错 &必须放在运算对象的左边,而且运算对象的类型必须与指针变 量的基类型相同。 q=&k ; scanf ( “%d” , &k ) ; 等价 scanf ( “ %d “ , q ) ;
1012 1013
float
x;
1201 1202 1203 1204
注意: 每个变量与具体地址的联系由C编译系统来完成,用户无需关心。
直接存取方式:直接按变量的地址存取变量值的方式称为直接存取方式。 间接存取方式:先找到变量P的地址(2002),从中取出变量a 的地址 (1012),然后再去访问以1012为首地址的存储单元,这种 通过变量p间接得到变量a 的地址,然后再存取变量a 的值 方式称为间接存取方式。
相关文档
最新文档