目录
递归函数
动态内存开辟
函数调用机制
递归函数
时间复杂度和递归的深度有关
1)函数直接或间接调用自己->递归的函数
2)函数退出条件
3)形参体现问题规模,问题规模不断缩小
分解:大规模问题分解为小规模问题直到找到小规模问题能解决
合并:将小问题规模的解逐层组合成原问题规模
举例:1)二分查找
int print(int *arr, int l,int r,int vlan){
if (l>=r) return -1;
int mid=((l-r)>>2)+r;
if (arr[mid] > vlan) return print(arr, l, mid-1,vlan);
if (arr[mid] < vlan) return print(arr, mid+1, r, vlan);
if (arr[mid] == vlan) return mid;
return 0;
}
int mun(int* arr, int len, int vlan){
return print(arr, 0, len - 1, vlan);
}
2)将一个整数的每位数字输出出来
int point(int num){
if (num == 0) return 0;
printf("%5d",num % 10);
point(num/10);//形参体现问题规模不断缩小
}
3)快速排序
void quick_sort(int* arr, int left, int right){
int x = arr[left];
int i = left, j = right;
while (i < j){
while (i<j&&x<=arr[j])
j--;
arr[i] = arr[j];
while (i<j&&x>=arr[i])
i++;
arr[j] = arr[i];
}
arr[i] = x;
if (i-1>left)
quick_sort(arr, left, i - 1);
if (i + 1 < right)
quick_sort(arr, i + 1, right);
}
动态内存开辟
三个函数 malloc realloc calloc free(释放)
内存开辟 栈:高地址->低地址
堆:1.5G~1.9G,动态内存开辟 低地址->高地址 进行内存开辟,程序员开辟,自己释放(防止内存泄漏)。
malloc :例:int *p=(int*)malloc(1.8*1024*1024*1024);malloc(字节数)
int main(){
int a=10;
int*p=(int*)malloc(sizeof(int*)*a);//1)开辟
assert(p!=NULL);//2)p==NULL 内存开辟失败
for(int i=0;i<n;i++){
printf("%d",p[i]);
}
free(p);//3)释放指向p的内存空间
p=NULL;//4)p=null
return 0;
}
以上代码便是开辟内存定义一个一维数组,等价于c++中定义int p[a];
动态开辟内存的四个步骤:
1)开辟内存
2)断言 p若等于空则说明没有开辟成功,
3)释放内存,
4)p=NULL,防止出现野指针(悬挂指针)
函数调用机制
局部变量内存 程序执行过程中“动态”建立和释放。动态->系统自动管理 栈内存
进行一个函数调用:
1)建立栈帧空间 (注:栈帧 函数的返回地址和函数调用上下文)
2)保护现场:主调函数运行状态 入栈
3)形参进行存储空间开辟,形参 拷贝 实参 ,函数局部变量内存分配
4)执行函数体
5)释放被调函数的栈空间
6)恢复现场:获取主调函数的运行状态,返回主调函数执行的地址
7)继续主调函数的后续语句