4. 数组传参和指针传参
在写代码的时候难免要把【数组】或者【指针】传给函数,那函数的参数该如何设计呢?请看下文
4.1 一维数组传参
1. #include <stdio.h> 2. void test(int arr[])//ok 3. {} 4. void test(int arr[10])//ok 5. {} 6. void test(int *arr)//ok 7. {} 8. void test2(int *arr[20])//ok 9. {} 10. void test2(int **arr)//ok 11. {} 12. int main() 13. { 14. int arr[10] = {0}; 15. int *arr2[20] = {0}; 16. test(arr); 17. test2(arr2); 18. }
4.2 二维数组传参
1. void test(int arr[3][5])//ok 2. {} 3. void test(int arr[][])//no 4. {} 5. void test(int arr[][5])//ok 6. {} 7. //总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。 8. //因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。 9. //这样才方便运算。 10. void test(int *arr)//no 11. {} 12. void test(int* arr[5])//no 13. {} 14. void test(int (*arr)[5])//ok 15. {} 16. void test(int **arr)//no 17. {} 18. int main() 19. { 20. int arr[3][5] = {0}; 21. test(arr); 22. }
4.3 一级指针传参
1. #include <stdio.h> 2. void print(int *p, int sz) 3. { 4. int i = 0; 5. for(i=0; i<sz; i++) 6. { 7. printf("%d\n", *(p+i)); 8. } 9. } 10. int main() 11. { 12. int arr[10] = {1,2,3,4,5,6,7,8,9}; 13. int *p = arr; 14. int sz = sizeof(arr)/sizeof(arr[0]); 15. //一级指针p,传给函数 16. print(p, sz); 17. return 0; 18. }
我们想一想,当一个函数得参数部分是一级指针时,函数能接受什么参数呢?
博主为大家整理了一些
4.4 二级指针传参
1. #include <stdio.h> 2. void test(int** ptr) 3. { 4. printf("num = %d\n", **ptr); 5. } 6. int main() 7. { 8. int n = 10; 9. int*p = &n; 10. int **pp = &p; 11. test(pp); 12. test(&p); 13. return 0; 14. }
同样我们想一想当函数的参数为二级指针的时候,可以接收什么参数?
贴心的博主也为大家准备了
5. 函数指针
前面已经讲过了数组指针,意思为指向数组的指针,同理得函数指针,指向函数得指针
我们知道函数是有地址的,如以下代码
1. #include <stdio.h> 2. void test() 3. { 4. printf("hehe\n"); 5. } 6. int main() 7. { 8. printf("%p\n", test); 9. printf("%p\n", &test);\\取出test函数得地址并打印出来 10. return 0; 11. }
运行结果如下
我们发现如同讲数组指针时一样,是相同的;但这二与前面不同,这里的test与&test都表示函数的地址,时相同的
那我们的函数的地址要想保存起来,怎么保存?
1. //下面pfun1和pfun2哪个有能力存放test函数的地址? 2. void (*pfun1)(); 3. void *pfun2();
首先,能给存储地址,就要求pfun1或者pfun2是指针,那哪个是指针? 答案是:
pfun1可以存放。pfun1先和*结合,说明pfun1是指针,指针指向的是一个函数,指向的函数无参数,返回值类型为void。
接下来为大家介绍两端有趣的代码,这两段代码来自《C陷阱和缺陷》
代码一
(*(void (*)())0)();
代码解释如下
代码二
void (*signal(int , void(*)(int)))(int);
代码与使用与解释如下
1. //int main() 2. //{ 3. // //signal 是一个函数声明 4. // //signal 函数有2个参数,第一个参数的类型是int,第二个参数的类型是 void(*)(int) 函数指针类型 5. // //该函数指针指向的函数有一个int类型的参数,返回类型是void 6. // //signal 函数的返回类型也是void(*)(int) 函数指针类型,该函数指针指向的函数有一个int类型的参数,返回类型是void 7. // //简化代码如下 8. // typedef void(*pf_t)(int); 9. // pf_t signal(int, pf_t); 10. // 11. // void (* signal(int, void(*)(int) ) )(int); 12. // 13. // return 0; 14. //}
关于指针进阶的后续讲解,请关注博主后续博文的状态!!!