关于指针与函数的几点小结
- 格式:pdf
- 大小:110.05 KB
- 文档页数:7
如果知道了一个函数所在的地址, 可以将其强制转化成某一 种类型的函数指针, 然后再根据这个指针去调用这个地址的函 数. 如:
1. #include<stdio.h>
2.
3. void f(int i) 4. { 5. printf("i = %d\n", i); 6. }
7.
8. int main() 9. { 10. unsigned long add; 11. add = (unsigned long)f; 12. ((void (*)(int))add)(10); 13. (*(void (*)(int))add)(20); 14. return 0; 15. } 复制代码
这种方式中,int (*a)[10]是一个指向一维数组的一个指针, 而 p()也是返回一个指向一维数组的一个指针.
5.返回一个函数指针的指针 对这个问题, signal()函数是最好的例子,
1. void (*signal (int signo, void (*func)(int))) (int); 复制代码
1. #include<stdio.h> 2. int max(int v1, int v2) 3. { 4. return (v1 > v2 ? v1 : v2);
5. }
6.
7. int min(int v1, int v2) 8. { 9. return (v1 < v2 ? v1 : v2); 10. }
23.
24. (signal(SIGUSR1, sig_fun2))(30); printf("done\n"); return 0;
25.
26. 27. 28. } 复制代码
6. 使用函数指针作为参数的情况 在函数的参数中, 可能会带有一个函数指针, 这在signal()函 数中是出现了的, 另外再写个例子如:
11.
12. int sum(int v1, int v2) 13. { 14. return (v1 + v2); 15. }
16.
17. int main() 18. { 19. int (*p[3])(int, int); 20. p[0] = max; 21. p[1] = min; 22. p[2] = sum;
1. void (*signal(int signo, void (*fun)(int))) (int); 复制代码
就可以看成是signal()函数(它自己是带两个参数,一个为整型, 一个为函数指针的函数), 而这个signal()函数的返回值也为一 个函数指针,这个函数指针指向一个带一个整型参数,并且返回 值为void的一个函数. signal函数返回的其实是指向以前的信号处理程序的指针, 所 以举一个例子来说明返回指向函数的指针的用法,如:
1. #include<stdio.h>
2.
3. int max(int v1, int v2)
4. { 5. 6. }
return (v1 > v2 ? v1 : v2);
7.
8. int min(int v1, int v2) 9. { 10. return (v1 < v2 ? v1 : v2); 11. }
ቤተ መጻሕፍቲ ባይዱ
17.
18. int main() 19. { 20. int (*a)[10]; 21. int i; 22. a = p(); 23. for (i = 0; i < 10; i++) 24. printf("%d ", *(*a+i)); 25. printf("\ndone\n"); 26. return 0; 27. } 复制代码
1. #include<signal.h> 2. #include<stdlib.h> 3. #include<stdio.h>
4.
5. void sig_fun2(int signo) 6. {
7. 8. }
printf("in sig_fun2:%d\n", signo);
9.
10. void sig_fun1(int signo) 11. { 12. printf("in sig_fun1:%d\n", signo); 13. }
14.
15. int main() 16. { 17. unsigned long i; 18. if (signal(SIGUSR1, sig_fun1) == SIG_ERR) 19. { 20. printf("signal fun1 error\n"); 21. exit(1); 22. }
很多朋友刚开始看这个函数定义的时候是不太懂, 其实可以一 步一步地慢慢看, 我以前是这样分析的, 希望能对大家有用. int (*p)(); 这是一个函数指针, p所指向的函数是一个不带任何参数, 并且 返回值为int的一个函数. int (*fun())(); 这个式子与上面式子的区别在于用fun()代替了p,而fun()是一 个函数,所以说就可以看成是fun()这个函数执行之后,它的返 回值是一个函数指针,这个函数指针(其实就是上面的p)所指向 的函数是一个不带任何参数,并且返回值为int的一个函数.所以 说对于
心血来潮, 想对函数指针的几个用法小结一下, 都是平常容易 见到的, 如果还有其它不觉的用法也请朋友们不吝赐教. 若有错误之处,还请指正. 1. 首先,在C语言中函数是一种function-to-pointer的方式, 即对于一个函数,会将其自动转换成指针的类型.如:
1. #include<stdio.h>
虽然感觉这种方法有点累赘, 但是也算是一种使用的方式, 所 以介绍一下. 4.返回一个指向数组的指针的方式 可以让函数返回一个指向数组的一个指针, 如:
1. #include<stdio.h>
2. #include<stdlib.h> 3. int (*p())[10] 4. { 5. int (*m)[10]; 6. int i; 7. m = (int (*)[10])malloc(10 * sizeof(int)); 8. if (m == NULL) 9. { 10. printf("malloc error\n"); 11. exit(1); 12. } 13. for (i = 0; i < 10; i++) 14. *(*m+i) = i+1; 15. return m; 16. }
使用(void (*)(int))的方式可以将一个地址转换成一个带int 参数且没有返回值的函数的指针类型, 然后再去调用, 由于第1 点中讲的function-to-pointer, 所以最后两条语句中加与不 加那个*号效果都是一样的. 在嵌入式方面经常用到这种方式. 3. 函数指针数组的用法. 有时候需要定义一个数组, 其内容为一系列的函数指针, 然后 对其进行调用, 如:
2.
3. void fun() 4. { 5. }
6.
7. int main() 8. { 9. printf("%p fun, *fun); 10. return 0; 11. } 复制代码
%p
%p\n", &fun,
这三个值的结果是一样的. 其实对于最后的那个*fun, 即使前 面加上很多个*号, 其结果也不变, 即**fun, ***fun的结果 都是一样的. 对于这个问题, 因为之前讲过函数是一种 function-to-pointer方式, 其会自动转换成指针的类型, &fun是该函数的地址, 为指针类型, fun是一个函数, 会转换成 其指针类型, 而对于*fun, 由于fun已经变成了指针类型, 指向 这个函数, 所以*fun就是取这个地址的函数, 而又根据 function-to-pointer, 该函数也转变成了一个指针, 所以以此 类推, 这三个值的结果是相同的. 2. 如何调用一个地址上的函数
23.
24. 25. 26. 27. 28. } 复制代码 printf("p[0] = %d\n", (p[0])(3, 5)); printf("p[1] = %d\n", (p[1])(4, 6)); printf("p[2] = %d\n", (p[2])(1, 2)); return 0;
12.
13. int sum(int v1, int v2) 14. { 15. return (v1 + v2); 16. }
17.
18. int fun(int a, int b, int (*call)(int, int)) 19. { 20. return (call(a, b)); 21. }
22.
23. int main() 24. { 25. printf("max=%d\n", fun(1, 2, max)); 26. printf("min=%d\n", fun(3, 4, min)); 27. printf("sum=%d\n", fun(5, 6, sum)); 28. return 0; 29. }