20150423函数指针

一.二维数组

1.在栈上创建数组

一维数组:int *p=(int []){0};

二维数组:int (*px)[4]=(int [][4]){0};

三维数组:int (*py)[3][4]=(int [][3][4]){0};


2.堆上分配二维数组(地址不连续)

void    main2()
{
	int **pp = calloc(3, 4);//分配指针数组
	for (int i = 0; i < 3;i++)
	{
		pp[i] = malloc(4 * sizeof(int));//每个指针分配内存
	}
	int num = 0;
	for (int i = 0; i < 3;i++)
	{
		for (int j = 0; j < 4;j++)
		{
			printf("%4d",pp[i][j]=num++ );// *( *(pp+i)+j)  pp[i][j]
			//*(pp+i)  ==pp[i]   pp+i  == &pp[i]
 		}
		printf("\n");
	}
	for (int i = 0; i < 3;i++)//先释放块
	{
		free(pp[i]);
	}
	free( pp);//再释放指针数组

	system("pause");
}

3.堆上分配二维数组(地址连续)

void main4()
{
	int(*p)[4] = malloc(sizeof(int)* 12);//连续

	int num = 0;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			printf("%4d", p[i][j] = num++);//
		}
		printf("\n");
	}
	free(p);

	system("pause");

}

二.函数指针

1.函数指针的非法调用

不可以在一个进程中调用另一个进程的函数,但可以用dll函数调用另一个进程的函数,实现非法调用

<span style="font-size:24px;">_declspec(dllexport)  void main()
{
	void (*p)()=0x10510b9;//函数指针,地址为要调用函数的地址
	p();//调用


}</span>

2.函数指针变量,在数据区,但是存储了代码区的地址,函数在代码区


四.函数指针强化

1.函数指针用法

int add(int a, int b)
{
	return a + b;
}

int sub(int a, int b)
{
	return a - b;
}
int mul(int a, int b)
{
	return a * b;
}
int divv(int a, int b)
{
	return a /b;
}

int  getmax(int a, int b)
{
	return a > b ? a : b;
}

int  getmin(int a, int b)
{
	return a < b ? a : b;
}
void op(  int (*p)(int,int)  ,int a,int b  )
{
	printf("%d\n", p(a, b));

}

void main2()
{
	op(add, 1, 2);

	op(divv, 1, 2);


	system("pause");
}

2.返回函数时的用法

void main1()
{
	int(*p1)(int a, int b)=add(1,2);
	int(*p2)(int, int)=add;//参数名可以省略
	p1(1, 2);
	//p1++;  函数指针没有自增,自建
	//p2++;
	//p3 + n;

}
//int(*p)(int, int)函数指针
//int(*)(int, int) 函数指针类型
//int(* get() )(int, int)  //一个函数,参数为空,返回值是一个函数指针
//

//   int(    * get(int (*y)(int,int),double)         )(int, int) 
// int(    *         )(int, int) //函数指针类型
//  get(  int (*y)(int,int)   ,    double)   整体

int(* getop())(int, int)
{
	return add;
}




void main()
{
	printf("%d", getop()(1, 2));

	system("pause");



}

五.函数指针数组与二级函数指针

1.动态函数指针用法

void main3()
{
	int(**pp)(int, int) = malloc(sizeof(int(*)(int, int)) * 4);//堆区
	*pp = add;
	*(pp + 1) = sub;
	*(pp + 2) = mul;
	*(pp + 3) = divv;

	for (int i = 0; i < 4; i++)
	{
		//	printf("%d\n", pp[i](100, 10));
		printf("%d\n", (*(pp + i))(100, 10));
	}


	system("pause");

}

2.int (*p)[5];  指向数组的指针,占四个字节

int *p[5];是一个数组,每一个元素是一个指针


七.函数指针数组与多线程

1.多线程异步执行多个函数

void run1(void*p)
{
	MessageBoxA(0, "1", "1", 0);
}
void run2(void*p)
{
	MessageBoxA(0, "2", "2", 0);
}
void run3(void*p)
{
	MessageBoxA(0, "3", "3", 0);
}

void main()
{
	//run1(NULL);
	//run2(NULL);
	//run3(NULL);
	//for (int i = 0; i < 3;i++)
	//{
	//    HANDLE hd=	_beginthread(run1, 0, NULL);
	//	//WaitForSingleObject(hd, INFINITE);//无限等待
	//	WaitForSingleObject(hd, 3000);//3000等待3秒
	//}
	//HANDLE hd[3] = { 0 };
	HANDLE *hd = malloc(12);
	//void(*pfun[3])(void*p) = { run1, run2, run3 };//函数指针数组
	void(**pfun)(void*p) = (void(*[3])(void*p)){ run1, run2, run3 };

	for (int i = 0; i < 3;i++)
	{

		hd[i] = _beginthread(pfun[i], 0, NULL);
	}
	//TRUE等待所有线程,fause等待一个
	WaitForMultipleObjects(3, hd, FALSE, INFINITE);//等待多个线程结束

	//

	//主线程,控制全局,

	//system("pause");
}
//线程可以同步,也可以异步
//WaitForSingleObject(hd, 3000);//3000等待3秒
//主线程,控制全局  
//WaitForMultipleObjects(3, hd, TRUE, INFINITE);//

八.栈内存分配

int *p=alloca(sizeof(int)* 10);

alloca分配内存后自动释放内存


十.函数返回值副本机制

1.函数返回指针的时候,不可以返回指针指向栈区的内存,要获取指针函数返回值,该函数必须在堆上开辟内存

int * rungetmin()
{
	int *p = calloc(10, sizeof(int));//不会自动释放
	time_t ts;
	unsigned int num = time(&ts);//地址改变数据
	srand(num);
	for (int i = 0; i < 10;i++)
	{
		p[i] = rand() % 100;
		printf("\n%d", p[i]);
	}
	int imin = 0;//下标
	for (int i = 1; i < 10;i++)
	{
		if (p[i]<p[imin])
		{
			imin = i;//记录下标
		}


	}
	// p + imin   &p[imin]
	//*(p+imin)  p[imin]
	return p + imin;



}


void   main10()
{

	printf("最小的是%d", *rungetmin());

	system("pause");
}

2.普通在栈上的函数返回值有副本机制,存储在cpu,所以不能对其取地址等操作


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值