![](/img/trans.png)
[英]Why the below code is giving different output when variable type is different?
[英]3 different functions giving the same output depending on variable type in C
我正在尝试编写一个模块化代码来对一组数据(数组)进行操作,操作是; 查找:平均值、最大值、最小值、中位数。 对数组进行排序,并打印统计信息。
我完成了这个项目的一半,写了 3 个函数:均值、最大值和最小值。
问题是,这 3 个函数根据数组声明变量类型输出相同的值。 当它是 unsigned char 时,它们都返回 93.000,当它是 unsigned int 时,它们都返回 24.000。 我知道我的数组函数设置有问题。 我已经找了 4 天了。 我找不到任何东西,也找不到问题所在。
这是我的代码
我有一个用于函数原型文档的 .h 文件:
/******************************************************************************
* Copyright (C) 2017 by Alex Fosdick - University of Colorado
*
* Redistribution, modification or use of this software in source or binary
* forms is permitted as long as the files maintain this copyright. Users are
* permitted to modify this and use it to learn about the field of embedded
* software. Alex Fosdick and the University of Colorado are not liable for any
* misuse of this material.
*
*****************************************************************************/
/**
* @file Module of the code
* @brief function declarations to include in header
*
* it defines 7 functions which are used in statistical analysis
*
* @author Mahmoud Saad
* @date October 10, 2018
*
*/
#ifndef __STATS_H__
#define __STATS_H__
/* Add Your Declarations and Function Comments here */
void print_array (int array[], int length);
/**
* @brief prints array
*
* prints each element with spaces in between
*
* @param array[] the array itself
* @param length length of array
* @param
* @param
*
* @return
*/
/* Add Your Declarations and Function Comments here */
float find_median (int array[], int length);
/**
* @brief finds median
*
* sorts elements and if odd number picks the middle if even, divide the 2 middle elements to get median
*
* @param array[] the array itself
* @param length length of array
* @param
* @param
*
* @return returns median
*/
/* Add Your Declarations and Function Comments here */
float find_mean (unsigned char array[], int count);
/**
* @brief finds mean
*
* adds all elements and dividies by their number
*
* @param array[] the array itself
* @param length length of array
* @param
* @param
*
* @return mean
*/
/* Add Your Declarations and Function Comments here */
int find_maximum (int numbers[], int length);
/**
* @brief finds maximum
*
* stores first value in varable then replace it with any higher value
*
* @param array[] the array itself
* @param length length of array
* @param
* @param
*
* @return maximum
*/
/* Add Your Declarations and Function Comments here */
int find_minimum (int numbers[], int length);
/**
* @brief finds minimum
*
* stores first value in vaiable then replaces it with any lower value
*
* @param array[] the array itself
* @param length length of array
* @param
* @param
*
* @return minimum
*/
/* Add Your Declarations and Function Comments here */
int sort_array ( int array[], int length);
/**
* @brief sorts array
*
* <Add Extended Description Here>
*
* @param array[] the array itself
* @param length length of array
* @param <Add InputName> <add description here>
* @param <Add InputName> <add description here>
*
* @return <Add Return Informaiton here>
*/
/* Add Your Declarations and Function Comments here */
void print_statistics(float mean, int maximum, int minimum);
/**
* @brief sorts array
*
* <Add Extended Description Here>
*
* @param array[] the array itself
* @param length length of array
* @param <Add InputName> <add description here>
* @param <Add InputName> <add description here>
*
* @return <Add Return Informaiton here>
*/
#endif /* __STATS_H__ */
另一个用于 main 和函数定义和代码的 .c 文件:
/******************************************************************************
* Copyright (C) 2017 by Alex Fosdick - University of Colorado
*
* Redistribution, modification or use of this software in source or binary
* forms is permitted as long as the files maintain this copyright. Users are
* permitted to modify this and use it to learn about the field of embedded
* software. Alex Fosdick and the University of Colorado are not liable for any
* misuse of this material.
*
*****************************************************************************/
/**
* @file Statistical analysis
* @brief Does some analysis on databases
*
* <Add Extended Description Here>
*
* @author Mahmoud Saad
* @date October 4th, 2018
*
*/
#include <stdio.h>
#include "stats.h"
/* Size of the Data Set */
#define SIZE (40)
#define NULL (0)
int maximum, minimum;
float mean, median;
void main() {
unsigned char test[SIZE] = { 34, 201, 190, 154, 8, 194, 2, 6,
114, 88, 45, 76, 123, 87, 25, 23,
200, 122, 150, 90, 92, 87, 177, 244,
201, 6, 12, 60, 8, 2, 5, 67,
7, 87, 250, 230, 99, 3, 100, 90};
/* Other Variable Declarations Go Here */
int maximum, minimum;
float mean, median;
/* Statistics and Printing Functions Go Here */
print_array(test, SIZE);
print_array(test, SIZE);
mean = find_mean (test, SIZE);
median = find_median (test, SIZE);
maximum = find_maximum (test, SIZE);
minimum = find_minimum (test, SIZE);
print_statistics(mean, maximum, minimum);
}
/* Add other Implementation File Code Here */
print_array (int array[], int length){};
float find_median (int array[], int length){};
float find_mean (unsigned char array[], int count){
int i;
unsigned int sum =0 ;
for(i = 0; i < count; ++i){
sum += array[i];
}
float avg = sum/count;
return (avg);
};
int find_maximum (int numbers[], int length){
int max, i;
while ( i < length ){
if ( i == 0 ) {
max = numbers[0]; // Must initialize to values in set, not zero
}
if ( numbers[i] >= max){
max = numbers[i];
}
i++;
}
return(max);
};
int find_minimum (int numbers[], int length){
int min, i;
while ( i < length ){
if ( i == 0 ) {
min = numbers[0]; // Move to second item and start comparisons
}
if ( numbers[i] <= min){
min = numbers[i];
}
i++;
}
return (min);
};
int sort_array ( int array[], int length){};
void print_statistics(float mean, int maximum, int minimum){
printf( "The average is: %f\n", mean );
printf( "The maximum is: %f\n", maximum );
printf( "The minimum is: %f\n", minimum );
};
所有自动存储持续时间变量都需要在 C 中初始化。
你的部门都在整数运算,这也解释了全数字的结果。 使用1.f * sum / count
习惯用法强制以浮点计算。
printf
int
的格式说明符是%d
。 %f
用于float
或double
。
虽然原则上可能有效,但从unsigned char
值数组构造int
数组会使您面临许多潜在的错误和未定义的行为。 特别是, unsigned char
数组的对齐方式可能不适合您平台上的int
,您需要仔细计算元素的数量。 你似乎不会那样做。
(不要对任何符号使用前导双下划线。它们是保留的。)
假设数组的数据类型与函数期望的匹配,这里有两个问题。
第一个是在您的打印功能中:
void print_statistics(float mean, int maximum, int minimum){
printf( "The average is: %f\n", mean );
printf( "The maximum is: %f\n", maximum );
printf( "The minimum is: %f\n", minimum );
}
minimum
和maximum
类型为int
,但您使用的是%f
格式说明符,它需要一个double
。 使用错误的格式说明符会调用未定义的行为。
使用%d
打印 = 一个int
:
printf( "The maximum is: %d\n", maximum );
printf( "The minimum is: %d\n", minimum );
第二个问题是find_minimum
和find_maximum
。 这两个函数都使用while ( i < length )
进入 while 循环而不初始化i
。 这意味着它的价值是不确定的。 使用这个值来索引一个数组可能会读到数组的末尾,再次调用未定义的行为。
在两个函数中将i
初始化为 0。
执行此操作后,您将获得以下结果:
The average is: 93.000000
The maximum is: 250
The minimum is: 2
如果这确实是您正在使用的代码,那么您将有相当多的未定义行为。
标题中的声明:
int find_maximum (int array[], int length);
在你的 c 文件中实现:
int find_maximum (int numbers[], int length){
...
在您的 c 文件中的用法:
unsigned char test[SIZE] = { 34, 201, 190, 154, 8, 194, 2, 6,
114, 88, 45, 76, 123, 87, 25, 23,
200, 122, 150, 90, 92, 87, 177, 244,
201, 6, 12, 60, 8, 2, 5, 67,
7, 87, 250, 230, 99, 3, 100, 90};
...
maximum = find_maximum (test, SIZE);
您将一个char
数组输入到一个需要一个int
数组的函数中。 这不起作用,应该给你一些来自编译器的警告。 对任何数组元素的每次访问都将使用错误的地址,并且该函数将访问超出其合法内存位置的数组。
而不是比较值34, 201, 190, 154, ...
或在十六进制 (22, C9, BE, 9A, ...) 你正在处理值0x9ABEC922, ...
假设 32 位整数。
如果您将数组的类型更改为int
,则此函数没有此 UB,但您的其他函数也有类似的问题。
除此之外:
void main() {
在对main
不是有效签名的托管环境中。 它必须是以下之一:
int main(void)
int main(int argc, char *argv[])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.