数组作为函数的参数
#include<stdio.h>
void main(){
void print(int a[][2]); //函数的申明里的参数列表也是需要引用参数
int a[2][2]={{1,2},{3,4}};
int i,j;
print(a); //实参传递的是数组的首地址
for(i=0;i<2;i++){
for(j=0;j<2;j++){
printf("%d\n",a[i][j]);
}
}
getchar();
}
void print(int a[][2]){
int i,j;
for(i=0;i<2;i++){
for(j=0;j<2;j++){
printf("%d\n",a[i][j]);
}
}
a[0][1]=8;
}
//重点:原数组当成参数传递的时候,操作的是原内存,不开辟新的空间存储,为了节省内存
特殊情况:
原数组当成参数传递的时候,操作的是原内存,不开辟新的空间存储,为了节省内存重点: 指针数组 int(*p)[4] *p指的是a[0],a[1],a[2]........,a[i]
记住(*p)指向的是数组的行元素的首地址;
总结:
1) 形参数组和实参数组的类型必须一致,否则将引起错误。
(2)实参传递的是数组的首地址,传递到形参,形参一定要定义类型,形参是传递的数组或者变量
指针与多维数组的关系
将数组a中的元素以相反顺序存放
将数组中的第一个元素和最后一个元素交换,第0个和i-0个元素进行交换
#include<stdio.h>
void main(){
int a[6]={1,2,3,4,5,6};
int i; //在赋值前定义
for( i=5;i>=0;i--){
int x=0;
x=a[i];
a[i]=a[5-i]; //利用第三变量交换前后元素位置 ,可以用冒泡排序来实现排序。本人表示不熟,
a[5-i]=x;
}
for(i=0;i<6;i++){
printf("%d\n",a[i]);
}
getchar();
}*/
//用指针办法对10个整数由大到小进行排序(还有点小问题,)
/*#include<stdio.h>
void main(){
int a[]={2,4,1,5,8,9,15,46,3,6};
int *p;
p=a; //用指针取得数组a的首地址
int min=a[0];
int i;
for(i=0;i<10;i++){
if(min>*(p+i)){
min=*(p+i); //*(p+i)=a[i];
}
}
for(i=0;i<10;i++){
printf("%d\n",min);
}
getchar();
}*/
//三个学生四门课,计算总平均分数和第n个学生的成绩
//用average函数求取平均数,利用search函数找出并输出第i个学生的成绩
/*#include<stdio.h>
void main(){
void add();
int n,l,sun=0;
int a[3][4]={{50,80,78,67},{67,59,45,59},{63,74,87,78}};
add(a);
while(1){
printf("你要查找第几个学生的成绩:");
scanf("%d",&n);
if(n<=0){
printf("查无此人\n");
}
if(n==1){
sun=0; //没循环一次,应该重新复制,防止得到的结果累加
for(l=0;l<4;l++){
sun+=(a[0][l]); //第一排的每个元素加起来
}
printf("%d分\n",sun);
}
if(n==2){
sun=0;
for(l=0;l<4;l++){
sun+=(a[1][l]); //第二排的每个元素加起来
}
printf("%d分\n",sun);
}
if(n==3){
sun=0;
for(l=0;l<4;l++){
sun+=(a[2][l]); //第三排的每个元素加起来
}
printf("%d分\n",sun);
}
if(n>3){
printf("查无此人\n");
}
}
getchar();
getchar();
}
void add(int a[3][4]){
int i,j,sum=0;
float num=0;
for(i=0;i<3;i++){
for(j=0;j<4;j++){
sum+=a[i][j]; //二维数组的每个数都加起来
}
}
num=sum/12;
printf("总平均分为%f\n",num);
}*/
//利用指针解决二维数组问题(将数组首地址传递给形参)
/*#include<stdio.h>
void main(){
void add(int (*p)[4]);
int a[3][4]={{50,80,78,67},{67,59,45,59},{63,74,87,78}};
int (*p)[4]=a; //定义指针的方式并且与二维数组取得联系
add(a); //将数组的首地址传递给形参,然后就可以在被调用的函数中使用实参数组
getchar();
}
void add(int (*p)[4]){
int i,j,sum=0;
float num=0;
for(i=0;i<3;i++){
for(j=0;j<4;j++){
sum+=*(*(p+i)+j);
}
}
num=sum/12;
printf("总平均分为%f\n",num);
}*/
//函数指针(定义一个函数,编译时,系统会为函数代码分配一段储存空间,这段储存地址的起始地址,称为这个函数的指针)
//定义一个指向该函数的指针变量,用来存放该函数的起始地址,意味着该指针变量指向该函数
1:定义方式
int(*p)(int,int);
注意: *(p+n); *(p++); *(p--) 等运算毫无意义
直接调用
add(参数)
间接调用 int (*p)(int a,int b);
p=add; 注意(p=add();这是一个错误的定义)add()是一个函数 ,而add是该函数的首地址
p取得函数地址 printf("%x",p);
int c=p(10,10); 标识符传值
重点
三步曲:
复制调用函数,将函数名改为(*p) 然后p=add; 然后标识符传值(*p)(可以写无数据类型的参数)
用途:把函数的地址作为参数传递到其他函数 具体是 指向函数的指针可以作为函数参数,把函数的入口地址传递给形参,这样就可以在被调用的函数中
使用实参函数
例题
//请输入俩个数,再输入一个数,如果这个数是1就求最大值,如果是2就求最小值,如果是3就求和
/*#include<stdio.h>
#include<stdlib.h>
void main(){
int a,b,c;
void (*p)(int a,int b,int c); //三部曲第一步
void add(int a,int b,int c); // 函数的申明,参数记得写
printf("请输入俩个数");
scanf("%d,%d",&a,&b);
printf("请再输入一个数");
scanf("%d",&c);
p=add; //第二步
(*p)(a,b,c); //第三步
system("pause");
}
void add(int a,int b,int c){
if(c==1){
if(a>b){
printf("%d",a);
}
else{
printf("%d",b);
}
}
if(c==2){
if(a>b){
printf("%d",b);
}
else{
printf("%d",a);
}
}
if(c==3){
printf("%d",a+b);
}
}*/
输入a,b和c的值,编写一个程序求这三个数的最大值和最小值。要求把求最大值和最小值编写成函数,并使用指针作为形式参数把结果返回函数main
如果报乱七八糟的语法错误,就将函数的申明,函数的定义或者数组的定义放到输入的前面
/*#include<stdio.h>
//#include<stdlib.h>
void main(){
int a,b,c;
int max(int a,int b,int c);
int min(int a,int b,int c);
int (*p)(int a,int b,int c);
int (*p1)(int a,int b,int c);
printf("请输入三个数");
scanf("%d,%d,%d",&a,&b,&c);
p=max;
(*p)(a,b,c);
p1=min;
(*p1)(a,b,c);
getchar();
getchar();
//system("pause");
}
int max(int a,int b,int c){
if(a>b&&a>c){
printf("最大值%d\n",a);
}
if(b>a&&b>c){
printf("最大值%d\n",b);
}
else{
printf("最大值%d\n",c);
}
return 1;
}
int min(int a,int b,int c){
if(a<b&&a<c){
printf("最小值%d",a);
}
if(b<a&&b<c){
printf("最小值%d",b);
}
if(c<a&&c<b){
printf("最小值%d",c);
}
return 0;
}*/