zoukankan      html  css  js  c++  java
  • 指针数组 数组指针 函数指针 函数指针数组 指向函数指针数组的指针

    1.指针数组:指针数组是数组,是存放指针的数组

    1 int *arr1[10] //存放10个整形指针的数组
    2 char *arr2[4]//存放4个字符指针的数组
    3 char **arr3[5]//同样也是指针数组

    2.数组指针:数组指针是指针

    整形指针:int *pint;能够指向整形数据的指针
    浮点型指针:float *pf;能够指向浮点型数据的指针
    注意:int (*p)[10]//数组的地址存放到数组指针当中;(p先和*结合,说明p是一个指针变量,然后指针指向的是一

    个大小为10的整形的数组。所以p是一个指针,指向一个数组,即数组指针。)
    例: int arr[10];
         int (*p)[10]=&arr;
         int *arr[10];
         int *(*p)[10]=&arr;
    注意:以上的赋值都是合法的,[]的优先级要高于*号的,所以必须加上()来保证p先和*结合。

    3.指针数组的使用:

     int arr[10]={0};

     arr;//表示数组首元素的地址

     &arr;//表示数组的地址

     printf("%p ",arr);//首元素的地址

     printf("%p ",arr+1);数组中第二个元素的地址

     printf("%p ",&arr+1);数组最后一个元素之后的地址

    (我们可以看出产生的结果是截然不同的,读者可以去验证,原因是数组的地址和首元素的地址是相同的,但意义却不同)

    4.数组的地址通过数组指针存放。因此在传参的时候,如果将一个二维数组的数组名传给形参,我们知道,二维数组的数组

    名即为该数组第一行的地址,也就是说该数组名为一个一维数组的地址,因此函数在接收实参传过来的值时应该用数组指针接收。

    5.指针和数组的定义和声明
      定义是不存在的时候要让他存在,而声明是不知道的要让他知道。

    1 //test.c
    2 //数组的定义
    3 char arr[]="abcdef";
    4 //指针的定义
    5 char *p="abcdef";
    1 //main.c
    2 extern char arr[];
    3 extern char *p;
    4 int main()
    5 {
    6    printf("%s
    ",arr);
    7    printf("%s
    ",p);
    8 return 0;
    9 }

    读者可以自行试验,小编在这儿给出运行结果的截图:

    a.定义为数组,声明为指针,运行结果如下图:

    若要它正确输出,则可以以如下图的方式输出:

    b.若定义为指针,声明为数组:

    若要正确输出,则可以以下图两种方式输出:

    注意:定义为数组,声明为指针时,程序崩溃,原因是将数组内存空间中的四个字节的内容(本例中为abcd的阿斯卡码值61626364)传给指针,指针将其视为一个地址,但该地址为非法地址,指针访问时出错,程序崩溃。定义为指针,声明为数组时,输出随机值,原因是将指针的地址以字符的形式输出,所以为随机值。


    6.数组参数,指针参数

    在写代码时难免要把数组或者指针传给函数,那函数的参数该如何设计呢?

    a.一维数组传参:

     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])//指针数组传给指针数组
     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    return 0;
    19 }

    b.二维数组传参:

     1 #include<stdio.h>
     2 void test(int arr[3][5])//ok
     3 {}
     4 void test(int arr[][])//错误,没有列
     5 {}
     6 void test(int arr[][5])//ok
     7 {}
     8 //总结:二维数组传参,函数形参的设计只能省略第一个[]的数字
     9 //因为对于一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
    10 void test(int *arr)//错误,因为arr是一个二维数组,数组名是第一行,也就是一维数组,不能把一位数组传给一级指针,应该传给数组指针
    12 {}
    13 void test(int *arr[5])//此处形参为指针数组,不是数组指针,错误
    14 {}
    15 void test(int (*arr)[5])//ok
    16 {}
    17 void test(int **arr)//错误,不能把一维数组传给二级指针
    18 {}
    19 int main()
    20 {
    21   int arr[3][5]={0};
    22   test(arr);
    23   return 0;
    24 }

    c.一级指针传参:

     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
    ",*(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 }

    d.二级指针传参:

    #include<stdio.h>
    void test(int **ptr)
    {
      printf("num=%d
    ",**ptr);
    }
    int main()
    {
      int n=0;
      int *p=&n;
      int **pp=&p;
      test(pp);
      test(&p);
      return 0;
    }

    e.函数指针:

     1 #include<stdio.h>
     2 void test()
     3 {
     4   printf("hehehe
    ");
     5 }
     6 int main()
     7 {
     8   printf("%p
    ",test);
     9   printf("%p
    ",&test);
    10   return 0;
    11 }

    读者可以行验证,这里输出的是同一块空间的地址,说明函数名就是函数的地址。同样,可以将函数的地址存放到一个指针中,即函数指针,有了函数指针,便有了存放函数指针的数组,即函数指针数组,同理,有了函数指针数组,便有了函数指针的数组的指针。小编不在这里具体阐述。对于函数指针的用途,在很多地方都有应用,比如转移表,计算器,读者有兴趣的话可以阅读相关书籍。

  • 相关阅读:
    CSS清除浮动常用方法小结
    json格式的javascript对象用法分析
    jQuery on()方法绑定动态元素的点击事件无响应的解决办法
    一道思考题(二进制枚举的应用的想法)切金条
    对于excel中,无法把字符型转成数字型解决办法
    对于excel中,无法把字符型转成数字型解决办法
    python文本挖掘输出权重,词频等信息,画出3d权重图
    python文本挖掘输出权重,词频等信息,画出3d权重图
    python使用scikit-learn计算TF-IDF
    python使用scikit-learn计算TF-IDF
  • 原文地址:https://www.cnblogs.com/love-you1314/p/9025623.html
Copyright © 2011-2022 走看看