1第九讲指针2指针是C语言中的一个重要概念。掌握指针的用法,可使程序简洁、高效、灵活,但并不难学。为了了解什么是指针,先看一个小故事地下工作者阿金接到上级指令,要去寻找打开密电码的密钥,这是一个整数。几经周折,才探知如下线索,密钥藏在一栋三年前就被贴上封条的小楼中。一个风雨交加的夜晚,阿金潜入了小楼,房间很多,不知该进哪一间,正在一筹莫展之际,忽然走廊上的电话铃声响起。艺高人胆大,阿金毫不迟疑,抓起听筒,一个陌生人说:“去打开211房间,那里有线索”。阿金疾步上楼,打开211房间,用电筒一照,只见桌上赫然6个大字:地址1000。阿金眼睛一亮,迅速找到1000房间,取出重要数据66,完成了任务。3我们画出下图1000…66…2111000P说明:1、数据藏在一个内存地址单元中,地址是1000。2、地址1000又由P单元所指认,P单元的地址为211。3、66的直接地址是1000;66的间接地址是211;211中存的是直接地址1000。4、称P为指针变量,1000是指针变量的值,实际上是有用数据藏在存储器中的地址。4指针变量——用来存放另一变量地址的变量变量的指针就是变量的地址。1、指针的概念指针是一种特殊的变量,特殊性表现在类型和值上。从变量讲,指针也具有变量的三个要素:(1)变量名,这与一般变量取名相同,由英文字符开始。(2)指针变量的类型,是指针所指向的变量的类型,而不是自身的类型。(3)指针的值是某个变量的内存地址。5从上面的概念可知,指针本身类型是int型,因为任何内存地址都是整型的。但是指针变量的类型却定义成它所指向的变量的类型。2、指针的定义(说明,先说明后引用)例如:int*p,*q;//定义p,q为指向整数类型变量的指针float*point;//定义point为指向float型变量的指针double*pd;//定义pd为指向double型数组的指针int(*pa)[10];//定义pa为指向int型数组的指针int(*pu)();//定义pu为指向int型函数的指针int**qq;//定义qq为指向int型指针的指针还有指向结构、联合的指针,后面再介绍63、指针赋值例intakey;//定义一个整型变量akeyint*p,*q;//定义p,q为指向整型变量的指针变量akey=66;//将变量a的地址赋给p,这时见图1q=p;//将p的值赋给q,见图266&apa&pp变量的地址&aa变量的地址图1的说明:将a变量的地址赋给指针p,意味着让指针p指向a图1766&apa图2的说明:当着执行q=p;之后,p中所存的a变量的地址值,也就被放到q变量中,意味着让指针q也指向a图2&aq&p&qq=p;8//指针1.c#includestdio.h//预编译命令voidmain()//主函数{//函数体开始inta[5]={0,1,2,3,4};//定义数组,赋初值int*p1,*p2;//定义指针变量p1=&a[1];//赋值给指针变量,让p1指向a[1]p2=&a[2];//赋值给指针变量,让p1指向a[2]printf(a[1]=%d;a[2]=%d\n,*p1,*p2);//输出a[1]和a[2]的值}9说明:见图01234&a[0]&a[1]&a[2]&a[3]&a[4]&a[1]&a[2]&p1&p2p1p2p1和p2分别指向a[1],a[2],这里&——取地址运算符*——指针运算符(间接访问运算符)*p1——间接访问p1所指向的内存单元,当然是输出a[1]的值*p2——间接访问p2所指向的内存单元,当然是输出a[2]的值10//指针2.c#includestdio.h//预编译命令voidmain()//主函数{//函数体开始intakey,b;//定义整型变量int*p,*q;//定义指针变量akey=66;//赋值给变量akeyp=&akey;//赋值给指针变量p,让p指向变量akeyq=&b;//赋值给指针变量q,让q指向变量b*q=*p;//将p所指向的akey的值赋给q所指向的变量bprintf(b=%d\n,b);//输出b的值printf(*q=%d\n,*q);//输出b的值}//函数体结束4、向指针所指向的内存单元赋值116666&akeyp&akey*q=*p&aq&b12//指针3.c#includestdio.h//预编译命令voidmain()//主函数{//函数体开始inta[5]={1,3,5,7,9};//定义数组,赋初值int*p;//定义指针变量inti;//定义整型变量p=a;//赋值给指针变量,让p指向a数组for(i=0;i5;i=i+1){//循环体开始printf(a[%d]=%d\n,i,*p);//输出a数组元素的值p=p+1;//指针变量加1}//循环体结束}//函数体结束5、指针与数组先看一个程序13说明(1)p=a;这里数组名作为数组的起始地址,即a[0]的地址。因此p=a等效于p=&a[0];(2)p=p+1;如p指向a[0],则p=p+1之后,p指向a[1](3)如果p=a等效于p=&a[0];则p=a+4等效于p=&a[4];a[0]a[1]a[2]a[3]a[4]*p*(p+1)*(p+2)*(p+3)*(p+4)pp+1p+2pp+1p+2等效14//指针4.c#includestdio.h//预编译命令voidmain()//主函数{//函数体开始inta[5]={1,3,5,7,9};//定义数组,赋初值int*p;//定义指针变量inti=0;//定义整型变量,赋初值for(p=a;pa+5;p=p+1)//赋值给指针变量,让p指向a数组{//循环体开始printf(a[%d]=%d\n,i,*p);//输出a数组元素的值i=i+1;//让i加1}//循环体结束}//函数体结束做下面的实验15//指针5.c#includestdio.hvoidmain(){char*p;//定义指向字符类型的指针变量pstaticchars[]=“abcdefgh”;//定义字符数组,并赋值p=s;//数组名是一个常量指针,//它指向该数组首地址while(*p!=‘\0’)//当p所指向的数组元素不为’\0’时{p=p+1;//让指针加1}printf(“字串长度为%d\n”,p-s);//输出字串长}数组名是一个常量指针,指向该数组的首地址,例16012345678abcdefgh\0ssp图中数组的首地址是s[0]的地址,即&s[0]。s可看作是指向s[0]的指针。s是不会动的,是常量指针。17//指针6.c#includestdio.h//预编译命令voidmain()//主函数{//函数体开始staticcharshuzi[]=“987654321”;//定义数组,//赋初值为数字字符串char*p=&shuzi[8];//让指针p指向shuzi[8]元素,//该处是字符‘1’do//直到型循环{//循环体开始putchar(*p);//putchar函数的作用是向终端//输出一个字符,该字符由p指向p=p-1;//让p减1}//循环体结束while(p=shuzi);//当p=shuzi时,继续循环putchar(‘\n’);//换行}数组名是一个常量指针,指向该数组的首地址,例18结束