标签:style blog color io 使用 ar sp 数据 div
虚拟内存自上而下分为 堆栈段,数据段,代码段 , 堆栈段分为堆区和栈区 ,栈区从上往下分配内存,堆区从下往上分配内存 。数据段分为静态区和全局区。两者的作用域不同。代码段分为只读区和代码区 。最后还有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 的配置。这些就不写了。
标签:style blog color io 使用 ar sp 数据 div
原文地址:http://www.cnblogs.com/linrong/p/4029506.html