首页 新闻 会员 周边 捐助

C语言定义动态数组问题

0
悬赏园豆:5 [已解决问题] 解决于 2020-03-10 21:08

在C语言中,假设我们需要定义一个数组来接收用户输入的数据,并且这个数组的长度是不确定的,用户也不知道具体要输入多少个数,像这种数组,我们需要怎么定义了?

陈太浪的主页 陈太浪 | 初学一级 | 园豆:138
提问于:2020-03-10 08:58
< >
分享
最佳答案
1

这是个好问题!
通过定义一个结构体来实现动态数组:

struct dynamic_array{
    int size; //表示当前的数组存放了多少元素
    int capacity; //表示数组的总容量
    int *ptr;
}

通过上面定义的结构体可以实现动态数组,大致思路如下:

while(循环读取数据number){
    if 检查size ==  capacity?
          ptr = realloc(ptr, capacity*2);
          capacity = capacity*2;
    ptr[size] = number
}

大致思路就是上面这样,还有些细节问题,可以写代码的时候考虑进去

如有帮助,请采纳~~~

收获园豆:5
wengle | 小虾三级 |园豆:567 | 2020-03-10 09:11

另外,Redis中的sds就是一个经典的动态数组

wengle | 园豆:567 (小虾三级) | 2020-03-10 09:12

你这种写法我倒是理解了,但是感觉存在一些问题,
1,我们还是需要给结构体中的capacity赋一个初值,这个值又应该赋值为多少了?size初始值倒没问题,应该赋值为0;
2,循环终止的条件又是什么了?
3,在你判断size和capacity是否相等中,如果相等就将ptr的内存扩大为原来的两倍,这样虽然解决了数组存不足的问题,但是我觉得会比较浪费内存。有没有其他的,更简便的方法来解决这个问题了。

陈太浪 | 园豆:138 (初学一级) | 2020-03-10 09:33

@陈太浪:

  1. capacity 赋任意值都行,一般是64,遍历的时候是根据size来的
  2. 从scanf不能再读取数据了
  3. 这个内存空间不会占用太多,很多源码都是这种扩充方式,而且这种方式是简洁、高效的,还有一些复杂的扩充方式,但是对于你的需求来说没必要用,这已经是C语言实现动态数组最简便的方式了

如有帮助,请采纳~~~

wengle | 园豆:567 (小虾三级) | 2020-03-10 09:52

你好,我还想继续请教一下,如何通过while(循环读取数据number),也就是说如何读取用户输入的数据,怎么判断用户输入数据的过程有没有结束。麻烦将过程说得详细一点,谢谢!0.0

陈太浪 | 园豆:138 (初学一级) | 2020-03-10 19:45

@陈太浪:
scanf是有返回值的,用户不输入数据后,scanf就会返回0

while(scanf("%d", &number) == 1){
    do something
}

可参考:https://blog.csdn.net/qq_15037231/article/details/51868739
如有帮助,请采纳~~~

wengle | 园豆:567 (小虾三级) | 2020-03-10 19:51

@wengle: 谢谢 我去试试

陈太浪 | 园豆:138 (初学一级) | 2020-03-10 20:08

@陈太浪: 能够帮到你,我很高兴,如果解决了你的问题,请采纳~~~ 这是对我最大的鼓励,谢谢

wengle | 园豆:567 (小虾三级) | 2020-03-10 20:09

麻烦再帮我看一下我写的代码哪里出现了问题,运行之后没有结果输出
代码的作用就是通过你所给的方法定义一个动态的数组,然后往里面存值,最后再将存储的内容
打印出来,但是却没有任何输出.

#include <stdio.h>
#include <stdlib.h>

struct dynamicArray
{
    int size;
    int capicity;
    int *ptr;
};

int main()
{
    typedef struct dynamicArray dnArray;
    dnArray arr;
    //size初始化为0
    arr.size = 0;
    //capicity初始化为4
    arr.capicity = 4;
    //给结构体的指针动态分配内存
    arr.ptr = (int *) malloc(arr.capicity* sizeof(int));
    //需要存储的数据
    int num;
    while (scanf("%d",&num) == 1)
    {
        arr.ptr[arr.size] = num;
        arr.size++;
        if(arr.capicity ==arr.size)
        {
            arr.ptr = (int *) realloc(arr.ptr, 2*arr.capicity*sizeof(int));
            arr.capicity = arr.capicity*2;
        }
    }
    //打印存储后的结果
    for (int i = 0; i < arr.size; i++)
    {
        printf("%d\n",arr.ptr[i]);
    }
    
    
    return 0;
}
陈太浪 | 园豆:138 (初学一级) | 2020-03-10 20:38

@陈太浪: 代码写的没问题,你输完之后,记得按一下ctrl+D,这个表示输入结束

或者这样先把数据保存到文件里,然后重定向到程序的标准输入
data

./hello < data.out

result

不错啊~有潜力
能够帮到你,我很高兴,如果解决了你的问题,请采纳~~~ 这是对我最大的鼓励,谢谢

wengle | 园豆:567 (小虾三级) | 2020-03-10 21:05

@wengle: 终于搞好了,真的非常感谢你,麻烦你一天了。

陈太浪 | 园豆:138 (初学一级) | 2020-03-10 21:08

@陈太浪: 能帮到你就行,一起加油~~~

wengle | 园豆:567 (小虾三级) | 2020-03-10 21:10
其他回答(1)
0

可以用realloc,递进地分配内存

jakio6 | 园豆:1325 (小虾三级) | 2020-03-10 09:49

麻烦你稍微说具体一点,上边哪位兄弟用的就是realloc递进分配内存

支持(0) 反对(0) 陈太浪 | 园豆:138 (初学一级) | 2020-03-10 09:50

@陈太浪: ?每多读一组数据,就多分配对应的内存,或者像上面那样doubling,但是结构体没有必要,直接几个局部变量就行了

array = realloc(array, size* (size_of_each_element)

每次size++或者times 2

支持(0) 反对(0) jakio6 | 园豆:1325 (小虾三级) | 2020-03-10 10:13
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册