zoukankan      html  css  js  c++  java
  • 指针和数组

    数组的本质

    上一章节讲过了指针,那么数组是什么,数据类型是什么,为什么数组做函数参数的时候会退化为指针,怎么理解。
    先看一段代码:

    int i,*p,a[] = {3,4,5,6,79};
    p= a;
    for (i=0;i<=9;i++)
    {
        printf("%d
    ",a[i])//通过数组名访问元素
        printf("%d
    ",*a+i)//也可以这样
        printf("%d
    ",p[i]//也可以这样
    }

    其实从程序上看数组和指针没有区别,数组从内存上是获取连续的内存区域进行数据存放,通过数组名获取了这块内存地址,所以数组名就是这块内存的代表,被定义为这块内存的首地址。数组名是一个地址,不可修改的常量,一个地址常量。数组名这个符号就是代表内存的首地址,本身就是这个地址。它是一个右值,不能放在=左边进行赋值,而指针是变量确实一个左值。
    数组作为形参,在编译器当做指针来看,编译器从效率上将不提倡传入内存空间,但同时要操作一段内存空间,所以编译器默认的将数组名转化为指针,只是转化,传入的是数组地址而已。

    多维数组和多级指针

    在C语言中并不存在多维数组,从本质上讲是数组的数组,也就是数组的嵌套,各维之间有鲜明的层次关系。上一维把下一维看做作下一级数组,也就是数组的嵌套。
    这里写图片描述
    首先存储行号为0的n个元素,对于这n个元素按列号从小到大依次存储:紧接着存储行号为1的n个元素…最后存储行号为m-1的n个元素。
    这里写图片描述
    经过上面的分析,我们用sizeof来强化对数组的理解。

    int a[5][8][9];
    sizeof(a)//5*8*9*sizeof(int)
    sizeof(a[0])//8*9*sizeof(int)
    sizeof(a[1])//8*9*sizeof(int)
    sizeof(a[0][3])//9*sizeof(int)
    sizeof(a[2][2][4])//sizeof(int)
    sizeof(&a[0])//sizeof(int)

    从上面很容易得到a[0]是指向一个二维数组,通过a[0]可以获取这个二维数组内存值,当然用sizeof,就是获取一个二维数组的内存大小。&a[0]这是像获取指向二维数组指针的大小,也就是二维数组开始的内存地址。在数组中&a和&a[0],&a[0][0]是一样的,这就是都是内存开始的地址值。但是一定注意&a与&a[0]作为右值赋值是,是不一样的分别赋值给三级指针和二级指针

    指针数组和数组指针

    指针数组:array of pointers,即用于存储指针的数组,也就是数组元素都是指针

    数组指针:a pointer to an array,即指向数组的指针

    还要注意的是他们用法的区别,下面举例说明。

    1. int* a[4] 指针数组

      表示:数组a中的元素都为int型指针
      元素表示:a[i] (a[i])是一样的,因为[]优先级高于*

    2. int (*a)[4] 数组指针
      表示:指向数组a的指针
      元素表示:(*a)[i]
      其中()是不能去掉的,因为[]优先级比*高,这样就变成指针数组了
      注意:在实际应用中,对于指针数组,我们经常这样使用:

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
    int c[4]={1,2,3,4};
    int *a[4]; //指针数组
    int (*b)[4]; //数组指针
    b=&c;//数组指针指向数组的地址,用数组的地址进行初始化
    //将数组c中元素赋给数组a
    for(int i=0;i<4;i++)
    {
    a[i]=&c[i];//指针数组,数组中存放的时指针,所以传入的内存地址
    }
    //输出看下结果,两者的输出方式不同
    cout<<*a[1]<<endl; //输出2就对
    cout<<(*b)[2]<<endl; //输出3就对
    return 0;
    }
    View Code

    重点讲解

    数组和指针的区别
    定义一个数组的时候,需要在栈中静态分配一块内存,那么需要知道内存的大小,因为定义数组的时候需要确定各维的上限。数组是一个可以拥有内存,保存变量的数组类型,数组名代表地址。指针是一个存储内存地址的数据类型,定义一个指针需要知道它指向对象的类型,不需知道对象的大小。
    字符串常量
    字符串常量在c语言就是一个字符数组,尽管外部表现和数组不一样,实际上字符串常量本身就是数组的首地址,并且具有数组类型。sizeof(“abdaaff”)是 7而不是4。重点区别是字符串常量放在静态存储区,不允许改变;数组在栈中静态分配
    运算符&和*
    &是取地址符,*是间接运算符。
    &a的结果是一个指针,指针指向的类型就是a的类型加上。在运算中加上就是获取了指针指向的内存值。

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    TED_Topic9:How we're priming some kids for college — and others for prison
    TED_Topic8:How to control someone else's arm with your brain
    ML—随机森林·1
    ML—R常用多元统计分析包(持续更新中……)
    ML—机器学习常用包(持续更新….)
    TED_Topic7:How we unearthed the spinosaurus
    R9—R常用函数分类汇总
    将博客搬至CSDN
    产品经理读书笔记(一)
    Python数据结构:集合
  • 原文地址:https://www.cnblogs.com/polly333/p/4705669.html
Copyright © 2011-2022 走看看