版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
本章导读
指针是C语言中的一个重要的概念,也是C语言的一个重要特色。正确而灵活地运用它,可以有效地表示复杂的数据结构;能动态分配内存;能方便地使用字符串;有效而方便地使用数组,能直接处理内存地址等,这对设计系统件是很必要的。掌握指针的应用,可以使程序简洁、紧凑、高效。每一个学习和使用C语言的人,都应当深入地学习和掌握指针。可以说,不掌握指针就不掌握C的精华。。《C语言程序设计》
(VisualC++6.0环境)返回本书目录第6章指针与引用本章主要知识点
(1)
关于指针的C程序实例
(2)指针
(3)指针与数组
(4)指针与函数
(5)多级指针与指针数组
(6)内存管理
(7)引用第6章指针与引用《C语言程序设计》
(VisualC++6.0环境)返回本章导读6.2指针6.3指针与数组6.5多级指针与指针数组6.4指针与函数6.1关于指针的C程序实例6.6引用6.7内存管理
6.1.1C程序实例(1)《C语言程序设计》
(VisualC++6.0环境)下一例1.C程序实例1【例6.1】指针变量的定义示例。
/*程序名为l5_1.cpp*//*程序功能:验证指针变量的定义*/#include"stdio.h"main(){intnum_int=12,*p_int; /*定义一个指向int型数据的指针变量p_int*/floatnum_f=3.14,*p_f; /*定义一个指向float型数据的指针变量p_f*/charnum_ch='p',*p_ch; /*定义一个指向char型数据的指针变量p_ch*/p_int=&num_int; /*取变量num_int的地址,赋值给p_int*/p_f=&num_f; /*取变量num_f的地址,赋值给p_f*/p_ch=&num_ch; /*取变量num_ch的地址,赋值给p_ch*/printf("num_int=%d,*p_int=%d\n",num_int,*p_int);printf("num_f=%4.2f,*p_f=%4.2f\n",num_f,*p_f);printf("num_ch=%c,*p_ch=%c\n",num_ch,*p_ch);} 程序运行结果:num_int=12,*p_int=12num_f=3.14,*p_f=3.14num_ch=p,*p_ch=p程序演示[例6.1]程序演示单击运行输入源程序弹出运行结果窗口返回例题返回本节目录6.1.1C程序实例(2)《C语言程序设计》
(VisualC++6.0环境)2.C程序实例2【例6.2】输入2个整数,按升序(从小到大排序)输出。/*程序名为l5_2.cpp*//*程序功能:使用指针变量求解2个整数的升序输出*/#include"stdio.h"main(){intnum1,num2;int*num1_p=&num1,*num2_p=&num2,*pointer;printf("Inputthefirstnumber:");scanf("%d",num1_p);printf("Inputthesecondnumber:");scanf("%d",num2_p);printf("num1=%d,num2=%d\n",num1,num2);if(*num1_p>*num2_p) /*如果num1>num2,则交换指针*/{pointer=num1_p;num1_p=num2_p;num2_p=pointer;}printf("min=%d,max=%d\n",*num1_p,*num2_p);} 程序运行情况:Inputthefirstnumber:9<CR>Inputthesecondnumber:6<CR>num1=9,num2=6min=6,max=9返回本章目录程序演示[例6.2]程序演示单击运行输入源程序弹出运行结果窗口返回例题返回本节目录《C语言程序设计》
(VisualC++6.0环境)返回本章目录6.2.2指向变量的指针变量6.2.1地址和指针的概念6.2指针
6.2.1地址和指针的概念《C语言程序设计》
(VisualC++6.0环境)1.内存地址──内存中存储单元的编号2.变量地址──系统分配给变量的内存单元的起始地址
(1)计算机硬件系统的内存储器中,拥有大量的存储单元(每个存储单元容量为1字节)。每一个存储单元编号--------存储单元的“地址”。每个存储单元都有一个唯一的地址。(2)在地址所标识的存储单元中存放数据。注意:内存单元的地址内存单元中的数据完全不同的概念。假设有这样一个程序:main(){intnum;scanf("%d",&num);printf("num=%d\n",num);}C编译程序编译到该变量定义语句时,将变量num登录到“符号表”中。符号表的关键属性有两个:一是“标识符名(id)”,二是该标识符在内存空间中的“地址(addr)”。为描述方便,假设系统分配给变量num的2字节存储单元为3000和3001,则起始地址3000就是变量num在内存中的地址。返回本节目录6.2.1地址和指针的概念《C语言程序设计》
(VisualC++6.0环境)3.变量值的存取──通过变量在内存中的地址进行(1)直接访问──直接利用变量的地址进行存取上例中scanf(“%d”,&num)的执行过程是这样的:用变量名num作为索引值,检索符号表,找到变量num的起始地址3000;然后将键盘输入的值(假设为3)送到内存单元3000和3001中。
printf("num=%d\n",num)的执行过程,与scanf()很相似:首先找到变量num的起始地址3000,然后从3000和3001中取出其值,最后将它输出。返回本节目录6.2.1地址和指针的概念《C语言程序设计》
(VisualC++6.0环境)(2)间接访问──通过另一变量访问该变量的值C语言规定:在程序中可以定义一种特殊的变量(称为指针变量),用来存放其它变量的地址。例如,假设定义了这样一个指针变量num_pointer,它被分配到4000、4001单元,其值可通过赋值语句“num_pointer=&num;”得到。此时,指针变量num_pointer的值就是变量num在内存中的起始地址3000。
【例5.2】中printf(“min=%d,max=%d\n”,*num1_p,*num2_p);语句:通过指针变量,间接访问变量的值。返回本节目录6.2.2指向变量的指针变量《C语言程序设计》
(VisualC++6.0环境)返回本节目录1.指针与指针变量
(1)指针──即地址一个变量的地址称为该变量的指针。通过变量的指针能够找到该变量。(2)指针变量──专门用于存储其它变量地址的变量指针变量num_pointer的值就是变量num的地址。指针与指针变量的区别,就是变量值与变量的区别。(3)为表示指针变量和它指向的变量之间的关系,用指针运算符“*”表示。例如,指针变量num_pointer与它所指向的变量num的关系,表示为:*num_pointer,即*num_pointer等价于变量num。因此,下面两个语句的作用相同:num=3; /*将3直接赋给变量num*/num_pointer=#/*使num_pointer指向num*/*num_pointer=3; /*将3赋给指针变量num_pointer所指向的变量*/6.2.2指向变量的指针变量《C语言程序设计》
(VisualC++6.0环境)返回本节目录2.指针变量的定义与应用定义:
数据类型*指针变量[,*指针变量2……];注意:此时的指针变量未指向某个具体的变量(称指针是悬空的)。使用悬空指针很容易破坏系统,导致系统瘫痪。取地址运算的格式:&变量指针变量只能存放指针(地址),且只能是相同类型变量的地址。C语言中用NULL表示空指针。
《C语言程序设计》
(VisualC++6.0环境)返回本章目录6.3.2通过指针引用数组元素 6.3.1指向数组元素的指针6.3指针与数组6.3.3
数组名作函数参数6.3.4
指针与字符数组6.3.5数组指针6.3.1指向数组元素的指针《C语言程序设计》
(VisualC++6.0环境)
返回本节目录指向数组的元素指针变量的定义,与指向普通变量的指针变量的定义方法一样例如,intarray[10];(定义array为包含10个整型变量的数组)int*pointer(定义pointer为指向整型变量的指针变量)应当注意,如果数组为int型,则指针变量亦应指向int型。下面是对该指针赋值:pointer=&array[0];把array[0]元素的地址赋给指针变量pointer。也就是说,pointer指向array数组的第0号元素。C语言规定数组名代表数组的首地址,也就是第一个元素的地址。因此,下面两个语句等价pointer=&array[0];pointer=array;注意:数组名不代表整个数组,上述“pointer=array;”的作用是“把array数组的第一个元素的地址赋给指针变量pointer”而不是“把array数组各元素的值赋给pointer”。
6.3.2通过指针引用数组元素 《C语言程序设计》
(VisualC++6.0环境)返回本节目录1通过指针引用一维数组中的元素
如果有“intarray[10],*pointer=array;”,则:(1)pointer+i和array+i都是数组元素array[i]的地址。(2)*(pointer+i)和*(array+i)就是数组元素array[i]。(3)指向数组的指针变量,也可将其看作是数组名,因而可按下标法来使用。例如,pointer[i]等价于*(pointer+i)。注意:pointer+1指向数组的下一个元素,而不是简单地使指针变量pointer的值+1。其实际变化为pointer+1*size(size为一个元素占用的字节数)。例如,假设指针变量pointer的当前值为3000,则pointer+1为3000+1*2=3002,而不是3001。6.3.2通过指针引用数组元素 《C语言程序设计》
(VisualC++6.0环境)返回本节目录【例6.3】使用指向数组的指针变量来引用数组元素。/*程序名为l6_3.cpp*//*程序功能:使用指向数组的指针变量来引用数组元素*/#include"stdio.h"main(){intarray[10],*pointer=array,i;printf("Input10numbers:");for(i=0;i<10;i++)scanf("%d",pointer+i); /*使用指针变量来输入数组元素的值*/printf("array[10]:");for(i=0;i<10;i++)printf("%d",*(pointer+i)); /*使用指向数组的指针变量输出数组*/printf("\n");}
6.3.2通过指针引用数组元素 《C语言程序设计》
(VisualC++6.0环境)返回本节目录程序运行情况:Input10numbers:0123456789<CR>array[10]:0123456789程序说明:程序中第3行和第6行的2个for语句,等价于下面的程序段:for(i=0;i<10;i++,pointer++)scanf(“%d”,pointer);printf(“array[10]:”);pointer=array; /*使pointer重新指向数组的第一个元素*/for(i=0;i<10;i++,pointer++)printf(“%d”,*pointer);
6.3.2通过指针引用数组元素 《C语言程序设计》
(VisualC++6.0环境)返回本节目录2通过指针引用二维数组中的元素在C语言中,二维数组是按行优先的规律转换为一维线性存放在内存中的,因此,可以通过指针访问二维数组中的元素。如果有:inta[M][N];
则将二维数组中的元素a[i][j]转换为一维线性地址的一般公式是:线性地址=a+i×M+j
其中:a为数组的首地址,M和N分别为二维数组行和列的元素个数。
6.3.2通过指针引用数组元素 《C语言程序设计》
(VisualC++6.0环境)返回本节目录【例6.4】:给定某年某月某日,将其转换成这一年的第几天并输出。此题的算法很简单,若给定的月是i,则将1、2、3、……、i-1月的各月天数累加,再加上指定的日。但对于闰年,二月的天数29天,因此还要判定给定的年是否为闰年。为实现这一算法,需设置一张每月天数列表,给出每个月的天数,考虑闰年非闰年的情况,此表可设置成一个2行13列的二维数组,其中第1行对应的每列(设1~12列有效)元素是平年各月的天数,第2行对应的是闰年每月的天数。程序中使用指针作为函数day_of_year的形式参数。/*程序名为l6_4.cpp*//*程序功能:使用指向数组的指针变量来引用数组元素*/#include<stdio.h>day_of_year(int*day_tab,intyear,intmonth,intday){inti,j;i=(year%4==0&&year%100!=0)||year%400==0;for(j=1;j<month;j++)day+=*(day_tab+i*13+j);/*day_tab+i*13+j:对二维数组中元素进行地址变换*/return(day);}
6.3.2通过指针引用数组元素 《C语言程序设计》
(VisualC++6.0环境)返回本节目录main(){staticintday_tab[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}};inty,m,d;scanf("%d%d%d",&y,&m,&d);printf("%d\n",day_of_year(&day_tab[0][0],y,m,d));/*实参为二维数组名*/}
由于C语言对于二维数组中的元素在内存中是按行存放的,所以在函数day_of_year中要使用公式"day_tab+i*13+j"计算main函数的day_tab中元素对应的地址。
6.3.3
数组名作函数参数
《C语言程序设计》
(VisualC++6.0环境)返回本节目录数组名可以用作函数的形参和实参。如:main(){intarray[10];f(array,10)}f(arr,n)intarr[],n;{}array为实参数组名,arr为形参数组名。
6.3.3
数组名作函数参数
《C语言程序设计》
(VisualC++6.0环境)返回本节目录【例6.5】将数组a中n个整数按相反顺序存放解此题的算法为:将a[0]与a[n-1]对换,再将a[1]与a[n-2]对换,……,直到将a[(n-1)/2]与a[n-int((n-1)/2)]对换。今用循环处理此问题,设两个“位置指示变量”i和j,i的初值为0,j的初值为n-1。将a[i]与a[j]交换,然后使i的值加1,j的值减1,再将a[i]与a[j]对换,直到i=(n-1)/2为止。程序如下:程序名为l6_5.cpp#include"stdio.h"voidinv(int*x,intn)/*形参x是为指针变量*/{int*p,temp,*i,*j,m=(n-1)/2;i=x;j=x+n-1;p=x+m;for(;i<=p;i++,j--) {temp=*i; *i=*j; *j=temp;}return;}
6.3.3
数组名作函数参数
《C语言程序设计》
(VisualC++6.0环境)返回本节目录main(){inti,a[10]={3,7,9,11,0,6,7,5,4,2};for(i=0;i<10;i++) printf("%d",a[i]);printf("\n");inv(a,10);for(i=0;i<10;i++) printf("%d",a[i]);printf("\n");}运行情况如下:3,8,11,0,5,9,4,7,10,2,<CR>2,10,7,4,9,5,0,11,8,3,程序说明:主函数中数组名为a,赋以各元素初值。函数inv中的形参数组名为x,在inv函数中不具体定义数组元素的个数,元素个数由形参变量n传入(今对应的实参值为10)。这样做可以增加函数的灵活性。即不必要求函数inv中的形参数组x和main函数中的实参数组a长度相同。如果在main函数中有函数调用语句:“inv(a,10)”,表示要求对a数组的前10个元素实行题目要求的颠倒排列。如果改为“inv(a,5)”,则表示将a数组的前5个元素实行颠倒排列,此时,函数inv只处理5个数组元素。函数inv中的m是i值的上限,当i<m时,循环继续执行,当i>m时,则结束循环过程。
6.3.3
数组名作函数参数
《C语言程序设计》
(VisualC++6.0环境)返回本节目录
小结:
引入指向数组的指针变量后,数组及指向数组的指针变量作函数参数时,可有4种等价形式(本质上是一种,即指针数据作函数参数):(1)形参、实参都用数组名(2)形参、实参都用指针变量(3)形参用指针变量、实参用数组名(4)形参用数组名、实参用指针变量
6.3.4指针与字符数组 《C语言程序设计》
(VisualC++6.0环境)返回本节目录1.字符串的表示与引用在C语言中,既可以用字符数组表示字符串,也可用字符指针变量来表示;引用时,既可以逐个字符引用,也可以整体引用。(1)逐个引用【例6.6】使用字符指针变量表示和引用字符串。/*程序名为l6_6.cpp/#include"stdio.h"main(){char*string="IloveBeijing.";for(;*string!='\0';string++)printf("%c",*string);printf("\n");}
程序运行结果:
IloveBeijing.程序说明:char*string="IloveBeijing.";语句定义并初始化字符指针变量string:用串常量“IloveBeijing.”的地址(由系统自动开辟、存储串常量的内存块的首地址)给string赋初值。
6.3.4指针与字符数组 《C语言程序设计》
(VisualC++6.0环境)返回本节目录(2)整体引用【例6.7】采取整体引用的办法,改写[例6.9]。/*程序名为l6_7.cpp*//*程序功能:使用字符指针变量表示和引用字符串*/#include"stdio.h"main(){char*string="IloveBeijing.";printf("%s\n",string);}
程序说明:printf(“%s\n”,string);语句通过指向字符串的指针变量string,整体引用它所指向的字符串的原理:系统首先输出string指向的第一个字符,然后使string自动加1,使之指向下一个字符;重复上述过程,直至遇到字符串结束标志。注意:其它类型的数组,是不能用数组名来一次性输出它的全部元素的,只能逐个元素输出。
6.3.4指针与字符数组 《C语言程序设计》
(VisualC++6.0环境)返回本节目录2.字符指针变量与字符数组之比较虽然用字符指针变量和字符数组都能实现字符串的存储和处理,但二者是有区别的,不能混为一谈。(1)存储内容不同。字符指针变量中存储的是字符串的首地址,而字符数组中存储的是字符串本身(数组的每个元素存放一个字符)。(2)赋值方式不同。对字符指针变量,可采用下面的赋值语句赋值:
char*pointer;pointer="Thisisaexample.";而字符数组,虽然可以在定义时初始化,但不能用赋值语句整体赋值。下面的用法是非法的:
charchar_array[20];
char_array="Thisisaexample."; /*非法用法*/(3)指针变量的值是可以改变的,字符指针变量也不例外;
6.3.4指针与字符数组 《C语言程序设计》
(VisualC++6.0环境)返回本节目录3.字符串指针作函数参数【例6.8】用函数调用方式,实现字符串的复制。/*程序名为l6_8.cpp*//**********************************************************//*string_copy()函数:复制一个字符串*//*形参:字符指针str_from接收源串,字符指针str_to存储目标串*//*返回值:无*//**********************************************************/#include"stdio.h"voidstring_copy(char*str_from,char*str_to){inti=0;for(;(*(str_to+i)=*(str_from+i))!='\0';i++);/*循环体为空语句*/}main(){chararray_str1[20]="Iamateacher.";
6.3.4指针与字符数组 《C语言程序设计》
(VisualC++6.0环境)返回本节目录chararray_str2[20];string_copy(array_str1,array_str2);/*数组名作实参*/printf("array_str2=%s\n",array_str2);}程序运行结果:
Iamateacher.程序说明:
for(;(*(str_to+i)=*(str_from+i))!=’\0’;i++);
语句的执行过程为:首先将源串中的当前字符,复制到目标串中;然后判断该字符(即赋值表达式的值)是否是结束标志。如果不是,则相对位置变量i的值增1,以便复制下一个字符;如果是结束标志,则结束循环。其特点是:先复制、后判断,循环结束前,结束标志已经复制。
6.3.5数组指针 《C语言程序设计》
(VisualC++6.0环境)返回本节目录
我们上面介绍的指针都是指向某一类型的变量的,例如可以使一个指针p指向某一数组元素。如果p的值加1,则指向下一个元素,这样指针在处理一维数组时非常方便,但在处理二维数组时就不适合了。如果定义一个指针p,让它指向一个包含n个元素的一维数组,且p的增值以一维数组的长度为单位,此时,如果指针P指向二维数组的某一行,则p+1就指向了该二维数组的下一行。在C++中,这样的指针被称为数组指针,使用数组指针可以很方便地处理二维数组。数组指针的说明形式如下:
存储类型数据类型(*指针名)[元素个数]
例如,在程序中定义一个数组指针:
int(*p)[4];
它表明指针p指向的数组指针p指向一个一维数组,p的值就是该一维数组的首地址。在使用数组指针时,有两点一定要注意:(1)*p两侧的括号一定不要漏掉,如果写成*p[4]的形式,由于[]的运算级别高,因此p先和[4]结合,是数组,然后再与前面的*结合,*p[4]是指针数组。
6.3.5数组指针 《C语言程序设计》
(VisualC++6.0环境)返回本节目录(2)p是一个行指针,它只能指向一个包含n个元素的一维数组,不能指向一维数组中的元素。【例6.9】:用数组指针处理二维数组。程序名为l6_9.cpp#include<stdio.h>main(){inta[2][3]={1,3,5,7,9,11};int(*p)[3];inti,j;p=a;for(i=0;i<2;i++){for(j=0;j<3;j++)printf(“%2d”,(*p)[j]);p++;}}程序运行结果为:1357911
《C语言程序设计》
(VisualC++6.0环境)返回本章目录6.4.2函数指针6.4.3指针函数6.4.1指针作函数参数6.4指针与函数 6.4.1指针作函数参数 《C语言程序设计》
(VisualC++6.0环境)返回本节目录1.指针变量,既可以作为函数的形参,也可以作函数的实参。2.指针变量作实参时,与普通变量一样,也是“值传递”,即将指针变量的值(一个地址)传递给被调用函数的形参(必须是一个指针变量)。
注意:被调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指向的变量的值。
6.4.1指针作函数参数 《C语言程序设计》
(VisualC++6.0环境)返回本节目录【例6.10】使用函数调用方式改写例6.2,要求实参为指针变量。/*程序名为l6_10.cpp/
/******************************************************//*exchange()功能:交换2个形参指针变量所指向的变量的值*//*形参:2个,均为指向整型数据的指针变量*//*返回值:无*/
/******************************************************/#include"stdio.h"voidexchange(int*pointer1,int*pointer2){inttemp;temp=*pointer1,*pointer1=*pointer2,*pointer2=temp;}/*主函数main()*/main(){intnum1,num2;/*定义并初始化指针变量num1_p和num2_p*/int*num1_p=&num1,*num2_p=&num2;printf("Inputthefirstnumber:");scanf("%d",num1_p);
6.4.1指针作函数参数 《C语言程序设计》
(VisualC++6.0环境)返回本节目录
printf("Inputthesecondnumber:");scanf("%d",num2_p);printf("num1=%d,num2=%d\n",num1,num2);if(*num1_p>*num2_p) /*即num1>num2)*/exchange(num1_p,num2_p); /*指针变量作实参*/printf("min=%d,max=%d\n",num1,num2);/*输出排序后的num1和num2的值*/}
程序运行情况:Inputthefirstnumber:9<CR>Inputthesecondnumber:6<CR>num1=9,num2=6min=6,max=9程序说明:形参指针变量pointer1(指向变量num1)和pointer2(指向变量num2),在函数调用开始时才分配存储空间,函数调用结束后立即被释放。虽然被调用函数不能改变实参指针变量的值,但可以改变它们所指向的变量的值。
6.4.2函数指针 《C语言程序设计》
(VisualC++6.0环境)返回本节目录1.函数指针的概念一个函数在编译时,被分配了一个入口地址,这个地址就称为该函数的指针。可以用一个指针变量指向一个函数,然后通过该指针变量调用此函数。【例6.11】:求a和b中的大者。程序名为l6_11.cpp#include"stdio.h"main(){intmax(int,int);int(*p)(int,int);inta,b,c;p=max;scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d",a,b,c);}6.4.2函数指针
《C语言程序设计》
(VisualC++6.0环境)返回本节目录max(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}程序说明:其中int(*p)()说明p是一个指向函数的指针变量,此函数带回整型的返回值。注意*p两侧的括弧不可省略,表示p先与*结合,是指针变量,然后再与后面的()结合,表示此指针变量指向函数,这个函数值(即函数返回的值)是整型的。如果写成“int*p”,则由于()优先级高于*,它就成了说明一个函数了,这个函数的返回值是指向整型变量的指针。
6.4.2函数指针
《C语言程序设计》
(VisualC++6.0环境)返回本节目录2.指向函数的指针变量(1)定义格式
函数类型(*指针变量)();注意:“*指针变量”外的括号不能缺,否则成了返回指针值的函数。例如,int(*fp)(); /*fp为指向int函数的指针变量*/(2)赋值函数名代表该函数的入口地址。因此,可用函数名给指向函数的指针变量赋值。指向函数的指针变量=[&]函数名;
注意:函数名后不能带括号和参数;函数名前的“&”符号是可选的。(3)调用格式
(*函数指针变量)([实参表])(4)函数名作实参时,因为要缺省括号和参数,造成编译器无法判断它是一个变量还是一个函数,所以必须加以说明。(5)注意:对指向函数的指针变量,诸如p+i、p++/p--等运算是没有意义的。
6.4.2函数指针
《C语言程序设计》
(VisualC++6.0环境)返回本节目录3.指向函数的指针变量作函数参数指向函数的指针变量的常用用途之一,就是将函数指针作参数,传递到其它函数。【例6.12】:设一个函数process,在调用它的时候,每次实现不同的功能。输入a和b两个数,第一次调用process时找出a和b中大者,第二次找出其中小者,第三次求a与b之和。程序如下:程序名为l6_12.cpp#include"stdio.h"process(intx,inty,int(*fun)(int,int))/*函数定义。int(*fun)(int,int)表示fun是指向*//*函数的指针,该函数是一个整型函数,有两个整型形参*/{intresult;result=(*fun)(x,y);printf("%d\n",result);}
6.4.2函数指针
《C语言程序设计》
(VisualC++6.0环境)返回本节目录main(){intmax(int,int); /*函数声明*/intmin(int,int); /*函数声明*/intadd(int,int); /*函数声明*/inta,b;scanf("%d,%d",&a,&b);printf("max=");process(a,b,max);printf("min=");process(a,b,min);printf("sum=");process(a,b,add);}max(intx,inty) /*函数定义*/{intz;if(x>y)z=x;elsez=y;return(z);}
6.4.2函数指针
《C语言程序设计》
(VisualC++6.0环境)返回本节目录min(intx,inty) /*函数定义*/{intz;if(x<y)z=x;elsez=y;return(z);}add(intx,inty)/*函数定义*/{intz;z=x+y;return(z);}
6.4.2函数指针
《C语言程序设计》
(VisualC++6.0环境)返回本节目录程序运行结果如下:3,9<CR>max=9min=3sum=12程序说明:
max、min和sum是已定义的三个函数,分别用来实现求大数、求小数和求和的功能。在main函数中第一次调用process函数时,除了将a和b作为实参将两个数传给process的形参x、y外,还将函数名max作为实参将其入口地址传送给process函数中的形参----指向函数的指针变量fun,这时,process函数中的(*fun)(x,y)相当于max(x,y),执行process可以输出a和b中大者。在main函数第二次调用时,改以函数名min作实参,此时process函数的形参fun指向函数min,在process函数中的函数调用(*fun)(x,y)相当于min(x,y)。同理,第三次调用process函数时,(*fun)(x,y)相当于add(x,y)。从本例可以清楚地看到,不论执行max、min或add,函数process一点都没有改动,只是在调用process函数时实参函数名改变而已。这就增加了函数使用的灵活性。
6.4.3指针函数
《C语言程序设计》
(VisualC++6.0环境)返回本节目录指针函数是指返回值为指针的函数,函数的返回值可以是不同类型的指针指针函数定义格式如下:函数类型*函数名([形参表])例如:int*pr(x,y);pr是函数名,调用它以后能得到一个指向整型数据的指针(地址)。x、y是函数pr的形参。请注意在*pr两侧没有括弧,在pr的两侧分别为*运算符和()运算符。而()优先级高于*,因此a先与()结合。显然这是函数形式。这个函数前面有一个*,表示此函数是指针型函数(函数值是指针)。最前面的int表示返回的指针指向整型变量。
《C语言程序设计》
(VisualC++6.0环境)返回本章目录6.5.2指针数组6.5.3main函数的参数6.5.1多级指针6.5
多级指针与指针数组
6.5.1多级指针《C语言程序设计》
(VisualC++6.0环境)1.概念
在前面的叙述中,一个指针变量可以指向一个相应数据类型的数据,例如:
inta,*p;p=&a;
使指针p指向a,则指针p所指向的变量*p就是要处理的数据变量a.如果同时存在另一个指针pp,并且把指针p的地址赋予指针变量pp,即:pp=&p;
则pp就指向指针p,这时指针pp所指向的变量*pp就是指针p。在C++中,把pp这样的指向指针的指针称为多级指针。返回本节目录2.定义格式
数据类型**指针变量[,**指针变量2……];6.5.1多级指针《C语言程序设计》
(VisualC++6.0环境)返回本节目录【例6.13】用二级指针处理多个字符串。程序名为l6_13.cpp#include"stdio.h"main(){staticchar*name[]={"Followme","BASIC","FORTRAN","GreatWall","Computerdesign"};char**p;inti;for(i=0;i<5;i++){p=name+i;printf("%s\n",*p);}}程序运行结果:FollowmeBASICFORTRANGreatWallComputerdesign6.5.1多级指针《C语言程序设计》
(VisualC++6.0环境)返回本节目录程序说明:指针数组的元素也可以不指向字符串,而指向整型数据或实型数据等,例如:inta[5]={l,3,5,7,9},int*num[5]={&a[0],&a[l],&a[2],&a[3],&a[4};int**p;此时为了得到数据“5",可以先使p=num+2,然后输出**p。注意*p是p间接指向的对象的地址。而**p是p间接指向的对象的值。6.5.2指针数组《C语言程序设计》
(VisualC++6.0环境)1.概念2.定义格式
数组的每个元素都是一个指针数据。
数据类型*数组名[元素个数]
指针数组常适用于指向若干字符串,这样使字符串处理更加灵活方便。返回本节目录6.5.3main函数的参数《C语言程序设计》
(VisualC++6.0环境)返回本节目录指针数组的一个重要应用是作为main函数的形参。在前面讲述的程序中,main函数的第一行全部写成了以下形式:main
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 音乐厅地暖系统安装工程合同
- 工业烟囱安装合同模板
- 河道游艇码头施工合同
- 体育场馆倒板施工合同
- 古玩店电梯供应协议
- 钢结构观景台施工合同
- 员工节假日工作安排
- 森林度假村土方平整协议
- 文创产品店员工聘用协议
- 建筑工程人员聘用合同书
- 2023年江西省公安机关警务辅助人员条例训练题库115题及答案
- 跨境人民币结算人行RCMIS商业银行业务信息报送工作指引XXXX
- 石油企业QHSE管理体系存在的问题与对策2400字
- 培智六年级生活数学寒假作业
- 压型钢板底模砼楼承板施工交底培训课件
- 高血压病人的护理
- 压力容器安全技术规程
- GB/T 9065.2-2010液压软管接头第2部分:24°锥密封端软管接头
- 运用PDCA提高患者身份识别正确率课件
- 部编版八年级上册语文标点符号考点汇总
- 国家开放大学电大《药物化学》期末题库及答案
评论
0/150
提交评论