📄 ex8.cpp
字号:
第8章函数
// [例8.1]swap函数仅交换函数局部变量的值
#include <stdio.h>
inline void swap(int x,int y)
{ int t=x; x=y; y=t;
printf("%d,%d;",x,y);}
void main(void)
{ int a=1,b=2;
swap(a,b);
printf("%d,%d\n",a,b);
}
// [例8.2]内层块交换内层局部变量的值
#include <stdio.h>
void main(void)
{ int a=1,b=2;
{ int x=a; int y =b;
int t=x; x=y; y=t;
printf("%d,%d;",x,y);
}// 内层块是swap(a,b)的内联展开
printf("%d,%d\n",a,b);
}
//[例8.3]指针的数值形参交换间接变量
#include <stdio.h>
inline void swap(int *x,int *y)
{ printf("%d,%d",*x,*y);
int t=*x; *x=*y;*y=t;
}
void main(void)
{ int a=1,b=2;
swap(&a,&b);
printf("%d,%d\",a,b);
}
// [例8.4]内层块交换间接变量的值
#include <stdio.h>
void main(void)
{ int a=1,b=2;
{ int *y =&b;
int* x=&a;
printf("%d,%d ",*x,*y);
int t=*x; *x=*y; *y=t;
}//内层块是swap(&a,&b)的内联展开
printf("%d,%d",a,b);
}
// [例8.5]函数f返回n的立方,引用形参x计算正方形周长,访问指针*p得到正方形面积
#include <stdio.h> // 函数调用z=f(x,&y,3)导致x=4*3,*(&y)=3*3, z=3*3*3。
int f(int & r,int*p ,int n)//引用形参r匹配左值x, 指针数值形参p匹配右值地址&y。
{ r=4*n;
*p=n*n;
return n*n*n;
}//变量数值形参n匹配右值3。
void main()
{ int x,y,z;
z=f(x,&y,3);
printf("%d,%d,%d\n",x,y,z);
} //输出:12,9,27
// [例8.6]交换变量值的函数。 程序运行都输出:1,2 ;2,1
//[1]指针的数值形参版本
#include <stdio.h>
void swap(int *x,int *y)
{ printf("%d,%d;",*x,*y);
int t=*x; *x=*y;*y=t;
}
void main(void)
{ int a=1,b=2;
swap(&a,&b);
printf("%d,%d",a,b);
}
// [2]变量的引用形参版本
#include <stdio.h>
void swap(int &x,int &y)
{ printf("%d,%d;",x,y);
int t=x; x=y; y=t;
}
void main(void)
{ int a=1,b=2;
swap(a,b);
printf("%d,%d",a,b);
}
/////////////////// [3]相当于引用版本的内联展开
#include <stdio.h>
void main(void)
{ int a=1,b=2;
{ int& y =b;
int& x=a;
printf("%d,%d;",x,y);
int t=x; x=y; y=t;
}// swap(a,b)的内联展开
printf("%d,%d",a,b);
}
//// [例8.7]求函数极大值(多学时)。两边程序都输出: x=200.000000,y=0.000000
/// [1]double*型指针输入和指针返回
#include<stdio.h>
double* pmax(double* x,double* y)
{ if(*x>*y) return x;
else return y;
}
void main(void)
{ double x=100, y=0;
*pmax(&x,&y)+=100;
printf("x=%f,y=%f\n",x,y);
}
// [2]double&型引用输入和引用返回
#include<stdio.h>
double& rmax(double& x,double& y)
{ if(x>y) return x;
else return y;
}
void main(void)
{ double x=100, y=0;
rmax(x,y)+=100;
printf("x=%f,y=%f\n",x,y);
}
//// [例8.8]参数类型和位置不同的重载函数
#include<stdio.h>
long& max(long& s,long& l)
{ printf("max(long&);");
return s>l?s:l;
}
double& max(double& s,double& l)
{ printf("max(double&);\n");
return s>l?s:l;
}
long min(short s,long l) { printf("min(short,long);"); return s<l?s:l; }
long min(long l,short s) { printf("min(long,short);"); return s<l?s:l; }
void main(void)
{ long l='l'; long L='L'; short s='s';
double d= 'd';double D='D'; //输出结果:
max(L,l)--; max(D,d)++; // max(long&);max(double&);
printf("min=%c\n",min(s,l)); // min(short,long) ; min=k
printf("min=%c\n",min(L,s)); // min(long,short) ; min=L
}
//// [例8.9]指针形参和引用形参强制类型转换
#include <stdio.h>
void f(short v) { printf("%d\t",v); }
void f(short * p) { printf("%d\t",*p); }
void f(int & r) { printf("%d\t",r); }
void main()
{ long v;
v=10; f( v); //warning : conversion from 'long' to 'short', possible loss of data
v=20; f((short*)&v);
v=30; f((int&)v); //输出: 10 20 30
}
// [例8.10] 函数重载时的参量提升匹配和精确匹配
#include <stdio.h>
void f(long v) { printf("long %d;",v); }
void f(unsigned long n) { printf("unsigned long %d;",n);}
void f(double d) { printf("double %3.1f;",d); }
void f(char* v) { printf("char*%s;",v); }
void f(const char * p) { printf("const char*%s\t",p); }
void main()
{ f(1L); f(2Lu); f(3.0f); f(4.0) ;
char* p="aa"; f(p); const char* r="bb"; f(r);
} //输出:long 1;unsigned long 2;double 3.0;double 4.0 ; char*aa ;const char* bb
/// [例8.11]默认参数值的函数
#include<stdio.h>
int d;
int f3(int n=3) {return n;} // 默认值为3
void f(int i=1,long l=2,int f=f3()) //所有的参数都有缺省值
{ d=i+l+f; }
void main(void)
{ f(); /*等价于函数调用f(1,2,3);*/ printf("f() sets d=%d\n",d);
f(2); /*等价于函数调用f(2,2,3);*/ printf("f(2) sets d=%d\n",d);
f(2,3); /*等价于函数调用f(2,3,3);*/ printf("f(2,3) sets d=%d\n",d);
f(2,3,4); printf("f(2,3,4) sets d=%d\n",d);
} //输出:f() sets d=6 f(2) sets d=7 f(2,3) sets d=8 f(2,3,4) sets d=9
/// [例8.12]默认参数导致的语法模糊
#include<stdio.h>
double d;
void funct(int i,long =2,float f=3); //函数原型中默认值可省去形参名
void funct(int i,long l) { d=i+l; }
void main(void)
{ funct(2); //调用void funct(int i,long =2,float f=3);
funct(2,3); // error take place here,
funct(2,3,4); //调用void funct(int,long,float);
}
void funct(int i,long l,float f) { d=i+l+f; }
/// [例8.14] 嵌套与递归的比较
#include<stdio.h>
long fac1(long n) { return 1; }
long fac2(long n) { return n*fac1(n-1); }
long fac3(long n) { return n*fac2(n-1); }
long fac4(long n) { return n*fac3(n-1); }
long facn(long n) //注意facn实现了(n>0)条件
{ if(n>0) return n*facn(n-1);
else return 1;
} //首先判断if(n>0) 然后递归调用是关键的
void main(void)
{ printf(" embedding 3!=%d,recursion 3!=%d\t",fac3(3),facn(3));
printf(" embedding 4!=%d,recursion 4!=%d\n",fac4(4),facn(4));
} //输出:embedding 3!=6,recursion 3!=6 embedding 4!=24,recursion 4!=24
/// [例8.15] 递归和嵌套计算数组的和
#include<stdio.h>
long rsum(long *p,int n) //递归实现求数组元素从p[n-1]到p[0]的和
{ if(n>0) return rsum(p,n-1)+p[n-1];
else return 0; //递归结束条件,递归函数的结果一般并不简单地等于0
} // rsum(p,n)计算的结果相当于p[n-1]+ p[n-2]+ ...+p[1]+ p[0]+0= rsum(p,n)
long sum0(long *p,int n=0) { return 0;}
long sum1(long *p,int n=1) { return sum0(p,n-1)+p[n-1];}
long sum2(long *p,int n=2) { return sum1(p,n-1)+p[n-1];}
long sum3(long *p,int n=3) { return sum2(p,n-1)+p[n-1];}
void main(void) // sum3(p,n)计算的结果相当于p[n-1]+ p[n-2]+ p[n-3]+ (p[n-4]=0)
{ long a[]={1,2,3,4,5,6,7,8,9,10};
printf("1+2+3 =%d,sum=%d\t",sum3(a,3),rsum(a,3));
printf("4+5+6=%d,sum=%d\t",sum3(a+3),rsum(a+3,3));
printf("7+8+9=%d,sum=%d\n",sum3(a,9),rsum(a,9));
} // 输出: 1+2+3=6,sum=6 4+5+6 =15,sum=15 7+8+9=24,sum=45
// [例8.16]递归显示字符串。f1顺序显示指针数组的字符串,f2逆序显示。
# include<stdio.h>
char* s[]={ "a", "bb", "ccc", "dddd", 0 }; //定义全局指针数组,0作为结束标志
void f2(char* *p) { if(*p!=0) f2(p+1), printf("%s;",*p); }//*p!=0作为过滤条件
void f1(char* p[]) { if(*p!=0) printf("%s;",*p), f1(p+1);}// *p==0不进入递归调用
void main() { f1(s); f2(s); }//输出:a; bb;ccc;dddd;dddd;ccc;bb;a;
//// [例8.17]间接递归交错地显示字符数组的字符
# include<stdio.h>
char s[]="abcd"; //定义全局字符数组,0作为结束标志
void f1(char p[]); //逗号表达式语句作为if分支的执行语句
void f2(char *p) { if(*p!=0) f1(p+1), printf("%c",*p); }//*p!=0作为过滤条件
void f1(char p[]) { if(*p!=0) printf("%c",*p), f2(p+1);}
void main() { f1(s); f2(s); }//输出:acdbbdca
//// [例8.18] 直接插入排序
# include<stdio.h>
void show(long * a,int i,int n)
{ printf("%d ",i);
for(int k=0;k<n;k++) printf("%d\t ",a[k]);
printf("\n");
}
void InsertSort(long a[],int n)
{ for(int i=1;i<n;i++) //将中小的元素依次前插
{ //某次插入排序前
show(a,i,n); //i++导致无序区变小
long temp=a[i]; //记住要搬迁的元素值,无序区的第一个元素
int j=i; //定位搜寻的初始位置
for(;temp<a[j-1];j--) //从起 向前搜寻要插入的位置,条件是temp>=a[j-1]
a[j]=a[j-1]; //元素依次后移,跳出循环时即找到插入位置
a[j]=temp; //内层循环一次后
}
}
void main(void)
{ long a[7]={5,4,3,1,2,6,7};
InsertSort(a,7); show(a,7,7);
}
//// [例8.19] 选择排序
void swap(int &x,int &y) { int t=x; x=y; y=t;}
void SelectSort(int a[], int n)
{ for(int i=0;i<n-1;i++)
{ //进入内层循环前[]()
int min=i; //设置最小元素下标初始值为i
for(int j=i+1;j<n;j++) //在区间中()寻找最小值对应的下标min
if (a[j]<a[min]) //条件成立时
min=j; //最小元素下标动态对应最小元素的位置
if(min!=i) //如果最小值对应的下标min在区间()中
swap(a[i],a[min]); //交换元素后[,]()
} //设置if(min!=i)过滤条件可以防止min==i时多余的交换
}
//// [例8.20] 交换法实现冒泡排序
void swap(int &x,int &y) { int t=x; x=y; y=t;}
void BubbleSortB(int a[],int n) //大的元素优先降落
{for(int i=1;i<n;i++) //外层循环i共循环n-1回
for(int j=0;j<n-i;j++) //内层循环从0~n-i扫描,前半部正序扫描
if (a[j]>a[j+1]) //比较判断
swap(a[j],a[j+1]); //大的元素排在后面
}
void BubbleSortS(int a[],int n) //小元素优先上升
{ for(int i=0;i<n-1;i++) //外层循环i共循环n-1回
for(int j=n-1;j>i;j--) //内层循环从n-1到i扫描,后半部反序扫描
if (a[j-1]>a[j]) //比较判断
swap(a[j-1],a[j]); //小的元素排在前面
}
void main(void)
{ int a[7]={4,6,1,5,2,3,0};
int b[7]={4,6,1,5,2,3,0};
BubbleSortS(a,7);
BubbleSortB(b,7);
}
//// [例8.21]三路分支确定二分查找函数的流程
/*BinSearch:在a[low]<=a[low+1]<=......<=a[high-1]中查找x对应的索引下标*/
#include <stdio.h>
int BinSearch (int a[],int low,int high,int x)
{ int mid; //mid用于将low和high圈围的空间折半
while(low<=high) //低边界小于等于高边界则继续搜寻
{ mid=(low+high)/2; //将原来的区间一分为二,mid为中值
if(x<a[mid]) high=mid-1; //待查元素在前半区间high设置为mid-1
else if(x>a[mid]) low=mid+1; //待查元素在后半区间low设置为mid+1
else return mid; //知道mid是要找的元素下标
}
return -1; //区间根本没有要找的值,-1标志失败
}
void main()
{ int a[]={2,4,6,8,10,12,12,14,18}; const int n=sizeof(a)/sizeof(a[0]);
int s= BinSearch(a,0,n-1,6); int f = BinSearch(a,1,n-1,18);
printf("s=%d,f=%d\n",s,f);
} //程序运行输出结果:s=2,f=8
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -