?? 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 + -