指针的进阶(一)(下)

简介: 指针的进阶(一)(下)

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. //}


关于指针进阶的后续讲解,请关注博主后续博文的状态!!!

相关文章
|
4天前
|
存储
指针进阶详解(下)
指针进阶详解(下)
22 0
|
4天前
|
C语言
【C语言】指针进阶之sizeof和strlen函数的对比
【C语言】指针进阶之sizeof和strlen函数的对比
|
4天前
|
C语言
C语言---指针进阶
C语言---指针进阶
22 0
|
4天前
C进阶:指针的练习(1)
C进阶:指针的练习(1)
|
4天前
C进阶:指针的进阶(4)
C进阶:指针的进阶(4)
|
4天前
|
存储 C语言
C进阶:指针的进阶(1)
C进阶:指针的进阶(1)
|
4天前
|
存储 C语言 C++
C语言指针进阶-1
C语言指针进阶-1
28 1
|
4天前
|
搜索推荐 C语言
详解指针进阶2
详解指针进阶2
|
4天前
|
存储 编译器 C语言
指针进阶详解(上)
指针进阶详解(上)
87 0
指针进阶详解(上)

热门文章

最新文章