14 指针函数
返回值是指针的函数。
(1)动态内存分配
①使用方式:
#include<stdlib.h>
void *malloc(size_t size)
②返回连续的内存空间的首元素地址,内存空间未被初始化,申请的是堆区的空间。
③内存空间申请失败会返回空指针。
④释放函数:不能多次使用。
void *free(void *stc)
⑤用指针承载函数返回值时,不能改变指针的值。
⑥realloc (void *stc,size_t size)----重开size大小的空间。
int main(void)
{
int *p;
int n = 10;
p = malloc(n * sizeof(int));
if(p != NULL)
{
int i;
for(i = 0;i < n;++i)
{
p[i] = i + 1;
}
for(i = 0;i < n;++i)
{
printf("%d\n", p[i]);
}
}
free(p);
return 0;
}
15 指针函数
定义:类型标识符(*p)(形参表列);p = 函数名;
(1)函数名为函数的入口地址。
(2)定义指针和函数的类型和形参一致。
(3)降低程序代码的耦合性。
算法:回调函数:
int div2(int n)
{
return n % 2 == 0;
}
void printArray(int *s,int len,int (*pfn)(int))
{
int i ;
for(i = 0;i < len;++i)
{
if(pfn(s[i]))
{
printf("%d\n",s[i]);
}
}
}
int main(void)
{
double s[] = {1.1,2,3.3,4,5,-6,7,8,9,0};
int len = sizeof(s) / sizeof(s[0]);
printArray(s,len,div2);
return 0;
}
考题:程序传入到0x30001000处执行代码
void (*pfn)(void);
pfn = ((void *)(void))0x30001000;
16 指针数组
(1)一个数组,若其元素均为指针类型数据,称为指针数组,也就是说,指针数组中的每一
个元素都相当于一个指针变量。一维指针数组的定义形式为
类型名*数组名[数组长度];
(2)数组元素都是字符串首地址
char *s[] = {"china","hello","world"};
17 指针的指针
char **p;//char *--基类型,*---类型说明符,表示是个指针
可用与在被调函数中改变主调函数中指针中的地址。
void swap(char **a,char **b)
{
char *t;
t = *a;
*a = *b;
*b = t;
}
void reverseString(char **s,int len)
{
int i;
for(i = 0;i < len / 2;++i)
{
swap(&s[i],&s[len - i - 1]);
}
}
考点:

编译无问题,运行程序崩溃,原因为函数调用时指针是值传递,无法从被调函数修改主调函数中指针的地址。
注:
(1)二维数组作为函数参数,形参为指向数组的指针。
(2)指针数组作为函数参数,形参为指向指针的指针。
练习:
(1)编写程序实现单词的倒置
"how are you" -> "you are how"
#include<stdio.h>
#include<string.h>
int countera(char *s)//统计单词个数
{
int i = 0;
while( *s != '\0')
{
if(*s == ' ')
{
++i;
}
++s;
}
return i + 1;
}
int sum(char *s)//统计单词长度
{
int i = 0;
while(s[i] != ' ' && s[i] != '\0')
{
++i;
}
return i + 1;
}
void write(char **p,char *s,int n)//将每个单词的首字母地址装入指针数组中
{
p[0] = s;
int i;
for(i = 1;i < n;++i)
{
p[i] = p[i - 1] +sum(p[i - 1]);
}
}
void reverse(char **p,int n)//逆序
{
int i;
for(i = 0;i < n / 2;++i)
{
char *t;
t = p[i];
p[i] = p[n - i - 1];
p[n - i - 1] = t;
}
}
void Strcat(char *a,char *p)//连接
{
int i = 0;
while(a[i] != '\0')
{
++i;
}
a[i++] = ' ';
int j = 0;
while(*(p + j) != ' ' && *(p + j) != '\0')
{
a[i] = *(p + j);
++j;
++i;
}
a[i] = '\0';
}
int main(void)
{
char s[100] = "how old are you";
int n = countera(s);
char *p[n];
char a[100] = {0};
write(p,s,n);
reverse(p,n);
strcpy(a,p[0]);
int i ;
for(i = 1;i < n;++i)
{
Strcat(a,p[i]);
}
if(a[strlen(a) - 1] == ' ')
{
a[strlen(a) - 1] = '\0';
}
puts(a);
return 0;
}