What my program does is it finds 2 numbers of an array that are closest to the average, one is bigger, one is smaller. It works fine, however I need to change for example **array+a to *array[a].
However, when I load the program, it crashes after I input the numbers. If I try to print *array[0], *array[1], etc. it works fine. When I try to print or just do something with *array[a], *array[b], it crashes. Thank you for your help.
#include <stdio.h>
#include <stdlib.h>
int input (int *t, int *array[]);
void calculation (int *array[], int *t, int *x, int *y);
void output (int *x, int *y);
int main()
{
int *array, t, x, y;
input (&t, &array);
calculation (&array, &t, &x, &y);
output (&x, &y);
return 0;
}
int input (int *t, int *array[])
{ int n, *ptr;
printf ("How big is the array?");
scanf ("%d", &n);
ptr = (int*) malloc(n * sizeof(int));
int k;
printf ("Enter the numbers:");
for (k=0; k<n; k++)
{ scanf ("%d", ptr + k);
}
*t=n;
*array=ptr;
return 0;
}
void calculation (int *array[], int *t, int *x, int *y)
{ float sum=0, avg;
int min, max;
int more, less;
int a, b, c;
for (a=0; a<(*t); a++)
{sum=sum+ **array + a;
}
avg=sum/(*t);
min= *array[0];
max= *array[0];
for (b=0; b<(*t); b++)
{ if (max < (**array + b)) max=(**array + b);
if (min > (**array + b)) min=(**array + b);
}
more=max;
less=min;
for (c=0; c<(*t); c++)
{ if (((**array + c) < avg) && ((**array + c) > less)) less=(**array + c);
if (((**array + c) > avg) && ((**array + c) < more)) more=(**array + c);
}
*x=less;
*y=more;
}
void output (int *x, int *y)
{ printf("Number that is less than the average:%d\n", *x);
printf("Number that is more than the average:%d\n", *y);
}
It would be better to rethink your function prototypes a bit. It makes sense to pass a pointer to array to the input() function since you are allocating memory for it, and you want to be able to access it when you return. But you don't need to pass in the pointer to int t; instead, just return the value of n, and assign it to t in main.
There is no reason to pass a pointer to array to the function calculation(), since you are not changing the array allocation. You can also pass in the value of t from main(), since you only use this value in calculation(), but do not change it.
Similarly, the output() function only needs copies of x and y, since it does not change them.
The rule of thumb here is that you pass a pointer to a value into a function when you want to modify the value inside the function and have access to the modified value in the calling function. But you can also return a value instead of using a pointer to it.
These changes do not alter the functionality of your code, but they substantially improve its readability. You even get a sense of what is being modified in each function just by looking at the function prototypes. Well, the changes do alter the functionality in that your original **array + a was incorrect, and needed to be either *(*array + a) or (*array)[a]. But sorting that problem out should help you to appreciate the virtue of the simpler function prototypes. Here is the modified code:
#include <stdio.h>
#include <stdlib.h>
int input(int *array[]);
void calculation(int array[], int t, int *x, int *y);
void output(int x, int y);
int main(void)
{
int *array, t, x, y;
t = input(&array);
calculation(array, t, &x, &y);
output(x, y);
return 0;
}
int input(int *array[])
{ int n, *ptr;
printf("How big is the array?");
scanf("%d", &n);
ptr = (int*) malloc(n * sizeof(int));
int k;
printf("Enter the numbers:");
for (k=0; k<n; k++)
{ scanf("%d", ptr + k);
}
*array=ptr;
return n;
}
void calculation(int array[], int t, int *x, int *y)
{ float sum=0, avg;
int min, max;
int more, less;
int a, b, c;
for (a=0; a<t; a++)
{sum=sum+ array[a];
}
avg=sum/t;
min= array[0];
max= array[0];
for (b=0; b<t; b++)
{ if (max < array[b]) max=array[b];
if (min > array[b]) min=array[b];
}
more=max;
less=min;
for (c=0; c<t; c++)
{ if ((array[c] < avg) && (array[c] > less)) less=array[c];
if ((array[c] > avg) && (array[c] < more)) more=array[c];
}
*x=less;
*y=more;
}
void output(int x, int y)
{ printf("Number that is less than the average:%d\n", x);
printf("Number that is more than the average:%d\n", y);
}
Just like BLUEPIXY and Some programmer dude said, it's supposed to be (*array)[a]
Related
Only Value of 1st row of matrix is passing through Add().I am getting erroneous results.for Eg : matrix 1 has elements 1,2,3,4 .However when i print these values in add() ,I am getting 1,2,0,0.
#include <stdio.h>
int main()
{
int arr[100][100], arr1[100][100];
int m, n, x, y, z;
printf("\n Enter order of matrix");
scanf("%d %d ", &m, &n);
//ENTRY OF MATRIX
printf("\n Enter Values of Matrix 1");
for (x = 0; x < m; x++)
{
for (y = 0; y < n; y++)
scanf("%d ", &arr[x][y]);
}
printf("\n Enter Value of Matrix two ");
for (x = 0; x < m; x++)
{
for (y = 0; y < n; y++)
scanf("%d ", &arr1[x][y]);
}
add(m, n, arr, arr1);
return 0;
}
void add(int m, int n, int a[m][n], int b[m][n])
{
int x, y;
for (x = 0; x < m; x++)
{
for (y = 0; y < n; y++)
printf("%d ", a[x][y]);
printf("\n");
}
}
In C, functions must be declared before use and the type of the arguments must match between declaration and call.
In OP's code, a couple of 2D array declared as
int arr[100][100];
are passed to a function defined after main() as
void add(int m, int n, a[m][n], b[m][n]) { /* ... */ }
Generating two issues:
add() is used in main(), but it's not declared before, it's defined only after.
arr and arr1 are 2D arrays of 100 x 100 ints, but function add() as written, accepts two Variable Length Arrays of size m x n.
OP have two ways to fix, either they change the interface of the function and declare it before main(), like this:
void add(int m, int n, a[][100], b[][100]); // and define after main
Or change the declarations of arr and arr1:
// includes...
void add(int m, int n, a[m][n], b[m][n]);
int main(void)
{
int m, n;
// ...
// read n and m before using them to declare the two VLA
int arr[m][n], arr1[m][n];
// ...
add(m, n, arr, arr1);
// ...
}
void add(int m, int n, a[m][n], b[m][n])
{
// ...
}
First of all, please fix your indentation, it makes your code really hard to read.
This error is because you can't use a function that has not been declared.
To fix that, either add a prototype after your includes :
void add(int m,int n,int a[m][n],int b[m][n]);
Or try to put your whole function before your main.
I have fixed some problem in your code.I have added declaration before main().
void add(int m,int n,int a[m][n],int b[m][n]);
Also, I have removed the whitespace into scanf function.
int main()
{
int arr[100][100],arr1[100][100];
int m,n,x,y,z;
printf("\n Enter order of matrix");
scanf("%d %d",&m,&n);
//ENTRY OF MATRIX
printf("\n Enter Values of Matrix 1");
for(x=0;x<m;x++)
{
for(y=0;y<n;y++)
scanf("%d",&arr[x][y]);
}
printf("\n Enter Value of Matrix two ");
for(x=0;x<m;x++)
{
for(y=0;y<n;y++)
scanf("%d",&arr1[x][y]);
}
add(m,n,arr,arr1);
return 0;
}
void add(int m,int n,int a[m][n],int b[m][n])
{
// Your operation
}
I'm trying to separate my code more neatly by using functions. An issue I've been having is passing variables through different functions. If I leave all my code in my working function it will run no problem. It's when I create another function and pass variables to that function, that's when I get the issues.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main(void)
{
workings();
output();
}
void workings()
{
int x;
int i;
double total = 0;
double squareRoot;
double overall;
scanf("%d", &x);
int* array = malloc(x * sizeof(int));
if (!array) {
printf("There isn't enough memory \n");
return;
}
int j = 0;
while (j < x) {
scanf("%d", &array[j]);
total += array[j] * array[j];
j++;
}
squareRoot = sqrt(total);
}
void output(int x, double overall, double squareRoot, int* array)
{
int k = 0;
while (k < x) {
overall = array[k] / squareRoot;
printf("%.3f ", overall);
k++;
}
}
You must pass arguments to functions which require them.
Try this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void workings(int *x_out, double *squareRoot_out, int** array_out);
void output(int x, double squareRoot, int* array);
int main(void)
{
int x;
double squareRoot;
int* array;
workings(&x, &squareRoot, &array);
output(x, squareRoot, array);
}
void workings(int *x_out, double *squareRoot_out, int** array_out)
{
int x;
double total = 0;
double squareRoot;
scanf("%d", &x);
int* array = malloc(x * sizeof(int));
if (!array) {
printf("There isn't enough memory \n");
return;
}
int j = 0;
while (j < x) {
scanf("%d", &array[j]);
total += array[j] * array[j];
j++;
}
squareRoot = sqrt(total);
/* pass data for later use to callee */
*x_out = x;
*squareRoot_out = squareRoot;
*array_out = array;
}
void output(int x, double squareRoot, int* array)
{
double overall;
int k = 0;
while (k < x) {
overall = array[k] / squareRoot;
printf("%.3f ", overall);
k++;
}
}
Changes I made are:
Add prorotype declaretions of functions to be used before main() (where the functions are used).
This is for safety: compilers cannot check arguments before knowing declaretions nor definitions of functions.
Add arguments to workings() in order to export data used in the function.
Use the arguments to export data.
Remove variables overall and i in workings() because they weren't used.
Remove overall parameter from output() function and declare it as local variable because the input is not used.
Modify main() function to allocate memory for passing data and pass data between functions.
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.
I'm trying to write a program that dynamically allocates memory for an array, which the user then fills with integer values and the program sorts said integer values. However, it seems that my array isn't working as intended. I have managed to get the program working with a static array, but the dynamic allocation is causing me a lot of problems with incorrect values and whatnot. Here's what I have so far for the dynamically allocated version (if it would help you guys, I can also provide the version that uses a static array):
#include <stdio.h>
#include "genlib.h"
#include "simpio.h"
void sortArray (int *numbers, int i2);
int indexMax (int *numbers, int low, int high);
void swap (int *num1, int *num2);
int getArray (int *numbers);
void displayArray (int *numbers, int i2);
main()
{
int *numbers, i2;
i2=getArray(numbers);
sortArray(numbers, i2);
displayArray (numbers, i2);
}
int getArray (int *numbers)
{
int i, i2;
printf("Please enter the amount of elements you wish to sort: ");
i2=GetInteger();
numbers=(int *)malloc(i2*sizeof(int));
for(i=0;i<i2;i++, numbers++)
{
printf("Enter next integer: ");
*numbers=GetInteger();
printf("\n");
}
return(i2);
}
void displayArray (int *numbers, int i2)
{
int i;
printf ("\nThe sorted list is: \n\n");
for (i=0;i<i2;i++, numbers++)printf ("%d\n", *numbers);
}
void sortArray (int *numbers, int i2)
{
int i, minInd;
for(i=0;i<i2;i++)
{
minInd=indexMax(numbers, i, i2-1);
swap(&numbers[i], &numbers[minInd]);
}
}
int indexMax (int *numbers, int low, int high)
{
int i, maxInd;
maxInd=high;
for (i=high;i>=low;i--)
{
if(*(numbers+i)>*(numbers+maxInd)) maxInd=i;
}
return (maxInd);
}
void swap (int *num1, int *num2)
{
int temp;
temp=*num1;
*num1=*num2;
*num2=temp;
}
Here is a working solution:
#include <stdio.h>
#include <stdlib.h>
void sortArray (int *numbers, int i2);
int indexMax (int *numbers, int low, int high);
void swap (int *num1, int *num2);
int getArray (int **numbers);
void displayArray (int *numbers, int i2);
main()
{
int *numbers, i2;
i2=getArray(&numbers);
sortArray(numbers, i2);
displayArray (numbers, i2);
}
int getArray (int **numbers)
{
int i, i2;
printf("Please enter the amount of elements you wish to sort: ");
scanf("%d", &i2);
(*numbers) = malloc(i2 * sizeof(int));
int *temp = *numbers;
for(i = 0; i < i2; i++)
{
printf("Enter next integer: ");
scanf("%d", &temp[i]);
printf("\n");
}
return(i2);
}
void displayArray (int *numbers, int i2)
{
int i;
printf ("\nThe sorted list is: \n\n");
for (i=0;i<i2;i++, numbers++)printf ("%d\n", *numbers);
}
void sortArray (int *numbers, int i2)
{
int i, minInd;
for(i=0;i<i2;i++)
{
minInd=indexMax(numbers, i, i2-1);
swap(&numbers[i], &numbers[minInd]);
}
}
int indexMax (int *numbers, int low, int high)
{
int i, maxInd;
maxInd=high;
for (i=high;i>=low;i--)
{
if(*(numbers+i)>*(numbers+maxInd)) maxInd=i;
}
return (maxInd);
}
void swap (int *num1, int *num2)
{
int temp;
temp=*num1;
*num1=*num2;
*num2=temp;
}
The thing is in your main when you are declaring int *numbers , numbers pointer is pointing to some junk memory location as local variables can have any garbage value, so while you are passing this numbers pointer to getArray() function you are passing its value, Suppose numbers is pointing to some random value = 1234 and suppose address of numbers is = 9999. Now when you call getArray(numbers) you tell taht whatever is there in numbers pass it to getArray's numbers variable that we are letting is 1234.
Then when you allocate memory to numbers that is local variable of getArray() function not main's and it might have address suppose = 0x8888. Then malloc allocates some address space as specified and stores the start address of that allocated address space(suppose i.e. = 0x7777) into location 0x8888 not 0x9999 which is the adress of main's numbers variable.
Thus when the getArray function ends and next time you call sortArray you pass it value present in numbers variable of main which is still junk 1234. and the actual value you should be passing is present at address 0x8888.
Try this:
int main(void)
{
int *numbers, i2;
i2 = getArray(&numbers);
sortArray(numbers, i2);
displayArray (numbers, i2);
return 0;
}
int getArray (int **numbers)
{
int i, i2;
printf("Please enter the amount of elements you wish to sort: ");
i2 = GetInteger();
*numbers = malloc(i2 * sizeof int);
etc...
You simply need one more level of indirection to make int getArray(int**) return a pointer to an allocated array.
As an aside, you can use the C library function qsort() to do the sorting work for you. Here is an example:
int main(void)
{
int a[]={4,7,9,1,34,90,66,12};
qsort(a, sizeof(a)/sizeof(a[0]), sizeof(int), compare);
return 0;
}
int compare(const void *a, const void *b){
const int *x = a, *y = b;
if(*x > *y)
return 1;
else
return(*x < *y) ? -1: 0;
}
Works just as well with dynamically allocated int arrays, or char arrays
i have code to array of func pointer
#include <stdio.h>
int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int div(int a, int b);
int (*p[4]) (int x, int y);
int main(void)
{
int result;
int i, j, op;
p[0] = sum; /* address of sum() */
p[1] = subtract; /* address of subtract() */
p[2] = mul; /* address of mul() */
p[3] = div; /* address of div() */
printf("Enter two numbers: ");
scanf("%d %d", &i, &j);
printf("0: Add, 1: Subtract, 2: Multiply, 3: Divide\n");
do {
printf("Enter number of operation: ");
scanf("%d", &op);
} while(op<0 || op>3);
result = (*p[op]) (i, j);
printf("%d", result);
return 0;
}
int sum(int a, int b)
{
return a + b;
}
int subtract(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
if(b)
return a / b;
else
return 0;
}
code for array of pointer to function:
#include <stdio.h>
int sum(int, int);
int product(int, int);
int subtract(int, int);
int main()
{
int i = 0;
int a = 10;
int b = 5;
int result = 0;
int (*pfun[3])(int, int);
pfun[0] = sum;
pfun[1] = product;
pfun[2] = subtract;
for( i = 0 ; i < 3 ; i++)
{
result = pfun[i](a, b);
printf("\nresult = %d", result);
}
result = pfun[1](pfun[0](a, b), pfun[2](a, b));
printf("\n\nThe product of the sum and the subtract = %d\n",result);
}
int sum(int x, int y)
{
return x + y;
}
int product(int x, int y)
{
return x * y;
}
int subtract(int x, int y)
{
return x - y;
}
now how to combine this two program. such that array of pointers pointing to func pointers and the func pointers may have different number of args? any suggestion.
You not only need to store function pointers with a variable number of arguments (that is not very difficult, you could use a union for instance), but you also need to make sure you call the functions with the correct argument, and that is a bit trickier given your design.
I suggest to use a stack instead. All your functions would only take the stack as an argument:
void sum(stack_t *stack);
void subtract(stack_t *stack);
void product(stack_t *stack);
And your array could be declared this way:
typedef void callback_t(stack_t *);
callback_t *p[] =
{
sum,
subtract,
product,
/* ... */
};
Then for instance sum would be implemented as such:
void sum(stack_t *stack)
{
if (depth(stack) < 2)
perror("Not enough arguments in stack!");
int b = popstack(stack);
int a = popstack(stack);
int c = a + b;
pushstack(stack, c);
}
But unary minus would be implemented this way:
void neg(stack_t *stack)
{
if (depth(stack) < 1)
perror("Not enough arguments in stack!");
int a = popstack(stack);
pushstack(stack, -a);
}
Each function decides how many arguments they need. The caller does not need to know.