zoukankan      html  css  js  c++  java
  • c语言 指针与数组

    关键概念:

    1.多个不同类型的指针可以对应同一个地址;

    2.(&p)则是这样一种运算,返回一个指针,该指针的值是当时声明p 时开辟的地址,指针的类型是p的类型对应的指针类型;

    3.(*p)操作是这样一种运算,获取指针p的值(变量的地址)找到对应的变量的值-----返回以(p 的值作为地址)的那个空间的值。但是如果这个变量本身就是一个地址,那么(*p)获取的值也是一个指针

    4.在数组中,指针的&,*运算符比较特殊,与普通变量的指针并不相同;

    5.数组名不是一个该数组的指针;

    一维数组

    #include<stdio.h>
    #include<stdlib.h>
    
    void main(){
        int arr[5] = {1,2,3,4,5};
        //通过int *p = arr这个定义,首先要明确arr的类型是int *
        int *p = arr;
        //c语言定义:当一个数组标识符出现在表达式中,
        //①这个标识符的类型就从“某种类型t的数组”转换成“指向类型t的指针”,
        //而且它的值就等于数组第一个元素的地址。并且这个指针是个常量指针,不可改变其值的。 
        //以上的叙述很官方,但是大家对①这个描述并不是很清楚,我以一维数组arr为例来解释一下
        //“某种类型t的数组”指的就是数组arr[5],“指向类型t的指针”指的是数组第一个元素arr[0],
        //通俗解释就是这样子的,②当一个arr出现在表达式中,arr所代表的就是数组第一个元素的指针,
        //②同样适用于多维数组,这个具体讲解将会在二维数组中详细介绍。
        //在本例子中,arr就是arr[0]的指针//有了以上的基础,我们来讨论一下arr+1,&arr+1
        //打印出数组arr中所有的元素和他们的地址
        for (int i = 0; i < 5; i++)
        {
            printf("%5d--%7x",arr[i],&arr[i]);
        }
        printf("
    ");
        //下面我们来分析arr+1的值,通过②,我们可以知道arr的类型是整型指针,
        //假设arr的地址是0x87f904,那么arr+1的地址就是在arr的值(指针的值是一个地址,以前文章有说明)上加上4个字节(char型1字节,int型4字节)
        //所以根据分析arr+1的地址应该是0x87f908
        printf("
    arr=%x,arr + 1=%x", arr, arr + 1);
        //以上代码的结果证明我的分析是正确的
        //现在对关键概念4做第一个证明,
        //对&arr做一个解释
        printf("
    arr=%x,&arr=%x", arr, &arr);
        //通过以上代码,我们发现arr和&arr的地址完全相同,
        //但是实际上&arr(为什么说&arr是一个指针,请参照关键概念2)的指针类型和arr的指针类型却完全不同
        //&arr返回的是arr数组的指针,&arr指针的类型是int(*)[5],
        //为此我们可以通过sizeof()运算符来查看&arr指针的类型
        //sizeof(*(&arr)),在这里我要解释一下,为什么不是sizeof(&arr)
        //根据关键概念2我们可以知道&arr本身是一个指针,sizeof(指针),那么大小一定是4个字节
        //我们要看一个指针的类型,还可以通过指针对应变量的类型来判断
        //所以用*(&arr)获取&arr这个指针对应的变量
        //*(&arr)又可以写成arr,所以sizeof(*(&arr))=sizeof(arr)
        //所以有些资料上会这么说“sizeof(数组名)返回的是整个数组的大小”,
        printf("
    sizeof(*(&arr))=%d,sizeof(arr)=%d", sizeof(*(&arr)), sizeof(arr));
        //结果显示sizeof(*(&arr))=20,正好是一个数组arr的大小
        //理解完&arr的本质后,我们在对&arr做加减运算就容易理解了,&arr+1,那么指针移动的单位是20个字节
        printf("
    &arr+1的地址=%x", &arr+1);
        //以上代码证明我的结论
    
        printf("
    ");
        system("pause");
    
    }

    运行结果截图:

    二维数组

    #include<stdio.h>
    #include<stdlib.h>
    
    
    
    void main(){
        //对于二位数组,我们主要需要理解arr,*arr,&arr三个指针的区别
        int arr[3][4] = {0};
        //为二维数组赋值
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                printf("%5d,%7x", arr[i][j] = i * 2 + j, &arr[i][j]);
            }
            printf("
    ");
        }
        //判断一个指针的类型,可以通过*运算符求指针对应变量的大小来判断
        printf("
    *arr==%d", sizeof(*(*arr)));  //打印  4
        printf("
    &arr==%d", sizeof(*(&arr)));  //打印  48
        printf("
    arr==%d", sizeof(*arr));      //打印  16
        //由以上结果推断*arr是整型指针,&arr是二维数组指针,arr是一维数组指针(即行指针)
        printf("
    %d", *(*arr));//打印  0
        //以上结果表明*arr是a[0][0]的指针,说明其*arr是一个列指针
        //arr[0][1]=*(*arr+1)
        //因为arr是一维数组指针,那么a[1][0]的指针是*(arr+1)
        //a[1][0]的指针是*(arr+1)+1
        //a[1][0]=*(*(arr+1)+1);
    
    
    
        //再次,我们要更深入一步,用指针来获取二维数组的值
        int x = 1, y = 2;
        //如何获取a[x][y]的值
        //通俗的说法,就是第几行的第几个的值
        //首先行的地址指针是arr+x,这里arr+x是一个行指针,但是我们获取的最终的值其实是列指针的值,
        //*(arr+x)这就是arr[x][0]这个整型变量的指针
        //y=2说明列指针向后移动2个单位(8个字节),所以*(arr+x)+2就是arr[x][y]的指针
        //求指针对应变量的值,用*运算符,
        //最终结果是*(*(arr+x)+y)==arr[x][y]
        printf("
    *(*(arr+x)+y)=%d,arr[x][y]=%d", *(*(arr + x) + y), arr[x][y]);
        //因为*(arr + x)可以简写成arr[y]
        //所以*(*(arr + x) + y)=*(arr[y] + y)
    
    
        printf("
    ");
        system("pause");
    }
  • 相关阅读:
    建设工程造价数据服务云平台(计价BIM)
    工程造价数据服务云平台(造价BIM)
    工程造价数据服务云平台(造价BIM)
    ie9下对象for..in..的bug
    JavaScript闭包
    JavaScript如何比较两个对象字面量是否一样(key 和 value都对比)
    JavaScript转码和编码
    JavaScript中正则编码
    Sizzle 官方API翻译
    JSONP跨域
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5124501.html
Copyright © 2011-2022 走看看