I'm working on a small program for school and can't get my array of doubles to sum properly. The specific error I'm getting is
warning C4244: 'return': conversion from 'double' to 'int', possible loss of data
on the line where sum is returned. And the sum displayed is gibberish.
The code is intended to:
fill an array of doubles with user input,
print the doubles on the screen in a column,
add up all the doubles in the array, and
print the sum onto the screen.
Code
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define MAX_SIZE 15
void FillArray(double a[], int *i);
void PrintArray(double a[], int i);
SumArray(double a[], int *i);
int main()
{
double input[15];
int input_size;
double sum;
FillArray(input, &input_size);
PrintArray(input, input_size);
sum = SumArray(input, &input_size);
printf("The sum is %f\n", sum);
return 0;
}
void FillArray(double a[], int *i)
{
int k;
printf("Filling an array of doubles\n");
printf("How many doubles do you want to enter (<15)\n");
scanf(" %d", i);
for (k = 0; k <*i; k++)
{
printf("Enter double:\n");
scanf("%lf", &a[k]);
}
}
void PrintArray(double a[], int i)
{
int k;
printf("Printing an array of integers:\n");
for (k = 0; k<i; k++)
{
printf("%f\n", a[k]);
}
printf("\n");
}
SumArray(double a[], int *i)
{
int k;
double sum = 0;
for (k = 0; k<*i; k++);
{
sum +=a[k];
}
return (sum) ;
}
You need to specify double SumArray(...) instead of merely SumArray(...) where you declare and define the function. If you do not specify a return type, int is assumed. Specifically:
void FillArray(double a[], int *i);
void PrintArray(double a[], int i);
double SumArray(double a[], int *i);
/*^^^^^^-- add return type*/
int main()
and
double SumArray(double a[], const int numElements)
/*^^^^^^- same deal*/ /* also ^^^^^ ^^^^^^^^^^^ */
{
int k;
double sum = 0.0; /* Edit 3: 0.0 rather than 0 for clarity */
for (k = 0; k < numElements; ++k) /* no ; here! --- Edit 3: ++k for speed and good practice */
{ /* ^^^^^^^^^^^ */
sum +=a[k];
}
return (sum) ;
}
Edit Also, you can use const int numElements instead of int *i in SumArray. You don't need to modify the value inside SumArray, so you don't need the * and you can specify const. And it's a good practice to give your variables descriptive names, e.g., numElements instead of i. That will help you understand your own code when you have to maintain it later! (Ask me how I know. ;) )
To use this, you also need to change the call in main to remove the &:
sum = SumArray(input, input_size);
/* ^ no & here */
Edit 2 As #BLUEPIXY pointed out, the trailing ; on the for loop was misplaced. As a result, the {} block ran once, after the loop had completed. That would be a significant cause of the "gibberish" you saw: the effect was to set k=numElements and then set sum=a[numElements], which was a non-existent element. So the sum was being set to whatever random memory contents happened to be after a.
Related
#include <stdio.h>
void avg_sum(double a[], int n, double *avg, double *sum)
{
int i;
sum = 0;
printf("%f", *sum);
for(i=0; i<n; i++)
*sum += a[i];
*avg = *sum/n;
}
int main()
{
double arr[2] = {0.0,1.0};
double *sum;
double *avg;
int n = 2;
avg_sum(arr, n, avg, sum);
printf("...Done...\n");
return 0;
}
Tried using both GCC(https://www.tutorialspoint.com/compile_c_online.php) and clang(from repl.it) online compilers
double *sum;
This creates a pointer to a double but it has an arbitrary value and therefore points at no dedicated memory.
In addition, in the called function, you set the sum pointer to zero (the null pointer) then try to use that pointer to dereference memory - that's a big non-no.
I'd also be wary of for(i=0; i<n-2; i++) for summing the values in the array. It's not going to include the final two which, since n is two, means it won't accumulate any of them.
The correct way to do this would be with:
void avg_sum(double a[], int n, double *avg, double *sum) {
int i;
*sum = 0; // set content, not pointer.
for(i=0; i<n; i++) // do all elements.
*sum += *(a+i);
*avg = *sum/n;
}
int main(void) {
double arr[2] = {0.0,1.0};
double sum; // ensure actual storage
double avg; // and here
int n = 2;
avg_sum(arr, n, &avg, &sum); // then pass pointers to actual storage
printf("Sum=%f, Avg=%f\n", sum, avg);
return 0;
}
This gives you, as expected:
Sum=1.000000, Avg=0.500000
Easy. In line 6 you assign 0 to sum but sum is not the actual sum but a pointer to it. When you try to print it you access invalid memory.
Edit:
BTW if you try compling with -fanalyzer you will get a warning and an explanation.
https://godbolt.org/z/W6ehh8
I am using gcc compiler in ubuntu18.10 os. And I don't know why this program is giving Error and Can't even understand the error. The Program is as follows and I presented ERRORS also.
#include<stdio.h>
#include<stdlib.h>
float Average(int*, int);
int main()
{
int *arr;
int n;
scanf("%d",&n);
float sum;
arr = (int *)malloc(n * sizeof(int));
for(int i=0;i<n;i++)
scanf("%d",&arr[i]);
sum = Average(int *arr, int n);
printf("%f\n",sum);
return 0;
}
float Average(int *arr, int size)
{
int sum;
int n = size;
printf("arr: %p\n",&arr);
printf("size: %p\n",&size);
printf("sum: %p\n",&sum);
for(int i=0;i<n;i++)
{
sum += arr[i];
}
return (sum * 1.0f) / size;
}
Errors are:
Test.c: In function ‘main’:
Test.c:16:16: error: expected expression before ‘int’
sum = Average(int *arr, int n);
^~~
Test.c:16:8: error: too few arguments to function ‘Average’
sum = Average(int *arr, int n);
^~~~~~~
Test.c:4:7: note: declared here
float Average(int*, int);
^~~~~~~
Please Help me to find out why and any reference materials to understand the concept clearly.
Thank you
sum = Average(int *arr, int n);
Type specifiers are something you give in the declaration and definition of the function, not in calls to it. You want:
sum = Average(arr, n);
Some other things you may want to check.
First, the int sum; in Average() does not initialise the value to zero, it sets it to some arbitrary value. That's not going to end well when you just add the integers to it. It should instead be:
int sum = 0;
Second, unless you're using massive arrays of floating point numbers, it's almost always better to use double for its greater range and precision.
Taking those into account, I probably would have written the function:
double Average(int *arr, int size) {
double sum = 0;
for (int i = 0; i < size; ++i)
sum += arr[i];
return sum / size;
}
When you call a function you don't specify the types of the arguments. That's a syntax error. If you look at where you call printf, you'll see that you don't specify the parameter types there. The same goes for your own functions.
So change this:
sum = Average(int *arr, int n);
To this:
sum = Average(arr, n);
My issue is that I am getting segmentation fault (core dumped) each time I try, I have yet to clean up my code, but I am stumped.
I must enter the values in with the compiler e.g "./filename 0 100" whereby 0 is min and 100 is max.
It must then fill the array of 10 elements with random numbers (0-100). I am so close, just can't fathom the main function.
Also, how can I print the array {0,1,2,3} in format "[0,1,2,3]" including the commas, without it looking like "[0,1,2,3, ]"
#include <stdlib.h>
#include <stdio.h>
int getRandom(int min, int max);
void fillArray(int data[], int size, int min, int max);
void printArray(int data[], int size);
int main(int argc, char *argv[]) {
int a;
int b;
if (argc>=3){
a = atoi(argv[1]);
b = atoi(argv[2]);
int arr[10];
printf("\t An array with random values from 0 to 100 \n");
fillArray(arr,10 ,a, b);
printArray(arr, 10);
} else {
printf("Incorrect number of arguments - please call with assignment min max\n");
}
return 0;
}
int getRandom(int min, int max) {
int result = 0;
int low = 0;
int high = 0;
if (min<max) {
low = min;
high = max+1;
} else {
low = max + 1;
high = min;
}
result = (rand() % (high-low)) + low;
return result;
}
void fillArray(int data[], int size, int min, int max){
int i;
for(i=min ; i < max+1; i++){
data[i] = getRandom(min,max);
}
}
void printArray(int data[], int size){
int i;
printf("[");
for(i=0; i<size; i++){
printf("%d,", data[i]);
}
printf("]");
}
I agree with #Steve Friedl that the main problem with your program lies in the fillArray function. There i should run from 0 to size.
As for your second question, testing whether you're printing the last number helps to suppress the unwanted comma:
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d", data[i]);
if (i < size - 1)
printf(",");
}
printf("]");
}
If you prefer a more compact solution (although with an optimizing compiler there's not really a difference), you could write it as:
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d%c", data[i], i < size-1 ? ',' : ']');
}
}
Also, in your main function, you should include a and b in your printing:
printf("\t An array with random values from %d to %d \n", a, b);
I believe this is blowing things up for you:
void fillArray(int data[], int size, int min, int max){
int i;
for(i=min ; i < max+1; i++){ // <-- HERE
data[i] = getRandom(min,max);
}
}
The calling function allocates 10 items in the arr array, and that's passed as the size parameter, but you're not using that parameter to limit filling up the array. If the max value is 100, then it's trying to fill one hundred slots instead of just ten.
for (i = 0; i < size; i++)
data[i] = getRandom(min,max);
should fix at least this issue.
EDIT: The comma thing, I prefer to add commas before the items unless this is the first. In this case it doesn't matter much, but it's more general, especially for variable-length lists where you don't know you're at the end until you get there. Augmenting the helpful response from #JohanC :
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
if (i > 0) printf(",");
printf("%d", data[i]);
}
printf("]");
}
I was given an assignment to write a code which takes in numbers as input from the user and provides the sum of it, specifically by the use of pointer arithmetic i.e. no array subscripting a[i] is allowed.
Below is the code that I wrote, which got compiled and even ran. But almost always it gives the sum of the input numbers as 0. I tried to fix it, but to no avail. Thus, I am asking for help, any help is greatly appreciated.
#include<stdio.h>
#define N 5
int sum_array( const int *p, int n)
{
int sum, a[N];
sum = 0;
for(p=&a[0]; p<&a[N]; p++)
sum += *p;
return sum;
}
int main()
{
int a[N], *i,x;
printf("Enter %d Numbers: ", N);
for(i=a; i<a+N; i++)
scanf("%d", i);
// all the input values get scanned as i or the array a
x= sum_array(i,N);
printf("the sum is %d\n", x);
return 0;
}
Beware, you are declaring array int a[N] in both main and sum_array. They are in different scopes, so they are different arrays (and the one from sum_array is never initialized so reading it invokes Undefined Behaviour).
The correct way is to pass the array along with its used length:
Here is a fixed version:
#include<stdio.h>
#define N 5
int sum_array( const int *a, int n) // a points to a array of at least n elements
{
int sum = 0; // initialize at definition time
for(const int *p=a; p<&a[n]; p++) // have the pointer p take all values from a
sum += *p;
return sum;
}
int main()
{
int a[N], *i,x;
printf("Enter %d Numbers: ", N);
for(i=a; i<a+N; i++)
scanf("%d", i);
// all the input values get scanned as i or the array a
x= sum_array(a,N); // pass the array address, not a pointer past last element
printf("the sum is %d\n", x);
return 0;
}
Finally it is mainly a matter of taste, but I was too often burnt for trying to add an instruction in a for loop without braces, so I strongly recommend using always braces for loops:
for(i=a; i<a+N; i++) {
scanf("%d", i);
}
int sum_array( const int *p, int n)
{
int sum = 0, i = 0;
for(i = 0; i < n ; i++)
sum += *(p+i);
return sum;
}
int main(void)
{
int a[N], i = 0, x = 0;
printf("Enter %d Numbers: ", N);
for(i=0; i<N; i++)
scanf("%d", a+i);
// all the input values get scanned as i or the array a
x= sum_array(a,N);
printf("the sum is %d\n", x);
return 0;
}
In x= sum_array(i,N); i is the iterator of your loop so after the loop has finished it points to the first position after the array.
You should pass the original array instead x= sum_array(a,N);
In the sum function you just throw away the passed pointer and replace it with your local a[].
int sum_array( const int *p, int n)
{
int sum = 0;
int *end = &p[n]; // first element after the array.
for(; p<end; p++) // just use p because you don't need the reference to the start of the array
{
sum += *p;
}
return sum;
}
but as you said that array notation is not allowed you can change it as follows
#include "stdio.h"
#define N 5
int sum_array( const int *p, int n)
{
int sum = 0;
const int *end = p+n; // first element after the array.
for(; p<end; p++)
{
sum += *p;
}
return sum;
}
int main()
{
int *a, *i, x;
a = malloc(N * sizeof(*a));
if (a == NULL)
exit(-1);
printf("Enter %d Numbers: ", N);
for(i=a; i<a+N; i++)
{
scanf("%d", i);
}
// all the input values get scanned as i or the array a
x= sum_array(a,N); // pass the array address, not a pointer past last element
printf("the sum is %d\n", x);
return 0;
}
in general, when programming, the code should be kept as simple as possible while still being complete.
The program criteria shows no need to keep a number after it is applied to the sum of the numbers, So in the proposed code, the input number is only kept long enough to be applied to the sum, then it is discarded.
The following proposed code:
cleanly compiles
performs the desired functionality
is kept very simple
properly checks for; and handles any errors
And now the proposed code:
#include <stdio.h> // scanf(), printf(), fprintf(), stderr
#include <stdlib.h> // exit(), EXIT_FAILURE
#define N 5
int main( void )
{
int num = 0;
int sum = 0;
printf("Enter %d Numbers: ", N);
for(size_t i=0; i<N; i++)
{
if( scanf("%d", &num) != 1 )
{
fprintf( stderr, "failed to read number\n" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
sum += num;
}
printf( "the sum is %d\n", sum );
return 0;
}
i wanted to create a function that reverses the contents of an array of double in C but its not working
My function is not returning the reversed array? Please help
//Reverse the content of an array of double
#include<stdio.h>
#define SIZE 5
double *reverse(double *func[],int n);
int main()
{
int i;
double *arr[SIZE];
printf("Please enter 5 numbers\n");
for(i=0;i<SIZE;i++) {
scanf("%lf",arr[i]); // takes the the content of array
}
double arr = reverse(&arr,SIZE); // takes the return value from the function
for(i=0;i<SIZE;i++) {
printf("%.2lf\n",arr[i]);
}
}
double *reverse(double *func[],int n)
{
int i,j;
static double *base[SIZE];
for(i=4,j=0;i>=0,j<n;i--,j++) {
base[j] = func[i]; // reverses the content of array
}
return *base;
}
I guess there is a problem in my function, but i am not able to find it
There are a number of issues with your code. Most important this:
double *arr[SIZE];
That is not an array of double (it is an array of pointers to double). That misunderstanding seem to go through all the program and cause several other mistakes.
For instance this:
scanf("%lf",arr[i]);
Here arr[i] is an uninitialized pointer so scanning into it is undefined behavior.
Further, your function call suffers from the array mistake as well.
A more correct version of your code could be:
#include<stdio.h>
#define SIZE 5
void reverse(double* d, int n);
int main()
{
int i;
double arr[SIZE]; // Array of double
printf("Please enter %d numbers\n", SIZE);
for(i=0;i<SIZE;i++)
{
scanf("%lf", &arr[i]); // TODO: Check scanf return value....
// ^ Notice the & (i.e. address-of)
}
reverse(arr, SIZE); // Just pass arr as it will decay into a double pointer
for(i=0;i<SIZE;i++)
{
printf("%.2lf\n",arr[i]);
}
return 0;
}
void reverse(double* d, int n) // Just pass a pointer to first double in the array
{
int i, j=0;
double temp;
for(i=n-1; i>j; i--,j++) // Stop when you reach the middle of the array
{
// Swap using a temp variable
temp = d[j];
d[j] = d[i];
d[i] = temp;
}
}
void reverse(double *arr,int n)
{
for(int i=0;i<n/2;i++)
{
double temp = arr[i];
arr[i] = arr[n-i-1];
arr[n-i-1] = arr[i];
}
}