精华内容
下载资源
问答
  • c语言变长动态数组 ArrayList

    千次阅读 2019-12-07 08:45:38
    但是看到别人在做arraylist时,我决定将网课上所学习的变长数组放上来。另一方面,正是由于变长数组的缺点使得我们可以引入链表的学习。 java实现arraylist 代码 h文件中的代码样例 #ifndef __ARRAY_H__ #...

    关于变长(动态)数组 ArrayList

    缘起

    在c语言的程序设计中,想要实现对一个数组的长度的动态变化其实是比较困难的,并且也是低效且不尽实用的。但是看到别人在做arraylist时,我决定将网课上所学习的变长数组放上来。另一方面,正是由于变长数组的缺点使得我们可以引入链表的学习。
    java实现arraylist

    代码

    h文件中的代码样例

    #ifndef __ARRAY_H__
    #define __ARRAY_H__
    
    typedef struct
    {
        int *array;
        int size;
    } Array;
    
    Array array_create(int init_size);
    void array_free(Array *a);
    int array_size(const Array *a);
    int *array_at(Array *a, int index);
    void array_inflate(Array *a, int more_size);
    
    #endif /* _____h */
    

    c文件中的代码样例

    #include "变长数组.h"
    #include <stdio.h>
    #include <stdlib.h>
    
    #define BLOCK_SIZE 20
    
    //typedef struct
    //{
    //    int *array;
    //    int size;
    //} Array;
    
    Array array_create(int init_size)
    {
        Array a;
        
        a.size = init_size;
        a.array = (int *)malloc(sizeof(int) * a.size);
        
        return a;
    }
    
    void array_free(Array *a)
    {
        free(a->array);
        a->array = NULL;
        a->size = 0;
    }
    
    int array_size(const Array *a)
    {
        return a->size;
    }
    
    int *array_at(Array *a, int index)
    {
        if (index >= a->size)
            array_inflate(a, (index / BLOCK_SIZE + 1) * BLOCK_SIZE - a->size);
        return &(a->array[index]);
    }
    
    void array_inflate(Array *a, int more_size)
    {
        int *p = (int *)malloc(sizeof(int) * (a->size + more_size));
        for (int i = 0; i < a->size; ++i)
        {
            p[i] = a->array[i];
        }
        free(a->array);
        a->array = NULL;
        a->size += more_size;
    }
    

    缺点分析

    1、变长

    在进行较大的数组进行变长时,每次需要新建一个更大的数组(长度增大为 (index / BLOCK_SIZE + 1) * BLOCK_SIZE ,但是每次都需要进行拷贝操作,将原数组拷贝给更长的新数组然后释放原数组的内存。当变长操作需要多次重复的进行时,用变长数组的方式效率会大大降低。

    2、内存

    假设我们能使用的内存是有一定的大小限制的,使用变长数组的方式时,每次在原数组的后面新开一个更长的数组(若前面的已经被释放出的内存足够会在前面开)当数组长度非常大的时候,可能会因为前面的长度不够新开增长的数组,后面的内存又不够用,所以导致程序崩溃。也就是说,使用变长数组的方式进行储存,其实只能利用好所分配的内存的大约三分之一,这当然是一种既舍弃空间又缺乏时间的处理方式。

    结语

    由此,我们引入了链表这种数据结构。

    展开全文
  • 主要介绍了C++ 手把手教你实现可变长数组实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 前天实训听见几位推免的大佬聊面试中出现了动态数组,而我们所学并没有涉及到动态数组,遂翻起了尘封已久的《C语言程序设计现代方法》以及...一、C99中的变长数组 下面程序用到了变长数组 #include<...

    前天实训听见几位推免的大佬聊面试中出现了动态数组,而我们所学并没有涉及到动态数组,遂翻起了尘封已久的《C语言程序设计现代方法》以及《C Primer Plus》,果然大神们写书都很全面(厚),后悔当初没有认真拜读。

    一、C99中的变长数组

    下面程序用到了变长数组

    #include<stdio.h>

    int main()
    {
    int i,n;

    printf(“How many numbers do you want to reverse?”);
    scanf(“%d”,&n);

    int a[n]; //只有C99支持n决定数组范围

    printf(“Enter %d numbers: “,n);
    for(i=0;i<n;i++)
    {
    scanf(“%d”,&a[i]);
    }
    printf(“In reverse order:”); //倒序输出数组
    for(i=n-1;i>=0;i–)
    printf(” %d”,a[i]);
    printf(“\n”);

    return 0;

    }

    上面程序中的数组a是一个变长数组(variable-length array,简称VLA)。变长数组的长度是在程序执行时计算的,而不是在程序编译时计算的。变长数组的主要优点是程序员不必在构造数组时随便给定一个长度,程序在执行时可以准确地计算出所需的元素个数。如果让程序员来制定长度,数组可能过(浪费)或过短(导致程序出错)。

    变长数组的长度不一定要用变量来指定,任意表达式(可以含运算符)都可以,例如:

    int a[3*i+5];

    int b[j+k];

    现在我们已经知道什么是变长数组了,但是,假如,变长数组作为形式参数,到底应该如何写呢?

    现在,假设有一函数

    int sum_array( int a[n] , int n )

    {

    ……

    }

    编译器会在遇到int a[n]时显示出错信息,因为此前它没有见过n。

    下面给出正确的函数原型:

    int sum_array(int n , int a[n] );    //version 1

    int sum_array(int n , int a[*] );    //version  2

    一般来说,变长数组形式参数的长度可以是任意表达式。例如,假设我们要编写一个函数来连接两个数组a和b,要求先复制a的元素,再复制b的元素,把结果写入第三个数组c:

    int concatenate(int m , int n , int  a[m] , int  b[n] , int c[m+n] )

    {

    }

    数组c的长度是a和b的长度之和。这里用于指定数组c长度的表达式只用到了另外两个参数;但一般来说,该表达式可以使用函数外部的变量,甚至可以调用其他函数。

    敲黑板!!!重点来了

    变长数组的大小不会变化,变长数组中的“变”并不表示在创建数组后还可以修改它的大小。变长数组的大小在创建后就是保持不变的。“变”的意思是说其维大小可以用变量来指定。

    变长数组允许动态分配存储单元,这表示可以在程序运行时指定数组的大小。常规的C数组是静态存储分配的,也就是说在编译时数组的大小就已经确定。

    接下来要说的动态数组,才是大小会变化的数组。

    二、动态数组

    现在我们讨论C语言中如何实现动态数组。请系好安全带,加速了加速了。

    基本思路就是使用malloc()库函数(内存分配)来得到一个指向一大块内存的指针。然后,像引用数组一样引用这块内存,其机理就是一个数组下标访问可以改写为一个指针加上偏移量。

    1.使用malloc函数为数组分配存储空间

    假设正在编写的程序需要n个整数构成的数组,这里的n可以在程序执行期间计算出来。首先,声明一个指针变量:

    int *a;

    一旦n的值已知了,就让程序调用malloc函数为数组分配存储空间:

    a=malloc( n * sizeof(int) );

    一旦a指向动态分配的内存块,就可以忽略a是指针的事实,可以把它作为数组的名字。这都要感谢C语言中数组和指针的紧密关系。例如,可以使用下列循环对a指向的数组进行初始化:

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

    a[i]=0;

    当然,用指针算数运算取代下标操作来访问数组元素也是可行的。

    2.使用calloc函数为数组分配存储空间

    calloc函数在<stdlib.h>中具有如下所示的原型:

    void * calloc ( size_t nmemb , size_t size );

    calloc函数为nmemb个元素的数组分配内存空间,其中每个元素的长度都是size个字节。如果要求的空间无效,那么此函数返回空指针。在分配了内存之后,calloc函数会通过把所有位设置为0的方式进行初始化。例如下列calloc函数调用为n个整数的数组分配存储空间,并且保证所有整数初始均为零:

    a=calloc(n,sizeof(int));

    3.使用realloc函数调整数组的大小

    一旦为数组分配完内存,稍后可能会发现数组过大或过小。realloc函数可以调整数组的大小使它更适合需要。<stdlib.h>中的realloc原型:

    void * realloc ( void *ptr, size_t size );

    当调用realloc函数时,ptr必须指向先前通过malloc、calloc或realloc的调用获得的内存块。size表示内存块的新尺寸,新尺寸可能会小于或大于原有尺寸。虽然realloc不要求ptr指向正在用作数组的内存,但实际上通常是这样的。

    在要求减少内存块大小时,realloc函数应该“在原先的内存块上”直接进行缩减,而不需要移动存储在内存块中的数据。同理,扩大内存块时也不应该对其进行移动。如果无法扩大内存块(因为内存块后面的字节已经用于其他目的),realloc函数会在别处分配新的内存块,然后把旧块中的内容复制到新块中。所以,一旦realloc函数返回,一定要对指向内存块的所有指针进行更新,因为realloc函数可能会使内存块移动到了其他地方。

    转载于:https://my.oschina.net/shuangquan/blog/1599776

    展开全文
  • 变长数组动态数组)

    万次阅读 2016-09-20 11:04:15
     这里说的变长数组是指在编译时不能确定数组长度,程序在运行时需要动态分配内存空间的数组。实现变长数组最简单的是变长一维数组,你可以这样做: //文件名: array01.cpp #include using namespace std; ...
    1.变长一维数组
    

      这里说的变长数组是指在编译时不能确定数组长度,程序在运行时需要动态分配内存空间的数组。实现变长数组最简单的是变长一维数组,你可以这样做:

    //文件名:   array01.cpp   
      #include<iostream>   
      using   namespace   std;   
        
      int   main()   
      {   
        int   len;   
        cin>>len;   
        //用指针p指向new动态分配的长度为len*sizeof(int)的内存空间   
        int   *p=new   int[len];   
    /*注意int   *p=new   int[len];这一句,你不能这样做:   
      int   p[len];   
      C++编译器会报错说len的大小不能确定,因为用这种形式声明数组,数组的大小需要在编译时确定。而且这样也不行:   
      int   p[]=new   int[len];   
      编译器会说不能把int*型转化为int[]型,因为用new开辟了一段内存空间后会返回这段内存的首地址,所以要把这个地址赋给一个指针,所以要用int   *p=new   int[len]*/
        ...........   
        delete[]   p;//<span style="color: rgb(85, 85, 85); font-family: 宋体, "Arial Narrow", arial, serif; font-size: 14px; line-height: 28px;">注意要注销指针p,使程序释放用new开辟的内存空间</span>
        return   0;   
      }   
      当然使用C++标准模版库(STL)中的vector(向量)也可以实现变长数组:

    //文件名:   array02.cpp   
      #include<iostream>   
      #include<vector>   
      using   namespace   std;   
        
      int   main()   
      {   
        int   len;   
        cin>>len;   
        vector<int>   array(len);//声明变长数组   
        
        for(int   i=0;i<len;i++)   
        {   
          array[i]=i;   
          cout<<array[i]<<"\t";   
        }   
        return   0;   
      }   
    
      这里的变长数组让我联想到了java的java.util包中的vector和C#中的ArrayList,它们也可以在各自的语言中实现变长数组。不过C++中的vector不能像C#一样有托管的垃圾回收机制回收被占用的内存空间,但是你可以在使用完vector后调用~vector()析构函数释放内存。

    2.变长n维数组

      在C++中可以通过new和delete运算符动态开辟和释放空间,其中new与C中malloc函数的功能相似,delete与C中free函数的功能相似。用C++实现变长二维数组时可以采用两种方法:双指针方法使用STL中vector(向量)的方法。

      首先介绍一下双指针方法,在这里双指针就是指像指针的指针,比如你可以这样声明一个数组:   
      int   **p   =   new   int*[num1];   
      而对每一个*p(一共num1个*p)申请一组内存空间:   
      for(int   i=0;   i<num1;   ++i)   

        p[i]   =   new   int[num2];   

      其中,num1是行数,num2是数组的列数。测试的源程序如下:

    //文件名:   array04.cpp   
      #include   <iostream>   
      #include   <iomanip>   
      using   namespace   std;   
        
      int   main()   
      {   
        int   num1,//行数   
                num2;//列数   
        
        cout<<"Please   enter   the   number   for   row   and   column:   "<<endl;  
        cin   >>   num1   >>   num2;   
        
        //为二维数组开辟空间   
        int   **p   =   new   int*[num1];   
        for(int   i=0;   i<num1;   ++i)   
          p[i]   =   new   int[num2];   
        
        for(int   j=0;j<num1;j++)   
        {   
          for(int   k=0;k<num2;k++)   
          {   
            p[j][k]=(j+1)*(k+1);   
            cout<<setw(6)<<p[j][k]<<':'<<setw(8)<<&p[j][k];   
          }   
          cout<<endl;   
        }   
        
        //释放二维数组占用的空间   
        for(int   m=0;m<num1;m++)   
          delete[]   p[m];   
        delete[]   p;   
        
        return   0;   
      }   
    以下是运行结果:   
        
      Please   enter   the   number   for   row   and   column:   
      4   5   
     1:004915F0     2:004915F4      3:004915F8       4:004915FC     5:00491600   
     2:00491180     4:00491184      6:00491188       8:0049118C     10:00491190   
     3:00491140     6:00491144      9:00491148       12:0049114C    15:00491150   
     4:00491100     8:00491104      12:00491108      16:0049110C    20:00491110   
      Press   any   key   to   continue   

      程序清单array04.cpp可以显示分配的内存空间单元的地址,大家可以看到,由于数组空间是动态分配的,数组行之间的地址空间是不连续的,因为不同行的数组元素的地址空间是用不同的new来分配的。而每一行之中列之间的地址空间是连续的。   
      那么用vector(向量)怎样实现二维数组呢?以下给出源程序:

    //文件名:   array05.cpp   
      #include   <iostream>   
      #include   <vector>   
      #include   <iomanip>   
      using   namespace   std;   
      int   main()   
      {   
        int   i,   
                j,   
                m,   //行数   
                n;   //列数   
        
        cout   <<   "input   value   for   m,n:";   
        cin>>m>>n;   
          
        //注意下面这一行:vector<int后两个">"之间要有空格!否则会被认为是重载">>"。   
        vector<vector<int>   >   vecInt(m,   vector<int>(n));       
        for   (i   =   0;   i   <   m;   i++)   
          for   (j   =   0;   j   <   n;   j++)   
            vecInt[i][j]   =   i*j;     
              
        for   (i   =   0;   i   <   m;   i++)   
        {   
          for   (j   =   0;   j   <   n;   j++)   
            cout<<setw(5)<<vecInt[i][j]<<":"<<setw(9)<<&vecInt[i][j];   
          cout<<endl;   
        }       
        return   0;   
      }   
    以下是运行结果:   
        
      input   value   for   m,n:3   4   
     0:   00491180      0:   00491184       0:   00491188         0:   0049118C   
     0:   00491140      1:   00491144       2:   00491148         3:   0049114C   
     0:   00491100      2:   00491104       4:   00491108         6:   0049110C   
      Press   any   key   to   continue   





    展开全文
  • 主要介绍了C#使用List类实现动态变长数组的方法,涉及C#中List类的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
  • 实践中经常碰到程序需要定义一个数组,但不知道定义多大合适的问题。...因此需要编写一个长度可变的数组类,该类的对象就能存放一个可变长数组。该数组类应该有以下特点:数组的元素个数可以在初始化...

    实践中经常碰到程序需要定义一个数组,但不知道定义多大合适的问题。按照最大的可能性定义,会造成空间浪费;定义小了则无法满足需要。

    如果用动态内存分配的方式解决,需要多少空间就动态分配多少,固然可以解决这个问题,但是要确保动态分配的内存在每一条执行路径上都能够被释放,也是一件头疼的事情。

    因此需要编写一个长度可变的数组类,该类的对象就能存放一个可变长数组。该数组类应该有以下特点:

    数组的元素个数可以在初始化该对象时指定。

    可以动态往数组中添加元素。

    使用该类时不用担心动态内存分配和释放问题。

    能够像使用数组那样使用动态数组类对象,如可以通过下标访问其元素。

    程序代码如下:

    #include

    #include

    using namespace std;

    class CArray

    {

    int size; //数组元素的个数

    int* ptr; //指向动态分配的数组

    public:

    CArray(int s = 0); //s代表数组元素的个数

    CArray(CArray & a);

    ~CArray();

    void push_back(int v); //用于在数组尾部添加一个元素 v

    CArray & operator = (const CArray & a); //用于数组对象间的赋值

    int length() const { return size; } //返回数组元素个数

    int & operator[](int i)

    { //用以支持根据下标访问数组元素,如“a[i]=4;”和“n=a[i];”这样的语句

    return ptr[i];

    };

    };

    CArray::CArray(int s) : size(s)

    {

    if (s == 0)

    ptr = NULL;

    else

    ptr = new int[s];

    }

    CArray::CArray(CArray & a)

    {

    if (!a.ptr) {

    ptr = NULL;

    size = 0;

    return;

    }

    ptr = new int[a.size];

    memcpy(ptr, a.ptr, sizeof(int) * a.size);

    size = a.size;

    }

    CArray::~CArray()

    {

    if (ptr) delete[] ptr;

    }

    CArray & CArray::operator=(const CArray & a)

    { //赋值号的作用是使 = 左边对象中存放的数组的大小和内容都与右边的对象一样

    if (ptr == a.ptr) //防止 a=a 这样的赋值导致出错

    return *this;

    if (a.ptr == NULL) { //如果a里面的数组是空的

    if (ptr)

    delete[] ptr;

    ptr = NULL;

    size = 0;

    return *this;

    }

    if (size < a.size) { //如果原有空间够大,就不用分配新的空间

    if (ptr)

    delete[] ptr;

    ptr = new int[a.size];

    }

    memcpy(ptr, a.ptr, sizeof(int)*a.size);

    size = a.size;

    return *this;

    }

    void CArray::push_back(int v)

    { //在数组尾部添加一个元素

    if (ptr) {

    int* tmpPtr = new int[size + 1]; //重新分配空间

    memcpy(tmpPtr, ptr, sizeof(int) * size); //复制原数组内容

    delete[] ptr;

    ptr = tmpPtr;

    }

    else //数组本来是空的

    ptr = new int[1];

    ptr[size++] = v; //加入新的数组元素

    }

    int main()

    {

    CArray a; //开始的数组是空的

    for (int i = 0; i<5; ++i)

    a.push_back(i);

    CArray a2, a3;

    a2 = a;

    for (int i = 0; i

    cout << a2[i] << " ";

    a2 = a3; //a2 是空的

    for (int i = 0; i

    cout << a2[i] << " ";

    cout << endl;

    a[3] = 100;

    CArray a4(a);

    for (int i = 0; i

    cout << a4[i] << " ";

    return 0;

    }

    程序的输出结果为:

    0 1 2 3 4

    0 1 2 100 4

    []是双目运算符,有两个操作数,一个在里面,一个在外面。表达式 a[i] 等价于 a.operator[](i)。按照[]原有的特性,a[i]应该能够作为左值使用,因此 operator[] 函数应该返回引用。

    思考题:每次在数组尾部添加一个元素都要重新分配内存并且复制原有内容,显然效率是低下的。有什么办法能够加快添加元素的速度呢?

    展开全文
  • 展开全部java中的数组一旦被定义e5a48de588b662616964757a686964616f31333337393533度是不允许修改长度的,如果题主希望实现类似的功能可以采用ArrayList。ArrayList的底层结构就是数组。当ArrayList实例化时会...
  • solidity定长数组动态数组

    千次阅读 2019-08-02 14:36:39
    固定长度的数组 固定长度数组声明 直接在定义数组的时候声明固定长度数组的值: uint[5] fixedArr = [1,2,3,4,5]; 可通过数组的length属性来获得数组的长度,进而进行遍历操作。 // 通过for循环计算数组值的总和 ...
  • 主要介绍了java可参数当做数组处理的方法,结合实例形式分析了java可参数当做数组处理相关原理、步骤与操作注意事项,需要的朋友可以参考下
  • 这就是我们常说的动态数组,也就是变长数组。 先不要乱,让我们再看一段代码 #include #include typedef struct { int len; int array[]; }SoftArray; int main() { int len = 10; SoftArray *p=(SoftArray*)malloc...
  • C++ 手把手教你实现可变长数组

    千次阅读 2019-12-01 21:44:07
    01 实现自定义的可变长数组类型 假设我们要实现一个会自动扩展的数组,要实现什么函数呢?先从下面的main函数给出的实现,看看有什么函数是需要我们实现的。 int main() { MyArray a; // 初始化的数组是空的 for...
  • 创建变长数组类型 CREATE TYPE varray_type AS VARRAY(2) OF VARCHAR2(50); 这个变长数组最多可以容纳两个数据,数据的类型为 varchar2(50) 更改元素类型的大小或精度 可以更改变长数组类型和嵌套表类型 元素的...
  • c++实现动态变长数组

    千次阅读 2019-03-12 08:34:30
    概述:自己封装一个数组MyArray,添加一些方法,改成动态变长数组(数组容量不固定,当发现size==capicity时,将capicity扩大两倍,当size==capicity/4时,将capicity缩小两倍。size为数组当前元素个数,capicity...
  • 变长数组 C99标准支持变长数组,允许在程序运行时再指定数组大小,但指定后就不能再变了。内存分配在栈上,超出命名空间的范围,自动释放内存。 动态分配内存 malloc/free 函数 是stdlib.h 的库函数。允许在程序运行...
  • 一些好的答案似乎取决于提前计算数组的最终大小。看起来这应该很简单,而且我是个新手,所以我可能只是搜索了错误的术语。。。在我的问题是:当数组长度未知且随时间变化时,如何让PyPlot刷新源于numpy数组的现有行...
  • C语言可变长数组

    2021-03-15 16:57:07
    通常,数组变量的长度必须有常量表达式进行定义,但是在C99中,有时候也可以使用非常量表达式 1.代码演示: #include<stdio.h> int main(void){ int i, n; printf("你想颠倒多少个数字?"); scanf("%d",...
  • C语言变长数组讲解

    万次阅读 多人点赞 2018-05-08 21:10:31
    C语言柔性数组讲解 看如下代码: #include&amp;amp;amp;amp;amp;amp;amp;lt;stdio.h&amp;amp;amp;amp;amp;amp;amp;gt; typedef struct _SoftArray{ int len; int array[]; }SoftArray; int main() { ...
  • 转自 https://blog.csdn.net/qq_39736982/article/details/82849769 https://www.cnblogs.com/hwy89289709/p/6840196.html ... 在标准C和C++中,长度为0的数组是被禁止使用的。不过在GN...
  • 下面小编就为大家带来一篇C++使struct对象拥有可大小的数组(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 下面小编就为大家带来一篇浅谈C++内存分配及变长数组动态分配。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • C#变长数组

    千次阅读 2018-10-30 22:24:49
     ArrayList就是传说中的动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了如下一些好处:  动态的增加和减少元素  实现了ICollection和IList接口  灵活的设置数组的大小  ...
  • 如何在java中创建变长数组

    千次阅读 2019-04-22 16:58:42
    传统的数组创建 在java中我们都知道创建简单数组较为简单,和C很相似。如下是创建1、2、3维数组的代码。 int [] array = new int[5]; int [][] array = new int[5][5]; int [][][] array = new int[5][5][5]; 但是...
  • 本文主要介绍C语言中柔性数组问题,感性趣的朋友可以看看。
  • 变长数组(VLA)

    2020-09-24 09:51:08
    处理二维数组的函数原型 #define COLS 4 int junk2(int ar[][COLS],int rows) ;//ar是rows*4的数组 处理n维数组的函数原型: int junkn(int arn[][4]...[5],int rows);/*arn是rows*4*...*5的数组*/ 通过以上两个...
  • C++之变长数组与变长结构体

    千次阅读 2018-03-18 19:54:52
    在C99标准中,新加入了变长数组和变长结构体变长数组如下:其中a[n]就是...}该变长数组也可以对应于malloc的动态空间分配,等价于int *a = malloc(n * sizeof(int));二者的区别:1.变长数组从栈上分配空间,malloc...
  • 变长数组 C99中支持变长数组,即支持数组在定义时以一个变量来声明长度; int i; int n; scanf("%d",&n); int arrat[n]; //用 一个变量来声明数组长度 for(i=0;i<n;i++) { arrat[i]=i+1;...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 435,653
精华内容 174,261
关键字:

变长动态数组