1.动态内存空间
void *malloc(size_t size):
该函数从堆区中给出空间,其所给出的空间是连续的。
free(void *p):
清除p的空间, 但不能连续两次调用free,因被free清除之后的指针为野指针,清除野指针会造成系统错误。
eg 1:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char s[] = "Hello";
char *p = malloc(strlen(s) + 1);
strcpy(p, s);
puts(p);
free(p);
p = NULL;
return 0;
}
realloc(void *p, size_t size):
重新分配空间,重新分配空间的同时,会将原有内容复制到新的空间内,并会释放原空间。
eg2:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char s[] = "Hello";
char a[] = " World";
char *p = malloc(strlen(s) + 1);
strcpy(p, s);
puts(p);
p = realloc(p, strlen(s) + strlen(a) + 1);
strcat(p, a);
puts(p);
free(p);
p = NULL;
return 0;
}
2.函数指针
函数指针,即指向函数的指针,其中保存的是某个函数的入口地址;
int (*p)(形参类型与个数)
p = 函数名;
回调函数:
不在主函数中调佣,而在被调函数中调用的函数,被称为回调函数;
eg3:
#include <stdio.h>
int div3(int a)
{
return a % 3 == 0;
}
//pfn可以根据自己的需求来写出相应的函数,对打印条件进行限制
void printfAllIntArray(int *a, int len, int (*pfn)(int))
{
int i;
for(i = 0; i < len; ++i)
{
if(pfn(a[i]))
{
printf("%d\n", a[i]);
}
}
return ;
}
int main(void)
{
int a[] = {1,2,3,4,5,6,7,8,9,0};
int len = sizeof(a) / sizeof(*a);
printfAllIntArray(a, len, div3);
return 0;
}
3.指针的指针
指针的指针(二级指针),即指向指针的指针,其中存储着,某个指针的地址;
int **p //第二个*是声明p为一个指针,其基类型为(char *);
eg4
#include <stdio.h>
//交换了指针p和指针q所指向的变量(即p和q中所保存的地址改变)
void swapStrings(int **p, int **q)
{
int *t = *p;
*p = *q;
*q = t;
return ;
}
int main(void)
{
int i = 10;
int j = 20;
int *p = &i;
int *q = &j;
printf("%d %d\n", *p, *q);
swapStrings(&p, &q);
printf("%d %d\n", *p, *q);
return 0;
}
指针数组:
指针数组作为函数参数时,形参是指向指针的值;
eg5:
#include <stdio.h>
#include <string.h>
char *maxStrings(char **p, int len)
{
char *max = p[0];
int i;
for(i = 1; i < len; ++i)
{
if(strcmp(max, p[i]) < 0)
{
max = p[i];
}
}
return max;
}
int main(void)
{
char *s[] = {"Hello", "World", "China"};
int len = sizeof(s) / sizeof(*s);
puts(maxStrings(s, len));
return 0;
}