zoukankan      html  css  js  c++  java
  • C语言-第25课

    第25课 - 指针数组和数组指针分析

     

    思考:

    下面这些声明合法吗?
    int array[5];     常规数组

    int matrix[3][3];   二维数组

    int* pA = array;   pA指针用array初始化,pA指向的是首元素的地址,pA不是数组指针

    int* pM = matrix;  pM指针用matrix初始化

    问题:

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

    l arrry(数组首元素的地址,int*类型)和&array(数组的起始地址)的地址相同,但是意义不同,那么指向它们的指针类型相同吗?

    一般情况下声明一个数组之后,比如int array[5],数组名array就是数组首元素的首地址,而且是一个地址常量。但是,在函数声明的形参列表中除外。

    C中, 在几乎所有使用数组的表达式中,数组名的值是个指针常量,也就是数组第一个元素的地址。 它的类型取决于数组元素的类型: 如果它们是int类型,那么数组名的类型就是指向int的常量指针——C和指针》

    在以下两中场合下,数组名并不是用指针常量来表示,就是当数组名作为sizeof操作符和单目操作符&的操作数时。 sizeof返回整个数组的长度,而不是指向数组的指针的长度。 取一个数组名的地址所产生的是一个指向数组的指针,而不是一个指向某个指针常量的指针。所以&a后返回的指针便是指向数组的指针,跟a(一个指向a[0]的指针)在指针的类型上是有区别的。——C和指针》

    “+1”就是偏移量问题:一个类型为T的指针的移动,是以sizeof(T)为移动单位。 
    array+1:在数组首元素的首地址的基础上,偏移一个sizeof(array[0])单位。此处的类型T就是数组中的一个int型的首元素。由于程序是以16进制表示地址结果,array+1的结果为:0012FF34+1*sizeof(array[0])=0012FF34+1*sizeof(int)=0012FF38 
    &array+1:在数组的首地址的基础上,偏移一个sizeof(array)单位。此处的类型T就是数组中的一个含有5int型元素的数组。由于程序是以16进制表示地址结果,&array+1的结果为:0012FF34+1*sizeof(array)=0012FF34+1*sizeof(int)*5=0012FF48。注意1*sizeof(int)*5(等于00000014)要转换成16进制后才能进行相加。

    1. 数组类型

    1c语言中的数组有自己特有的类型,数组的类型由元素类型和数组大小共同决定。

    eg

    int array[5]的类型为int[5];

    2C语言中通过typedef为数组类型重命名:typedef type(name)[size]

    eg

    typedef int(AINT5)[5];

    typedef float(AFLOAT10)[10];

    数组定义:AINT5 iArray;

    AFLOAT10 fArray;

    1. 数组指针

    1)数组指针用于指向一个数组。

    2)数组名是数组首元素的地址,但不是数组的起始地址。

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

    int i[5]; int* PI = &i;

    4)可通过数组类型定义数组指针:

    ArrayType* pointer;(如AINT5* vp

    也可以直接定义:type *pointer[n];

    pointer为数组指针变量名,type为指向的数组的类型,n为指向的数组的大小。

    int (*p)[n];

    例程:

    #include <stdio.h>

    typedef int(AINT5)[5];

    typedef float(AFLOAT10)[10];

    typedef char(ACHAR9)[9];

    // three array's type

    int main()

    {

        AINT5 a1;

        float fArray[10];

        AFLOAT10* pf = &fArray;

        ACHAR9 cArray;

        char(*pc)[9] = &cArray;  //数组指针

        char(*pcw)[4] = cArray;  //char*类型的指针赋值给数组指针,是不合理的,

        int i = 0;

        printf("%d, %d ", sizeof(AINT5), sizeof(a1));

        for(i=0; i<10; i++)

        {

            (*pf)[i] = i;

        }

        for(i=0; i<10; i++)

        {

            printf("%f ", fArray[i]);

        }

    printf("%0X, %0X, %0X ", &cArray, pc+1, pcw+1);

    //pc+1   ----- (unsigned int)pc + 1*sizeof(*pc)

    }

    运行结果:

    2020

    0.000000

    1.000000

    2.000000

    3.000000

    4.000000

    5.000000

    6.000000

    7.000000

    8.000000

    9.000000

    18FEFC18FF0518FF00

    分析:18FF0518FEFC差九个字节,18FF0018FEFC差四个字节。

    1. 指针数组

    1)指针数组是一个普通的数组。

    2)指针数组中每个元素为一个指针。

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

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

    eg:

    例子:指针数组的使用,关键字查找

    #include <stdio.h>

    #include <string.h>

    int lookup_keyword(const char* key, const char* table[], const int size)

    {

        //数组在函数中变成了一个指针,大小必须要另一个变量来定义

    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()

    {

        const char* keyword[] = {

                "do",

                "for",

                "if",

                "register",

                "return",

                "switch",

                "while",

                "case",

                "static"

        };//char*指向字符串

        printf("%d ", lookup_keyword("return", keyword, DIM(keyword)));

        printf("%d ", lookup_keyword("main", keyword, DIM(keyword)));

    }

    运行结果:

    4

    -1

    1. main函数的参数

    1main函数可以理解为操作系统调用的函数。

    2)在执行程序的时候可以向main函数传递参数。

    int main()

    int main(int argc)

    int main(int argc, char* argv[])

    int main(int argc, char* argv[], char* env[])

    argc:命令行参数个数

    argv:命令行参数数组

    env:环境变量数组

    例子:

    #include <stdio.h>

    #include <string.h>

    int lookup_keyword(const char* key, const char* table[], const int size)

    {

        //数组在函数中变成了一个指针,大小必须要另一个变量来定义

    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()

    {

        const char* keyword[] = {

                "do",

                "for",

                "if",

                "register",

                "return",

                "switch",

                "while",

                "case",

                "static"

        };//char*指向字符串  

        printf("%d ", lookup_keyword("return", keyword, DIM(keyword)));

        printf("%d ", lookup_keyword("main", keyword, DIM(keyword)));

    }

    运行结果:(打印命令行和windows下面的一些信息)

    小结:

    l 数组指针本质是一个指针

    l 数组指针指向的值是数组的地址

    l 指针数组本质上是一个数组

    l 指针数组中每个元素的类型都是指针

     

  • 相关阅读:
    三次握手与四次挥手原理
    动态主机配置协议(DHCP)
    网络知识-OSI7层模型说明和相关协议
    企业面试题合集
    优先队列(priority_queue)自定义排序方法
    优先队列(priority_queue)自定义排序方法
    C. Playlist(权值线段树查询前k大和)
    C. Playlist(权值线段树查询前k大和)
    C++判断四个点能否构成正方形/矩阵
    C++判断四个点能否构成正方形/矩阵
  • 原文地址:https://www.cnblogs.com/free-1122/p/9758912.html
Copyright © 2011-2022 走看看