• 22 数组指针与指针数组


    问题

    • 下面这些声明合法么?

      int array[5];
      int matrix[3][3];
      int* pa = array;
      int* pm = matrix;
      

    array 代表数组首元素的地址,那么 matrix 代表什么?

    array&array 的地址值相同,但是意义不同,那么它们所代表的类型相同么?

    1 数组类型

    • C语言中的数组有自己特定的类型
    • 数组的类型由元素类型数组大小共同决定
      • 例如:int array[5] 的类型为 int[5]

    2 定义数组类型

    • C语言中通过 typedef 为数组类型重命名

      typedef type(name)[size];

      数组类型的元素类型为:type ,数组类型的数组大小为:size ,数组类型重命名为 name

    • 示例

      • 数组类型

        typedef int(AINT5)[5];
        typedef float(AFLOAT10)[10];
        
      • 利用重命名的数组类型进行数组定义

        AINT5 iArray;
        AFLOAT10 fArray;
        

    3 数组指针

    • 类似于定义了一个 int 类型,可定义一个 int 型指针,可以利用上面定义的数组类型来定义数组指针

    • 数组指针用于指向一个数组(而不是数组首元素)

    • 数组名是数组首元素的起始地址,但并不是数组的起始地址

    • 通过将取地址符 & 作用于数组名可以得到数组的起始地址

    • 通过数组类型定义数组指针ArrayType* pointer; ;也可以直接定义:type(*pointer)[n];

      ArrayType 为重命名的数组类型,pointer 为数组指针变量名,type 为指向的数组的元素类型,n 为指向的数组的大小

    • 数组类型和数组指针示例

      • Demo

        #include <stdio.h>
        
        //重命名数组类型
        typedef int(AINT5)[5];
        typedef float(AFLOAT10)[10];
        typedef char(ACHAR9)[9];
        
        int main()
        {
            AINT5 a1;  //利用重命名的数组类型定义一个数组,共有5个元素,每个元素类型为int
            float fArray[10];  //直接定义一个数组,共有10个元素,每个元素类型为float
            AFLOAT10* pf = &fArray;  //利用数组类型定义一个数组指针,指向的类型为AFLOAT10,即pf指针指向的是一个数组,数组共有10个元素,每个元素类型为float,再初始化为fArray的地址
            ACHAR9 cArray;  //利用重命名的数组类型定义一个数组,共有9个元素,每个元素类型为char
        
            char(*pc)[9] = &cArray;  //直接定义一个数组指针pc,pc指针指向的是一个数组,数组共有9个元素,每个元素类型为char,再初始化为cArray的地址
            char(*pcw)[4] = cArray;  //error:直接定义一个数组指针pcw,pcw指针指向的是一个数组,数组共有4个元素,每个元素类型为char,再初始化为cArray首元素的地址(类型为char*),这里非法!
            
            int i = 0;
            
            printf("%d, %d
        ", sizeof(AINT5), sizeof(a1));  //20=4*5
            
            for(i=0; i<10; i++){
                (*pf)[i] = i;  // => fArray[i] = i;
            }
            
            for(i=0; i<10; i++){
                printf("%f
        ", fArray[i]);
            }
            
            printf("%p, %p, %p
        ", &cArray, pc+1, pcw+1);  //pc+1 = (unsigned)pc+sizeof(*pc) = (unsigned)pc+9, pcw+1 = (unsigned)pcw+sizeof(*pc) = (unsigned)pcw+4
        
            return 0;
        }
        
      • 编译

        test.c: In function 'main':
        test.c:16 warning: initialization from incompatible(不匹配) pointer type
        
      • 运行

        20,20
        0.000000
        1.000000
        2.000000
        3.000000
        4.000000
        5.000000
        6.000000
        7.000000
        8.000000
        9.000000
        0xbf8b43d3,0xbf8b43dc,0xbf8b43d7
        

    4 指针数组

    • 指针数组是一个普通的数组

    • 指针数组中每个元素为一个指针

    • 指针数组的定义:type* pArray[n];

      type* 为数组中每个元素的类型,pArray 为数组名,n 为数组大小

    • 指针数组的应用

      • Demo

        #include <stdio.h>
        #include <string.h>
        
        //定义一个宏:计算数组大小
        #define DIM(a) (sizeof(a)/sizeof(*a))
        
        //table为一个指针数组,数组中每个元素为const char*,而数组作为形参时会退化为指针,即 => const char** table
        int lookup_keyword(const char* key, const char* table[], const int size)
        {
            int ret = -1;
            
            int i = 0;
            
            for(i=0; i<size; i++){
                //比较字符串key与table数组中的每一个字符串是否相等
                if( strcmp(key, table[i]) == 0 ){
                    ret = i;
                    break;
                }
            }
            
            return ret;
        }
        
        int main()
        {
            const char* keyword[] = {
                    "do",
                    "for",
                    "if",
                    "register",
                    "return",
                    "switch",
                    "while",
                    "case",
                    "static"
            };
            
            printf("%d
        ", lookup_keyword("return", keyword, DIM(keyword)));
            printf("%d
        ", lookup_keyword("main", keyword, DIM(keyword)));
        
            return 0;
        }
        
      • 编译运行

        4
        -1
  • 相关阅读:
    [PHP] 适配器模式的日常使用
    [MySQL] timestamp和datetime的区别和大坑
    [PHP] foreach循环的引用赋值可能导致的问题
    [PHP] 邮件发送mail()函数失败问题 sendmail命令与postfix
    [日常] 腾讯云发送邮件失败问题
    [日常] 正则表达式 小括号() 中括号[] 大括号{}
    [Linux] awk与posix字符集
    [PHP] 工厂模式的日常使用
    [PHP] 抽象类abstract的回顾
    [日常]灵活的频率限制实现
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13655840.html
Copyright © 2020-2023  润新知