函数中的错误最小和最大分配

Posted

技术标签:

【中文标题】函数中的错误最小和最大分配【英文标题】:False min and max assignments in function 【发布时间】:2022-01-15 18:04:38 【问题描述】:

我有一个函数,它应该使用 struct 在数组中找到最小值和最大值。 但不知何故,该函数为 min 和 max 变量分配了错误的值。有人可以解释我哪里有错误吗?非常感谢。附言在我的作业中,函数不需要获取数组的第一个元素

min_max_t min_max(unsigned int *array, int size)

    min_max_t flag;
    flag.min = array[1];
    flag.max = array[1];
    printf("Flag.min: %d | ", flag.min);
    printf("Flag.max: %d\n", flag.max);
    for (int i = 1; i < size; i++)
    
        printf("i = %d - [A:%d - Min:%d - Max:%d]\n", i, array[i], flag.min, flag.max);
        if(array[i] > flag.max)
        
            flag.max = array[i];
        
        else if (array[i] < flag.min)
        
            flag.min = array[i];
        
        printf("i = %d - [A:%d - Min:%d - Max:%d]\n\n", i, array[i], flag.min, flag.max);
    
    return flag;

Screenshot of function process

【问题讨论】:

对于初学者,您将忽略数组的第一个元素。 在 C 中,数组中第一个元素的索引为零。所以开始 i=0。 你的数组是无符号整数,但你告诉printf()它们是有符号整数,看起来你的输入有负数? 我的作业说,数组的第一个元素(数组[0])用于表示项目后期的另一个值。所以我必须在其中找到 min 和 max 的数组是从 array[1] 到 array[size-1] 的数组。 问题似乎是您将int 数组传递给了将其作为unsigned int 数组处理的函数。因此-1 的值被转换为大的正值(即可用的最大无符号值)。 【参考方案1】:

求最小值和最大值的逻辑没有错。

您的代码的问题在于您使用%d 打印unsigned int。打印 unsigned int 值时使用%u

您可能会考虑处理的另一个问题是函数参数size 的非法值。您的函数要求 size 至少为 2。为避免未定义的行为,您可能需要进行检查。

在函数的开头,你可以例如添加

assert(size >= 2);

if (size < 2)

    // return some suitable value

也就是说,您也可以只记录要求 size 至少为 2 的函数。在 C 中,为函数设置此类合同要求并不少见。几个stdlib函数都有这样的要求。

顺便说一句:如果您添加检查 size,您可能还应该检查 array 不为 NULL。

顺便说一句:您的屏幕截图表明您将 int 数组 传递给函数。如果这是真的,那么你在调用者代码中有一个错误。不要将int数组传递给期望unsigned int数组的函数。

【讨论】:

【参考方案2】:

对于初学者来说,函数应该声明为

min_max_t min_max( const unsigned int *array, size_t size );

结构 min_max_t 应该包含两个数据成员,它们将存储最小和最大元素的索引。例如

typedef struct min_max_t

    size_t min;
    size_t max;
 min_max_t;

否则,当用户作为第二个参数 0 传递时,函数可能会调用未定义的行为。

数组中的索引从 0 开始。所以你在函数中跳过了传递数组的第一个元素。

由于数组具有unsigned int 类型的元素,因此表达式-1 被隐式转换为unsigned int 类型的最大值。因此,您需要决定是否确实要处理无符号整数数组或有符号整数数组。

在调用 printf 时使用转换说明符 %d 而不是 %u 来输出 unsigned int 类型的对象,如果该对象的值不适合该类型的对象,则会调用未定义的行为诠释。

所以你的函数可以如下所示

typedef struct min_max_t

    size_t min;
    size_t max;
 min_max_t;

min_max_t min_max( const unsigned int *array, size_t size )

    min_max_t flag =  .min = 0, .max = 0 ;

    printf( "Flag.min: %zu | ", flag.min );
    printf( "Flag.max: %zu\n", flag.max );

    for ( size_t i = 1; i < size; i++ )
    
        printf( "i = %zu - [A:%u - Min:%u - Max:%u]\n", i, array[i], array[flag.min], array[flag.max] );

        if ( array[flag.max] < arra[i] )
        
            flag.max = i;
        
        else if ( array[i] < array[flag.min] )
        
            flag.min = i;
        

        printf( "i = %zu - [A:%u - Min:%u - Max:%u]\n\n", i, array[i], array[flag.min], array[flag.max] );
    

    return flag;

【讨论】:

@Gerhardh 正如我在答案中已经写的那样,用户可以将值 0 传递给参数大小。在这种情况下,该函数将具有未定义的行为。您需要存储索引而不是数组的值。 对不起。我忽略了那部分。 存储索引解决不了任何问题。顺便说一句:%d%u 仍然存在不匹配 哦,原来问题不在于函数块,而在于我将变量初始化为无符号整数的结构中,而我只需要常规整数。非常感谢你们。 @Leon 这个解决方案与你的代码完全不同......

以上是关于函数中的错误最小和最大分配的主要内容,如果未能解决你的问题,请参考以下文章

C程序查找最大和最小元素时出错

如何最小化函数中的嵌套级别?

UISlider 最小和最大轨道色调清除颜色 iOS 7.1 错误

Python中的最小-最大归一化

数组中的 Java 最小值和最大值

C ++中动态分配的向量中的分段错误