1
第十章 指针与指针变量主讲 福州大学数学与计算机学院 韩晓芸
E-mail,hxy@fjtv.net
第 10章 指针
2
第一节 概述第二节 指针变量第三节 指针与数组第四节 指针与字符串第五节 指针与函数第六节 指针数组第七节 多级指针和命令行参数第 10章 指针
3
一、地址在程序中所定义的变量,编译系统会根据变量的类型,分配一定长度的存储空间。 内存中每一个字节有唯一编号。如:
int a 2个字节
float b 4个字节
char c 1个字节
6
5.3
2000
2002
2006 A
a
b
第一节 指针概述
c2007
第 10章 指针
4
二、访问变量的方式
直接访问方式按变量的 地址 存取变量的值 。
例如:
printf("%f",b);
scanf(“%d”,&a);
第一节 指针概述
2000
a
6
第 10章 指针
5
间接访问方式按变量的 地址的地址 存取变量的值。
例如,假设 变量 pa的地址为 1000,用变量 pa来存放 变量 a的地址 &a,此时 pa的值为 2000。如果要得到 a的值,可以 先访问变量 pa,得到 pa的值为 2000(变量 a的地址 ),再通过地址 2000找到所指存储单元中的值 (a的值 ),见图,
pa(1000) a
200
0
6
2000
第一节 指针概述第 10章 指针
6
三、指针一个变量的地址称为该变量的指针 。如地址
2000是变量 a的指针,2002是变量 b的指针。
四、指针变量如果有一个变量专门用来存放另一个变量的地址(即指针),称为指针变量 。如 pa是一个 指针变量,pa中的值为 指针 。
注意:指针和指针变量的概念第一节 指针概述第 10章 指针
7
一,指针变量的定义二,指针变量的引用三,指针作为函数的参数第二节 指针与变量第 10章 指针
8
一,指针变量定义类型说明符 *标识符;
例如,int *p1,*p2;
int——p1,p2是 指向 整型变量 的指针变量 。
*——指针标记 。
p1,p2——指针变量名 。
说明
指针可以指向 任何类型 的对象。
在定义了一个指针变量 p1,p2以后,系统为这个指针变量分配一个 存储单元 (一般为 2个字节)用来存放地址。
第二节 指针与变量第 10章 指针
9
例如,
int a,b;
int *p1,*p2;
p1= &a;
p2= &b;
&a
p1
p2
a
b
&b
第 10章 指针
10
二,指针变量的引用
&,取变量地址 运算符例如,&a为变量 a的 地址 。
*:,指向,运算符或称,间接访问,运算符例如,*p为指针变量 p所 指向的变量 。
如果有 p=&a,则 *p就是 a。
第二节 指针与变量第 10章 指针
11
例 1:
main( )
{int a,*pa;
float b,*pb;
a=10;
b=1.5;
pa=&a;
pb=&b;
printf("%d,%f\n”,a,b);
printf("%d,%f\n”,*pa,*pb);
}
单击鼠标,演示程序的执行过程:
pa
pb
a
b
&a
&b 1.5
10
第 10章 指针
12
说明:,&”和,*”两个运算符的 优先级相同,但按 自右向左 方向结合
–执行了 pa=&a;后,&*pa的含义?
与 &a相同。
–*&a的含义? 即 a,*pa。
–(*pa)++相当于 a++
–*pa++
相当于 *(pa++),即先取 *pa,即 a的原值,之后 pa自增,不再指向 a了。
第 10章 指针
13
例 2,指针变量应用的例子,
由大到小输出 a,b。
main()
{int a,b,*p,*pa,*pb;
a=3;b=6;
pa=&a; pb=&b;
if(a<b)
{ p=pa; pa=pb; pb=p;}
printf("%d%d\n",a,b);
printf("%d%d\n",*pa,*pb);
}
单击鼠标,演示程序的执行过程:
pa
pb
p
a
b
&a
&b 6
3
&a
&b
&a
第 10章 指针
14
第二节 指针与变量三,指针变量作为函数的参数
函数的参数也可以是指针类型,实际参数可以是地址常量或指针变量,形式参数则为指针变量 。 这种传递 也是值传递,即将实参指针变量的值传给对应的形参 。 但是由于指针变量存放的是地址值,作为函数的参数来进行传送的是 实参的值 -- --变量的地址 。
第 10章 指针
15
p1
pb
a
&a
6
3
&b
&a
pa
b
p2
&b
temp
3
6
3
void swap(int *p1,int *p2)
{int temp;
temp=*p1; *p1=*p2;
*p2=temp; }
main( )
{int a,b; int *pa,*pb;
scanf("%d,%d",&a,&b);
pa=&a; pb=&b;
if(a<b) swap(pa,pb);
printf("%d,%d\n",a,b);
printf("%d,%d\n",*pa,*pb);}
第二节 指针与变量例 3,用函数来实现 两个数由大到小顺序输出。
第 10章 指针
16
?
P是不确定的值
,用 *p可能破坏系统的正常工作状态。
swap()能否写成下面的形式呢?
swap(int *p1,int *p2)
{int *p;
*p=*p1;
*p1=*p2;
*p2=*p;}
第二节 指针与变量第 10章 指针
17
?
a,b值的交换是通过形参传递回实参实现的吗? swap( )能否写成下面的形式呢?
swap(int x,int y)
{int t; t=x;x=y;y=t;}
如果在 main函数中有 swap(a,b),结果会怎样?
第二节 指针与变量第 10章 指针
18
?
swap()能否写成下面这种形式?
swap(p1,p2)
int *p1,*p2;
{int *p;
p=p1;
p1=p2;
p2=p;}
main( )
{int a,b; int *pa,*pb;
scanf("%d,%d",&a,&b);
pa=&a; pb=&b;
if(a<b) swap(pa,pb);
printf("%d,%d\n",a,b);
printf("%d,%d\n",*pa,*pb);
}
第二节 指针与变量第 10章 指针
19
例 4:输入 a,b,c三个整数,由大到小顺序输出。
void swap(int *p1,int *p2)
{int temp;
temp=*p1;
*p1=*p2;
*p2=temp;}
第二节 指针与变量第 10章 指针
20
例 4(续 ):输入 a,b,c三个整数,由大到小输出。
main()
{int a,b,c; int *pa,*pb,*pc;
scanf(“%d,%d,%d”,&a,&b,&c);
pa=&a;pb=&b;pc=&c;
if(*pa<*pb) swap(pa,pb);
if(*pa<*pc) swap(pa,pc);
if(*pb<*pc) swap(pb,pc);
printf(“%d,%d,%d\n",a,b,c);
printf(“%d,%d,%d\n",*pa,*pb,*pc);}
第二节 指针与变量第 10章 指针
21
一、指向数组元素的指针二、通过指针引用数组元素三、数组名做函数参数四、多维数组与指针第三节 指针和数组第 10章 指针
22
一、指向数组元素的指针首先定义一个 整型数组 a,再定义一个指向整型变量的 指针变量 p,然后将此数 组的 第 0号元素的地址赋予 p,此时 p就是指向 a数组的指针,数组的指针就是数组的 起始地址 。例如:
int a[5];
int *p;
p=&a[0];
第三节 指针和数组
p a[0] a[4]
第 10章 指针
23
说明:
C语言中数组名代表数组的首地址,因此 p= &a[0]与 p= a 等价,这里 a代表数组的首地址 。
指针的类型必须同于数组元素的类型
定义指针的同时 赋予数组的首地址 。
例如,int a[8];
int *p= a; 或 int *p=&a[0];
第 10章 指针
24
二,通过指针变量引用一维数组的元素例如:定义如下数组和指针变量 p:
int a[8],i;
int *p= a;
p+1——指向数组的 下一个元素,而 不是 p值加 1。
(1)p+i和 a+i是地址,
可以 用 a+i*d计算,就是 a[i]的地址。
(2)*(p+i)和 *(a+i)
就是 p+i或 a+i所指向的数组元素 a[i]。
(3)a[i]和 *(p+i)等价第 10章 指针
25
引用一个数组元素的方法有:
(1) 下标法:
用 a[i] 来引用数组 a的第 i个数组元素。
(2) 指针法:
用 *(a+ i),*(p+ i)引用数组的第 i个数组元素。
第 10章 指针
26
例 5,输出 数组的全部元素。
1)用下标法
main()
{int a[10],i;
for( i=0; i<10; i++)
scanf ("%d ",&a[i]);
for(i=0;i<10;i++)
printf("%d ",a[i]);}
第 10章 指针
27
2) 通过 数组名 计算出数组元素的地址,找出元素的值
main()
{int a[10],i;
for( i=0; i<10; i++)
scanf ("%d ",&a[i]);
for(i=0;i<10;i++)
printf("%d ",*(a+i));}
第 10章 指针
28
3)用 指针变量 指向数组元素
main()
{int a[10],*p,i;
for(i=0; i<10; i++)
scanf ("%d ",&a[i]);
for(p=a; p<(a+10); p++)
printf("%d ",*p);}
第 10章 指针
29
三种方法的比较:
1,第 (1)(2)种方法执行效率相同,编译系统都将 a[i]转换为 *(a+i)算出地址。费时较多。
2、第 (3)种方法的表示方法较快,用指针变量直接指向元素,不必每次重新计算元素地址。 p++的运算很快 。
3,用下标法更直观一些。
第 10章 指针
30
说明:
( 1) 指针变量可以实现使本身的值改变。 如 使用 p++使 p的值不断改变,
但数组名 a却不行,因为 a是数组名,
表示的是数组的首地址,在程序运行期间其值固定不变,是常量,a++
是无意义的 。
第 10章 指针
31
( 2)注意 指针变量的当前值 。 下列程序是错误的
main()
{int *p,i,a[10]; p=a;
printf(“\nenter 10 numbers:\n");
for(i=0;i<10;i++) scanf("%d",p++);
printf("\n");
for(i=0;i<10;i++,p++) printf("%d ",*p); }
p
p
a[0] a[9]
要 插入 p=a;否则出错第 10章 指针
32
正确的程序为,
main()
{int *p,i,a[10]; p=a;
printf(“\nenter 10 numbers:\n");
for(i=0;i<10;i++)
scanf("%d",p++);
printf("\n"); p=a;
for(i=0;i<10;i++,p++)
printf("%d ",*p);}
第 10章 指针
33
(3)注意指针变量的运算
p++; ++p; /*使 p指向数组的后一个元素 */
p--; --p; /*使 p指向数组的前一个元素 */
p+n; p-n; /*使 p往后 (往前 )移 n个元素 */
p-q; /*求指针变量 p和 q之间元素的个数,
且 q在 p前 */
p+q /*两个地址相加,无意义 */
第 10章 指针
34
(3)注意指针变量的运算
*p++等价于 *(p++)
其作用是先得到 p指针变量的值 (即 *p),
然后再使 p+1→p
*(p++)与 *(++p)的作用不同前者先取 *p的值,后使指针变量 p加 1;
后者先使指针变量 p的值加 1,再取 *p。
(*p)++表示 p所指向的元素值加 1
第 10章 指针
35
三、数组名作函数的参数
用 指向数组的 指针变量作为函数的参数,
根据形式参数和实际参数的用法可有以下 4
种形式:
实际参数与形式参数 均为数组名
实际参数为数组名,形式参数为指针变量
实际参数为指针变量,形式参数为数组名
实际参数和形式参数 均为指针变量第三节 指针和数组第 10章 指针
36
形参和实参都是数组名,
main()
{int a[10];
…
f(a,10);
}
f(int x[ ],int n)
{…
}
第 10章 指针
37
例 7a,将数组 a中的 n个数逆序存放 。
void invert(int x[],int n) /*形参用数组名 */
{int i,temp;
for(i=0;i<=(n-1)/2;i++)
{temp=x[i];x[i]=x[n-1-i];x[n-1-i]=temp;}}
main()
{int a[10]={1,3,5,7,9,11,13,15,17,19}; int i;
for(i=0;i<10;i++)printf(“%5d”,a[i]);
invert(a,10); /* 实参为数组名 */
for(i=0;i<10;i++)printf(“%5d”,a[i]);}
第三节 指针和数组第 10章 指针
38
形参是指针变量,实参是数组名
main()
{int a[10];
…
f(a,10);
}
f(int *x,int n)
{…
}
第 10章 指针
39
例 7b,将数组 a中的 n个数逆序存放 。
main()
{int a[10]={1,3,5,7,9,11,13,15,17,19};int i;
void invert();
for(i=0;i<10;i++)printf(“%5d”,a[i]);
invert(a,10); /* 实参为数组名 */
for(i=0;i<10;i++)printf(“%5d”,a[i]);}
void invert(int *x,int n) /*形参用指针变量 */
{int i,temp;
for(i=0;i<=(n-1)/2;i++)
{temp=*(x+i); *(x+i)=*(x+n-1-i);
*(x+n-1-i)=temp;}}
第三节 指针和数组第 10章 指针
40
形参是数组名,实参是指针变量
main()
{int a[10],*p;
p=a;
…
f(p,10);
}
f(int x[ ],int n)
{…
}
第 10章 指针
41
例 7c,将数组 a中的 n个数逆序存放 。
void invert(int x[],int n) /*形参为数组名 */
{int i,temp;
for(i=0;i<=(n-1)/2;i++)
{temp=x[i];x[i]=x[n-1-i];x[n-1-i]=temp;}}
main()
{int a[10]={1,3,5,7,9,11,13,15,17,19};
int i,*p; p=a;
for(i=0;i<10;i++)printf(“%5d”,a[i]);
invert(p,10); /*实参为指针变量 */
for(i=0;i<10;i++)printf(“%5d”,a[i]);}
第三节 指针和数组第 10章 指针
42
形参和实参都是指针变量
main()
{int a[10],*p;
p=a;
…
f(p,10);
}
f(int *x,int n)
{…
}
第 10章 指针
43
例 7d,将数组 a中的 n个数逆序存放 。
main()
{int a[10]={1,3,5,7,9,11,13,15,17,19},i,*p;
void invert(); p=a;
for(i=0;i<10;i++) printf(“%5d”,a[i]);
invert(p,10); /*实参为指针变量 */
for(i=0;i<10;i++) printf(“%5d”,a[i]);}
void invert(int *x,int n)/*形参为指针变量 */
{int i,temp;
for(i=0;i<=(n-1)/2;i++)
{temp=*(x+i);*(x+i)=*(x+n-1-i);
*(x+n-1-i)=temp;} }
第三节 指针和数组第 10章 指针
45
int max,min; /* 全局变量 */
void max_min(int x[],int n)
{int *p; max=min=*x;
for(p=x+1;p<x+n;p++)
if(*p>max) max=*p
else if(*p<min) min=*p;}
main()
{int i,a[10]={2,5,8,3,9,0,6,4,1,7};
max_min(a,10);
printf(“\nmax=%d,min=%d”,max,min);}
例 8,从 10个数中找出最大数和最小数。
第 10章 指针
46
例 9,求一维数组中 下标为偶数 的元素之和。
main()
{ int a[8]={1,2,3,4,5,6,7,8}; int *p=a,sum;
sum=add(p,8);
printf(“\nsum=%d\n”,sum);}
int add(int *p1,int n)
{ int i,total=0;
for(i=0;i<n;i=i+2,p1=p1+2)
total=total+*p1;
return(total);}
第 10章 指针
47
main()
{int *p,i,a[10];
p=a; printf("\n");
for(i=0;i<10;i++)
scanf("%d",p++);
p=a; sort(p,10);
for(p=a,i=0;i<10;i++)
printf("%5d",*p++);
}
sort(int x[],int n)
{int i,j,k,t;
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)
{t=x[i];x[i]=x[k];x[k]=t;}
}
}
例 10:用选择法对 10个整数排序。
第 10章 指针
65
一,字符串的表示形式二,指向字符串指针变量三,字符指针作为函数的参数第四节 指针与字符串第 10章 指针
66
一、字符串的表示形式在前面,我们用过了字符数组,即通过数组名 来表示字符串,数组名就是数组的首地址,是字符串的起始地址 。
如,char c[10];
scanf(“%s”,a); scanf(“%c”,&a[5]);
printf(“%s”,a); printf(“%c”,a[2]);
第五节 指针与字符串第 10章 指针
67
一、字符串的表示形式
C语言中,既可以用 字符数组 表示字符串,也可用 字符指针变量 来表示;引用时,
既可以 逐个字符引用,也可以 整体引用 。
char ch[10]=“I am a student!”;
char *q=“my name is boy!”;
第五节 指针与字符串第 10章 指针
68
一、字符串的表示形式
( 1) 逐个引用例,使用字符指针变量表示和引用字符串
main()
{ char *string=”I love Beijing.”;
for( ; *string!=’\0’; string++)
printf(“%c”,*string); }
第五节 指针与字符串第 10章 指针
69
一、字符串的表示形式
( 2) 整体引用例,采取整体引用的办法,改写上例。
main()
{ char *string=”I love Beijing.”;
printf(“%s\n”,string); }
第五节 指针与字符串第 10章 指针
70
一、字符串的表示形式
( 3) 字符串指针变量与字符数组 之比较虽然用字符指针变量和字符数组都能实现字符串的存储和处理,但二者是有区别的,
不能混为一谈。
存储内容不同,字符指针变量中存储的是 字符串的首地址,而字符数组中存储的是 字符串本身 。
第五节 指针与字符串第 10章 指针
71
一、字符串的表示形式
( 3) 字符串指针变量与字符数组 之比较赋值方式不同,
假设有 char *p; char a[30]; 则,
p=“This’s a example.”; p=a;( 正确 )
scanf(“%s”,a); ( 正确 )
a=“This is a example.”; ( 错误 )
scanf(“%s”,p); ( 错误 )
第五节 指针与字符串第 10章 指针
72
一、字符串的表示形式
( 3) 字符串指针变量与字符数组 之比较另外,字符指针变量的值是可以改变的,即可以指向另一个字符串或者字符串的任意一个字符;而字符数组名代表数组的起始地址
,是一个常量,而常量是不能被改变的。
第五节 指针与字符串第 10章 指针
73
说明:
在定义一个字符指针变量时,先给它赋一个初值,否则,有可能会破坏程序,造成严重的后果。
请看下面的程序段:
(1) char s[10];
scanf(“%s”,s);
(2) char *p;
scanf(“%s”,p);
(3) char s[10],*p; p=s;
scanf(“%s”,p);
第 10章 指针
74
1.用字符数组来实现
main( )
{char st[20];
scanf(“%s”,st);
printf(“%s”,st);}
第五节 指针与字符串二、指向字符串指针变量的应用
2.用 字符指针变量来实现
main( )
{char st[20],*pc;
pc=st;
scanf("%s",pc);
printf("%s\n",pc);}
第 10章 指针
75
1,用字符数组来实现
main( )
{char a[]=“I am a
student.”,b[30];
int i=0;
while(a[i]!=?\0?)
{b[i]=a[i];i++;}
b[i]=?\0?;
printf(“%s”,b);}
第五节 指针与字符串例 17,将字符串 a复制到字符串 b
2.用 字符指针变量来实现
main( )
{ char a[]=“I am a
student.”,b[30],*pa,*pb;
pa=a;pb=b;
while(*pa!= '\0')
{*pb=*pa;pa++;pb++;}
*pb=?\0?;
printf("%s",b);}
第 10章 指针
76
使用指针变量输出字符串中的部分数据 。
main()
{ char *s1="C language";
s1+=2;
printf("%s\n",s1);}
程序运行结果如下,language
说明:
如果定义 char s1[20],则不能使用如下语句,s1+=2;因为 s1是一个常量,不能对它赋值 。
第 10章 指针
77
例 18,输入一行文字,统计其中大写字母、小写字母、数字、空格和其它字符的个数 。
#include "stdio.h"
main()
{int up=0,low=0,space=0,digit=0,other=0,i;
char str[60],*p;
gets(str);
for(p=str;*p!='\0';p++)
{if('A'<=*p&&*p<='Z') up++;
else if('a'<=*p&&*p<='z') low++;
else if(*p==' ') space++;
else if(*p<='9'&&*p>='0') digit++;
else other++; }
printf("up=%d low=%d space=%d",up,low,space);
printf(" digit=%d other=%d\n",digit,other);}
第 10章 指针
78
三,字符指针作为函数的参数
1,字符指针作为函数的实参字符指针也可以作为函数的实际参数,因为传送的是 字符串的首地址,所以 形参修改了,实参也会随之做相同的改变 。
例 19,将例 17中的字符串的复制用函数来实现 。
void strcopy(char from[],char to[])
{ int i=0;
while(from[i]!= '\0')
{to[i]=from[i];i++}
to[i]= '\0';}
第五节 指针与字符串第 10章 指针
79
main( )
{ char a[80],b[80],*pa,*pb;
pa=a;pb=b;
scanf("%s",pa); /* 或用 scanf("%s",a); */
strcopy(pa,pb); /* 或用 strcopy(a,b); */
printf("%s",pb); /* 或用 printf("%s",b); */
}
第 10章 指针
80
2、字符指针作为函数的形参
void strcopy(char *from,char *to)
{while(*from!= '\0')
{*to=*from;to++;from++;}
*to= '\0'; }
main()
{char a[80],b[80],*pa,*pb;
pa=a;pb=b;
scanf("%s",pa); /*或用 scanf("%s",a);*/
strcopy(pa,pb); /*或用 strcopy(a,b);*/
printf("%s",pb); } /*或用 printf("%s",b);*/
第 10章 指针
81
一、指向函数的指针变量二、用指向函数的指针变量作函数的参数三、返回指针值的函数第五节 指针与函数第 10章 指针
82
一、指向函数的指针变量
一个函数在内存中占一片存储空间 。在函数被编译时,被分配给一个入口地址,这个入口地址 就称为 函数的指针 。
用一个指针变量指向函数,然后用 指向函数的指针变量代替函数名来调用这个函数。
第四节 指针与函数第 10章 指针
83
函数的指针的定义类型说明符 (*指针变量名 )( );
例如,int (*p)( );
表示定义了一个指向函数的指针变量 p,函数的返回值是整型。
函数的调用形式
( *指针变量)(实参表列 );
例如,(*p) (a,b);
注意!
与 int *p();的区别第 10章 指针
84
说明:
(*p)()表示定义一个指向函数的指针变量,它不固定指向哪一个函数,把哪个函数的地址赋给它,
就指向哪一个函数;
函数的调用可以通过 函数名,也可以通过 函数指针;
给函数指针赋值时,只需给出函数名,不需给出参数,如 p=min;
调用时,只需将 (*p)代替函数名即可;
对指向函数的指针变量 p,p++的运算是无效的。
第 10章 指针
85
例 15,求 a,b中的最小者。
min(int x,int y)
{ int z; z=x<y? x:y; return(z); }
main()
{int (*p)(int,int); int a,b,m; p=min;
scanf(“\n%d,%d",&a,&b);
m=(*p)(a,b);
printf("\na=%d,b=%d,min=%d\n",a,b,m); }
程序中 用函数的指针变量来调用函数 min。需要注意的是,在用指针变量调用函数之前,应先将函数入口地址赋给指针变量。
m=(*p)(a,b);
m=min(a,b);
第 10章 指针
86
二、用指向函数的指针作函数的参数可以用 指向函数的指针变量 作为被调用函数的参数,由于指针变量是指向某一函数的,所以先后使指针指向不同的函数,就可以在主调函数中调用不同的函数。 例如,定义一个函数 sub,它有两个形参 x1,x2为指向函数的指针变量,调用函数 sub时,实参用两个函数名 f1,f2给形参传递函数地址:
第四节 指针与函数第 10章 指针
87
二、用指向函数的指针作函数的参数
sub(x1,x2) main()
int (*x1)( ),(*x2)( ); {...
{int a,b,c,d; sub(f1,f2);
c=(*x1)(a); sub(f3,f4);
d=(*x2)(a,b); …}
}
第四节 指针与函数第 10章 指针
88
例 16,设一个函数 process,在调用它的时候,每次实现不同的功能,
(1)求 a和 b之和 (2)指 a,b中大者 (3)求 a,b中小者
main()
{int add(),max(),min(); int a,b;
printf("please input a and b:\n");
scanf("%d,%d",&a,&b);
printf("sum="); process(a,b,add);
printf("max="); process(a,b,max);
printf("min="); process(a,b,min); }
第 10章 指针
89
add(int x,int y)
{int z;
z=x+y;
return(z);}
max(int x,int y)
{int z;
if(x>y) z=x;
else z=y;
return(z);}
min(int x,int y)
{int z;
if(x<y) z=x;
else z=y;
return(z);}
process(int x,int y,int(*fun)())
{int result;
result=(*fun)(x,y);
printf("%d\n",result);}
第 10章 指针
92
三、返回指针值的函数
一个函数可以带回一个整型值、字符值、实型值等,也可以带回指针型的数据,即地址。 这种函数的定义形式如下:
类型说明符 *函数名 (参数表 )
参数说明 ;
{函数体 }
例如定义,int *search(int *x,int n)
{int *p;
p=x+n;
return(p);}
第四节 指针与函数第 10章 指针
109
指针小结
int *p; 指向整型量的指针
int (*p)[4]; 指向一维整型数组的,行指针
int (*p)( ); 指向函数的指针
int *p( ); 返回指针值的函数
int *p[4]; 指针数组,由 4个指针元素组成
int **p; 指向指针的指针注意,
指针在使用前一定要有明确的指向
优点,灵活、可实现动态存储分配
缺点,易出大错
第十章 指针与指针变量主讲 福州大学数学与计算机学院 韩晓芸
E-mail,hxy@fjtv.net
第 10章 指针
2
第一节 概述第二节 指针变量第三节 指针与数组第四节 指针与字符串第五节 指针与函数第六节 指针数组第七节 多级指针和命令行参数第 10章 指针
3
一、地址在程序中所定义的变量,编译系统会根据变量的类型,分配一定长度的存储空间。 内存中每一个字节有唯一编号。如:
int a 2个字节
float b 4个字节
char c 1个字节
6
5.3
2000
2002
2006 A
a
b
第一节 指针概述
c2007
第 10章 指针
4
二、访问变量的方式
直接访问方式按变量的 地址 存取变量的值 。
例如:
printf("%f",b);
scanf(“%d”,&a);
第一节 指针概述
2000
a
6
第 10章 指针
5
间接访问方式按变量的 地址的地址 存取变量的值。
例如,假设 变量 pa的地址为 1000,用变量 pa来存放 变量 a的地址 &a,此时 pa的值为 2000。如果要得到 a的值,可以 先访问变量 pa,得到 pa的值为 2000(变量 a的地址 ),再通过地址 2000找到所指存储单元中的值 (a的值 ),见图,
pa(1000) a
200
0
6
2000
第一节 指针概述第 10章 指针
6
三、指针一个变量的地址称为该变量的指针 。如地址
2000是变量 a的指针,2002是变量 b的指针。
四、指针变量如果有一个变量专门用来存放另一个变量的地址(即指针),称为指针变量 。如 pa是一个 指针变量,pa中的值为 指针 。
注意:指针和指针变量的概念第一节 指针概述第 10章 指针
7
一,指针变量的定义二,指针变量的引用三,指针作为函数的参数第二节 指针与变量第 10章 指针
8
一,指针变量定义类型说明符 *标识符;
例如,int *p1,*p2;
int——p1,p2是 指向 整型变量 的指针变量 。
*——指针标记 。
p1,p2——指针变量名 。
说明
指针可以指向 任何类型 的对象。
在定义了一个指针变量 p1,p2以后,系统为这个指针变量分配一个 存储单元 (一般为 2个字节)用来存放地址。
第二节 指针与变量第 10章 指针
9
例如,
int a,b;
int *p1,*p2;
p1= &a;
p2= &b;
&a
p1
p2
a
b
&b
第 10章 指针
10
二,指针变量的引用
&,取变量地址 运算符例如,&a为变量 a的 地址 。
*:,指向,运算符或称,间接访问,运算符例如,*p为指针变量 p所 指向的变量 。
如果有 p=&a,则 *p就是 a。
第二节 指针与变量第 10章 指针
11
例 1:
main( )
{int a,*pa;
float b,*pb;
a=10;
b=1.5;
pa=&a;
pb=&b;
printf("%d,%f\n”,a,b);
printf("%d,%f\n”,*pa,*pb);
}
单击鼠标,演示程序的执行过程:
pa
pb
a
b
&a
&b 1.5
10
第 10章 指针
12
说明:,&”和,*”两个运算符的 优先级相同,但按 自右向左 方向结合
–执行了 pa=&a;后,&*pa的含义?
与 &a相同。
–*&a的含义? 即 a,*pa。
–(*pa)++相当于 a++
–*pa++
相当于 *(pa++),即先取 *pa,即 a的原值,之后 pa自增,不再指向 a了。
第 10章 指针
13
例 2,指针变量应用的例子,
由大到小输出 a,b。
main()
{int a,b,*p,*pa,*pb;
a=3;b=6;
pa=&a; pb=&b;
if(a<b)
{ p=pa; pa=pb; pb=p;}
printf("%d%d\n",a,b);
printf("%d%d\n",*pa,*pb);
}
单击鼠标,演示程序的执行过程:
pa
pb
p
a
b
&a
&b 6
3
&a
&b
&a
第 10章 指针
14
第二节 指针与变量三,指针变量作为函数的参数
函数的参数也可以是指针类型,实际参数可以是地址常量或指针变量,形式参数则为指针变量 。 这种传递 也是值传递,即将实参指针变量的值传给对应的形参 。 但是由于指针变量存放的是地址值,作为函数的参数来进行传送的是 实参的值 -- --变量的地址 。
第 10章 指针
15
p1
pb
a
&a
6
3
&b
&a
pa
b
p2
&b
temp
3
6
3
void swap(int *p1,int *p2)
{int temp;
temp=*p1; *p1=*p2;
*p2=temp; }
main( )
{int a,b; int *pa,*pb;
scanf("%d,%d",&a,&b);
pa=&a; pb=&b;
if(a<b) swap(pa,pb);
printf("%d,%d\n",a,b);
printf("%d,%d\n",*pa,*pb);}
第二节 指针与变量例 3,用函数来实现 两个数由大到小顺序输出。
第 10章 指针
16
?
P是不确定的值
,用 *p可能破坏系统的正常工作状态。
swap()能否写成下面的形式呢?
swap(int *p1,int *p2)
{int *p;
*p=*p1;
*p1=*p2;
*p2=*p;}
第二节 指针与变量第 10章 指针
17
?
a,b值的交换是通过形参传递回实参实现的吗? swap( )能否写成下面的形式呢?
swap(int x,int y)
{int t; t=x;x=y;y=t;}
如果在 main函数中有 swap(a,b),结果会怎样?
第二节 指针与变量第 10章 指针
18
?
swap()能否写成下面这种形式?
swap(p1,p2)
int *p1,*p2;
{int *p;
p=p1;
p1=p2;
p2=p;}
main( )
{int a,b; int *pa,*pb;
scanf("%d,%d",&a,&b);
pa=&a; pb=&b;
if(a<b) swap(pa,pb);
printf("%d,%d\n",a,b);
printf("%d,%d\n",*pa,*pb);
}
第二节 指针与变量第 10章 指针
19
例 4:输入 a,b,c三个整数,由大到小顺序输出。
void swap(int *p1,int *p2)
{int temp;
temp=*p1;
*p1=*p2;
*p2=temp;}
第二节 指针与变量第 10章 指针
20
例 4(续 ):输入 a,b,c三个整数,由大到小输出。
main()
{int a,b,c; int *pa,*pb,*pc;
scanf(“%d,%d,%d”,&a,&b,&c);
pa=&a;pb=&b;pc=&c;
if(*pa<*pb) swap(pa,pb);
if(*pa<*pc) swap(pa,pc);
if(*pb<*pc) swap(pb,pc);
printf(“%d,%d,%d\n",a,b,c);
printf(“%d,%d,%d\n",*pa,*pb,*pc);}
第二节 指针与变量第 10章 指针
21
一、指向数组元素的指针二、通过指针引用数组元素三、数组名做函数参数四、多维数组与指针第三节 指针和数组第 10章 指针
22
一、指向数组元素的指针首先定义一个 整型数组 a,再定义一个指向整型变量的 指针变量 p,然后将此数 组的 第 0号元素的地址赋予 p,此时 p就是指向 a数组的指针,数组的指针就是数组的 起始地址 。例如:
int a[5];
int *p;
p=&a[0];
第三节 指针和数组
p a[0] a[4]
第 10章 指针
23
说明:
C语言中数组名代表数组的首地址,因此 p= &a[0]与 p= a 等价,这里 a代表数组的首地址 。
指针的类型必须同于数组元素的类型
定义指针的同时 赋予数组的首地址 。
例如,int a[8];
int *p= a; 或 int *p=&a[0];
第 10章 指针
24
二,通过指针变量引用一维数组的元素例如:定义如下数组和指针变量 p:
int a[8],i;
int *p= a;
p+1——指向数组的 下一个元素,而 不是 p值加 1。
(1)p+i和 a+i是地址,
可以 用 a+i*d计算,就是 a[i]的地址。
(2)*(p+i)和 *(a+i)
就是 p+i或 a+i所指向的数组元素 a[i]。
(3)a[i]和 *(p+i)等价第 10章 指针
25
引用一个数组元素的方法有:
(1) 下标法:
用 a[i] 来引用数组 a的第 i个数组元素。
(2) 指针法:
用 *(a+ i),*(p+ i)引用数组的第 i个数组元素。
第 10章 指针
26
例 5,输出 数组的全部元素。
1)用下标法
main()
{int a[10],i;
for( i=0; i<10; i++)
scanf ("%d ",&a[i]);
for(i=0;i<10;i++)
printf("%d ",a[i]);}
第 10章 指针
27
2) 通过 数组名 计算出数组元素的地址,找出元素的值
main()
{int a[10],i;
for( i=0; i<10; i++)
scanf ("%d ",&a[i]);
for(i=0;i<10;i++)
printf("%d ",*(a+i));}
第 10章 指针
28
3)用 指针变量 指向数组元素
main()
{int a[10],*p,i;
for(i=0; i<10; i++)
scanf ("%d ",&a[i]);
for(p=a; p<(a+10); p++)
printf("%d ",*p);}
第 10章 指针
29
三种方法的比较:
1,第 (1)(2)种方法执行效率相同,编译系统都将 a[i]转换为 *(a+i)算出地址。费时较多。
2、第 (3)种方法的表示方法较快,用指针变量直接指向元素,不必每次重新计算元素地址。 p++的运算很快 。
3,用下标法更直观一些。
第 10章 指针
30
说明:
( 1) 指针变量可以实现使本身的值改变。 如 使用 p++使 p的值不断改变,
但数组名 a却不行,因为 a是数组名,
表示的是数组的首地址,在程序运行期间其值固定不变,是常量,a++
是无意义的 。
第 10章 指针
31
( 2)注意 指针变量的当前值 。 下列程序是错误的
main()
{int *p,i,a[10]; p=a;
printf(“\nenter 10 numbers:\n");
for(i=0;i<10;i++) scanf("%d",p++);
printf("\n");
for(i=0;i<10;i++,p++) printf("%d ",*p); }
p
p
a[0] a[9]
要 插入 p=a;否则出错第 10章 指针
32
正确的程序为,
main()
{int *p,i,a[10]; p=a;
printf(“\nenter 10 numbers:\n");
for(i=0;i<10;i++)
scanf("%d",p++);
printf("\n"); p=a;
for(i=0;i<10;i++,p++)
printf("%d ",*p);}
第 10章 指针
33
(3)注意指针变量的运算
p++; ++p; /*使 p指向数组的后一个元素 */
p--; --p; /*使 p指向数组的前一个元素 */
p+n; p-n; /*使 p往后 (往前 )移 n个元素 */
p-q; /*求指针变量 p和 q之间元素的个数,
且 q在 p前 */
p+q /*两个地址相加,无意义 */
第 10章 指针
34
(3)注意指针变量的运算
*p++等价于 *(p++)
其作用是先得到 p指针变量的值 (即 *p),
然后再使 p+1→p
*(p++)与 *(++p)的作用不同前者先取 *p的值,后使指针变量 p加 1;
后者先使指针变量 p的值加 1,再取 *p。
(*p)++表示 p所指向的元素值加 1
第 10章 指针
35
三、数组名作函数的参数
用 指向数组的 指针变量作为函数的参数,
根据形式参数和实际参数的用法可有以下 4
种形式:
实际参数与形式参数 均为数组名
实际参数为数组名,形式参数为指针变量
实际参数为指针变量,形式参数为数组名
实际参数和形式参数 均为指针变量第三节 指针和数组第 10章 指针
36
形参和实参都是数组名,
main()
{int a[10];
…
f(a,10);
}
f(int x[ ],int n)
{…
}
第 10章 指针
37
例 7a,将数组 a中的 n个数逆序存放 。
void invert(int x[],int n) /*形参用数组名 */
{int i,temp;
for(i=0;i<=(n-1)/2;i++)
{temp=x[i];x[i]=x[n-1-i];x[n-1-i]=temp;}}
main()
{int a[10]={1,3,5,7,9,11,13,15,17,19}; int i;
for(i=0;i<10;i++)printf(“%5d”,a[i]);
invert(a,10); /* 实参为数组名 */
for(i=0;i<10;i++)printf(“%5d”,a[i]);}
第三节 指针和数组第 10章 指针
38
形参是指针变量,实参是数组名
main()
{int a[10];
…
f(a,10);
}
f(int *x,int n)
{…
}
第 10章 指针
39
例 7b,将数组 a中的 n个数逆序存放 。
main()
{int a[10]={1,3,5,7,9,11,13,15,17,19};int i;
void invert();
for(i=0;i<10;i++)printf(“%5d”,a[i]);
invert(a,10); /* 实参为数组名 */
for(i=0;i<10;i++)printf(“%5d”,a[i]);}
void invert(int *x,int n) /*形参用指针变量 */
{int i,temp;
for(i=0;i<=(n-1)/2;i++)
{temp=*(x+i); *(x+i)=*(x+n-1-i);
*(x+n-1-i)=temp;}}
第三节 指针和数组第 10章 指针
40
形参是数组名,实参是指针变量
main()
{int a[10],*p;
p=a;
…
f(p,10);
}
f(int x[ ],int n)
{…
}
第 10章 指针
41
例 7c,将数组 a中的 n个数逆序存放 。
void invert(int x[],int n) /*形参为数组名 */
{int i,temp;
for(i=0;i<=(n-1)/2;i++)
{temp=x[i];x[i]=x[n-1-i];x[n-1-i]=temp;}}
main()
{int a[10]={1,3,5,7,9,11,13,15,17,19};
int i,*p; p=a;
for(i=0;i<10;i++)printf(“%5d”,a[i]);
invert(p,10); /*实参为指针变量 */
for(i=0;i<10;i++)printf(“%5d”,a[i]);}
第三节 指针和数组第 10章 指针
42
形参和实参都是指针变量
main()
{int a[10],*p;
p=a;
…
f(p,10);
}
f(int *x,int n)
{…
}
第 10章 指针
43
例 7d,将数组 a中的 n个数逆序存放 。
main()
{int a[10]={1,3,5,7,9,11,13,15,17,19},i,*p;
void invert(); p=a;
for(i=0;i<10;i++) printf(“%5d”,a[i]);
invert(p,10); /*实参为指针变量 */
for(i=0;i<10;i++) printf(“%5d”,a[i]);}
void invert(int *x,int n)/*形参为指针变量 */
{int i,temp;
for(i=0;i<=(n-1)/2;i++)
{temp=*(x+i);*(x+i)=*(x+n-1-i);
*(x+n-1-i)=temp;} }
第三节 指针和数组第 10章 指针
45
int max,min; /* 全局变量 */
void max_min(int x[],int n)
{int *p; max=min=*x;
for(p=x+1;p<x+n;p++)
if(*p>max) max=*p
else if(*p<min) min=*p;}
main()
{int i,a[10]={2,5,8,3,9,0,6,4,1,7};
max_min(a,10);
printf(“\nmax=%d,min=%d”,max,min);}
例 8,从 10个数中找出最大数和最小数。
第 10章 指针
46
例 9,求一维数组中 下标为偶数 的元素之和。
main()
{ int a[8]={1,2,3,4,5,6,7,8}; int *p=a,sum;
sum=add(p,8);
printf(“\nsum=%d\n”,sum);}
int add(int *p1,int n)
{ int i,total=0;
for(i=0;i<n;i=i+2,p1=p1+2)
total=total+*p1;
return(total);}
第 10章 指针
47
main()
{int *p,i,a[10];
p=a; printf("\n");
for(i=0;i<10;i++)
scanf("%d",p++);
p=a; sort(p,10);
for(p=a,i=0;i<10;i++)
printf("%5d",*p++);
}
sort(int x[],int n)
{int i,j,k,t;
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)
{t=x[i];x[i]=x[k];x[k]=t;}
}
}
例 10:用选择法对 10个整数排序。
第 10章 指针
65
一,字符串的表示形式二,指向字符串指针变量三,字符指针作为函数的参数第四节 指针与字符串第 10章 指针
66
一、字符串的表示形式在前面,我们用过了字符数组,即通过数组名 来表示字符串,数组名就是数组的首地址,是字符串的起始地址 。
如,char c[10];
scanf(“%s”,a); scanf(“%c”,&a[5]);
printf(“%s”,a); printf(“%c”,a[2]);
第五节 指针与字符串第 10章 指针
67
一、字符串的表示形式
C语言中,既可以用 字符数组 表示字符串,也可用 字符指针变量 来表示;引用时,
既可以 逐个字符引用,也可以 整体引用 。
char ch[10]=“I am a student!”;
char *q=“my name is boy!”;
第五节 指针与字符串第 10章 指针
68
一、字符串的表示形式
( 1) 逐个引用例,使用字符指针变量表示和引用字符串
main()
{ char *string=”I love Beijing.”;
for( ; *string!=’\0’; string++)
printf(“%c”,*string); }
第五节 指针与字符串第 10章 指针
69
一、字符串的表示形式
( 2) 整体引用例,采取整体引用的办法,改写上例。
main()
{ char *string=”I love Beijing.”;
printf(“%s\n”,string); }
第五节 指针与字符串第 10章 指针
70
一、字符串的表示形式
( 3) 字符串指针变量与字符数组 之比较虽然用字符指针变量和字符数组都能实现字符串的存储和处理,但二者是有区别的,
不能混为一谈。
存储内容不同,字符指针变量中存储的是 字符串的首地址,而字符数组中存储的是 字符串本身 。
第五节 指针与字符串第 10章 指针
71
一、字符串的表示形式
( 3) 字符串指针变量与字符数组 之比较赋值方式不同,
假设有 char *p; char a[30]; 则,
p=“This’s a example.”; p=a;( 正确 )
scanf(“%s”,a); ( 正确 )
a=“This is a example.”; ( 错误 )
scanf(“%s”,p); ( 错误 )
第五节 指针与字符串第 10章 指针
72
一、字符串的表示形式
( 3) 字符串指针变量与字符数组 之比较另外,字符指针变量的值是可以改变的,即可以指向另一个字符串或者字符串的任意一个字符;而字符数组名代表数组的起始地址
,是一个常量,而常量是不能被改变的。
第五节 指针与字符串第 10章 指针
73
说明:
在定义一个字符指针变量时,先给它赋一个初值,否则,有可能会破坏程序,造成严重的后果。
请看下面的程序段:
(1) char s[10];
scanf(“%s”,s);
(2) char *p;
scanf(“%s”,p);
(3) char s[10],*p; p=s;
scanf(“%s”,p);
第 10章 指针
74
1.用字符数组来实现
main( )
{char st[20];
scanf(“%s”,st);
printf(“%s”,st);}
第五节 指针与字符串二、指向字符串指针变量的应用
2.用 字符指针变量来实现
main( )
{char st[20],*pc;
pc=st;
scanf("%s",pc);
printf("%s\n",pc);}
第 10章 指针
75
1,用字符数组来实现
main( )
{char a[]=“I am a
student.”,b[30];
int i=0;
while(a[i]!=?\0?)
{b[i]=a[i];i++;}
b[i]=?\0?;
printf(“%s”,b);}
第五节 指针与字符串例 17,将字符串 a复制到字符串 b
2.用 字符指针变量来实现
main( )
{ char a[]=“I am a
student.”,b[30],*pa,*pb;
pa=a;pb=b;
while(*pa!= '\0')
{*pb=*pa;pa++;pb++;}
*pb=?\0?;
printf("%s",b);}
第 10章 指针
76
使用指针变量输出字符串中的部分数据 。
main()
{ char *s1="C language";
s1+=2;
printf("%s\n",s1);}
程序运行结果如下,language
说明:
如果定义 char s1[20],则不能使用如下语句,s1+=2;因为 s1是一个常量,不能对它赋值 。
第 10章 指针
77
例 18,输入一行文字,统计其中大写字母、小写字母、数字、空格和其它字符的个数 。
#include "stdio.h"
main()
{int up=0,low=0,space=0,digit=0,other=0,i;
char str[60],*p;
gets(str);
for(p=str;*p!='\0';p++)
{if('A'<=*p&&*p<='Z') up++;
else if('a'<=*p&&*p<='z') low++;
else if(*p==' ') space++;
else if(*p<='9'&&*p>='0') digit++;
else other++; }
printf("up=%d low=%d space=%d",up,low,space);
printf(" digit=%d other=%d\n",digit,other);}
第 10章 指针
78
三,字符指针作为函数的参数
1,字符指针作为函数的实参字符指针也可以作为函数的实际参数,因为传送的是 字符串的首地址,所以 形参修改了,实参也会随之做相同的改变 。
例 19,将例 17中的字符串的复制用函数来实现 。
void strcopy(char from[],char to[])
{ int i=0;
while(from[i]!= '\0')
{to[i]=from[i];i++}
to[i]= '\0';}
第五节 指针与字符串第 10章 指针
79
main( )
{ char a[80],b[80],*pa,*pb;
pa=a;pb=b;
scanf("%s",pa); /* 或用 scanf("%s",a); */
strcopy(pa,pb); /* 或用 strcopy(a,b); */
printf("%s",pb); /* 或用 printf("%s",b); */
}
第 10章 指针
80
2、字符指针作为函数的形参
void strcopy(char *from,char *to)
{while(*from!= '\0')
{*to=*from;to++;from++;}
*to= '\0'; }
main()
{char a[80],b[80],*pa,*pb;
pa=a;pb=b;
scanf("%s",pa); /*或用 scanf("%s",a);*/
strcopy(pa,pb); /*或用 strcopy(a,b);*/
printf("%s",pb); } /*或用 printf("%s",b);*/
第 10章 指针
81
一、指向函数的指针变量二、用指向函数的指针变量作函数的参数三、返回指针值的函数第五节 指针与函数第 10章 指针
82
一、指向函数的指针变量
一个函数在内存中占一片存储空间 。在函数被编译时,被分配给一个入口地址,这个入口地址 就称为 函数的指针 。
用一个指针变量指向函数,然后用 指向函数的指针变量代替函数名来调用这个函数。
第四节 指针与函数第 10章 指针
83
函数的指针的定义类型说明符 (*指针变量名 )( );
例如,int (*p)( );
表示定义了一个指向函数的指针变量 p,函数的返回值是整型。
函数的调用形式
( *指针变量)(实参表列 );
例如,(*p) (a,b);
注意!
与 int *p();的区别第 10章 指针
84
说明:
(*p)()表示定义一个指向函数的指针变量,它不固定指向哪一个函数,把哪个函数的地址赋给它,
就指向哪一个函数;
函数的调用可以通过 函数名,也可以通过 函数指针;
给函数指针赋值时,只需给出函数名,不需给出参数,如 p=min;
调用时,只需将 (*p)代替函数名即可;
对指向函数的指针变量 p,p++的运算是无效的。
第 10章 指针
85
例 15,求 a,b中的最小者。
min(int x,int y)
{ int z; z=x<y? x:y; return(z); }
main()
{int (*p)(int,int); int a,b,m; p=min;
scanf(“\n%d,%d",&a,&b);
m=(*p)(a,b);
printf("\na=%d,b=%d,min=%d\n",a,b,m); }
程序中 用函数的指针变量来调用函数 min。需要注意的是,在用指针变量调用函数之前,应先将函数入口地址赋给指针变量。
m=(*p)(a,b);
m=min(a,b);
第 10章 指针
86
二、用指向函数的指针作函数的参数可以用 指向函数的指针变量 作为被调用函数的参数,由于指针变量是指向某一函数的,所以先后使指针指向不同的函数,就可以在主调函数中调用不同的函数。 例如,定义一个函数 sub,它有两个形参 x1,x2为指向函数的指针变量,调用函数 sub时,实参用两个函数名 f1,f2给形参传递函数地址:
第四节 指针与函数第 10章 指针
87
二、用指向函数的指针作函数的参数
sub(x1,x2) main()
int (*x1)( ),(*x2)( ); {...
{int a,b,c,d; sub(f1,f2);
c=(*x1)(a); sub(f3,f4);
d=(*x2)(a,b); …}
}
第四节 指针与函数第 10章 指针
88
例 16,设一个函数 process,在调用它的时候,每次实现不同的功能,
(1)求 a和 b之和 (2)指 a,b中大者 (3)求 a,b中小者
main()
{int add(),max(),min(); int a,b;
printf("please input a and b:\n");
scanf("%d,%d",&a,&b);
printf("sum="); process(a,b,add);
printf("max="); process(a,b,max);
printf("min="); process(a,b,min); }
第 10章 指针
89
add(int x,int y)
{int z;
z=x+y;
return(z);}
max(int x,int y)
{int z;
if(x>y) z=x;
else z=y;
return(z);}
min(int x,int y)
{int z;
if(x<y) z=x;
else z=y;
return(z);}
process(int x,int y,int(*fun)())
{int result;
result=(*fun)(x,y);
printf("%d\n",result);}
第 10章 指针
92
三、返回指针值的函数
一个函数可以带回一个整型值、字符值、实型值等,也可以带回指针型的数据,即地址。 这种函数的定义形式如下:
类型说明符 *函数名 (参数表 )
参数说明 ;
{函数体 }
例如定义,int *search(int *x,int n)
{int *p;
p=x+n;
return(p);}
第四节 指针与函数第 10章 指针
109
指针小结
int *p; 指向整型量的指针
int (*p)[4]; 指向一维整型数组的,行指针
int (*p)( ); 指向函数的指针
int *p( ); 返回指针值的函数
int *p[4]; 指针数组,由 4个指针元素组成
int **p; 指向指针的指针注意,
指针在使用前一定要有明确的指向
优点,灵活、可实现动态存储分配
缺点,易出大错