dfc6
- 格式:pps
- 大小:549.00 KB
- 文档页数:49
共49 页第1页第6章指针大连理工大学
共49 页第2页本章要点1. 理解指针与地址的概念;2. 掌握指针的定义和运算;3. 掌握指向基本类型、数组、字符串的指针的使用;4.充分理解指针和数组的等价性;
共49 页第3页预备知识内存:就是内部存储器,是由存储单元组成的。它的特点是存储单元是线性连续的。存储单元的最小单位是字节。1. 内存的概念
共49 页第4页地址:为了访问内存中的某个存储单元,我们要为它编号,这种编号称为内存地址。通过地址我们就能够访问该地址所标识的存储单元。2. 地址的概念共49 页第5页变量的地址:变量的地址是变量在内存中占用连续字节的首地址。2007存储单元
共49 页第6页以往对变量的访问:•定义变量: int k;编译系统根据类型为k分配内存。•输入变量的值:scanf(“%d”,&k);&k就代表了变量k在内存中的地址。•通过变量名访问变量,这种操作称为直接访问:通过指针间接访问:•C提供了另一种方式,将变量k的地址存放在另一个变量处(假定为pk),通过访问pk,就可以间接地访问变量k,这种方式称为间接访问。变量的存取方法:直接存取和间接存取。
共49 页第7页引入指针程序设计的优点1.有效表示复杂的数据结构。2.方便使用字符串、数组。3.可以得到多个返回值。4.可以进行动态分配内存。5.程序简洁、紧凑, 执行效率高。
共49 页第8页6.1.1 指针的基本概念指针:一个变量的地址称为该变量的指针。指针变量:若一个变量专用于存放另一个变量的地址(指针),则称此变量为指针变量。若指针变量p的值等于变量x的地址, 则说指针变量p指向变量x。1000351000pxx的值p的值X的内存地址6.1 指针和指针变量共49 页第9页指针的对象:当把变量的地址存入指针变量后,就可以说这个指针指向了该变量。共49 页第10页6.1.2 指针变量的定义指针变量定义的一般形式:类型标识符*标识符[例]:int *p1;float *p2;作用:定义变量为指针类型,使之专门用于存放地址。指针所指的变量的类型指针变量名共49 页第11页说明:(1)“*”用于定义指针变量,但指针变量名不带*。如: int *p1; float *p2;定义的指针变量为p1,p2。(2) 一个指针变量只能指向同一类型的变量。如: p1 只能用于指向整型变量p2 只能用于指向实型变量(3)无论指针变量指向何种类型,指针变量本身都是整型的,指针变量本身也有自己的地址,占两个字节的存储空间。
共49 页第12页1.取地址运算格式: &变量给指针变量赋值:指针变量=地址表达式例如:设有变量说明int a, b, *p, *q;p=&a;把a的地址赋给p,使p指向aq=p;让q也指向a,使p、q都指向ap=&b;让p指向b,使q指向a,p指向b6.2 指针变量的引用和运算C语言提供两种与指针有关的运算符:& *
共49 页第13页2.取内容运算格式:* 指针表达式设p是一个指针表达式,则:(1)若*p出现在赋值号左边,表示给p所指变量赋值(2)若*p不出现在赋值号左边,表示p所指变量的值例如:若有变量说明int a, *p ; p=&a; 让p指向变量a*p=10; 等价于a=10printf(“%d”, *p); 打印p所指变量的值scanf(“%d”, &a); 给变量a输入值scanf(“%d”, p); 给变量a输入值*p+25 等价于a+25
共49 页第14页3. 为指针变量赋初值指针变量使用前必须有值指针变量的初值必须是地址值(不能是整数)方法:(1)在说明指针变量时同时初始化int a,*p = &a;(2) 使用赋值语句赋值int a,*p;p =&a;可以为指针赋空值(NULL),此时指针不指向任何变量, 如p=NULL;或p=„\0‟; p=0;共49 页第15页对*及&的说明:(同级运算,由右向左)若pa=&a (将a 的地址送指针变量pa), 则•&*pa&(*pa)&(a)&a•*&a *(&a)*pa a•(*pa)++ a++•*pa++ *(pa++)注意:此时pa不再指向a
共49 页第16页如定义i_pointer为指针变量,i_pointer=&i;如何访问?(1)先找到存放i的地址的单元地址(3010,3011);(2)取出i的地址(2000);(3)到2000,2001中取出i的值3 32000变量i_pointer内存用户数据区…...69…...32000变量i变量j变量k20002002200430102000i
共49 页第17页[例6-1] 输出变量的值。main( ){int a,b;int *pa, *pb; a=100; b=10;pa=&a; pb=&b; printf(“%d,%d\n”, a,b);printf(“%d,%d\n”, *pa,*pb);}定义指针变量pa,pb将a的地址送pa将b的地址送pb输出所指向的变量的值运行结果为100,10100,10共49 页第18页例:将两个整型数a,b按由大到小次序输出。[例6-2]main( ){ int *p1, *p2, *p, a, b;scanf(“%d,%d”, &a,&b); p1=&a; p2=&b;if(a
共49 页第19页&b5p1a9&ap2b&b9p2b函数调用过程如下图所示:&a5ap1p1p2指针交换注意:a和b并未交换,但p1和p2的值交换了
共49 页第20页在C语言中,凡是可以通过数组下标方式完成的访问(操作)均可以通过指针方式实现。称为指针方式.6. 3 数组与指针数组中的每个元素都可以通过下标唯一确定,即通过下标可以访问(操作)数组中的元素,称为下标方式。访问数组的两种方式:下标方式,指针方式C语言规定:数组名就是数组的首地址常量.于是:a==&a[0]
共49 页第21页int a[5], *p=a; 使p指向a数组的第一个元素a[0]各元素的指针按存储单元递增对下标为i的元素访问:对a[i]的地址表示:a[i], p[i] ,*(a+i), *(p+i) &a[i], &p[i],a+i, p+i 指向数组1.指针与一维数组的对应关系2.用指针访问数组的一般形式6.3.1 指针变量与一维数组之间的联系*(指针变量+i) *(数组名+i) 指针变量[i] 数组名[i]a[0]a[2]a[4]a[3]a[1]memorypP+1P+2P+5
共49 页第22页p, ap+1, a+1p+9, a+9p+i, a+ia[0]a[1]a[2]a[i]a[9]a数组例如:int a[10], *p;p=a; *(p+i)
共49 页第23页1.指针表达式与整数的加减运算形式:p+n或p-n其中:p是任意一个指针表达式,n 是任何一种整型表达式计算规则:表达式p+n的值=p的值+p所指类型长度*n表达式p-n的值=p的值-p所指类型长度*n说明:只有当p和p+n或p-n都指向连续存放的同类型数据区域(数组)时,指针加、减才有实际意义。C语言规定:表达式p+n和p-n的类型与p相同。6.3.2 指针基本运算
共49 页第24页例如:设有变量定义:int a[10], *p , *q ;则p=a p指向a[0]q=a+6 q指向a[6]p=q-4 p指向a[2]q=a+6 1000+6*2=10123412115678910p=aa[0]a[6]a[9]q=a+6q-4100010121004p=q+4 1012-4*2=1004
共49 页第25页!不可用数组名表示++a、a++--a、a--2. 自增自减运算语法:p++ ; p--; ++p ; --p ;⑴++p或p++运算后都使p指向下一个数据p++与++p的区别:表达式p++的值等于p的原来值; 表达式++p的值等于p的新值;⑵取内容运算符“* ”、取地址运算符“& ”和自增自减运算符都是单目运算符,运算的优先级相同,结合方向都是自右至左。例如:int a[ ]={1,2,3,4,5}, *p, *q ;p=q=&a[3];*p++=100 ; a[?]变成100*++q=100 ; a[?]变成100
共49 页第26页p-2p-1pp+1p+2............p-3............数组低地址高地址指针的关系运算◆当两个指针指向同一个数组中的元素时,才能进行>、<、>=、<=、!=、==的关系运算。◆任何指针p与NULL进行“P==NULL”或“P!=NULL”运算均有意义:判断指针p 是否指向空。3.指针的关系运算◆指针的关系运算只有同类指针进行比较才有意义
共49 页第27页p==q 两指针指向同一元素时为1,反之为0。p!=q 两指针不指向同一元素时为1,反之为0。假定指针p 和q指向同一个数组,则:p>q p指针所指元素位于q所指元素之后时为1,反之为0。p>=q p指针所指元素位于q所指元素之后(或两指针指向同一元素)时为1,反之为0。= =和!=运算符,比较的是两个指针表达式是否指向同一个内存单元;<、<=、>、>=,比较的是两个指针所指内存区域的先后次序语法格式:指针表达式关系运算符指针表达式例:int a[10]; int *p=a, *q=a+3;判断以下表达式的值p==&a[0] p==&a[1] p==q p+4==q+2 pa+2 p>q
共49 页第28页4. 同类指针相减同类指针相减时,两个指针应该指向连续存放的同类数据区域。语法:p-q说明:p-q 的值,等于(p的值-q的值)/所指类型长度,即p, q两个指针之间数据元素的个数。例如:若有int a[10] , *p, *q;p=a;q=&a[3];则p,q之间有5个整型数据。q-p=(1006-1000)/2=3p-q=-33456p=aa[0]q10001006a[3]
共49 页第29页#include “stdio.h”main(){ char str[50],*p=str;printf(“Enter string:”);gets(str);while(*p)p++;printf(“string length=%s\n”, p-str);}[例6-3]编写程序,求字符串的长度。
共49 页第30页例: 输出数组全部元素。下标法:main( ){ int a[10], i;for(i=0;i<10;i++)canf(“%d”,&a[i]);printf(“\n”);for(i=0;i<10;i++)printf(“%5d”, a[i]);}通过数组名计算数组元素地址,找出数组元素for(i=0;i<10;i++)printf(“%5d”, *(a+i));用指针变量指向数组元素for(p=a;p<(a+10);p++)printf(“%5d”, *p);