C++:定义两个函数vb中swap函数1和vb中swap函数2,目的是实现两个整数的次序交换……

swap1交换变量地址为什么变量值不变呢?;swap2进行X与Y的值互换为什么X=Y=10了呢?
[问题点数:40分,结帖人Recruit_S]
本版专家分:0
结帖率 100%
CSDN今日推荐
本版专家分:137847
2017年 总版技术专家分年内排行榜第六
2018年1月 总版技术专家分月排行榜第一2016年12月 总版技术专家分月排行榜第一2016年11月 总版技术专家分月排行榜第一2016年10月 总版技术专家分月排行榜第一
2016年10月优秀大版主2016年8月优秀大版主
2018年5月 总版技术专家分月排行榜第二2017年12月 总版技术专家分月排行榜第二2016年9月 总版技术专家分月排行榜第二
本版专家分:66803
2016年7月 总版技术专家分月排行榜第一2016年6月 总版技术专家分月排行榜第一2016年4月 总版技术专家分月排行榜第一
2016年5月 总版技术专家分月排行榜第二
2016年10月优秀大版主2016年8月论坛优秀大版主
2016年11月 总版技术专家分月排行榜第三2016年8月 总版技术专家分月排行榜第三
本版专家分:370092
2017年 总版技术专家分年内排行榜第一
2014年 总版技术专家分年内排行榜第二
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
本版专家分:0
匿名用户不能发表回复!
其他相关推荐在一个c语言程序源文件中
把所有的东西都写在main函数中,这是最原始的写法,整个源文件里只有一个函数
升级的写法是,对函数的功能进行拆分,一个函数只完成一个相对完整、独立的功能,c语言中函数存在的意义就是实现某一类具体的功能——整个源文件中,有多个函数——一个main函数,和main函数中调用的多个子函数
任何一个函数都是,函数的入口——一对一、对应一个——函数的出口,是一一映射
对于main函数最主要的说法是——main函数是整个程序的入口,这个体现在哪里??
如果是整个源文件里,只有一个main函数(即,把所有的东西都写在main函数中)——整个程序是从main函数进入程序,由于整个源文件里只有main函数一个函数,体现不出来所谓“整个程序的入口”
只有,当整个源文件里,除了main函数自己、还有其他子函数存在的时候,才能体现出来这句话的含义——即 一个程序片里有多个函数,并且通常的书写顺序是 子函数写在main函数的前头(至少是子函数声明在前 子函数的定义可以写在main函数的后头),但即便是这样,即便c语言遵循顺序结构,当系统执行程序的时候,程序依然只会从main函数开始执行,将它作为程序的唯一入口,即便有其他的子函数书写在main函数的前面
现在我们的程序源文件中,不再是一个main函数包打天下,而是一个孤立的main函数、和若干个被调用的子函数(n&=1)——以这个作为前提,我们讨论下面的话题
函数中,变量的作用域
——变量在main函数的作用域、有效期限
——变量在子函数的作用域、有效期限
子函数swap()的实例
1.单纯的交换:交换两个整型数字变量——升级——交换两个整形数组
子函数的形参、main函数调用子函数时的实参
——要想好使 需要将main函数中的printf()一起打包
void swap(int a,int b)
tmp=a;a=b;b=
printf("子函数的作用域内 %d %d\n",a,b);
void swap(int a,int b)
tmp=a;a=b;b=
printf("子函数的作用域内 %d %d\n",a,b);
int main()
int a1,a2;
swap(a1,a2);
printf("主函数的作用域内 %d %d\n",a1,a2);
system("pause");
int main()
swap(a[1],a[2]);
printf("主函数的作用域内 %d %d\n",a[1],a[2]);
system("pause");
2.坑爹的冒泡排序:这tm是使用了全局变量
——要想不打包printf(),那就得用全局变量
#include &stdio.h&
#include &stdlib.h&
int book[100];
void bubbleSort(n)
int f_x,g_f_x;
for(g_f_x=1;g_f_x&=n-1;g_f_x++)
for(f_x=0;f_x&=(n-1)-g_f_x;f_x++)
if(book[f_x]&=book[f_x+1])
temp=book[f_x];book[f_x]=book[f_x+1];book[f_x+1]=
int main()
printf("请你告诉我,一共有多少个数要排序? \n");
scanf("%d",&n);
for(i=0;i&=n-1;i++)
printf("请输入第%d个要排序的数:",i+1);
scanf("%d",&book[i]);
bubbleSort(n);
printf("冒泡排序得出的结论是:",book[i]);
for(i=0;i&=n-1;i++)
printf("%d ",book[i]);
printf("\n");
system("pause");
3.然而——c语言 尽量不用全局变量(本科老师确实讲过 网上大家也都说是这样并给出了充分的理由)——原因 自己百度
百度关键字 c语言 尽量不用全局变量
4.既不想打包printf(),又不想用全局变量怎么办——用指针——啥是指针——零基c,第十章中对于“传值”和“传址”的讲解,自己看
子函数swap()
1.可以使用int型数字变量做形参——同时使用int型一维数组元素做实参
2.使用整个int型一维数组、而不是单个的数组元素做形参,与1.中所说的情况不是一回事,是另外一种情况——两者不要搅和到一起
3.内部函数 与 外部函数
以上讲述的内容,其范畴在于整个工程只有一个程序源文件(但是这个源文件中可以有多个函数)——属于内部函数问题,即人民内部矛盾
——整个工程中如果有多个程序源文件(每个源文件中又有多个函数),源文件1中的某个函数甲,需要调用源文件3中的某个函数丁——这属于外部函数问题,即洋人和中华民族的矛盾——外部函数问题,关键字static专门解决这个问题
这是两回事儿,不要搅和到一起
main函数参数的使用和指针数组的理解结合实例
1.使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。
实参和形参指针做函数参数时,如何改变main函数变量的值
//对输入的两个整数按大小顺序输出
代码如下:
int main()
void swap(int *p1,int *p2);...
c++指针使用形参改变实参
将10个整数按由小到大的顺序排列
int main()
//使用形参改变实参数
//将10个整数按由小到大的顺序排列
C语言——通过调用函数改变形参指针 改变实参指针问题
1,按值传递,在调用函数的时候,将指向数据的指针实参传递到调用函数的形参中去
2,单向传递,形参中的指针子函数改变地址后不能传给主调函数,变量同样指向了我们希望处理的数据,然后对形参的指针变量指向的...
C语言中数组指针
在修改程序的过程中,看到两种将数组作为形参的方法,于是搜了一下,找了一下比较全面地介绍数组指针的文章。
先写下我遇到的两种方式:
void filter_c(lo...
函数调用参数为指针时,实参跟形参的问题
void change(int *p){
int val = 5;
printf(&%p\n&, p);
用指针变量作函数形参接收数组地址,解决10个整数按由小到大顺序排序问题
用指针变量作函数形参接收数组地址,解决10个整数按由大到小顺序排序问题
void select_Sort(int *p,in...
C++中数组作为形参时,实际传的是指针
传数组时,实际上是创建了临时的指针变量,指向传进去的那个数组。在函数中改变形参数组(临时指针变量)的指向是可以的,只不过这样做不会改变原来的数组
//例子说明数组做形参时,实际上是用一个临时...
指针数组做函数参数
int main()
void average(float *p, int n);
void search(float (*p)[4], int...
数组指针作为形参传递
当数组作为函数形参时,数组的地址可以用做函数调用的实参。
可以通过数组地址的传递,在函数内可以对该数组进行访问和修改。
#define SIZE 10
/* 形式1 */...
没有更多推荐了,def swapIntegers(self,A,index1,index2):
t = A[index1]
A[index1] = A[index2]
A[index2] = tA=[1,2,3,4]print(A)swapIntegers(A,A,2,3)
#输入俩个A..print(A)
Python中交换两个元素的方法
Python既具有普通程序开发语言的特点,也具有Matlab语言用于数值计算的特点,,当然了数值计算是由其其强大的第三方库numpy实现的,矩阵在python中数据类型是ndarray,python中...
numpy.ndarray 交换多维数组(矩阵)的行/列
&& import numpy as np
python 中List 与array互换
输入list:&&& import numpy as np
&&& a = [[1,2],[3,4]]
&&& type(a)
将list转换为数组:&&& b = np.array(a)
交换数组两个元素
超级幼稚的一道题,结果硬是纠结了好久:题目链接:点击打开链接代码:python:class Solution:
@param A: An inte...
【Python】变量数值交换、判断数组是否含有某个元素
本来,这两个问题都属于的编程入门简单得不能再简单的问题,根本就不值得写篇记录来记录的。
一、变量数值交换
先说变量数值交换,从C语言开始,我们就知道要先设置一个临时变量,再把某元素的值覆盖此临时变量,...
Python 中怎么写 swap()交换函数
******Python
不需要交换函数swap(),如果要交换a,b的话,只需要使用如下语句:
即可(因为:Python以引用方式管理对象,你可以交换引用,...
Python 高级编程(第2版)
Python 作为一种高级程序设计语言,凭借其简洁、易读及可扩展性日渐成为程序设计领域备受推崇的语言之一。
本书基于 Python 3.5 版本进行讲解,深度揭示了 Python 编程的高级...
高级编程技术(Python)作业12
11.盛最多水的容器
给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。画 n 条垂直线,使得垂直线 i 的两个端点分别为 (i, ai) ...
python中 list 与数组的互相转换
python中 list 与数组的互相转换(1)list转array
np.array(a)(2)array 转list
a.tolist()...
python面向对象高级编程
1.请利用@property给一个Screen对象加上width和height属性,以及一个只读属性resolution:
class Screen(object):
@property...
没有更多推荐了,DESCRIPTION第8讲 函数的设计方法 周水庚 日/9日 《程序设计》-2005年秋 提要 函数形参(Formal parameters of function) 函数说明(Function declaration)…Transcript
函数的设计方法
《程序设计》-2005年秋
函数形参(Formal parameters of function)
函数说明(Function declaration)
函数指针(Function pointer)及其应用
返回指针值的函数
递归函数基础
命令行参数
函数程序设计实例
《程序设计》-2005年秋
指针类型、数组类型、字符指针
函数指针及其应用
返回指针值的函数
递归函数基础
命令行参数
函数程序设计实例
《程序设计》-2005年秋
函数设置形参的目的是让函数被调用时,能从调用处获得数据或指针信息
C语言关于函数形参遵守以下规定
函数调用时,形参从实参获得初值
函数形参可看作函数内部的局部变量,函数体内对形参的修改不会影响实参本身
函数形参的作用由形参的类型确定
基本类型、指针类型、数组类型
当函数的形参是某种指针类型或数组类型时,形参从实参处得到某环境变量的指针,函数体就能通过指针形参间接引用环境变量,能改变环境变量的值
《程序设计》-2005年秋
指针类型形参
指针形参从实参处得指针值。它使函数得到了调用环境中某变量的指针,函数就可用这个指针间接访问函数之外的变量,或引用其值,或修改其值。因此,指针类型形参为函数改变调用环境中的数据对象提供了手段
以交换两个整型变量值的函数swap()为例说明指针形参的作用和用法
函数swap()的功能是交换两个整型变量的值,函数swap()设置了两个能指向整型变量的指针形参。在函数swap()的体中,用指针形参间接访问它们所指向的变量。调用函数swap()时,提供的两个实参必须是要交换值的两个变量的指针,而不再是变量的值
《程序设计》-2005年秋
指针类型形参示意程序-1
对于简单类型形参,实参向形参传值,函数不能改变实参变量值的示意程序
void paws(int u, int v)
printf(“In paws: u = %d, v = %d\n”, u, v);
void main()
int x = 1, y = 2;
paws(x, y);
printf(“In main: x = %d, y = %d\n”, x, y);
《程序设计》-2005年秋
指针类型形参示意程序-2
void swap-1(int u, int v)
t = u = v =
void swap-2(int *pu, int *pv)
t = * *pu = *
void swap-1(int u, int v); void swap-2(int *pu, int *pv);
void main()
{ int a = 1, b = 2; printf(”Befor swap. a = %d\tb = %d\n”, a, b);
swap-1(a, b); /* 以变量的值为实参 */
printf(“After swap: a = %d\tb = %d\n”, a, b);
swap-2(&a, &b); /* 以变量的指针为实参 */
printf(“After swap:
a = %d\tb = %d\n”, a, b);
《程序设计》-2005年秋
指针类型形参(续)
如希望函数能按需要任意引用指定的变量,需要在三个方面协调一致
函数应设置指针类型的形参
函数体必须通过指针形参间接访问变量,或引用其值或修改其值
调用函数时,要以欲改变值的变量的指针为实参调用函数
《程序设计》-2005年秋
void f1(int x, int y){int t=x;x=y;y=t;}
void f2(int *x, int *y){int t=*x; *x=*y; *y=t;}
void f3(int **x, int **y){int *t=*x; *x=*y;*y=t;}
Void main()
int x=1, y=2;
int *xpt=&x,*ypt=&y;
printf(First: x=%d
y=%d\n\n,x,y);
int x=1, y=2;f1(x,y);
printf(After call f1(): x=%d
y=%d\n\n,x,y);
int x=1, y=2;f2(&x,&y);
printf(After call f2(): x=%d
y=%d\n\n,x,y);
int x=1, y=2;
printf(Before call f3(): x=%d
y=%d\n\n,x,y);
printf(Before call f3(): *xpt=%d
*ypt=%d\n\n,*xpt,*ypt);
f3(&xpt,&ypt);
printf(After call f3(): x=%d
y=%d\n\n,x,y);
printf(After call f3(): *xpt=%d
*ypt=%d\n\n,*xpt,*ypt);
《程序设计》-2005年秋
数组类型形参
使函数能处理不同的成组变量,应使用数组类型形参
对应数组形参的实参是数组某元素的地址,最通常的情况是数组首元素的地址。由于数组名能代表数组首元素的地址,所以常用数组名实参对应数组形参
例如,下面定义的函数sum()用于求数组的前n个数之和
int sum(int a[], int n)
for(s = 0, i = 0; i < i++)
s += a[i];
函数sum有两个形参,一个形参是数组类型的,用于对应可变的实在数组;另一个形参是整型的,用于指定求和数组的元素个数
《程序设计》-2005年秋
数组类型形参(续)
前面定义的函数sum()用于求数组的前n个数之和
利用函数sum(),如有以下变量定义
x[] = {1, 2, 3, 4, 5};
i = sum(x, 5);
j = sum(&x[2], 3);
printf("i = %d\nj = %d\n", i, j);
函数调用sum(x,5)将数组x的地址(&x[0])传送给形参a; 函数调用sum(&x[2], 3)将数组x中的x[2]的地址(&x[2])传送给形参a,而x[2]的地址就是数组元素段x[2]、 x[3]、 x[4]的开始地址
《程序设计》-2005年秋
数组类型形参(续)
与数组类型形参对应的实在数组有多少个元素是不确定的,可能会对应一个大数组,也可能会对应一个小数组,甚至会对应数组中的某一段。所以在数组形参说明中,形参数组不必指定数组元素的个数。为了正确指明某次函数调用实际参与计算的元素个数,应另引入一个整型形参来指定
因传递给数组形参的实参是数组段的开始地址,函数内对数组形参的访问就是对实参所指数组的访问。函数也可以改变实参所指数组元素的值
《程序设计》-2005年秋
数组类型形参示例
函数 initArray()是给数组元素赋指定值的
void initArray(int x[], int n, int val)
for(i = 0; i < i++)
如另有数组定义
int a[10], b[100];
initArray(a, 10, 1);
initArray(b, 50, 2);
initArray(&b[50], 50, 4);
分别给数组a的所有元素置值1,为数组b的前50个元素置值2,后50个元素置值4
《程序设计》-2005年秋
数组类型形参(续)
数组形参也可以是多维数组。当数组形参是多维时,除数组形参的第一维大小不必指定外,其它维的大小必须明确指定
如下面的函数sumAToB(),用于将一个n行10列的二维数组各行的10个元素之和存于另一个数组中
sumAToB(int a[][10], int b[], int n)
for(i = 0; i < i++)
for(b[i] = 0, j = 0; j < 10; j++)
b[i] += a[i][j];
在函数sumAToB()的定义中,对形参a的说明如写成
int a[][];是错误的
《程序设计》-2005年秋
数组类型形参(续)
因二维数组的元素只是按行存放,并不自动说明数组的列数(即每行元素个数)。如在数组形参中不说明它的列数,就无法确定数组元素a[i][j]的实际地址
在实际使用数组形参编写函数时,注意程序中实参所指数组大小不能小于函数实际要用的数组的大小。如实参数组太小,因系统不检查超界情况,可能会使用实际数组后面别的变量的空间,这会发生意想不到的错误
《程序设计》-2005年秋
数组类型形参函数示例-1
为数组输入值的函数
void readArray(int a[], int n)
for(i = 0; i < i++)
printf("Enter a[%d]
scanf("%d", &a[i]);
《程序设计》-2005年秋
数组类型形参函数示例-2
求数组中最大元素值的函数
int max(int a[], int n)
for(m = 0, i = 1; i < i++)
if (a[m] < a[i])
return a[m];
《程序设计》-2005年秋
数组类型形参即指针形参
数组形参对应的实参也可以是数组某元素的地址,即数组某元素的指针,所以数组形参也是一种指针形参
所以任何数组形参说明
都可改写成
如前面的函数sum()的定义可改写成如下形式
int sum(int *a, int n)
for(s = i = 0; i < i++)
s += a[i];
《程序设计》-2005年秋
数组类型形参-指针形参示例
函数形参也是函数的局部变量,指针形参就是函数的指针变量,函数sum()的定义又可改写成如下形式
int sum(int *a, int n)
int s = 0;
for(; n--; )
s += *a++;
《程序设计》-2005年秋
数组类型形参-指针形参示例(续)
为使函数对表进行操作更具一般性,可为函数设置表的首元素指针和元素个数等形参,而函数体用指向表元素的指针对表作处理
如函数sum()也可改写成以下形式
int sum(int *a, int n)
{ int *ap,
for(s = 0, ap = ap < a+n; ap++)
《程序设计》-2005年秋
数组类型形参程序示例
设某个班有若干位学生,共学5门功课。学生成绩单的学号和各门功课成绩存放在二维数组s[][]中,s的每一行存储一位学生的有关信息,其中每行的第一列存放学生的学号
程序设计分析
设计函数 search(int (*p)[6], int m, int no) 用于寻找指定学号的学生,并输出该生的各门功课成绩
其中,形参p是指向数组的指针,它所指数组有6个int 型元素;形参m是学生数;形参no是待寻找学生的学号
主函数按以下格式调用 search(s, m, n);
其中s为成绩单首行数组的指针;m为成绩单行数,即学生人数;n为某学生的学号
《程序设计》-2005年秋
数组类型形参程序示例(续)
学生成绩单程序(续)-P1
#define MAXN 3
int s[MAXN][6] = {{ 5, 70, 80, 96, 70, 90},
{ 7, 40, 80, 50, 60, 80},
{ 8, 50, 70, 40, 50, 75}};
void search(int (*)[6], int, int);
void main()
{ search(s, MAXN, 7);
search(s, MAXN, 5);
search(s, MAXN, 8);
search(s, MAXN, 2);
《程序设计》-2005年秋
数组类型形参程序示例(续)
学生成绩单程序(续)-P2
void search(int (*p)[6], int m, int no)
{ int (*ap)[6], *
for(ap = ap < p+m; ap++)
if (**ap == no)
printf(“%d 号学生是 :\n", no);
for(pp = *ap+1; pp
数组类型形参程序示例(续)
学生成绩单程序(续)
内循环的ap是找到的那位学生的信息数组指针,*ap是该数组的第一个元素的指针,*ap+1是第二个元素的指针
利用二维数组元素按行连续存放的规则,如有必要,二维数组也可看作一维数组。如下面的代码段能累计全班学生的全部成绩之和,并存于变量total中
{ int *pp = *s,
for(total = 0, i = 0; i < MAXN*6; i++; pp++)
if (i%6) /* 跳过学号 */
total += *
工作变量pp是一个指向int型的指针,每次循环增加1个单位,遍历整个二维数组 s
《程序设计》-2005年秋
字符指针形参
字符指针形参,是说它指向字符串的首字符,对应的实参或是字符数组某个元素的指针,或是字符串的首字符指针
字符串就是元素为字符的一维数组。所以字符指针形参与指向数组元素指针形参有相同的使用方法。但因字符串的特殊性,在编写字符串处理函数时还会有许多技巧
《程序设计》-2005年秋
字符指针形参示例-1
字符串拷贝函数 strcpy()
实现该函数功能的代码前面讨论过,这里把它改写成函数,是将一个已知字符串内容复制到另一字符数组中
拷贝函数设有两个形参from,to。from为已知字符串的首字符指针,to为存储复制的字符串首字符指针
void strcpy(char *to, char *from)
while ((*to++ = *from++) != ’\0’);
由于字符串结束符 ’\0’的ASCII码值为0,因此上述测试当前拷贝字符不是字符串结束符的代码“!= ’\0’”可以省略。函数可简写为
void strcpy (char *to, char *from)
while (*to++ = *from++);
《程序设计》-2005年秋
字符指针形参示例-2
两字符串比较函数 strcmp()
比较两字符串大小的函数strcmp()有两个形参s和t;分别为两个待比较字符串的首字符指针。如s所指的字符串小于t所指的字符串,函数返回值小于零;如s所指字符串大于t所指字符串,函数返回值大于零;如两个字符串相同,则函数返回零
int strcmp(char *s,char *t)
while (*s == *t) {
/* 对应字符相等循环 */
if (*s == '\0')
return *s - *t; /* 返回比较结果 */
《程序设计》-2005年秋
字符指针形参示例-3
输入字符行函数getnch()
函数getnch()输入字符行,输入的字符存于由指针形参指定的字符数组中。为避免输入过多字符,函数getnch() 另设一个int型形参,它给出最多能存储的字符数
int getnch(char *s, int lim)
while (ps 0)
while (n%2 == 0)
《程序设计》-2005年秋
程序有函数说明的两种情况-1
被调用函数是库函数。程序需使用预处理命令 #include将包含有库函数的模型、它们所使用的常量、宏定义、数据类型定义等信息的文件包含进来
习惯称文件名以“. h”为后缀的文件为头文件(header file)
在头文件中通常包含宏定义、数据类型说明和定义、公共变量的外部说明等
在大型C程序设计中,用户程序也会有自己的头文件,如有头文件名为 d_type.h使用包含预处理命令
#include "d_type.h"
《程序设计》-2005年秋
程序有函数说明的两种情况-2
调用同一程序文件中后面定义的函数,或是调用别的程序文件中定义的函数,应在调用函数之前对被调用函数作函数说明
在C语言中,如被调用函数的返回值是整型或字符型,也可以不对它作说明。因编译系统发现程序要调用一个还未被定义或说明的函数时,就假定被调用函数的返回值是整型的,而字符型又是与整型相通的。但习惯仍给这样的函数作说明
在C++语言中,调用后面定义或别的文件中定义的函数时,都必须在调用之前对被调用函数作说明
《程序设计》-2005年秋
函数指针及其应用
函数指针和函数指针变量、利用函数指针调用函数
函数指针形参、函数指针数组
返回指针值的函数
递归函数基础
命令行参数
函数程序设计实例
《程序设计》-2005年秋
函数指针和函数指针变量
在C语言中,函数不可设置函数形参,但函数可以设置函数指针形参,函数要调用的函数也可以由实参指定
为了实现函数要调用的其它函数可以由实参指定,C语言引入函数指针类型、函数指针和函数指针变量等概念
函数指针如同一般数据一样能复制、存贮,函数指针变量能作为复杂数据结构的成分,也能作为函数的形参等
函数的目标码有入口地址,这个入口地址就认作该函数的指针,并用函数名来表记函数的指针
函数指针变量是一种特殊的指针变量,它能存储函数的指针值,使它指向某个函数。如同数据指针变量可间接访问它所指变量一样,程序也可利用函数指针变量间接调用它所指的函数
《程序设计》-2005年秋
函数指针和函数指针变量(续)
为区别能指向不同特性函数的函数指针变量,用函数的返回值类型和函数的参数类型等来区分不同的函数指针,并以函数指针类型来标识
定义指向函数的指针变量的一般形式为
函数返回值类型
(* 指针变量名)(形参类型表);
例如, int
(*fp)(int);
定义fp是一个能指向函数的指针变量,它能指向的函数的返回值必须是int 型的,并有一个int类型的形参
注意,*fp两侧的括弧是必需的,表示fp 先与* 结合,说明它是一个指针变量。然后与后随的()结合,表示指针变量fp是指向函数的。最前面的int表示所指向的函数应是返回int型值的函数
而代码“int *f(int)”,因()优先级高于*,就变成是说明一个函数f(),该函数的返回值是指向int型量的指针。
《程序设计》-2005年秋
函数指针和函数指针变量(续)
在C语言中,定义函数指针变量时,形参类型表也可省略不写
指向函数的指针变量表示它能存放函数的入口地址,它能指的函数是函数指针变量定义时所规定的。
在程序执行时,某个符合要求的函数入口地址都能赋给函数指针变量,使函数指针变量指向该函数,可以用该指针变量间接调用它所指函数
可根据需要向函数指针变量赋不同的函数入口地址,使它指向的函数可以按需要改变
《程序设计》-2005年秋
利用函数指针调用函数
定义了指向函数的指针变量,就可向它赋某函数的入口地址
C语言约定,单独的函数名本身就是函数的入口地址(不可以在函数名之后加上一对园括号,否则变成函数调用)
如语句“ fp = min;” 使函数指针变量fp指向函数min()
当一个指向函数的指针变量确实指向某个函数时,就可用它调用它所指向的函数。一般形式的函数调用是
函数名(实参表)
改用指向函数的指针变量调用该函数,就要改写成
(*函数指针变量名) (实参表)
《程序设计》-2005年秋
利用函数指针调用函数示例
求两个整数中小的值的函数min(),它返回int型值
int (*fp)(int,int),x=5, y=8, z, min(int,int);
使指针变量fp指向函数min()
用fp间接调用函数min(),写成
z = (*fp)(x, y);
《程序设计》-2005年秋
利用函数指针调用函数示例
用函数指针变量调用函数的示意程序
void main()
int (*fp)(int, int), x, y,
int min(int, int), max(int, int);
printf("Enter x, y:");scanf("%d%d", &x, &y);
/*让fp指向函数min()*/
z = (*fp)(x, y);
/*调用fp所指函数*/
printf("MIN(%d, %d) = %d\n", x, y, z);
fp = /*现在更改fp,使它指向函数max()*/
z = (*fp)(x, y); /* 调用fp所指函数 */
printf("MAX(%d, %d) = %d\n", x, y, z);
int min(int a, int b)
《程序设计》-2005年秋
函数指针形参
为什么要为函数设函数指针形参?
设有一个函数fun(),它有一个函数指针形参fp和若干其他形参
函数fun()利用函数指针形参fp和其他形参,根据给定的算法计算结果
调用函数fun()时,除提供其他实参外,还得为它提供与形参fp相对应的实在函数指针
这样,用不同的实在函数指针调用函数fun(),就能获得不同的结果
《程序设计》-2005年秋
函数指针形参示例
对给定实数数表,求它的最大值、最小值和平均值
程序设计分析
程序有三个函数max()、min()和ave(),另设一个函数afun()
主函数调用函数afun(),并提供数组、数组元素个数和求值函数指针作为实参
由函数afun() 根据主函数提供的函数指针实参调用实际函数
《程序设计》-2005年秋
函数指针形参示例(续)
给定实数数表,求最大值、最小值和平均值(续)
N sizeof a / sizeof a[0]
double max(double a[], int n)
for(r = a[0], i = 1; i < i++)
if (r < a[i]) r = a[i];
double min(double a[], int n)
for(r = a[0], i = 1; i
a[i]) r = a[i];
double ave (double a[], int n)
for (r = 0.0, i = 0; i < i++)
r += a[i];
return r/n;
double afun(double a[], int n,
double (*f)(double *, int))
return (*f)(a, n);
《程序设计》-2005年秋
函数指针形参示例(续)
给定实数数表,求最大值、最小值和平均值(续)
void main()
{ double a[]={1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0, 9.0};
printf("\n\nThe results are :
result = afun(a, N, max);
printf("\t%s = %4.2f", "MAX", result);
result = afun(a, N, min);
printf("\t%s = %4.2f", "MIN", result);
result = afun(a, N, ave);
printf("\t%s = %4.2f", "AVERAGE", result);
printf("\n\n\n");
《程序设计》-2005年秋
函数指针数组
利用函数指针能被存储的性质, 可将若干函数指针存于一数组中
如以下代码
double (*fpt[])(double*, int)={ max, min , ave}; /* 函数指针数组 */
定义了函数指针数组fpt[],并用函数名对它初始化,将函数max()、min()和ave()的函数指针填写在函数指针数组fpt[]中,使数组fpt[]成为函数的入口表
例子:设计一个通用的菜单处理函数,除其他有关菜单位置、大小、颜色等信息外,另设两个数组形参。一个数组的元素为指向菜单项字符串的指针,另一个数组的元素为指向对应处理函数的指针
《程序设计》-2005年秋
函数指针数组示例
通用的菜单处理函数(续)
N sizeof a / sizeof a[0]
void main ()
{ double a[] ={1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0, 9.0};
double(*fpt[])(double *,int)={ max, min , ave};
char *title[]={"最大值", "最小值", "平均值"};
char *menuName[] ={”求最大值”, ”求最小值”, ”求平均值”,””};
《程序设计》-2005年秋
函数指针数组示例(续)
通用的菜单处理函数(续)
while (1) {
printf(”请选择以下菜单命令。\n”);
for(k = 0; menuName[k][0] != ’\0’ ; k++)
printf(”\t%d:
%s\n”, k+1, menuName[k]);
printf(“\t其它选择结束程序运行。\n”);
scanf(“%d”, &ans);
printf("\n\n结果: ");
result = (*fpt[ans-1])(a, N);
printf("\t%s=%4.2f\n\n",title[ans-1], result);
《程序设计》-2005年秋
函数指针及其应用
返回指针值的函数
返回数据对象指针的函数
返回函数指针的函数
递归函数基础
命令行参数
函数程序设计实例
《程序设计》-2005年秋
返回数据对象指针的函数
函数可以返回整型值、字符值、实型值等,也可以返回指向某种数据对象的指针值。返回指针值的函数与以前介绍的函数在概念上是完全一致的
定义(或说明)返回指针值函数的一般形式为
类型说明符
* 函数名(形参表);
例如,函数说明:
int *f(int,int);
函数f()返回指向int型数据的指针,有两个整型形参
注意:在函数名两侧分别为*运算符和( ) 运算符,而( )的优先级高于*,函数名先与()结合。函数名()是函数的说明形式。在函数名之前的*,表示函数返回指针类型的值
《程序设计》-2005年秋
返回数据对象指针的函数示例-1
编制在给定的字符串中找特定字符的第一次出现。若找到,返回指向字符串中该字符的指针;否则,返回NULL值
程序设计分析
设函数为sear_ch(),该函数有两个形参,指向字符串首字符的指针和待寻找的字符
函数sear_ch() 的定义
char *sear_ch(char *s, char c)
while (*s && *s != c)
return *s ? s : NULL;
《程序设计》-2005年秋
返回数据对象指针的函数示例-2
改写例5.5(学生成绩单)的函数 search(),使新的search()函数具有单一的寻找功能,不再包含输出等功能。新的函数search() 的功能是从给定的成绩单中找指定学号的成绩表。新的函数search()的形参与例5.5中的函数search()的形参相同,但新的函数search()返回找到的那位学生的成绩表(不包括学号)的指针
函数 search() 定义如下
int *search (int (*p)[6], int m, int no)
{ int (*ap)[6];
for(ap = ap < p+m; ap++)
if(**ap == no)
return *ap+1;
return NULL;
《程序设计》-2005年秋
返回函数指针的函数
返回函数指针值函数定义或说明的一般形式为
类型说明符
(*函数名(形参表))(形参类型表);
例5.11的菜单函数接受用户选择,返回相应处理函数的指针: double (*menu(char **))(double*, int)
在menu()函数说明中,
先是menu(char **),menu同园括号结合,说明menu是函数;
随后是(*menu(char **)),同*结合,函数返回指针;
接着是(*menu(char **))(double*, int)
同一对园括号结合,表示是指向函数的指针,所指函数有double*和int类型两个形参;
最后是double (*menu(char **))(double*,int),说明指向的函数的返回值是double类型
《程序设计》-2005年秋
返回函数指针的函数示例程序
N sizeof a / sizeof a[0]
double max(double *, int), min(double *, int), ave(double *, int);
double (*fpt[])(double *, int) = {max, min, ave, NULL}; /*函数指针数组*/
char *title[] = {“最大值”, “最小值”, “平均值”,“”};
char *menuName[] ={"求最大值","求最小值","求平均值",""};
double a[] ={1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
double (*menu(char **titptr))( double *, int)
/*函数返回函数的指针*/
{ int ans,
printf("请选择以下菜单命令。\n");
for(k=0; menuName[k][0] !='\0';k++) printf("\t%d:%s\n", k+1, menuName[k]);
printf("\t其它选择结束程序运行。\n"); scanf("%d", &ans);
3) return NULL;
*titptr = title[ans-1];
return fpt[ans-1];
/* 返回函数的指针 */
《程序设计》-2005年秋
返回函数指针的函数示例程序(续)
void main ()
{ double (*fp)( double *, int); char *
while (1) {
if ((fp = menu(&titstr)) == NULL)
result = (*fp)(a, N);
printf("\n结果:%s = %4.2f\n\n", titstr, result);
double max(double a[], int n)
for(r = a[0], i = 1; i < i++)
if (r < a[i]) r = a[i];
《程序设计》-2005年秋
返回函数指针的函数示例程序(续)
double min(double a[], int n)
for(r = a[0], i = 1; i
a[i]) r = a[i];
double ave(double a[], int n)
for (r = 0.0, i = 0; i 1) 张金片时,按同样算法先搬前 n-1 张金片 */
(2) 将A 针上的 n-1 张金片搬到 B 针上,中间可使用 C 针;
(3) 将金片 n 从 A 针搬到 C 针; /* 搬动第 n 张金片 */
/* 搬 B 针上前 n-1 张金片 */
(4) 将 B 针上的n-1张金片搬到C针,中间可使用A针;
《程序设计》-2005年秋
Hanoi问题的解法是递归的,是直接递归
递归函数示例-3(续)
《程序设计》-2005年秋
递归函数示例-3(续)
Hanoi塔问题(续)
void hanoi (int n,char A,char C,char B)
//解决汉诺塔问题的算法
if ( n == 1 )
printf( " move %c
to %c\n ",A, C);
hanoi ( n-1, A, B, C );
printf( " move %c
to %c\n ",A, C);
hanoi ( n-1, B, C, A );
《程序设计》-2005年秋
递归函数(续)
对于算法间接地由其自身定义情况,称为间接递归。在间接递归情况,函数调用链中,在同一个函数再次出现之前,有一个或多个其他别的函数
递归程序特点
通常,以递归形式定义算法与非递归算法比较,算法结构会更紧凑、清晰
但是,递归函数在递归调用过程中,会占用更多的内存空间和需更多的运行时间
另外,在编写递归函数时,必须防止遗漏递归终止条件和防止振荡式的相互递归调用,否则会产生无限递归调用现象
《程序设计》-2005年秋
直接递归 vs. 间接递归
《程序设计》-2005年秋
在算法的递归定义形式中,有一种称之为线性递归的情况,线性递归的算法有以下所示的一般形式
if (E(n)) {
/* 递归调用 */
其中,S(n)、E(n)、T(n)和U(n) 是可能与n有关的非递归计算的代码段,也可能为空
《程序设计》-2005年秋
线性递归(续)
线性递归能机械地被转换成一个功能等价的非递归描述
int k = n+1;
} while E(k);
用递推实现递归的示意程序
勒让得多项式的递归定义为
p(n,x)= ┤ x,
└ ((2n-1)xp(n-1,x)-(n-1)p(n-2,x))/n,n>1
程序设计分析
用递归函数实现,能很容易地写出它的函数定义如下
double p(int n, double x)
if (n==0) return 1.0;
return ((2.0*n-1.0)*x*p(n-1,x)-(n-1.0)*p(n-2,x))/n;
《程序设计》-2005年秋
用递推实现递归的示意程序(续)
勒让得多项式用递推方法实现
程序设计分析
计算p(n,x)的困难是n>1情况
然而,若知道了 p(n-2,x) 和 p(n-1,x) 的话,就能立即按公式计算出 p(n,x)
由于p(0,x)与p(1,x)是能立即得到的
这样就能用递推方法,从p(0,x)与p(1,x)出发,依次计算出p(2,x),p(3,x),…
即从幂次低的勒让得多项式到幂次高的勒让得多项式的递推解法
《程序设计》-2005年秋
用递推实现递归的示意程序(续)
勒让得多项式用递推方法实现,函数定义如下
double p(int n, double x)
{ double first, second,
if (n == 0)
return 1.0;
if (n == 1)
for(count = 2; count
函数指针及其应用
返回指针值的函数
递归函数基础
命令行参数
函数程序设计实例
《程序设计》-2005年秋
命令行参数
执行C程序,可以看作是对该程序的main()函数的调用。main()函数执行结束,返回环境。为能从环境向C程序传递信息,启动C程序的命令行可带有任选的参数
命令行的一般形式为
其中程序名和各参数之间用空白符分隔
为能让main()函数读取命令行中的参数,环境将多个参数以两个参数形式传递给main() 函数。其中第一个参数(习惯记作argc)表示命令行中参数的个数(包括程序名);第二个参数(习惯记作argv)是一个字符指针数组。其中argv[0]指向程序名字符串,argv[1]指向参数1字符串,...,argv[argc-1]指向最后一个参数字符串。
如果argc等于1,则表示程序名后面没有参数
《程序设计》-2005年秋
命令行参数示例
说明main()函数对参数argc与argv引用方法的程序
打启动程序时的命令行各参数
void main(int argc, char *argv[] /* 或 char ** */
for(k = 1; k < k++)
printf("%s
%c", argv[k], k
printf("%s %c", *++argv,argc > 1 ? ' ' : '\n');
这里,++argv使指针argv先加1,让它一开始就指向参数1;逐次增1,使它遍历指向各参数
又利用函数printf()的第一个格式参数是字符串表达式,上述程序对printf()的调用可改写成
printf((argc > 1)? "%s
" : "%s\n",*++argv);
《程序设计》-2005年秋
命令行参数示例-1
假定启动程序时给出的命令行参数是一串整数,程序将全部整数求和后输出
void main(int argc, char **argv)
for(s = 0, k = 1; k
0 && (*++argv)[0] == ’-’)
/* *++argv是指向任选参数串的首字符指针,(*++argv)[0]是任选参数字符串的首字符*/
for(s = argv[0]+1; *s != ’\0’; s++)
switch (*s)
case 'x' :
if (inverse) err = 1;
/*限制x最多只能出现1次*/
else inverse = 1;
case 'n' :
if (num) err = 1; /*
限制n最多只能出现1次*/
else num = 1;
/*正确情况下,至此argc应为2*/
if (err || argc != 2) {
/*如有使用不当*/
printf("Usage:find -x -n pattern filename\n");
《程序设计》-2005年秋
命令行参数程序示例(续)
if ((fp = fopen(*(argv+1), "r")) == NULL) {
fprintf(stderr, "Can't open %s. \n", *(argv+1));
while ((len = getline(fp, line, MAXLINE)) > 0)
if ((index(line, *argv) >= 0) != inverse)
if ((s = (char *)malloc(len+1)) == NULL)
lineno[n] =
strcpy(s, line);
lineptr[n++] =
fclose(fp);
for(m = 0; m < m++)
printf("%4d: ", lineno[m]);
printf("%s\n", lineptr[m]);
《程序设计》-2005年秋
命令行参数程序示例(续)
int getline(FILE *fp, char *s, int lim)
while (ps = len2。则它们最长的公共子串长度不会超过len2。设要寻找的子串长为ln,ln的初值为len2,即以str2字符串的最长子串开始寻找,当在str1中没有长为ln的相同子串时,就让ln减1,即用str2更短的子串重新寻找。若找到,则该子串就可作为函数要找的str1和str2的一个最长子串。若直至找遍了str2的所有可能的子串,还未在str1中找到相同的子串,则说明str1和str2没有公共子串
《程序设计》-2005年秋
函数程序设计实例-2(续)
编制从两个已知非空字符串中找出最长公共子串的的长度和最长公共子串的个数的函数(续)
int commStr(char *str1, char *str2, int *lenpt)
/*函数返回最长公共子串的个数, 通过指针参数传回最长公共子串的长度*/
int len1, len2, ln, count, i, k,
if((len1=strlen(str1))
函数程序设计实例-2(续)
for(ln=len2;ln>0;ln--) {
/* 找长ln的公共子串 */
for(k = 0; k + ln
函数程序设计实例-3
编写函数int trans(unsigned n, int d, char s[]),将无符号整数n翻译成d(2
函数程序设计实例-3(续)
编写函数int trans(unsigned n, int d, char s[])(续)
M sizeof(unsigned int)*8
int trans(unsigned n, int d, char s[])
char digits[] = ”ABCDEF”;
char buf[M+1];
int j, k = M;
s[0] = ’\0’;
buf[k] = ’\0’;
buf[--k] = digits[n%d];
} while (n);
for(j = 0; s[j++] = buf[k++]; );
return j-1;
《程序设计》-2005年秋
函数程序设计实例-4
编制判定正整数n的d进制表示形式是否是回文数的函数。回文数就是自左向右读和自右向左读是相同的数。例如,n = 232,其十进制表示是回文数;n = 27,其二进制表示11011是回文数
设函数circle(int n, int d)是要判n的d进制表示是否是回文数。实现这个判定有两种方法:
一是顺序译出n的d进制表示的各位数字,然后将其首末对应位数字两两比较,若对应位数字都相同,则n的d进制表示是回文数。
二是在顺序从低位到高位译出n的d进制各数字位的同时,把译出的各位数字看作是另一个d进制数字的高位至低位,并将其重新转换成整数。若转换所得整数与n相等,则n的d进制表示是回文数
《程序设计》-2005年秋
函数程序设计实例-4(续)
判n的d进制表示是否回文数函数circle(int n, int d)(续)
下面是参照第二种方法编写的函数
int circle(int n, int d)
int s = 0, m =
while (m) {
s = s*d + m%d;
return s ==
《程序设计》-2005年秋
函数程序设计实例-5
编制函数 int part(int a[], int low, int high)
对数组元素a[low] -- a[high]以a[low]为基准,对它们作划分,使a[low]移至a[k]后,新的a[low] -- a[k-1]中的元素均小于a[k];a[k+1] -- a[high]中的元素均大于等于a[k]。函数返回k值,a[k]是数组a中的第k+1大元素
令函数要调整存储位置的元素是a[k]至a[j],变量k和j就是未确定存储位置元素区间的下界和上界,它们的初值分别为low和high
首先将a[low]暂存于变量temp,然后是一个循环,循环内是交替地执行从后向前考察元素的循环和从前向后考察元素的循环
《程序设计》-2005年秋
函数程序设计实例-5(续)
编制函数 int part(int a[], int low, int high)(续)
在从后向前考察循环中,当考察元素a[j]不比temp小时,让j减1。当发现元素a[j]比temp小时,结束从后向前的循环,并将a[j]移至a[k],和让k增1
在从前向后考察循环中,当考察元素a[k]比temp小时,让k增1。当发现a[k]不比temp小时,结束从前向后的考察循环,并将a[k]移至a[j],和让j减1
上述循环直至调整区间不再有元素时结束。最后将暂存于temp中的值回填到a[k]中,返回k值
《程序设计》-2005年秋
函数程序设计实例-5(续)
编制函数 int part(int a[], int low, int high)(续)
int part(int a[], int low, int high)
int k = low, j = high, temp = a[low];
while ( j > k && a[j] >= temp )
if (k < j)
a[ k++ ] = a[j];
while ( k < j && a[k] < temp )
if (k < j)
a[ j-- ] = a[k];
} while ( k
h = t - 1 ;
if ( t < k ) m = t + 1 ;
} while ( t != k );
return a[k];
int a[] = {0, 1, 9, 7, 6, 4, 5, 2, 3, 8};
void main()
printf("Enter i
"); scanf("%d", &i);
printf("%d
%d\n", i, kth(a, i, 10));
《程序设计》-2005年秋
第5章 小结
函数形参(指针类型、数组类型、字符指针)
函数指针及其应用
函数指针和函数指针变量、利用函数指针调用函数
函数指针形参、函数指针数组
返回指针值的函数(返回数据对象指针、返回函数指针)
递归函数基础(直接递归、间接递归、线性递归、递推)
命令行参数
函数程序设计实例
《程序设计》-2005年秋
Recommended

我要回帖

更多关于 用swap函数交换两个数组 的文章

 

随机推荐