C语言-------函数指针&实参形参的传递&**p

一.知识点

1. 函数指针的定义

int (*p)();//p为指向函数的指针,该函数返回一个整型值

先确定函数返回值,再写两个括号.
例:

#include <stdio.h>
int sum(int a,int b);
int main(void){
	int (* pfun)(int ,int);	
	pfun=sum;//将sum的入口地址赋给pfun; 
	//下面的写法都是对的 
	printf("%d\n",sum(1,2)); 
	printf("%d\n",pfun(1,2)); 

	printf("%d\n",(*sum)(1,2)); 
	printf("%d\n",(*pfun)(1,2)); 
	return 0;

} 
int sum(int a,int b){
	return a+b;
}
int a[4][5];
int *(*p[5]) (void *int **) = {fun, fun, fun, fun, fun};//数组里面每一个元素都是函数指针
int (*p[4])[5] = {a, a+1, a+2,a+3};//数组里面每一个元素都是行指针数组指针
int (*p)[5];//行指针
2.实参形参的传递

实参是一个变量p,传递值给形参,则函数内部无论怎么做
都不会改变实参p的值,只有传地址才可以改变值.

实参是一个指针变量p,传递给形参,则函数内部无论怎么做
都不会改变实参p的指向,但可以通过地址改变指向的内容.
//1.实参是-一个1级指针的地址,形参就是**
//2.当实参为指针数组时,形参也要用**

3. 回调函数

下层调用上层
int atexit(void (*function)(void));

void fun2(){
	printf ("he1lo world\n") ;
}
int main (void){
	atexit (fun2) ;
	printf ("1234567\n") ;
	return 0;
}

结果
1234567
he1lo world
4. const
const int a=10//常量
char*p;//可以通过p去访问(读取,修改)内存
const char*p;//这个指针时只读指针,它可以指向有效地址,可以指来指去
char const*p;//无法通过这个指针去修改内存,可以读取
char *const p//常量指针,一般都需要初始化,指向后无法再向其他地方,但是可以通过
//这个指针变量去修改内存。
const char* const p;//只读常量指针,不能指来指去,也无法通过这个指针去修改内存
char const const p
5. **p的使用

int **p; //二级指针指向的1级指针是int *类型
(1)用于指向1级指针,是指针的指针

int a =10:
int *q=&a;
p=&q;
//a==*q==**p
//&a==q==*p

(2)p可以指向于对应的指针数组

int *b[10];
p=b;         

错误用法:

int c[3][4];
int **p=c;

二维数组要行指针(数组指针—int (*p)[4])来指向
但是可以使用

int** p = (int**)malloc(sizeof(int*) * SIZE);
for(int i = 0; i < SIZE; i++)
{
    p[i] = (int*)malloc(sizeof(int) * SIZE);
}
指向动态申请的二维数组.
6. 实现一个函数myQsort()可以对int char 字符串或者其他类型进行排序的函数
#include <stdio.h> 
#include <string.h>
void myQsort(void *array,int size,int n,int (*pfun)(void *,void *));
int cmpint(void *a,void *b);
int cmpchar(void *a,void *b);
int cmpstr1(void *a,void *b);
int cmpstr2(void *a,void *b);
void myswap(void *a,void *b,int size);
int main(void){

	int a[5]={2,3,5,4,1};
	char buf[5]={'b','c','g','f','e'};
	char src[5][5]={"bbbb","cccc","eeee","aaaa","yyyy"};
	char *src2[5]={"bbbb","cccc","eeee","aaaa","yyyy"};
	int i; 
	
	myQsort(a,sizeof(int),5,cmpint);
	for(i=0;i<5;i++){
		printf("%d ",a[i]);
	} 
	printf("\n");
	
	myQsort(buf,sizeof(char),5,cmpchar);
	for(i=0;i<5;i++){
		printf("%c ",buf[i]);
	} 
	printf("\n");
	
	myQsort(src,5,5,cmpstr1);
	for(i=0;i<5;i++){
		printf("%s ",src[i]);
	} 
	printf("\n");
	
	myQsort(src2,1,5,cmpstr2);
	for(i=0;i<5;i++){
		printf("%s ",src2[i]);
	} 
	printf("\n");
	
	return 0; 
} 
void myQsort(void *array,int size,int n,int (*pfun)(void *,void *)){
	
	int i,j;
	for(i=0;i<n-1;i++){
		for(j=0;j<n-1-i;j++){
			if(pfun(array+j*size,array+(j+1)*size) ==1){
				myswap(array+j*size,array+(j+1)*size,size);
			}
		}
	}
} 
void myswap(void *a,void *b,int size){
	
	char buf[size];
	memcpy(buf,a,size);
	memcpy(a,b,size);
	memcpy(b,buf,size);
	
}
int cmpint(void *a,void *b){

	if( *(int *)a > *(int *)b ){
		return 1; 
	} 
	else{
		return 0;
	} 
} 
int cmpchar(void *a,void *b){
	
	if( *(char *)a > *(char *)b ){
		return 1; 
	} 
	else{
		return 0;
	} 
}
int cmpstr1(void *a,void *b){	//void *指针可以指向任何类型 
	
/*	//a,b行指针 
	 	char (*p1)[5]=(char (*)[5])a;//其他类型指针指向void *需要强制类型转换 
	char (*p2)[5]=(char (*)[5])b; 
	if(strcmp(*p1,*p2) == 1){      //strcmp的参数是列指针 
		return 1;
	}
	else{
		return 0;
	} 
	*/ 
	if(strcmp(*(char (*)[5])a,*(char (*)[5])b) == 1){
		return 1;
	} 
	else{
		return 0;
	}
				
}
int cmpstr2(void *a,void *b){

	if(strcmp(*(char **)a,*(char **)b) == 1){
		return 1;
	} 
	else{
		return 0;
	}
} 

二.个人感悟

感觉课上有些点没有反应过来,晚上把回放翻出来复习了一下.解决了不少疑惑.果然是温故而知新啊!任重而道远,加油!

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值