I tried to do something by combining functions, arrays and pointers, but I got this error, I couldn't figure out why, I would appreciate if you could help.
double findaverage(int howmany, *int grades[]);
#include <stdio.h>
double findaverage(int howmany, *int grades[]) {
int i;
int sum = 0;
for (i = 0; i < howmany; i++) {
sum = grades[i] + sum;
}
return sum / howmany;
}
int main()
{
const int size = 5;
int grades[5] = {30,56,23,44,45};
int average= findaverage(size, grades);
printf("%d", average);
return 0;
}
My interpretation on how to transform the comments into code.
removed obsolete prototype definition (it is obsolete due to function call order)
renamed function from findaverage to calculate_average due to what it does
changed *int grades[] to int grades[]
moved iterator declaration (int i) into loop as it is not used outside of the loop
changed type of sum from int to double
used += operation instead of sum = sum + ..., to keep the code short and expressive
changed type of average from int to double
added helper function to print input array
changed output type format, added two digital places and newline to output of average
add pointer versions of calculate_average to illustrate/clarify differences
The original data are structured as array. Therefore, they should be accessed in array style. Nevertheless, it is possible to process them in pointer style. See also the answers to What is the difference between char array and char pointer in C? for clarification.
calculate_average.c
#include <stdio.h>
double calculate_average(int howmany, int grades[]) {
double sum = 0.0;
for (int i = 0; i < howmany; i++) {
sum += grades[i];
}
return sum / howmany;
}
double calculate_average_pointers(int howmany, int *grades) {
double sum = 0.0;
for (int i = 0; i < howmany; i++) {
// calculate position of next int in memory 'grades + i' and
// retrieve int from it with dereference operator '*'
sum += *(grades + i);
}
return sum / howmany;
}
// working but bad mix of semantics, array as paramter, pointer arithmetic inside
double calculate_average_pointers_2(int howmany, int grades[]) {
double sum = 0.0;
for (int i = 0; i < howmany; i++) {
sum += *(grades + i);
}
return sum / howmany;
}
void print_array(int howmany, int grades[]) {
printf("[");
for (int i = 0; i < howmany; i++) {
char *comma_or_not = i < howmany - 1? "," : "";
printf(" %d%s", grades[i], comma_or_not);
}
printf(" ]\n");
}
int main()
{
const int size = 5;
int grades[5] = {30, 56, 23, 44, 45};
printf("Input: ");
print_array(size, grades);
double average = calculate_average(size, grades);
printf("Average: %.2lf\n", average); // two decimal places
average = calculate_average_pointers(size, grades);
printf("Average (pointers): %.2lf\n", average); // two decimal places
average = calculate_average_pointers_2(size, grades);
printf("Average (pointers 2): %.2lf\n", average); // two decimal places
return 0;
}
$ gcc -Wall calculate_average.c
$ ./a.out
Input: [ 30, 56, 23, 44, 45 ]
Average: 39.60
Average (pointers): 39.60
Average (pointers 2): 39.60
$
Related
When running this program using pointers and arrays to calculate the grade point average from the user input, it outputs a garbage value. How can I alter the code so that the output is correct?
void Insert_Grades(int *array)
{
int grades[4];
int i;
for (int i = 0; i < 4; i++)
{
printf("Enter grade %d: ", i + 1);
scanf("%d", &grades[i]);
}
array = grades;
}
void Calculate_Avg(int *array)
{
int i;
float avg;
float sum = 0;
for (i = 0; i < 4; i++)
{
sum += *(array + i);
}
avg = sum / 4;
printf( "Grade point average is: %f ", avg);
}
int main()
{
int grades[4];
int i;
printf("Enter the number of grades:\n");
Insert_Grades(grades);
Calculate_Avg(grades);
printf("\n");
return 0;
}
you cant assign arrays.
This operation assigns local pointer array with reference of the local array grades. For the extral world this operation means nothing.
array = grades;
You need to copy values instead.
memcpy(array, grades, sizeof(grades));
or
for (size_t index = 0; index < 4; index++)
array[index] = grades[index];
There are multiple problem in your code:
in function Insert_Grades, value are read into the local array grades. The last instruction array = grades has no effect because it only modifies the argument value, which is just local variable, a pointer to int that now points to the first element of grade array.
This explains why the program outputs garbage because the array grades defined in the main() function is uninitialized and is not modified by Insert_Grades().
You could copy the array grade to the caller array pointed to by array, but it seems much simpler to use the array pointer to read the values directly where they belong.
the variable i is defined multiple times, with nested scopes.
you should test the return value of scanf() to detect invalid or missing input.
Here is a modified version:
#include <stdio.h>
void Insert_Grades(int *array, int count) {
for (int i = 0; i < count; i++) {
printf("Enter grade %d: ", i + 1);
if (scanf("%d", &array[i]) != 1) {
fprintf(stderr, "invalid input\n");
exit(1);
}
}
}
float Calculate_Avg(const int *array, int count) {
float sum = 0;
for (int i = 0; i < count; i++) {
sum += array[i];
}
return sum / count;
}
int main() {
int grades[4];
int count = sizeof(grades) / sizeof(*grades);
float avg;
printf("Enter the grades:\n");
Insert_Grades(grades, count);
avg = Calculate_Avg(grades, count);
printf("Grade point average is: %.3f\n", avg);
return 0;
}
I am new to programing.
I'm doing an exercise witch the user inserts numbers in an array and the program prints the average of those numbers.
But part of the exercise is making the numbers that the user inserts using a function, and thats where i'm struggling.
my code:
#include <stdio.h>
main() {
int n = 10, i, array1[10];
float sum = 0.0, average;
printf("insert 10 numbers\n");
for (i = 0; i < n; ++i) {
printf("insert digit no%d: ", i + 1);
scanf("%d", &array1[i]);
sum += array1[i];
}
average = sum / n;
printf("average = %.2f", average);
return 0;
}
all the help is much apreciated :)
Here's a small program to show you how functions work:
#include "stdio.h"
void foo(int array[], int size)
{
for (int i = 0; i < size; i++)
scanf("%d", &array[i]);
}
size_t bar(int array[], int size)
{
int sum = 0;
for (int i = 0; i < size; i++)
sum += array[i];
return (sum);
}
int main(void)
{
int array[3] = {0};
int sum;
foo(array, 3);
sum = bar(array, 3);
printf("array sum = %d\n", sum);
return (0);
}
foo and bar are two functions, they both have a return type on the left side, a name (foo/bar), some parameters in the parentheses, and their body declaration between braces.
When you call a function from your main, you'll have to call it with its required parameters. In my exemple, both functions need an integer array, and an integer value as parameters. That's why we called it this way from the main: foo(array, 3); and bar(array, 3).
When we call a function, the given parameters are copied into memory so you can work with those params into the function body as if they were variables.
Some functions have a return type different than void. Those functions are able to (and must) return a value of the return type with the return statement. Those values can be used, assigned etc, as you can see with the instruction sum = bar(array, 3);
Even the main is a function !
If you want to move user input and average calculation into separate methods. It should be done something like this.
#include <stdio.h>
/*
* Takes an array and get input for N items specified
*/
void getUserInputForArray(int array[], int N) {
printf("insert %d numbers\n", N);
for (int i = 0; i < N; ++i) {
printf("insert digit no %d: ", i + 1);
scanf("%d", &array[i]);
}
}
/*
* Calculate average for a given array of size N
*/
float getAverage(int array[], int N) {
// Initialize sum to 0
float sum = 0.0f;
// Iterate through array adding values to sum
for (int i = 0; i < N; i++)
sum += array[i];
// Calculate average
return sum / N;
}
int main() {
int n = 10, array1[10];
// Pass array to method, since arrays in C are passed by pointers.
// So Even if you modify it in method it would get reflected in
// main's array1 too
getUserInputForArray(array1, n);
// Calculate Average by delegating average calculation to getAverage(...) method
float average = getAverage(array1, n);
printf("average = %.2f", average);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
float Findaverage(float n,float numbers[]) {
float sum = 0;
for (int j = 0; j < n; j++) {
sum += numbers[j];
}
printf("The average number of the array is: %f", sum/n);
}
int main() {
int sum = 0;
float numbers[50];
float average;
printf("Enter 50 elements: ");
// taking input and storing it in an array
for(int i = 0; i < 50; ++i) {
scanf("%f", &numbers[i]);
}
average = Findaverage(50,numbers[50]);
printf("\nThe average number of the array is: %f", average );
return 0;
}
The output gives an error "passing 'float' to parameter of incompatible type 'float *'; take the address with &". Why is this?
For starters the function Findaverage returns nothing.
You need to add this statement to the function
return sum / n;
And the first parameter shall have an integer type instead of the type float.
float Findaverage(float n,float numbers[]) {
^^^^^
Secondly in this call of the function
average = Findaverage(50,numbers[50]);
the argument numbers[50] having the type float instead of the type float * is invalid. You need to write
average = Findaverage(50,numbers);
The function can be declared and defined the following way
double Findaverage( const float numbers[], size_t n )
{
double sum = 0.0;
for ( size_t i = 0; i < n; i++ )
{
sum += numbers[i];
}
return n == 0 ? 0.0 : sum / n;
}
And the function can be called like
double average = Findaverage( numbers, sizeof( numbers ) / sizeof( *numbers ) );
Change
average = Findaverage(50,numbers[50]);
to
average = Findaverage(50,numbers);
numbers[50] refers to a single array element, not the entire array. It's also one past the end of your array (which is indexed from 0 to 49).
I have written a method to take an array (via pointer) and its size to calculate the average. I am still relatively new to pointers. I have tried to remove the reference operator all throughout the code to the point at which it will compile, but the values returning are not intended. For instance, if I pass in an array size of 3, and then my array values are {1, 2, 3}, with my eyes closed I can tell you that that average should be 2. However my code returns 2.666666667. Thinking in reverse, I multiplied 2.6666...7 by 3, which equals 8. This leads me to think that I somewhere, a 2 is getting amended to the array, like {1,2,3,2}, however I'm unsure at this point. If anyone has any experience with pointers/simple arithmetic I'd appreciate your advice, because again, I am new to pointers and this idea of reference by address. Thanks!
double *Average(double *arr, int size)
{
double *avg;
avg = (double *)malloc(sizeof(double));
*avg = 0;
int i;
for (i = 0; i < size; i++)
{
*avg = *avg + arr[i];
}
*avg = *avg / (double) size;
printf("The average of the array: %f\n", *avg);
return avg;
}
How the method gets called from main:
else if (choice == 'C' || choice == 'c')
{
int count;
printf("How many numbers do you want to use in the array?\n> ");
scanf("%d", &count);
double *arr;
arr = (double *)malloc(sizeof(double) * count);
int i;
for (i = 0; i < count; i++)
{
printf("Please enter a number (%d of %d)\n> ", i + 1, count);
scanf("%lf", &arr[i]);
}
Min(arr, count);
Max(arr, count);
Average(arr, count);
}
Tests:
Average({1,3,5}, 3)
Expected: 3, Got: 4.333333
Average({1,1,1}, 3)
Expected: 1, Got: 1
Average({1,2,3,4,5,6,7,8,9}, 9)
Expected: 5, Got: 5.888889
Two extra methods per user request:
double *Min(double *arr, int size)
{
double *min = &arr[0];
int i;
for (int i = 1; i < size; i++)
{
if (arr[i] < *min)
{
*min = arr[i];
}
}
printf("Smallest number in array: %f\n", *min);
return min;
}
double *Max(double *arr, int size)
{
double *max = &arr[0];
int i;
for (int i = 1; i < size; i++)
{
if (arr[i] > *max)
{
*max = arr[i];
}
}
printf("Largest number in array: %f\n", *max);
return max;
}
Problem is here, correct this one:
*max = arr[i];
you're changing the *max which is arr[0] to the max or min of your array. So when Average() function gets the array, it's not the array you've input, it's changed. For example:
Max({1,3,5})=5
array becomes:
arr={5,3,5}
It's average correctly is:
Average({5,3,5} = 4.3333
I am bashing my head because I cannot figure out why my C code keeps printing the wrong average of a set of n numbers!
This is my code below:
int main()
{
int i;
int n;
int sum = 0.0;
int lowest;
int highest;
float average;
int range;
int middle;
double median;
printf("\nEnter the amount of numbers you want?\n");
scanf("%d",&n);
int numbs[n];
int temp[n];
for(i = 0;i < n; i++)
{
printf("\nEnter a number from 0 to 15: ");
scanf("%d",&temp[i]);
}
while (temp[i] < 0 || temp[i] > 15) than 15
{
printf("This number is not from 0 to 15! Please re-enter another number: ");
scanf("%d",&temp[i]);
}
numbs[i] = temp[i];
sum += numbs[i];
}
int sortt = 0, j, x;
for (x = 1; x < n; x++) {
for (j = 0; j < n - x; j++) {
if (numbs[j] > numbs[j + 1]) {
sortt = numbs[j];
numbs[j] = numbs[j + 1];
numbs[j + 1] = sortt;
}
}
}
lowest = numbs[0];
highest = numbs[n-1];
middle = n/2;
if (n % 2)
{
median = numbs[middle];
}
else
{
median = (numbs[middle - 1] + numbs[middle]) / 2.0;
}
average = sum/n;
range = highest - lowest;
printf("\nSum: %d", sum);
printf("\nAverage: %.2f", average);
printf("\nMedian: %.2f", median);
printf("\nRange: %d\n", range);
return 0;
}
This is my input and output below. You can see that 8 divided by 3 is not 2, it is 2.67! I've tried using double and float.
Input & Output:
You need to correct the following line:
average = sum/n;
to
average = (float)sum/n;
You have to cast your return value into float. Think about it as a function with the following definition:
float divide(int x,int y){
return x/y; // returns an integer instead of float.
}
While this definition:
float divide(int x,int y){
return (float)x/y; // creates a temporary float variable and returns it immediately as the returned value of the function.
}
In addition, declaring int sum=0.0 is definitely going to show you a warning when compiling with -Wall. Try to follow warnings that you get from your compiler and fix all of them before you run your program.
8 divided by 3 is 2, remainder 2. 8 and 3 are integers, and when you divide two integers, you use integer division with integer rules.
Also, this line might be confusing you:
int sum = 0.0;
Since sum is an int, this just sets sum to zero.
And:
average = sum/n;
Since both sum and n are integers, this is integer division. What you do with a result does not affect how that result is computed -- C's rules are complex enough already.
/*Here see you can intake all values as float instead */
#include <stdio.h>
#include <stdlib.h>
void main()
{
float i,n,a,b,sum,ave;
printf("This is a program to calculate the average of 'n' numbers \n");
printf("Of How many numbers do you want to calculate average \n");
scanf("%f", &n);
printf("Enter the first number \n");
scanf("%f", &a);
sum = a;
for (i=1;i<n;i++)
{
printf("Enter another number \n");
scanf("%f", &b);
sum = sum + b;
}
ave = (sum/n);
printf("The average of the %f number is %f", n, ave);
getchar();
}