【问题标题】:How to let user determine array size of global variables?如何让用户确定全局变量的数组大小?
【发布时间】:2019-09-03 10:10:01
【问题描述】:

我想尝试创建一个 C 程序,让用户确定全局变量的数组大小(使我的程序更加动态)。但是有一个问题,因为您不能在范围之外使用scanf。你们能帮我解决这个问题吗?

我尝试在范围之外使用scanf,但这是不可能的。

这是有效的代码(用户无法确定全局变量的数组大小):

#include <stdio.h>

int arr[100];
int tempArr[100];

void merge(int left, int middle, int right){
    int leftIndex, rightIndex, index;
    for(leftIndex = left, rightIndex = middle + 1, index = left;leftIndex<=middle && rightIndex<=right;index++){<br>
        if(arr[leftIndex]<arr[rightIndex]){
            tempArr[index] = arr[leftIndex++];
        }else{
            tempArr[index] = arr[rightIndex++];
        }
    }
    while(leftIndex<=middle){
        tempArr[index++]=arr[leftIndex++];
    }
    while(rightIndex<=right){
        tempArr[index++]=arr[rightIndex++];
    }
    for(int j = left; j<=right; j++){
        arr[j]=tempArr[j];
    }
}

void sort(int left, int right){
    int middle =0;
    if(left<right){
        middle=(left+right)/2;
        sort(left, middle);
        sort(middle+1, right);
        merge(left,middle,right);
    }
}

int binarySearch(int arr[], int left, int right, int search){
    int middle = 0;
    if(left<right){
        middle = (left+right)/2;
        if(arr[middle]==search){
            return middle;
        }else if(arr[middle]>search){
            return binarySearch(arr,left,middle,search);
        }else{
            return binarySearch(arr,middle+1,right,search);
        }
    }
    return -1;
}

int main(){
    int search;
    int index = 0;
    int arraySize = 0;
    scanf("%d", &arraySize); getchar();
    for(int i=0;i<arraySize; i++){
        int number;
        scanf("%d", &number); getchar();
        arr[index] = number;
        index++;
    }

    printf("Before sorting\n");
    int size=sizeof(arr)/sizeof(arr[0])-1;

    for(int i =0;i<=arraySize;i++){
        if(arr[i]!=0){
            printf("%d %d\n",arr[i],i);
        }
    }

    sort(0, arraySize-1);

    printf("\nAfter sorting\n");
    for(int i =0;i<=arraySize;i++){
        if(arr[i]!=0){
            printf("%d %d\n",arr[i],i);
        }
    }   

    printf("\nSearch a number: ");
    scanf("%d",&search);
    int result = 0;
    result = binarySearch(arr,0,arraySize,search);
    printf("Result: %d",result);
    return 0;
}

我在下面尝试了这几行,但没有成功。我不确定我是否能想到其他方法。

#include <stdio.h>

int slot;
scanf("%d",&slot);
int arr[slot];
int tempArr[slot];

【问题讨论】:

  • 一句话送给你:malloc.
  • 我对如何实现malloc有了一些了解。也许,快速教程会有所帮助。感谢您的快速回复。
  • @JL2210 我猜他的意思是“如何使用malloc”。 Elmer:有无数关于如何做到这一点的教程(到目前为止,这里有几个回答你的问题)。我会尝试在网络上搜索“C malloc 动态数组”或类似的东西。
  • 如果重点是创建一个灵活、可重用的库,那么您是否考虑过全局变量对于此类目的的问题?
  • @JohnBollinger 一步一步,我会说。在担心全局变量之前,我会担心要求用户显式地预先指定一些程序可以说应该自己找出的东西,真正动态地。

标签: c arrays dynamic global


【解决方案1】:

如何让用户确定全局变量的数组大小?

用户无法确定变量的大小,程序员可以。例如,设置一个静态的最大允许大小可能非常有意义,然后一个有效的用例可能是只使用数组的一部分。

如果您需要在运行时设置数组的大小,您可以使用malloc 的动态分配。研究动态分配。就是这样。

【讨论】:

    【解决方案2】:

    原代码为:

    #include <stdio.h>
    
    int slot;
    scanf("%d",&slot);
    int arr[slot];
    int tempArr[slot];
    

    修改后的代码为:

    #include <stdio.h>
    #include <stdlib.h>
    
    int slot;
    scanf("%d",&slot);
    int *arr=malloc(sizeof *arr *slot);
    int *tempArr=malloc(sizeof *tempArr *slot);
    

    这里是一个关于“让用户确定全局变量的数组大小”的例子。

    #include <stdio.h>
    #include <stdlib.h>
    
    // [1]. use "pointer" instead of "array" 
    int *arr;
    int size=0;
    
    void init(void)
    {
        int i;
        for(i=0;i<size;i++)
        {
            arr[i]=i;
        }
    }
    
    void display(void)
    {
        int i;
        for(i=0;i<size;i++)
        {
            printf("%d, ",arr[i]);
        }
        printf("\n");
    }
    
    int main(void)
    {
        if(scanf("%d",&size)==-1)
        {
            return 0;
        }
    
        //[2]. use "malloc" to request variable size of memory
        //     "malloc" require <stdlib.h>
        arr=malloc(sizeof *arr *size);
        if(arr==NULL)
        {
            return 0;
        }
    
        //init and display
        init();
        display();
    
        //[3]. releasing the memory space is a good habit.
        free(arr);
    
        return 0;
    }
    

    【讨论】:

    • 请详细说明您在代码之外所做的更改。
    • 这是一个仅代码的答案,这是一件坏事。详细说明和解释,而不仅仅是给出代码示例。此外,这个答案是在教坏习惯。
    • @klutt,这几乎就像一个如何不写C的清单:忽略scanf()的结果,转换malloc()的结果,不检查失败的malloc(),变量无意义声明的名称超出了必要的范围,非原型 main() 而不是 main(void)
    • 不投射 malloc = 打死马的结果。从... 99 开始,我们就有了 C99。自从 malloc cast+missing stdlib 包含错误已经过时已经 20 年了。演员阵容相当无意义,但如今也无害。至于忽略scanf的结果...主要的错误是首先使用了stdio.h。这是一个错误的、危险的混乱,不应该在生产代码中使用。该库的主要目的是在学术环境中学习 C,在这种环境中,缓冲区溢出之类的东西是外围兴趣。
    【解决方案3】:

    声明为“全局”(在文件范围内)的数组不能在运行时设置其大小。它们的大小必须用一个可以在编译时计算的常量表达式来指定(例如一个数字文字或另一个对象上的sizeof 操作)。

    具有static 存储持续时间的对象(全局对象和使用static 关键字声明的任何内容)在程序启动后立即加载到内存中,在您提示用户输入任何内容之前,并且必须知道它们的大小立即地。

    因此,如果您想要一个直到运行时才知道其大小的“全局”数组,您将不得不使用malloccalloc

    int *arr = NULL;
    int *tmpArr = NULL;
    ...
    int main( void )
    {
      int arrsize = 0;
      ...
      scanf( "%d", &arrsize ); // ideally want to check that scanf succeeded.
    
      arr = malloc( sizeof *arr * arrsize );
      if ( !arr )
      {
        // malloc failed, probably want to exit here
      }
      tempArr = malloc( sizeof *tempArr * arrsize );
      if ( !tempArr )
      {
        // same as above
      }
    
      ...
    

    完成后,在退出程序之前使用free 释放内存:

      ...
    
      free( arr );
      free( tempArr );
    
      exit( EXIT_SUCCESS );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 2014-09-14
      • 2014-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多