NDK开发系列之第四次课-NDK-C语言-函数指针+动态内存

来源:互联网 发布:梅西c罗生涯数据对比 编辑:程序博客网 时间:2024/06/07 17:59
1.建立项目,导入基本包
//允许使用过时的函数和不安全的函数,去掉警告
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <Windows.h>

2.函数指针
2.1定义函数,相当于java中的方法
void showMessage(){
//弹窗,这个不懂可以不用理会因为这不是重点,只要知道这样写是一个弹窗即可
MessageBox(0, "消息内容", "消息标题", 0);
}
double add(double a, double b){
return a + b;
}


void add(int a, double b){

}
void main(){
//传统的写法
//直接调用,和java中直接调用方法一样
//showMessage();



//采用函数指针的方式调用
//void(*p)() = showMessage;
//p();


//间接调用
//带返回值和参数列表的函数指针
double(*p1)(double a, double b) = add;


double d = p1(2,3);
printf("%lf", d);


//补充:函数指针-不仅仅是地址,必须明确的指定函数的指针类型,以及返回值和参数列表
//回想Java语言:方法重载(方法名相同,参数列表不同,或者参数类型不同)
getchar();
}
2.2函数指针-案例
函数的返回值是一个指针,函数的参数列表是一个数组,返回数组的最小值
int* getMin(int a[], int len){


//printf("getMin地址:%#x\n", &a);


//int len = sizeof(a) / sizeof(int);

int i = 0;
//选择法进行判断筛选
//首选:假设数组中第一个元素是最小值
int min = a[0];
int *p = &a[0];
for (; i < len; i++){
if (a[i] < min){
min = a[i];
p = &a[i];
}
}
return p;
}


void main(){
int a[5];


// 我要让每一次都不一样
// 初始化随机数发生器
//time_t实际上就是一个时间---长整型
time_t t;
//srand传入的参数与不相同,那么就会生成新的随机数(随机数种子)
//time:1970年1月1日0分0秒
srand((unsigned)time(&t));


int i = 0;
for (; i < 5; i++){
a[i] = rand() % 50;
printf("%d\n", a[i]);
}


printf("main地址:%#x\n", &a);


//计算数组的长度
int len = sizeof(a) / sizeof(int);
int* min = getMin(a, len);
printf("最小值:%d", *min);


getchar();


}
3.动态分配内存
3.1一些基本
Stackoverflow栈溢出异常,数组的数据默认保存在栈内存中
栈区:自动分配自动释放(存放的内容:主要存放的是函数的参数值,局部变量)--更高效
堆区:需要自己回收释放
全局区和静态区 全局变量和静态变量(系统自动管理,当我们的应用程序结束的时候释放)
字符常量区 常量字符串(系统自动管理,当我们的应用程序结束的时候释放)
栈区内存的大小:操作系统和C库版本相关(大小是有限制的)

3.2创建一个数组,动态的指定数组的大小(动态分配数组大小)
void main(){
int len;
printf("请输入数组的长度:");
scanf("%d", &len);


//动态指定数组的大小(用于存储int类型的数据)
//注意:malloc开辟一个块内存空间返回void*
//在C语言void*方法指针可以指向任何类型的方法指针
//回想Java Object类型
//p就是首地址
int* p = (int*)malloc(5 * sizeof(int));
//double* p = (double*)malloc(len * sizeof(int));
//char* p = (char*)malloc(len * sizeof(int));


int i = 0;
for (; i < len; i++){
p[i] = rand() % 50;
printf("%d   %#x\n", p[i], &p[i]);
}


//C语言当中,动态分配
//联想到:java集合


system("pause");
}
3.3重新分配内存
void main(){
int len;
printf("请输入数组的长度:");
scanf("%d", &len);


//int* p = (int*)malloc(5 * sizeof(int));
//第一个参数:数组长度
//第二个参数:每个元素大小
//更方便
int* p = (int*)calloc(5,sizeof(int));
int i = 0;
for (; i < len; i++){
p[i] = rand() % 50;
printf("%d   %#x\n", p[i], &p[i]);
}


//改变原始内存区域的大小(增加-减小)
int addLen;
printf("请输入数组的增加长度:");
scanf("%d", &addLen);


//重新输出数组的数据---需要从新分配内存
//注意:新的=老的+增加的
//realloc更改已经配置的内存空间
//缩小:会导致一部分数据丢失
//扩大(连续不断-线性排列)
//情况一:如果当前的内存段后面有需要的内存空间,就会直接追加(注意:返回原指针)
//情况二:如果当前内存段后面空闲的字节空间不够
//那么就会重新再堆内存中寻找能够容纳该数据大小的内存区域(注意:返回值新的内存地址,原来的被释放)
//情况三:如果没有容身之处,申请内存失败,将返回NULL,而且原来的指针有效
int* p1 = (int*)realloc(p,sizeof(int)*(len+addLen));
i = len;
for (; i < len+addLen; i++){
p1[i] = rand() % 50;
}


//输出
i = 0;
for (; i < len + addLen; i++){
printf("%d   %#x\n", p1[i], &p1[i]);
}


system("pause");
}
3.4内存分配应该注意的
不能够多次释放内存
释放内存之后,给原来的指针设置NULL
内存泄漏
void main(){
int len;
printf("请输入数组的长度:");
scanf("%d", &len);


int* p = (int*)calloc(5, sizeof(int));
int i = 0;
for (; i < len; i++){
p[i] = rand() % 50;
printf("%d   %#x\n", p[i], &p[i]);
}


//释放内存
free(p);


//标记内存已经被释放
p = NULL;


free(p);

system("pause");
}
//以下情况导致内存泄漏
void heapMethod(){
//在堆区开辟了一块40M的内存空间
int* p = (int*)malloc(1024 * 1024 * 10 * 4);


p = NULL;


//回收内存
free(p);
printf("\n");
}


void main(){
//循环创建数组
while (1)
{
heapMethod();
Sleep(6000);
}
}
0 0
原创粉丝点击