繁体   English   中英

3 个不同的函数根据 C 中的变量类型提供相同的输出

[英]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  );


};
  1. 所有自动存储持续时间变量都需要在 C 中初始化。

  2. 你的部门整数运算,这也解释了全数字的结果。 使用1.f * sum / count习惯用法强制以浮点计算。

  3. printf int格式说明符%d %f用于floatdouble

  4. 虽然原则上可能有效,但从unsigned char值数组构造int数组会使您面临许多潜在的错误和未定义的行为。 特别是, unsigned char数组的对齐方式可能不适合您平台上的int ,您需要仔细计算元素的数量。 你似乎不会那样做。

  5. (不要对任何符号使用前导双下划线。它们是保留的。)

假设数组的数据类型与函数期望的匹配,这里有两个问题。

第一个是在您的打印功能中:

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  );
}

minimummaximum类型为int ,但您使用的是%f格式说明符,它需要一个double 使用错误的格式说明符会调用未定义的行为

使用%d打印 = 一个int

  printf( "The maximum is: %d\n", maximum  );
  printf( "The minimum is: %d\n", minimum  );

第二个问题是find_minimumfind_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM