因此,这是打印出给定数据集的垂直直方图的代码。 这里的数据在一个文件中,并且#34; H.in"用于在使用scanf时导入输入。输入的示例如下:
29
6 3 8 6 7 4 8 9 2 10 4 9 5 7 4 8 6 7 2 10 4 1 8 3 6 3 6 9 4
其中29是图表的数字,其余是需要转换为频率的数据。 检查程序保存数字,然后将其作为文件的输入。
基本上当我执行它时会出现分段错误。 现在我的理解是它是由于自由浮点或数组维度中的错误引起的......我试图搜索并解决问题,但我失败了,因为我找不到错误..
代码:
#include <stdio.h>
#include <stdlib.h>
//somewhere there is a segmentation fault.
int *readGrades(int num) {
int q;
int *grades[num];
for (q=0;q<num;q++){
scanf("%d",grades[q]);//this is taking input for each element and storing it
}
return *grades;
}
int arrayMax(int arr[]) {
int i, max = arr[0];
for (i=0; i < 9; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
void printHistogram(int freq[10], int *max)/*maxneeds to be added here?*/ {
int x,y, maxi;
maxi = *max;
for(x=0;x<maxi;x++){
for(y=0;y<10;y++){
if (freq[y] >= maxi){
printf("* ");
}
else{
printf(". ");
}
}
printf("\n");
}
printf("1 2 3 4 5 6 7 8 9 10 \n");
}
void computeFrequencies(int *grades[]) {
int a;
int freq[10]={0,0,0,0,0,0,0,0,0,0};
for(a=0;a<(sizeof(*grades)/sizeof(*grades[0]));a++){
switch(*grades[a]){
case 1:
freq[0]= freq[0]+1;
break;
case 2:
freq[1]= freq[1]+1;
break;
case 3:
freq[2]= freq[2]+1;
break;
case 4:
freq[3]= freq[3]+1;
break;
case 5:
freq[4]= freq[4]+1;
break;
case 6:
freq[5]= freq[5]+1;
break;
case 7:
freq[6]= freq[6]+1;
break;
case 8:
freq[7]= freq[7]+1;
break;
case 9:
freq[8]= freq[8]+1;
break;
case 10:
freq[9]= freq[9]+1;
break;
}
}
int *u;
*u = arrayMax(freq);
printHistogram(freq, *(&u));
}
int main(int argc, char *argv[]) {
int *grades;
int num;
scanf("%d",&num);/* this is the number of numbers*/
grades = readGrades(num);
computeFrequencies(&grades);
return 0;
}
答案 0 :(得分:1)
在您的函数中
computeFrequencies(int *grades[])
行
for(a=0;a<(sizeof(*grades)/sizeof(*grades[0]));a++){
不会做你认为会做的事情,sizeof(*等级)给你一个int ptr的大小,因为* grades []会衰减成一个int **指针。
而是将数组的大小作为单独的参数传递
computeFrequencies(int *grades[], size_t gradeArraySize)
更严重的是,此函数返回局部变量的地址:
int *readGrades(int num)
{
int q;
int *grades[num];
for (q=0;q<num;q++){
scanf("%d",grades[q]);//this is taking input for each element and storing it
}
return *grades;
}
返回你需要的数组,通常需要分配内存并返回一个指向它的内存,或者将内存传递给存储器,将值存储为具有一些最大大小的参数,或者如果值的数量大于适合的值则分配然后重新分配进入内存块。
在你的情况下,最简单的是给出最大尺寸(例如,未编译)
size_t readGrades(size_t maxgrades, int *grades)
{
// use fgets to read from the keyboard
int actualSize = 0;
char buffer[128];
if (fgets( buffer, sizeof(buffer), stdin ) != NULL && actualSize < maxgrades)
{
for (char* p = strtok(buffer, " "); p != NULL; p = strtok(NULL, " ")
{
grades[actualSize++] = atoi(p); // convert to number
}
}
return actualSize;
}
关于开关,它可以重写为
for (int i = 0; i < gradeArraySize; ++i)
{
freq[ grades[i] - 1 ]++;
}
如果成绩为1-10,而freq被声明为int freq[10] = {0};
<强> EDIT2 强>
如果要从函数返回数组,可以通过以下几种方式完成。
最简单但效率最低的方法是返回数组的副本:
typedef struct
{
int grades[100];
} returnarray;
returnarray foo()
{
returnarray ar;
ar.grades[0] = 42;
...
return ar;
}
或更有效
int foo(int **array)
{
...
size_t size = 10;
*array = malloc( size * sizeof(int) ); // changing what array points to
...
*array[0] = 42; // assigning an int in the array
...
return size;
}
<强> EDIT3 强>
要返回具有动态大小的数组,您可以像这样写
char** getLines()
{
const int maxLineLength = 32;
char** lines = malloc( 11 * sizeof(char*) ); // note the extra pointer 10+1
for (int i = 0; i < 10; ++i)
{
lines[i] = malloc( maxLineLength );
strcpy( lines + i, "hello" );
}
lines[10] = NULL;
return lines;
}
呼叫者
char** lines = getLines();
for (int i = 0; lines[i] != NULL; ++i)
{
puts( lines[i] );
}