一、指针
1、
指针只是一个变量,它存储数据在内存中的地址而不是存储数据本身。
C语言中指针变量拥有和其他变量一样的类型。
当声明一个指针时,仅仅是为指针本身分配了空间,并没有为指针所引用的数据分配空间。
结构不允许包含自身的实例,但可以包含指向自身实例的指针。
指针的运算是加减对应指向数据类型的字节数。
数组*(*(a+i)+j) a是个二维指针,先指向某行,在指向某列。对于二维数组声明,列元素个数必须固定如a[][3],二维数组由一维数组连续构成。
未初始化的指针是潜在的危险,应该char *p=NULL;
2、函数指针(也是一个变量:指针变量)
int (*fun_p)(void *p1, void *p2);
fun_p=fun;
a=fun_p(&x, &y);
二、递归
1、基本递归
int factorial(int n)
{
if((n == 1) || (n == 0))
{
return 1;
}
else
{
return n*factorial(n-1);
}
}
栈维护每个函数调用的信息直到函数返回后才释放,即每次切分由于每个上层问题都和下层有关,每次开辟相同大小的栈空间,这需要占用相当大的空间。
2、尾递归
定义:一个函数中所有递归形式的调用都出现在函数的末尾。
当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活跃记录二不是在栈中去创建一个新的。
int fact_tail(int n, int a)
{
if((n == 1) || (n == 0))
{
return a;//这里只能是a而不能是1,它覆盖活动域,是1会直接返回
}
else
{
return fact_tail(n-1,n*a);
}
}
尾递归求一个数的素数集合:
//子函数判断n是不是素数
int is_prime(int n)
{
int i;
for(i=2;i<n;i++)
{
if((n%i) == 0)
return 0;
}
return 1;
}
//尾递归
int *prime(int n, int venue[])
{
static mun = 0;
int i;
if(is_prime(n))
{
*venue=n;
//venue++;
mun++;
for(i=mun;i<10;i++)
{
*(++venue)=0;
}
return venue;
}
else
{
for(i=2;i<n;i++)
{
if((is_prime(i)) && ((n%i) == 0))
{
break;
}
}
*(venue++)=i;
mun++;
prime(n/i,venue);
}
}
另一个例子:级数加法
float add_series(int n)
{
if(n == 1)
{
return (float)1;
}
else
{
return add_series(n-1)+(float)1/(float)n;
}
}
float add_series_tail(int n, float a)
{
if(n == 1)
{
return a;
}
else
{
return (add_series_tail(n-1,a+(float)1/(float)n));
}
}