• 指针进阶2


    目录

    1.字符数组

    2.指针数组

    ​编辑​编辑 3.数组指针 

    数组指针的使用

    4.数组传参

    ​编辑 

    5.函数指针

     6.函数指针数组

    7.指向函数指针数组的指针

    1.字符数组

    在指针的类型中我们知道有一种指针类型为字符指针 char* ;

    这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域,当几个指针。指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4相同。 

    2.指针数组

    int* arr1[10]; //整形指针的数组

    char *arr2[4]; //一级字符指针的数组

    char **arr3[5];//二级字符指针的数组

     3.数组指针 

    数组指针是指针!

    int *p1[10];

    int (*p2)[10];

    //p1, p2分别是什么? 

    int (*p)[10];

    //解释:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。

    //这里要注意:[ ]的优先级要高于*号的,所以必须加上()来保证p先和*结合。

     

    根据上面的代码我们发现,其实&arr和arr,虽然值是一样的,但是意义应该不一样的。

    实际上: &arr 表示的是数组的地址,而不是数组首元素的地址。(细细体会一下) 本例中 &arr 的类型是: int(*)[10] ,是一种数组指针类型 数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40. 

    数组指针的使用

    既然数组指针指向的是数组,那数组指针中存放的应该是数组的地址。

    第2种方法一般用在二维数组中:

     

     

    4.数组传参

     

     

     

    5.函数指针

    1. int Add(int x, int y)
    2. {
    3. return x + y;
    4. }
    5. int main()
    6. {
    7. int arr[10] = { 0 };
    8. printf("%p\n", &arr);//取数组地址
    9. printf("%p\n", &arr);//取数组地址
    10. printf("%p\n", Add);//取函数地址(这两个没什么区别,拿到的都是函数的地址)
    11. printf("%p\n", &Add);//取函数地址
    12. int (*pf)(int x, int y) = &Add;//pf就是函数指针变量
    13. return 0;
    14. }

     

    1. int main()
    2. {
    3. //代码1
    4. (*(void (*)())0)();
    5. //void (*)()-->函数指针
    6. //(void (*)())0-->强制类型转换-->0转换一个函数的地址
    7. //(*(void (*)())0)()-->0转换成一个(void (*)())类型的函数指针,然后去调用0地址的函数
    8. typedef void(*pf_t)(int);//pf_t放在里面
    9. //代码2
    10. void (*signal(int, void(*)(int)))(int);
    11. pf_t signal(int, pf_t);
    12. //上述代码是一次函数声明
    13. //声明的函数叫:signal
    14. //signal函数的第一个参数是int类型
    15. //signal函数的第二个参数是一个函数指针类型,该函数指针指向的函数参数是int,返回类型是void
    16. //signal函数的返回类型也是一个函数指针类型,该函数指针指向的函数参数是int,返回类型是void
    17. //
    18. return 0;
    19. }

     6.函数指针数组

    要把函数的地址存到一个数组中,那这个数组就叫函数指针数组,那函数指针的数组如何定义呢?

     

     

    1. int Add(int x, int y)
    2. {
    3. return x + y;
    4. }
    5. int Sub(int x, int y)
    6. {
    7. return x - y;
    8. }
    9. int main()
    10. {
    11. int(*pf)(int, int);//函数指针
    12. //函数指针数组-->可以存放多个【参数相同,返回类型相同】的函数的地址
    13. int (*pfArr[2])(int, int) = { Add,Sub };//[]优先级高于*
    14. int ret = pfArr[1](2, 3);
    15. printf("ret = %d\n", ret);
    16. ret = pfArr[0](2, 3);
    17. printf("ret = %d\n", ret);
    18. return 0;
    19. }

     函数指针数组该如何使用?

    1. void menu()
    2. {
    3. printf("**************************\n");
    4. printf("**** 1.add 2.sub *****\n");
    5. printf("**** 3.mul 4.div *****\n");
    6. printf("**** 0.exit *****\n");
    7. printf("**************************\n");
    8. }
    9. int Add(int x, int y)
    10. {
    11. return x + y;
    12. }
    13. int Sub(int x, int y)
    14. {
    15. return x - y;
    16. }
    17. int Mul(int x, int y)
    18. {
    19. return x * y;
    20. }
    21. int Div(int x, int y)
    22. {
    23. return x / y;
    24. }
    25. int main()
    26. {
    27. int input = 0;
    28. int x = 0;
    29. int y = 0;
    30. int ret = 0;
    31. do
    32. {
    33. menu();
    34. printf("请选择:>");
    35. scanf("%d", &input);
    36. switch (input)
    37. {
    38. case 1:
    39. printf("请输入两个操作数:>");
    40. scanf("%d %d", &x, &y);
    41. ret = Add(x, y);
    42. printf("%d\n", ret);
    43. break;
    44. case 2:
    45. printf("请输入两个操作数:>");
    46. scanf("%d %d", &x, &y);
    47. ret = Sub(x, y);
    48. printf("%d\n", ret);
    49. break;
    50. case 3:
    51. printf("请输入两个操作数:>");
    52. scanf("%d %d", &x, &y);
    53. ret = Mul(x, y);
    54. printf("%d\n", ret);
    55. break;
    56. case 4:
    57. printf("请输入两个操作数:>");
    58. scanf("%d %d", &x, &y);
    59. ret = Div(x, y);
    60. printf("%d\n", ret);
    61. break;
    62. case 0:
    63. printf("退出计算机\n");
    64. break;
    65. default:
    66. printf("选择错误\n");
    67. break;
    68. }
    69. } while (input);
    70. return 0;
    71. }

     上面的代码过于冗余!简化后:

    1. void menu()
    2. {
    3. printf("**************************\n");
    4. printf("**** 1.add 2.sub *****\n");
    5. printf("**** 3.mul 4.div *****\n");
    6. printf("**** 0.exit *****\n");
    7. printf("**************************\n");
    8. }
    9. int Add(int x, int y)
    10. {
    11. return x + y;
    12. }
    13. int Sub(int x, int y)
    14. {
    15. return x - y;
    16. }
    17. int Mul(int x, int y)
    18. {
    19. return x * y;
    20. }
    21. int Div(int x, int y)
    22. {
    23. return x / y;
    24. }
    25. int main()
    26. {
    27. int input = 0;
    28. int x = 0;
    29. int y = 0;
    30. int ret = 0;
    31. int (*pfArr[5])(int, int) = { 0,Add,Sub,Mul,Div };
    32. do
    33. {
    34. menu();
    35. printf("请选择:>");
    36. scanf("%d", &input);
    37. if (input = 0)
    38. {
    39. printf("退出计算机\n");
    40. break;
    41. }
    42. if (input >= 1 && input <= 4)
    43. {
    44. printf("请输入两个操作数:>");
    45. scanf("%d %d", &x, &y);
    46. ret = pfArr[input](x, y);
    47. printf("%d\n", ret);
    48. }
    49. else
    50. {
    51. printf("选择错误!\n");
    52. }
    53. } while (input);
    54. return 0;
    55. }

    7.指向函数指针数组的指针

    指向函数指针数组的指针是一个 指针。

    指针指向一个数组 ,数组的元素都是函数指针。

    1. void test(const char* str)
    2. {
    3. printf("%s\n", str);
    4. }
    5. int main()
    6. {
    7. //函数指针pfun
    8. void (*pfun)(const char*) = test;
    9. //函数指针的数组pfunArr
    10. void (*pfunArr[5])(const char* str);
    11. pfunArr[0] = test;
    12. //指向函数指针数组pfunArr的指针ppfunArr
    13. void (*(*ppfunArr)[5])(const char*) = &pfunArr;
    14. return 0;
    15. }
  • 相关阅读:
    「Java」Java面试宝典:全面覆盖常见问题和难点解析
    Java反射详解
    Spring AOP使用与原理
    allatori8.0文档翻译-第十步:增加过期日期
    ADC、DMA以及串口之间的联系和区别?
    Jquery data-属性的获取与使用
    Sklearn机器学习中的主要算法原理以及实现
    【数据结构篇】堆
    TensorRT的结构
    【报错】cannot import name ‘DistanceMetric‘ from ‘sklearn.metrics‘
  • 原文地址:https://blog.csdn.net/m0_68071216/article/details/127334421