首页 > 代码库 > 第八天:C基础之内存分配与函数指针
第八天:C基础之内存分配与函数指针
虚拟内存自上而下分为 堆栈段,数据段,代码段 , 堆栈段分为堆区和栈区 ,栈区从上往下分配内存,堆区从下往上分配内存 。数据段分为静态区和全局区。两者的作用域不同。代码段分为只读区和代码区 。最后还有bss区现在还不涉及。
六个区域的定义如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int number = 200; 5 6 int hello() 7 { 8 static int s = 400; 9 int n = 100;10 char *p = malloc(10);11 char *m = "hello world";12 printf("stack is %p\n", &n);13 printf("global is %p\n", &number);14 printf("static is %p\n", &s);15 printf("heap is %p\n", p);16 printf("read only is %p\n", m);17 }18 19 int main()20 {21 int i = 10;22 hello();23 }
这几天的的C基础培训都离不开内存图。这个也许是在学校学习谭大爷的C语言最大的区别吧。知道程序代码在内存中的分布,画出程序在运行中的内存图,对于程序的理解是非常有帮助的,比如今天讲的函数指针。
函数名代表函数的首地址,这样的话,我们就可以通过函数指针来调用函数 。如定义了函数hello(); 函数指针为int (*fp)() = hello; 这时候使用hello的地方都可以用fp来代替了。当然 ,函数指针也能作为函数的参数。我们称参数中带有函数指针的函数叫做回调函数, 函数指针也够在结构体中定义 。下面的函数就是通过函数指针,回调函数,结构体三种方式调用函数。
1 #include<stdio.h> 2 3 struct person{ 4 char *name; 5 int (*fp)(char *); 6 int (*fd)(struct person); 7 }; 8 9 int hello(char *s)10 {11 printf("my name is %s\n",s);12 }13 int pson(struct person jack)14 {15 printf("jack is name is %s\n",jack.name);16 17 }18 int main()19 {20 struct person tom;21 tom.name = "tom";22 tom.fp = hello;23 tom.fp(tom.name);24 struct person jack;25 jack.name = "jack";26 tom.fd = pson;27 tom.fd(jack);28 29 30 }
回调函数也是函数,也可以继续被回调。于是乎有了下面的代码:
1 #include<stdio.h> 2 3 int func(int i) 4 { 5 printf("i is %d\n",i); 6 } 7 int call(int (*fp)(int),int i) 8 { 9 fp(i);10 11 }12 int recall(int (*fd)(int (*)(int),int ),int (*fp)(int),int i)13 {14 fd(fp,i); 15 }16 17 int main()18 { 19 int (*fp)(int);20 fp = func;21 call(fp,10);22 int (*fd)( int (*)(int),int) = call;23 recall(fd,fp,20);24 }
12行的回调再回调函数的参数会让人看晕的。。。 但是,这时候万能的内存图来了。画个图,问题就能解决。
老刘看我们被函数指针绕的迷糊。下午的时候就讲了linux的基础命令。 lsusb ,lspci 查看设备 tftp 的配置。这些就不写了。
第八天:C基础之内存分配与函数指针
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。