函数概述及其定义:
数据类型 函数名(形参说明表){
说明语句序列;
可执行语句序列;
}
注意:
- 函数的”数据类型”指出该函数通过return返回值的类型,除了常用的各种数据类型如int、float、char等外,还有一种特殊类型即void,void型函数无返回值。
- 函数的形参表由一个或多个形参组成,多个形参彼此之间用逗号隔开。也可以没有形参,但函数名后的()不能省略。
- 对于void型函数不能包含return语句,其它类型的函数至少包含一个return语句。
函数调用:
函数名(实参表);
说明:
- 在调用函数时,函数名后圆括号中的多个实参彼此之间用逗号隔开。如果调用无参函数,则实参表为空。
- 实参与形参的个数必须相等,对应类型应兼容,实参与形参按顺序对应,一一传递数据。
- 形参在函数调用前不占内存;函数调用时为形参分配内存;调用结束,内存释放。
参数传递方式
#include<stdio.h>
void swap(int *p,int *q){
int t=*p;
*p=*q;
*q=t;
}
int main(){
int a,b,*p,*q;
printf("input of a and b:\n");
scanf("%d%d",&a,&b);
p=&a;q=&b;
printf("a=%d,b=%d\n",a,b);
printf("交换后:d");
swap(p,q);
printf("a=%d,b=%d",a,b);
}
函数的嵌套和递归调用
1.计算N的阶乘。
#include<stdio.h>
int fac(int n){
if(n==1){
return 1;
}else{
return n*fac(n-1);
}
}
int main(){
int n,result;
printf("请输入一个数的阶乘!");
scanf("%d",&n);
result=fac(n);
printf("\n");
printf("%d",result);
}
2.汉诺塔问题。
#include<stdio.h>
void move(char getone,char putone){
printf("%c----->%c\n",getone,putone);
}
void haoni(int n,char one,char two,char three){
if(n==1){
move(one,three);
}else{
haoni(n-1,one,three,two);
move(one,three);
haoni(n-1,two,one,three);
}
}
int main(){
int m;
printf("输入盘子的个数:");
scanf("%d",&m);
haoni(m,'A','B','C');
}
设计递归函数必须符合以下3个条件:
- 可以把要解决的问题转化为一个新的问题,而这个新的问题的解法仍与原来的解法相同,只是所处理的对象有规律的递增或递减。
- 可以应用这个转化过程使问题得到解决
- 必须有一个明确的结束递归条件
函数的存储类型
- static型函数:只限于本编译单位中的其他函数调用它,而不允许其他编译中的函数调用它。
- extern型函数:一般的函数都隐含说明为extern。其基本特征是:该函数可以被其他编译单位中的函数调用。
变量的作用域和存储类型
- 局部变量和全局变量
- 局部变量:
函数内部或复合语句内定义的变量称为局部变量,也称内部变量。函数的形参也属于局部变量。
- 全局变量:
在函数外部定义的变量称为全局变量,也称为外部变量。全局变量的作用域是从该变量定义的位置开始,到整个源文件结束为止。
- 变量的存储类型
auto局部变量
auto变量的存储单元被分配在内存的动态存储区。每当进入函数体(或复合语句)时,系统自动为auto变量分配内存单元;退出时自动释放这些存储单元,再次进入函数体(或复合语句)时,系统将为它们另行分配存储单元,变量的值不可能被保留,因此,这类局部变量的作用域是从定义的位置开始,到函数体(或复合语句)结束为止。
1.编程生成nxn的螺旋矩阵。如下:
1 2 3 4 5
17 18 19 20 6
26 27 28 21 7
14 24 23 22 8
13 12 11 10 9
#include<stdio.h>
#define M 10
void function(int a[][M],int n){
int i;
int m=1;
for(i=0;i<=n/2;i++){ //从左到右
for(int j=0;j<n-i;j++){
a[i][j]=m++;
}
for(int j=i+1;j<n-i;j++){//从上到下
a[j][n-i-1]=m++;
}
for(int j=n-i-2;j>=i;j--){//从右到左
a[n-i-1][j]=m++;
}
for(int j=n-i-2;j>=i+1;j--){//从下到上
a[j][i]=m++;
}
}
}
int main(){
int a[M][M];
int n;
scanf("%d",&n);
function(a,n);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
printf("%d ",a[i][j]);
}
printf("\n");
}
}
2.编程实现将字符串中的最短的单词输出。
输入: Happy new year
最短单词为new,则输出:new
#include<stdio.h>
#define M 50
void cmp(char s[]){
char s1[M],s2[M];
int len1=0,len2=0,i=0;
while(s[i++]!='\0'); //为了简明,在s的末尾添加一个空格
s[i-1]=' ';
s[i]='\0';
i=0;
while(s[i]!='\0'){
if(s[i]==' '&&s[i+1]==' '&&s[i+1]!='\0'){ //跳过多余的空格
i++;
continue;
}
if(s[i]!=' '){
s2[len2++]=s[i];
}else if(len1==0){ //给s1置初始值
len1=0;
for(int j=0;j<len2;j++){ //将s2复制到s1中
s1[len1++]=s2[j];
}
s1[len1]='\0';
len2=0;
}else if(len1>len2){
len1=0;
for(int j=0;j<len2;j++){ //将s2复制到s1中
s1[len1++]=s2[j];
}
s1[len1]='\0';
len2=0;
}
i++;
}
printf("%s\n",s1);
}
int main(){
char s;
gets(s);
cmp(s);
}