【问题标题】:My pointer in an array doesn't work as it supposed to我在数组中的指针无法正常工作
【发布时间】:2019-08-27 15:26:43
【问题描述】:

我想创建一个函数,它可以接受 1:array_of_int 和 2:size_of_array,然后返回 3 个最大 int 的总和。代码如下:

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

int max_3(int arr[], int asize)
{ 
   int max_arr[3];
   int max =0; 
   int sum = 0;
   int* pi; 

   for(int j=0; j<3; j++)
   {   
      for(int i =0; i<asize;i++)
      {   
         if(arr[i] > max)
         {
           max = arr[i];
           pi = (arr + i); // to know the address of the max int of 'i' cycle
         }
      }   
      max_arr[j] = max;
      *pi = 0; // make the max int = 0 so that the next 'i' cycle doesnt have the previous max in it 
               //(so it can look for another max value - the second one)
   }   

   for(int i=0; i<3; i++)
      sum += max_arr[i];

   return sum;
}


int main (int argc, char** argv) {
   int arr[6] = {1,5,9,12,16,14};
   printf("%i\n",max_3(arr, 6));
   return (EXIT_SUCCESS);
}

指针pi 不会使当前max 的值变为0,并且for (int i..) 中的下一个循环与上一个一样再次变为最大。因此,它没有返回 max val1 + val2 + val3,而是返回 3 * val1(最大的一个)——在我的特定示例中——它打印出 48 而不是 42 (12 + 16 + 14)——它应该.但是当我将地址的值(我的指针指向的)设置为0 时如何?我不是很明白。

【问题讨论】:

  • 你试过debug your program吗?如果您使用变量来存储最大元素的 index(而不是指针),该索引是否正确?代码是否使用索引代替?
  • 还有一个小提示:在内循环之后,max的值是多少?你在哪里重置它?这应该非常通过一点调试很容易找到。
  • 函数修改输入数组会让大多数用户感到非常惊讶。
  • @molbdnilo 它是如何修改的?如果我进行一些排序 - 然后将修改数组,但在我的示例中,我制作了“辅助”数组 max_arr 并将最大值存储在其中,这样我就不会修改输入数组 arr - 所以它确实和你说的相反。
  • @Someprogrammerdude max int 的值每次都是不同的 - 在两个循环中 - 如图所示 - if(arr[i]&gt;max) max = arr[i] - 如果某物大于该数组中的最大值 - 然后它变成最大限度。每一个周期。这就是为什么它存储在函数空间中的原因 - 而不是在循环中

标签: c


【解决方案1】:

您的if 声明:

if (arr[i] > max)

在您第一次找到max 后不会输入(j &gt; 0 时)。

您需要在之后将其归零:

max_arr[j] = max;
max = 0;

【讨论】:

  • 不幸的是仍然得到48而不是42。我认为,无论我是否使 max = 0 中的值,它仍然在数组 arr 中(最大值 - 例如16 - 在我的具体示例中),所以我必须删除(也就是将其设为零)该数组中的max - 因此试图指向该地址。
  • @PatrikPatanPastyyr 我无法重现该问题。您的代码输出 42。
  • @VladfromMoscow 我也没有,但我只是在max_arr[j] = max; 行之后添加一行max = 0; - 它打印了 48。
  • @PatrikPatanPastyyr 正如我已经写过的,我可以重现这个结果。
【解决方案2】:

以下建议代码:

  1. 执行所需的功能
  2. 其算法非常简单
  3. 采用冒泡排序来选择数组中的前三个条目
  4. 消除“神奇”数字 6
  5. 将第二个参数修改为size_t,因为这是sizeof()返回的类型
  6. 表达式:sizeof(arr)/sizeof(arr[0]) 让编译器计算数组中的条目数
  7. 语句:int arr[] = {1,5,9,12,16,14}; 让编译器为数组分配空间
  8. 避免在排序时修改原始数组

现在,建议的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>  // memcpy()


void swap(int *xp, int *yp) 
{ 
    int temp = *xp; 
    *xp = *yp; 
    *yp = temp; 
} 


// A function to implement bubble sort 
void bubbleSort(int arr[], size_t n) 
{ 
    size_t i;
    size_t j; 
    for (i = 0; i < n-1; i++)  
    {     
       // Last i elements are already in place    
       for (j = 0; j < n-i-1; j++)  
       {
            if (arr[j] > arr[j+1]) 
            {
              swap(&arr[j], &arr[j+1]); 
            }
        }
    }
} 


int max_3(int arr[], size_t asize)
{ 
    int localArray[ asize ];
    memcpy( localArray, arr, asize*sizeof( int ) );
    // sort array
    bubbleSort( localArray, asize );

    // calculate sum of max 3 entries
    int sum = localArray[asize-1] + localArray[asize-2] + localArray[asize-3];
    return sum;
}   


int main ( void ) 
{
   int arr[] = {1,5,9,12,16,14};
   printf( "%i\n", max_3( arr, sizeof(arr)/sizeof(arr[0])) );
   return (EXIT_SUCCESS);
}

运行建议的代码会导致:

42

【讨论】:

  • 但不同的是,我的函数量大约是 30 行,而你的可能是 110 行(没有数过)。而且 - 此外 - bublesort 是最被贬低的类型之一,因为难度是 x^2。无论如何,如果我想进行排序,我会使用 qsort() 实现的功能,但这不是目的。
  • 你是什么意思:function volume
  • bubble sort 在要排序的条目数少于 10 时(大约)是最好的。
  • 冒泡排序不能很好地“扩展”,但是,OP 没有提到任何关于更大数组的内容。如果它是一个更大的数组,那么函数:qsort() 将是一个合适的函数
  • 卷 - 行数
【解决方案3】:

在外循环(循环for(int j=0; j&lt;3; j++))的第一次迭代之后,maxpi 的值将永远不会改变。

在外循环的第一次迭代中,您会发现数组中的第五个元素最大,max 将等于 16pi 将指向该元素。您将max_arr[0] 设置为16 并将*pi 设置为零。然后外部循环以max 重新开始,仍然等于16。现在数组中将没有任何值等于或大于该值。因此,您也将max_arr[1] 设置为16,并将*pi(其中pi 仍指向第五个元素)设置为零再次。下一次迭代也是如此。

自然的解决方案是定义maxpi inside 外循环:

for(int j=0; j<3; j++)
{
    // The variables will be redefined and reinitialized each iteration of the loop
    int max = 0;
    int *pi;

    for(int i =0; i<asize;i++)
    {
        if(arr[i] > max)
        {
            max = arr[i];
            pi = (arr + i); // to know the address of the max int of 'i' cycle
        }
    }
    max_arr[j] = max;
    *pi = 0; // make the max int = 0 so that the next 'i' cycle doesnt have the previous max in it
             //(so it can look for another max value - the second one)
}

代码还有一些其他问题,例如pi 可能永远不会被初始化。我把它作为一个练习留给读者来判断什么时候会发生以及如何解决它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多