函数中的错误最小和最大分配
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 这个解决方案与你的代码完全不同......以上是关于函数中的错误最小和最大分配的主要内容,如果未能解决你的问题,请参考以下文章