C中用户定义的数组元素和数组大小

Posted

技术标签:

【中文标题】C中用户定义的数组元素和数组大小【英文标题】:User defined array elements and array size in C 【发布时间】:2018-07-09 17:10:59 【问题描述】:

我对 C 编程非常陌生,并且正在自学。我想编写一个代码,要求用户输入一些数字并将它们存储到一个数组中。如果用户输入“q”,程序将停止。然后它应该打印数组并告诉用户该数组中有多少个数字。 (长度)

我编写了以下代码,但如果我将 int array[]; 留空,它就不起作用(显然)。我也无法定义它,因为它取决于用户输入了多少数字......我通过互联网搜索了很多并遇到了malloc和calloc。我尝试在这里使用它们,但老实说我不知道​​如何使用,而且我已经在这段代码上坐了几天了。

#include <stdio.h>
#include <stdlib.h>
int main()

int array[]; //I want to leave this empty but C doesn't allow me to.
int len=sizeof(array)/sizeof(array[0]);

for(int a=0;a<len;a++)

    printf("Enter element %d: ", a);
    scanf("%d",&array[a]);
    if(getchar()=='q')
        break;


printf("Array: [");
for(int a=0;a<len-1;a++)

    printf("%d, ", array[a]);
   printf("%d]", array[len]);
printf("\nArray length: %d\n", len);
return 0;

int array[5] 的示例输出;

Enter element 0: 1
Enter element 1: 2
Enter element 2: 3
Enter element 3: 4
Enter element 4: 5
Array: [1, 2, 3, 4, 5]
Array length: 5

非常感谢任何帮助。谢谢,祝您有愉快的一天。

【问题讨论】:

用户将输入任意数量的元素?你已经把它存储在数组中了吗? 我不知道我是否真的“必须”将数字存储到数组中。对于一系列输入,我没有想出任何其他更好的解决方案。我希望用户能够将例如不超过 100 个整数或类似的东西存储到该数组中。我不知道如何设置这个“限制”。对不起,如果我的定义不在书上。 是的,malloc/calloc 是在运行时创建大小数组的常规方法。但是您必须将数组声明为指针类型,而不是数组类型。 【参考方案1】:

Malloc 和 calloc 函数允许您为变量动态分配内存。 我认为如果您使用 int 指针 (int*) 而不是 int [],效果会更好。 你可以这样做

int * array = malloc (sizeof(int)); //this will allocate enough memory for 1 int element
Len = 1;

然后在循环结束时,如果用户没有输入'q',你可以这样做

len ++ ;
array = realloc(array,len*sizeof(int)); //this will reallocate memory for your int pointer

然后在代码的最后你必须像这样调用函数 free :free(array); 来释放分配的内存。

编辑:在 for 循环之后,您正在访问 array[len] 中不应该访问的内存。 我觉得你应该改成array[len-1]

【讨论】:

哇,非常感谢!这正是我想要的!是的,我通过编写 len-1 解决了这个问题,但是当它被打印时,我的数组中仍然会得到一个巨大的随机数。 现在一切正常,我只是发现我需要在最后一个 for 循环中删除 array[len],因为没有必要这样做。 :)【参考方案2】:

正如您自己所说,这个想法是分配一些元素,然后在其中存储元素。当它已满时,然后重新分配并线性增加其大小。在处理结束时,您释放未使用的内存。

我所说的一个紧密的实现:

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>

#define MAXLEN 3
#define MAXBUFF 30
int main(void)

    size_t sz = 0,tsz=MAXLEN;
    int *arr= malloc(sizeof*arr*MAXLEN);
    if( !arr)
        perror("malloc:");
        exit(EXIT_FAILURE);
    
    char s[MAXBUFF];
    while(fgets(s,MAXBUFF,stdin)!=NULL)
        if(strstr(s,"q") != NULL)
            break;
        
        else

            char *t;
            errno = 0;
            long n = strtol(s, &t, 10);
            if ((errno == ERANGE && (n == LONG_MAX || n == LONG_MIN))|| (errno != 0 && n == 0)) 
                perror("strtol");
                exit(EXIT_FAILURE);
            
            if (t == s) 
                fprintf(stderr, "No digits were found\n");
                exit(EXIT_FAILURE);
            
            if ( n >= INT_MIN && n <= INT_MAX)
            
                arr[sz++]=(int)n;  
            
            else
               fprintf(stderr, "Too big/small a number\n");
               exit(EXIT_FAILURE); 
            

        
        if( sz == tsz)
            int *p = realloc(arr,sizeof *p*(tsz+MAXLEN));
            if(!p)
                perror("Realloc:");
                exit(EXIT_FAILURE);
            
            arr = p;
            tsz+= MAXLEN;
        
    
    int *p = realloc(arr,sizeof *p*sz);
    if(!p)
        perror("Realloc:");
        exit(EXIT_FAILURE);
    
    arr = p;
    printf("Numbers entered = %zu\n",sz );
    for(size_t i = 0; i< sz; i++)
        printf("a[%zu]=%d\n",i,arr[i] );
    free(arr);
    return(0);

在阅读此代码时,我建议您查看手册页以了解每个函数返回的内容。最后一个realloc() 基本上将内存缩小到适当的大小(如果分配的内存比需要的多)。内存的增加是线性的(我们逐渐添加了size)。

【讨论】:

非常感谢您!它工作得很好,但我很难理解,因为里面有很多我不熟悉的东西。我将继续研究代码,因为它是一个非常有用的示例。 :) 您可以通过从arr = NULL; tsz = 0 开始并在循环开始时执行realloc() 来简化(请记住,您可以非常合理地使用realloc(NULL, size))。 @TobySpeight.: 可以..我只是用malloc/ 否则,这是非常健壮的代码 - 许多人会在调用 strtol() 之前忘记重置 errno,或者对 size_t 使用错误的 printf 转换 - 所以我认为这是有价值的教学资源。我可能会提醒初学者sizeof 的优先级 - 例如sizeof*arr*MAXLEN(sizeof *arr)*MAXLEN【参考方案3】:

只有在 c99 为您的问题发挥作用后才允许没有大小的数组您可以使用 malloc 和 realloc 动态定义数组的大小这里是程序的运行方式

#include <stdio.h>
#include <stdlib.h>
int main()

//Initially defining the size of our dynamic array=1
int *arr = malloc(1 * sizeof(int));
int counter=2;
while(1)

    printf("Enter element %d: ", a);
//reallocating array size after user enters a value
    arr = realloc(arr, counter * sizeof(int)); 
    counter++;

    scanf("%d",&arr[counter]);

    if(getchar()=='q')

     break;


printf("Array: [");
for(int a=0;a<counter-1;a++)

    printf("%d, ", array[a]);
   printf("%d]", array[counter]);
printf("\nArray length: %d\n", counter);
return 0;

如果有帮助请告诉我

【讨论】:

非常感谢。我将变量 len 更改为 counter 但出现以下错误:test.c:8:7: error: 'true' undeclared (first use in this function) while(true) 我已将 true 更改为 1 它的无限循环 非常感谢先生,是的,我做到了。你的回答对我帮助很大。但是我仍然得到一个随机的大数列表。我更改的代码中有几个未声明的变量,也许这就是问题所在,但我不断更改它们,代码仍然给我随机数。 对不起,这是我的错误,我再次对其进行了编辑,请相应地进行更改,并为您尚未投票的答案投票 别忘了查看malloc的返回值;更重要的是,在分配给arr之前检查realloc的返回值并泄漏内存!

以上是关于C中用户定义的数组元素和数组大小的主要内容,如果未能解决你的问题,请参考以下文章

c语言数组的定义

C程中如何计算数组(一维及二维)占内存空间的大小

c中可以定义变长数组吗

如何根据输入数量定义数组大小?

c语言如何取数组元素个数?

c语言报错不允许使用不完整类型,让用户自定义数组大小。