// 按值传递
int test(int p1,int p2)
{
int z;
z = p1 + p2;
return z;
/*
按值传递,其实就是复制数值一个副本,传给函数,所以改变的知识副本,原来的数值并没与改变,如果要改变原来的数值,请按值传递
*/
}
// 按址传递
void test1(int *p1,int *p2)
{
int z;
z = *p1;
*p1 = *p2;
*p2 = z;
}
// 数组作为函数的参数
float test2(float x[])
{
float average = 0;
float sum = 0;
for (int i = 0; i < 5; i ++)
{
sum = sum + x[i];
}
average = sum / 5;
return average;
}
// 将数组和长度作为函数的参数,不能在子函数里面计算数组长度,因为子函数里面数组会退化为指针
void show(char *x[],int size)
{
int i = 0;
for (i = 0; i < size; i ++)
{
puts(x[i]);
}
}
// 数组作为函数参数
/*
将数组作为函数的参数,实际上就是把数组名传给函数,而数组名就是数值中第一个元素的地址
*/
#include <stdio.h>
float getAverage(float x[])
{
float average; // 平均值
float sum = 0; // 总和
for (int i = 0; i < 5; i ++) // 这个的5就是数组的长度,也就是数组元素的个数,这个5必须事先知道,通过求数组的长度sizeof函数是求不出来的
{
sum += x[i];
}
average = sum / 5;
return average;
}
int main()
{
float score[5] = {78.5f,65.5f,88.7f,92.5f,100.0f};
float aver = getAverage(score);
printf("5门课的平均成绩为:%.2f\n",aver);
return 0;
}
// 数组的长度作为函数参数
/*
将数组的长度作为函数的参数,把数组的长度传给函数,实际上很有用处的,因为函数经常不知道数组的长度是多少,必须要传个数组长度
*/
#include <stdio.h>
#define N 5
float getAverage(float x[], int len)
{
float average; // 平均值
float sum = 0; // 总和
for (int i = 0; i < len; i ++) // 在这里,这个函数就不用担心怎么获得数组的长度了,只要使用传进来的数组长度就行了
{
sum += x[i];
}
average = sum / len;
return average;
}
int main()
{
float score[N] = {78.5f,65.5f,88.7f,92.5f,100.0f};
float aver = getAverage(score,N);
printf("5门课的平均成绩为:%.2f\n",aver);
return 0;
}
// 数组形参退化为指针
/*
数组作为函数的参数会退化为指针
*/
#include <stdio.h>
#define N 5
void show(int x[])
{
printf("x保存的地址:\t%p\n",x); // 数组已经退化为指针,这里x是一个指针了
printf("x的地址:\t%p\n",&x);
/*
之所以数组作为函数的参数会退化为指针,是因为数组只有一个原本,不可能在函数中再创建一个该数组的副本,所以只有将数组作为形参退化为指针,然后用指针来保存原始数组的地址
*/
}
int main()
{
int a[] = {0,1,2};
printf("a保存的地址:\t%p\n",a);
printf("a的地址:\t%p\n",a);
show(a);
return 0;
}
// 指针数组作为函数参数
/*
将指针数组传给函数
*/
#include <stdio.h>
void show(char *x[], int len)
{
for (int i = 0; i < len; i ++)
{
printf("%s\n",x[i]);
}
}
int main()
{
char *book[] = {
"荒野的呼唤",
"时光之轮",
"老人与海",
"教父",
"基督山伯爵",
"地海传说"
};
int size = sizeof(book)/sizeof(book[0]);
show(book,size);
return 0;
}
// 结构体变量作为函数参数
/*
将结构体变量作为形参传给函数
*/
#include <stdio.h>
#include <string.h>
struct book // 定义一个结构体book
{
char name[20];
float price;
};
void show(struct book sb)
{
printf("书名:%s\n",sb.name);
printf("价格:%.2f\n",sb.price);
}
int main()
{
struct book book1;
strcpy(book1.name, "中国好声音");
book1.price = 12.30f;
show(book1);
return 0;
}
// 结构体数组作为函数参数
/*
将结构体数组作为形参传给函数
*/
#include <stdio.h>
#include <string.h>
struct book // 定义一个结构体book
{
char name[40];
float price;
};
void show(struct book sb[], int len)
{
for (int i = 0; i < len; i ++)
{
printf("书名:%-20s\t价格:%.2f\n",sb[i].name,sb[i].price);
}
}
int main()
{
struct book myBook[] =
{
{"<荒野的呼唤>",11.20f},
{"<伏尔加河上的小房子>",3.00f},
{"<国富论>",50.0f},
{"<麦田里的守望者>",9.50f}
};
int size = sizeof(myBook)/sizeof(myBook[0]);
show(myBook,size);
return 0;
}
// 函数指针
/*
每个函数都有一个入口地址,即函数代码段在内存中的首地址,可用指针来保存该地址
*/
#include <stdio.h>
int add(int x, int y)
{
int z;
z = x + y;
return z;
}
int main()
{
int (*p) (int x, int y);
p = add;
int x = p(3,5);
printf("x:%d\n",x);
return 0;
/*
函数指针保存的是函数第1条代码的地址,而不是数据的地址,因此不能对函数指针执行算术运算,即没有++和--等运算,用时要格外小心
*/
/*
注意:*p两侧的括号不能省略,它表示p先与*结合,然后再与后面的一对括号结合;假如省略了括号,那么p先与后面的一对括号结合,再与*结合,p就成了函数,而不是函数指针
*/
}
// 函数指针应用
/*
函数名是死的,它代表一个函数的地址,而函数指针则是活的,它可以保存任意一个符合要求的函数的地址,因此函数指针要比函数名更加灵活
*/
#include <stdio.h>
#include <string.h>
int max(int,int);
int min(int,int);
int add(int,int);
int (*p)(int,int);
int max(int x, int y)
{
int z;
if (x > y)
{
z = x;
}
else
{
z = y;
}
return z;
}
int min(int x, int y)
{
int z;
if (x > y)
{
z = y;
}
else
{
z = x;
}
return z;
}
int add(int x, int y)
{
int z;
z = x + y;
return z;
}
int main()
{
int x,y;
int select;
char ch[20];
while (1)
{
printf("(0)退出(1)求最大数(2)求最小数(3)两数相加:");
scanf("%d",&select);
if (select == 0)
{
break;
}
else if (select < 0 || select > 3)
{
printf("请输入0-3之间的数字!\n");
continue;
}
printf("请输入第1个数:");
scanf("%d",&x);
printf("请输入第2个数:");
scanf("%d",&y);
switch (select)
{
case 1:
p = max;
strcpy(ch, "最大数为:");
break;
case 2:
p = min;
strcpy(ch, "最小数为:");
break;
case 3:
p = add;
strcpy(ch, "两数相加的和为:");
break;
default:
break;
}
printf("%s%d\n",ch,p(x,y));
}
return 0;
}
// 函数指针作为函数参数
/*
指针可以作为函数的参数,函数指针也不例外
*/
#include <stdio.h>
int add(int,int);
void func(int x, int y, int (*p)(int,int));
int add(int x, int y)
{
int z;
z = x + y;
return z;
}
void func(int x, int y, int (*p)(int,int))
{
int z;
z = p(x,y);
printf("%d\n",z);
}
int main()
{
int x,y;
printf("请输入第1个数:");
scanf("%d",&x);
printf("请输入第2个数:");
scanf("%d",&y);
func(x, y, add);
return 0;
}
// 函数指针数组
/*
可以声明一个由多个函数指针组成的数组,这个数组就是函数指针数组
*/
#include <stdio.h>
int max(int,int);
int min(int,int);
int add(int,int);
int (*p[3])(int,int); // 函数指针数组
int max(int x, int y)
{
int z;
if (x > y)
{
z = x;
}
else
{
z = y;
}
return z;
}
int min(int x, int y)
{
int z;
if (x < y)
{
z = x;
}
else
{
z = y;
}
return z;
}
int add(int x, int y)
{
int z;
z = x + y;
return z;
}
int main()
{
int x,y;
p[0] = max;
p[1] = min;
p[2] = add;
printf("请输入第1个数:");
scanf("%d",&x);
printf("请输入第2个数:");
scanf("%d",&y);
printf("最大数为:%d\n",p[0](x,y));
printf("最小数为:%d\n",p[1](x,y));
printf("两数相加之和为:%d\n",p[2](x,y));
return 0;
}