函数:
int is_prime(int x) {}
返回值 函数名(参数声明列表) {
return x
}
函数声明;
int is_prime(int);
K&r 风格的函数定义(上古级别)
int is_prime(x)
int x; // 声明在下面
{
代码段;
}
递推是算法(数学相关)
递归(编程技巧,不是算法):
递归程序的组成部分:
0,语义信息,如fac(n)用来表示n的阶乘
1,边界条件处理
2,针对于问题的【处理过程】和【递归过程】
3,结果返回。或传出参数(地址方式)
向下递推(函数调用),向上回归(回溯)
fac(n) = n * fac(n - 1)递推式很重要
数学归纳法: 、 动态规划
①确定f(1) = 1成立
②假设f(k)成立,推f(k +1)也成立
(函数调用需要栈空间) 栈(FILO):
函数调用f(5)->f(4)->f(3)->f(2)->f(1),然后f(1)先执行,最后f(5)
BUG:爆栈(超了系统栈)、栈溢出、segmentfalut
系统栈的大小:8MB(Linux), 2MB(Windows),默认当成8MB,大概800W个字节。比如int arr[200w]就可能会爆栈了。
①我们在函数内部定义的变量、数组占用的存储空间是内存上的栈区(系统栈8MB左右)
②函数调用的层数过深,也可能造成爆栈。
如果定义全局变量的数组,则是占用全局区(静态区);
如果使用malloc家族去动态申请,则是在堆区
(在函数中使用malloc也是使用堆区,堆区需要手动释放)
----------------------------------------------
函数指针(函数的参数列表中去传入函数):
存函数地址的指针。本质是指针。是个变量,存地址的,有类型的。
// 分段函数
int g(int (*f1)(int), int (*f2)(int), int (*f3)(int), int x) {
if (x < 0) return f1(x);
if (x < 100) return f2(x);
return f3(x);
} // 传入了3个函数和1个int
int Func(int x); /*声明一个函数*/ int (*p) (int x); /*定义一个函数指针*/ p = Func; /*将Func函数的首地址赋给指针变量p*/
int (*f1)(int)
类型 (*函数名)(参数列表)
函数指针接收的 值 是 函数名(不带参数列表!)
-----------------------------------------------
OULA 45题:
从六边形遍历,跨度大,时间开销小
无需判断三角形,因为六边形数肯定是三角形数
#include <iostream>
#define MIN 143
long long Triangle(long long n) {
return n * (n + 1) >> 1;
}
long long Pentagonal(long long n) {
return n * (3 * n - 1) >> 1;
}
long long Hexagonal(long long n) {
return n * (2 * n - 1);
}
//函数指针版本二分查找 找到返回1 没找到返回0
long long binary_search(long long (*arr)(long long), int max, long long x) {
int min = MIN, mid;
while (min <= max) {
mid = (min + max) >> 1;
if (arr(mid) == x) return 1;
if (arr(mid) < x) min = mid + 1;
else max = mid - 1;
}
return 0;
}
int main() {
int n = MIN; //六边形的项数
while (n++) {
long long num = Hexagonal(n);
if (!binary_search(Pentagonal, n * 2, num)) continue;
printf("%lld\n", num);
break;
}
return 0;
}
三角形数项数< 六边形数项数 * 2
五边形数项数∈(三角形数项数, 六边形数项数)
------------------------------------------------
arr[mid] 数组
arr(mid) 函数
函数与数组的(映射)关系:
函数是压缩的数组,
数组是展开的函数。