指针数组和数组指针

指针数组和数组指针

1.前言
  1. 数组

    1. 数组有自己的特定类型,由元素类型和数组大小共同决定
    2. 数组名的值是指针常量,也是数组第一个元素的地址
    3. 当数组名作为sizeof操作符或单目操作符&的操作数时,不用指针常量表示
    4. arrary[2]等价于*(2 + (arrary))等价于*(arrary + 2)等价于2[arrary]
    5. 数组在个函数传参时会被弱化为指针
  2. 指针

    1. 指针本质上是一个变量
    2. 指针需要占用一定的内存空间(4个字节)
    3. 指针用于保存内存地址的值
    4. 只有当两个指针指向同一个数组中的元素,指针相减(只能加减)才有意义,为指针所指元素下表差,否则结果未定义
    5. 指针进行关系运算(> < >= <=)前提是指向同一个数组中的元素
  3. 数组与指针的异同

    1. 数组声明时编译器自动分配一片连续的内存空间
    2. 指针声明时只分配了用于容纳指针的4个字节的空间
    3. 在作为函数参数时,数组参数和指针参数等价
    4. 数组名在多数情况下可以看做常量指针,值不可改变
    5. 指针本质是变量,保存的值被看做内存中的地址
2.指针数组
  1. 说明:

    1. 指针数组是一个普通的数组
    2. 指针数组中的每一个元素为一个指针
    3. 指针数组的定义:type* pArray[n];

    1. type*为数组中每个元素的类型
    2. pArray为数组名
    3. n 为数组大小
  • 示例:

  • int lookup_keyword(const char* key, const char* table[], const int size)
    {
        /*定义常指针接收传过来的字符串,定义常指针数组接收main中的指针数组(在函数参数中数组会被弱化为指针), 定义常变量接收数组大小*/
    
        /*第二个参数就相当于定义一个数组,数组中存放的是char*类型的数据*/
        int ret = -1;  //定义返回值
        int i = 0;
        for(i = 0; i < size; ++i)
        {
            if(strcmp(key, table[i]) == 0)
            {
                //循环比较数组中的字符串是否匹配
                ret = i;
                break;
            }
        }
        return ret;
    }
    
    //宏定义计算数组的大小
    #define DIM(a) (sizeof(a)/sizeof(*a))
    
    int main()
    {
        //定义一个指针数组,存放char*类型的数据(keyword还是一个数组)
        const char* keyword[] = {
             "do",
             "for",
             "if",
             "register",
             "return",
             "switch",
             "while",
             "case",
             "static"
        };
    
        //调用函数测试
        printf("%d\n", lookup_keyword("return", keyword, DIM(keyword)));
        printf("%d\n", lookup_keyword("main", keyword, DIM(keyword)));
        return 0;
    }
    • 注:在理解中主要还是把指针数组的本质(本质是一个数组,不过里面存放的是指针类型的数据)搞清楚
    3.数组指针
    1. 说明:

      1. 数组指针用于指向一个数组
      2. 数组名是数组首元素的起始地址,但不是数组的起始地址
      3. 可以通过取地址符&作用于数组名得到数组的起始地址
      4. 数组指针的定义:ArrayType* pointer
      5. 也可以直接定义:type (*pointer)[n](不推荐)

      1. pointer为数组指针变量名
      2. type为指向数组的类型
      3. n 为指向数组的大小
  • 示例:

  • typedef int(INT)[5];  //定义int类型大小为5的数组类型(INT为类型名)
    typedef float(FLOAT)[10];
    typedef char(CHAR)[9];
    
    int main()
    {
        INT a1;  //定义数组a1
        float fArrary[10];
        FLOAT *pf = &fArrary;  //定义数组指针pf,指向fArrary的地址
        CHAR cArrary;
        char(*pc)[9] = &cArrary;  //直接定义数组指针pc,大小为9,指向cArrary的地址
        char(*pcv)[4] = cArrary;  /*直接定义数组指针pcv,大小为4,指向cArrary的地址(系统会出现warning)
        (原因数组指针pcv指向的应该是大小为4的数组)*/
    
        int i = 0;
    
        printf("%d, %d\n", sizeof(INT), sizeof(a1));  //查看定义的类型有多大
    
        for(i = 0; i < 10; ++i)
        {
            /*循环给pf指向的数组赋值*/
            (*pf)[i] = i;
        }
    
        for(i = 0; i < 10; ++i)
        {
            /*循环打印fArrary数组中的值,应该和上面赋值的一样*/
            printf("%f\n", fArrary[i]);
        }
    
        //打印cArrary的地址,pc+1应该是cArrary首地址向后9个字节的地址,pcv+1应该是cArrary首地址向后4个字节的地址
        printf("%0x, %0x, %0x\n", &cArrary, pc+1, pcv+1);
        return 0;
    }
    4.参考
    • 《C和指针》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值