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");
    }
  • 相关阅读:
    第十二章学习笔记
    UVa OJ 107 The Cat in the Hat (戴帽子的猫)
    UVa OJ 123 Searching Quickly (快速查找)
    UVa OJ 119 Greedy Gift Givers (贪婪的送礼者)
    UVa OJ 113 Power of Cryptography (密文的乘方)
    UVa OJ 112 Tree Summing (树的求和)
    UVa OJ 641 Do the Untwist (解密工作)
    UVa OJ 105 The Skyline Problem (地平线问题)
    UVa OJ 100 The 3n + 1 problem (3n + 1问题)
    UVa OJ 121 Pipe Fitters (装管子)
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5124501.html
Copyright © 2011-2022 走看看