The following code block is only part of a larger one. In the program, I want to find the definite integral of a polynomial that needs to be inputted by the user.
I'm new to C and so I'm having a hard time trying to learn the syntax with regards to pointers. I find them very confusing.
So if you'll look at the code block below, I want to print the elements contained in the array coefficients just so I can see if the elements inputted are being stored in the array but to no avail. The program just terminates after the inputCoeffs() function.
#include <stdio.h>
#include <stdlib.h>
void inputDegree(int *deg) {
printf("Enter the degree of the polynomial: \n");
scanf("%d", *°);
}
void inputCoeffs(int deg, double *coeffs) {
printf("Enter the coefficients of the polynomial (A, B, C,...): \n");
for(int i = 0; i <= deg; i++) {
scanf("%lf", &coeffs[i]);
}
}
int main() {
int i;
int degree;
double lowerLimit;
double upperLimit;
double integral;
double *coefficients = NULL;
double *integralCoefficients = NULL;
inputDegree(°ree);
coefficients = (double*)malloc((degree + 1) * sizeof(double));
integralCoefficients = (double*)malloc((degree + 1) * sizeof(double));
inputCoeffs(degree, &coefficients);
for(i = 0; i <= degree; i++) {
printf("\t%lf\n", coefficients[i]);
}
return 0;
}
In this call
scanf("%d", *°);
it is enough to write
scanf("%d", deg);
It is unclear why you are allocating memory one element greater than the value of degree.
coefficients = (double*)malloc((degree + 1) * sizeof(double));
In this case the allocated array has degree + 1 elements.
The type of the second argument in this call
inputCoeffs(degree, &coefficients);
is invalid. There shall be
inputCoeffs(degree, coefficients);
The & operator is used to get a pointer to an existing variable, while * is used to dereference a pointer. Therefore
inputCoeffs(degree, &coefficients);
Makes no sense, because coefficients is already a pointer. inputCoeffs
accepts a pointer so you can just write
inputCoeffs(degree, coefficients);
Since the & and * operators basically do the opposite, this line
scanf("%d", *°);
is not an error, but could also just be written as
scanf("%d", deg);
Also, you should call free when ever you use malloc, so add to the end of the code:
free(coefficients);
free(integralCoefficients);
Related
This question already has answers here:
Can a const variable be used to declare the size of an array in C?
(5 answers)
Closed 10 months ago.
It is saying that the variable p in the final function int main needs to be a constant but I attempted to change it to a constant and it still didn't run. Any recommendations on ways to fix it?
#define _CRT_SECURE_NO_WARNINGS // Disable warnings (and errors) when using non-secure versions of printf, scanf, strcpy, etc.
#include <stdio.h> // Needed for working with printf and scanf
// defining a function to read input
void input(double* array, int p) {
// looping p times to read p values from user
for (int i = 0; i < p; i++) {
printf("Enter a value for #%d: ", i + 1);
scanf("%lf", &array[i]);
}
}
double processing(double* array, int p) {
// defining a variable to store sum of all values
double sum = 0;
// looping over p values in the array
for (int i = 0; i < p; i++) {
sum += array[i];
}
// return average = sum / size of array
return sum / p;
}
void output(double average) {
// displaying average of all the values
// displaying only one decimal point as given
printf("The average of the values is %.1lf\n", average);
}
int main(void) {
// Constant and Variable Declarations
// defining size and initializing it to 10 as mentioned
int p = 10;
// size of p
double array[p];
input(array, p);
double average = processing(array, p);
output(average);
return 0;
} // end main() '''
Maybe you could call your function so instead of making P a variable:
input(array, 10);
sorry if it doesnt work im new to c as well
The goal of the exercise is to calculate a complex number Z according to some formula and create an array of n such complex numbers. Here's the function that calculates Z
double complex convert(double R, int p)
{
double complex Z=0+0*I;
double complex A, B, C;
A=exp(M_PI/4) + 0*I;
B=cos(11*M_PI/6 + 2*p*M_PI) + 0*I;
C=I*sin(R*M_PI/6);
Z=A*((R*B)+C);
return Z;
}
The function that creates the array:
double complex *array_function (double *a, int n)
{
int i;
double complex array[100];
for (i=0; i<n; i++)
{
array[i]=convert(*(a+i),i);
}
return array;
}
And int main:
int main()
{
int N, i;
double complex *new_array[100];
double array[100];
printf("Enter the length of the array = ");
scanf("%d", &N);
for (i=0; i<N; i++)
{
printf("Element number %d is: ", i+1);
scanf("%f", &array[i]);
}
new_array=array_function(array, N); // where I get the error message
printf("The new array is: \n");
for (i=0; i<N; i++)
{
printf("%f + i%f \n", creal(new_array[i]), cimag(new_array[i]));
}
return 0;
}
But I keep getting the same error message: "assignment to expression with array type" in regards to the line: "new_array=array_function(array, N);"
Edit: Here's the edited code:
double complex convert(double R, int p)
{
double complex Z=0+0*I;
double complex A, B, C;
A=exp(M_PI/4) + 0*I;
B=cos(11*M_PI/6 + 2*p*M_PI) + 0*I;
C=I*sin(R*M_PI/6);
Z=A*((R*B)+C);
return Z;
}
double complex *array_function (double *a, int n)
{
int i;
double complex *array = malloc(100 * sizeof *array);
for (i=0; i<n; i++)
{
array[i]=convert(*(a+i),i);
}
return array;
}
int main()
{
int N, i;
double complex *new_array;
double array[100];
printf("Enter the length of the array = ");
scanf("%d", &N);
for (i=0; i<N; i++)
{
printf("Element number %d is: ", i+1);
scanf("%f", &array[i]);
}
new_array=array_function(array, N); // where I get the error message
printf("The new array is: \n");
for (i=0; i<N; i++)
{
printf("%f + i%f \n", creal(new_array[i]), cimag(new_array[i]));
}
return 0;
}
You cannot assign to arrays in C. You can only assign to array elements.
If you want to change arrays dynamically, declare a pointer of the appropriate type and assign the result of malloc and/or realloc.
If you have made the changes to insure you are reading doubles with scanf by adding the 'l' modifier to your %f format specifier (e.g. "%lf") and you have fixed your attempt to return a statically declared array, by declaring a pointer in main() to which you assign the return from array_function, and properly allocated the array in array_function, then your code should be working without crashing. Also, M_PI should be properly typed as double eliminating the integer division concern.
You must VALIDATE ALL USER INPUT (sorry for all caps, but if you learn nothing else here, learn that). That means validating the return of scanf and checking the range of the value entered where appropriate.
Putting those pieces together, you could do something like the following (with the code sufficiently spaced so old-eyes can read it):
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include <math.h>
#define MAXC 100 /* if you need a constant, define one */
double complex convert (double R, int p)
{
double complex Z = 0 + 0 * I; /* space your code so it is readable */
double complex A, B, C; /* (especially for older eyes......) */
A = exp (M_PI / 4.0) + 0 * I;
B = cos (11 * M_PI / 6.0 + 2 * p * M_PI) + 0 * I;
C = I * sin (R * M_PI / 6.0);
Z = A * ((R * B) + C);
return Z;
}
double complex *array_function (double *a, int n)
{
int i;
double complex *array = calloc (MAXC, sizeof *array); /* allocate */
if (!array) { /* validate allocation succeeded */
perror ("calloc-array");
exit (EXIT_FAILURE);
}
for (i = 0; i < n; i++) /* convert your values */
array[i] = convert (a[i], i);
return array; /* return pointer */
}
int main (void)
{
int N, i;
double complex *new_array; /* declare pointer to receive return */
double array[MAXC];
printf ("Enter array length: ");
if (scanf("%d", &N) != 1 || N > MAXC) { /* VALIDATE ALL USER INPUT */
fprintf (stderr, "error: invalid input or out of range.\n");
return 1;
}
for (i=0; i<N; i++) {
printf (" enter array[%2d]: ", i);
if (scanf("%lf", &array[i]) != 1) { /* VALIDATE ALL USER INPUT */
fprintf (stderr, "error: invalid conversion, array[%d].\n", i);
return 1;
}
}
new_array = array_function (array, N); /* call array_function */
printf("\nThe new array is: \n\n");
for (i=0; i<N; i++) /* output results */
printf (" %10.6f + i%f \n", creal(new_array[i]), cimag(new_array[i]));
free (new_array); /* don't forget to free memory you allocate */
return 0;
}
(note: you should free all memory you allocate)
Example Use/Output
$ ./bin/complex
Enter array length: 5
enter array[ 0]: 1.81
enter array[ 1]: 1.97
enter array[ 2]: .31
enter array[ 3]: 2.51
enter array[ 4]: 6.021
The new array is:
3.43798 + i1.781127
3.74189 + i1.881977
0.58883 + i0.354442
4.76758 + i2.121489
11.43651 + i-0.024116
Look things over and let me know if you have further questions.
double complex *new_array[100]; declares new_array to be an array of 100 pointers to double complex. That is not what you want. You merely want a pointer to double complex (which will point to the first element of an array that is provided by the function). The declaration for this is double complex *new_array;.
However, in array_function, you attempt to return array, where array is defined inside the function with double complex array[100];. That declaration, when used inside a function, declares an array that lasts only until the function returns. If you return its address (or the address of its first element), the pointer to that address will be invalid.
The proper way to return a new array from a function is to dynamically allocate the array, as with:
double complex *array = malloc(100 * sizeof *array);
if (!array)
{
fprintf(stderr, "Error, failed to allocate memory.\n");
exit(EXIT_FAILURE);
}
… // Assign values to the array elements.
return array;
Then the caller is responsible for releasing the array at some later time, by passing the address to the free routine.
(To use malloc, free, and exit, add #include <stdlib.h> to your program.)
If you want to let the array_function create the content of new_array, you can send the array pointer as a parameter to the function, and let the function use that. You also need to change the definition of new_array to double complex new_array[100]
That is,
void array_function (double *a, double complex array[], int n)
{
int i;
for (i=0; i<n; i++)
{
array[i]=convert(*(a+i),i);
}
}
And in main():
double complex new_array[100];
...
array_function(array, new_array, N);
So I'm brand new to C and playing around with memory allocation for arrays. I'm trying to create a program that will dynamically allocate space using malloc to reverse an array of floating point numbers.
#include <stdio.h>
#include <stdlib.h>
struct Rec {
float * x;
int size;
};
int main(){
struct Rec a[50];
int i, y;
printf("Enter the number of floating point numbers: ");
scanf("%d", &y);
x = malloc(y * sizeof(struct));
printf("Enter 5 floating point numbers: \n");
for(i = 0; i < sizeof(struct); i++){
scanf("%.3f", &x[i]);
}
printf("The numbers in reverse order are: \n");
for(i = --sizeof(struct); i >= 0; i--){
printf("%f \n", a[i]);
}
}
During compilation, the following errors are generated:
error: use of undeclared identifier 'x'
*x = malloc(y * sizeof(struct);
^
test.c:14:25: error: declaration of anonymous struct must be
a definition
*x = malloc(y * sizeof(struct);
^
test.c:14:32: error: type name requires a specifier or qualifier
*x = malloc(y * sizeof(struct);
^
test.c:14:31: error: type name requires a specifier or qualifier
x = malloc(y * sizeof(struct));
^
test.c:14:24: note: to match this '('
*x = malloc(y * sizeof(struct);
^
test.c:25:3: error: expected '}'
}
^
test.c:9:11: note: to match this '{'
int main(){
^
Your pointer x is part of the structure which is stored in an array. You probably want to access your "x" through the structure. So instead of
x = malloc(y * sizeof(struct));
You probalby want
a[some index].x = malloc(y * sizeof(struct));
This above line will compile but will most likely give you incorrect results. Since you want to allocate it, you want it to be the size of the variable that you are planning to store there, not the size of the struct.
I should mention that there are other problems. You can't iterate through a structure that way. You want to instead iterate over the length of the array (of structs) instead.
There are a lot of issues with your code. I would advise you to practice more with C basics before attempting to do this. Here is approximation of what you might have wanted to achieve with your code:
#include <stdio.h>
#include <string.h>
// This structure can hold array of floats - and their size
struct Rec
{
float * x;
int size;
};
int main()
{
// Declare variable of type rec
struct Rec a;
int i, y;
// How many floats to store? This could also be stored in a.size instead of y
printf("Enter the number of floating point numbers: ");
scanf("%d", &y);
// Create and populate dynamic array
a.x = malloc(y * sizeof(float));
printf("Enter floating point numbers: \n");
for(i = 0; i < y; i++)
{
scanf("%.3f", &a.x[i]);
}
// Print
printf("The numbers in reverse order are: \n");
for(i = y-1; i >= 0; i--)
{
printf("%f \n", a.x[i]);
}
free(a.x);
return 0;
}
I am new to C and have a question about making a simple function in which I hand in a given array and also an integer that tells the number of numbers in that array. I wrote this code but I am unsure if it is correct. What I was trying to do was to make it so that I could find the product of all the numbers in the array.
#include <stdio.h>
#include <math.h>
double my_product (int n, double x[]);
int main (void)
{
my_product(n, x);
return 0;
}
double my_product (int n, double x[])
{
int i;
product=0;
for(i=0; i<n; i++)
{
product=x[i]*x[i+1]
}
return product;
}
I will comment your code, pointing out your mistakes:
double my_product (int n, double x[])
{
int i;
product=0;
/* The variable "product" needs to have a type.
In your case, since your values have type "double",
and a "double" return is expected,
of course you need to declare:
double product;
On the other hand,
it has not sense to initialize a product to 0,
since multiplication by 0 "kills" every value,
giving you a value 0, not matter what you do.
So, initialize in this way:
double product = 1.0;
*/
for(i=0; i<n; i++)
{
/* A semicolon is missing in the next line: */
product=x[i]*x[i+1]
/* In every step of the loop,
the variable "product" will hold the value
given by the multiplication of two consecutive values
in the array.
Thus, you lose every previous factor.
Also, when i == n you are in trouble,
because x[i] == x[n] is beyond the limits of the array,
which may cause access violation to memory.
You need a cumulative product.
Starting by the initialized value 1.0,
you have to multiply the previous value of "product"
with the present value of the array: x[i]
product = product * x[i];
Thus, in the step i, it can be proved that
the variable "product" contains the cumulative product
of the factors x[0], x[1], ... up to x[i].
A more compact notation in C can be provided by the *= operator:
product *= x[i];
*/
}
return product;
}
In the function main():
int main (void) {
my_product(n, x);
/* The function "my_product()" has been called with
undeclared parameters "n" and "x".
First, you have to declare and define the value of "n",
as much as the array "x", having type double:
double x[] = {3.0, 1.41, -2.3, 9.4, };
int n = sizeof(x)/sizeof(double);
The first line would declare an array "x" having type "double",
and initialized to hold 4 values, as it's seen there.
The second line would declare an "int" variable "n"
holding the number of elements in the array,
which can be computed as the size of x (measured in bytes)
divided by the size of the type "double"
(of course, in this example we have n == 4).
Finally, you need to do something with the result returned by
the function "my_product()".
If not, the returned value will be completely lost.
For example, to hold it in a variable, or to show it on screen.
double ans;
ans = my_product(n, x);
*/
return 0;
}
The code will look like this:
#include <stdio.h>
#include <math.h>
double my_product (int n, double x[]);
int main (void)
{
double x[] = {3.0, 1.41, -2.3, 9.4, };
int n = sizeof(x)/sizeof(double);
double ans;
ans = my_product(n, x);
printf("Product is: %f\n", ans);
return 0;
}
double my_product (int n, double x[])
{
product=1.0;
int i;
for(int i=0; i<n; i++)
{
product *= x[i];
}
return product;
}
In your function my_product you overwrite the value of product in the loop
for(i=0; i<n; i++)
{
product=x[i]*x[i+1]
}
So suppose your array x = {2, 3, 4}, then first product gets the value of 2*3, but then you overwrite it with the value of 3*4. What you probably want is to use a variable in which you accumulate the results of the multiplications (e.g. total = total * number).
Also, watch out with your indexing. In your current code i+1 can be larger than the number of elements in x, so you run out of the array.
Using the same machine and IDE as reffered in my other question (third paragraph at Problems in code or my IDE/comp is bugged?)
I try to run this code:
#include <stdio.h>
#define n 3
int main()
{
int i;
float values[n],sumval,svmean,tmp;
for(i=0;i<n;++i)
{
scanf("%f",&tmp);
values[i]=tmp;
sumval = sumval + values[i];
}
svmean = sumval/n;
printf("%f \n",svmean);
return(0);
}
The above code is supposed to run this formula
That means that it has to add some values and divide the result by their total number.
As you see above I made an array with random n positions and I ask the user to fill in a value for each position then add them all up and divide them.
The problem is that it doesnt work. It outputs only the result 7 no matter what the iput is.
BUT if I include stdlib.h to the code it works fine.
so
Question A: why the code does not work properly using only the
stdio.h library? which element of the code does require the stdlib.h
library?
As you see the array values[n] seems to have an random n number of cells but actually I have already set this numer to be equal to 3 (using #define)
Question B: Is there a way to run a code with the same porpuse but letting the user to define the size of the array values[n] or in other words let the user input an integer that sets the value of n in values[n]?
First of all, you forgot to initialize sumval. You want it to be 0 at the beginning.
If you want the size of the array to be decided at runtime, you have to allocate it dynamically using malloc, for example like this:
int n;
float *values,sumval=0,svmean,tmp;
scanf("%d", &n);
values = (float *) malloc (n * sizeof(float));
Later, you should release the memory allocated by calling free:
free(values);
Initialize sumVal to o. Because for first iteration it adds garbage+values[i] into sumValue.
#include <stdio.h>
#define n 3
int main()
{
int i;
float values[n],sumval=0,svmean,tmp;
for(i=0;i<n;++i){
scanf("%f",&tmp);
values[i]=tmp;
sumval = sumval + values[i];
}
sumean = sumval/n;
printf("%f \n",svmean);
return(0);
}
The problem is that you do not initialize sumval. You should set it to 0.0 before you for loop.
The change occurring when including/not-including stdio.h is probably due to some initialization functions using the stack, and changing the values in memory, before you enter your function, and it happen that this memory is used for your sumval variable.
But you should NOT rely on this.
Question A answer
In the code you posted there is no need for stdlib.h. This library is needed if you use a function for allocating memory dynamically, such as malloc().
Question B answer:
This is a way to do what you want:
#include <stdio.h>
int main()
{
int i, choice;
float *values,sumval,svmean,tmp;
printf("Please enter the size of the array: ");
scanf("%d", &choice);
values = (float*) malloc(choice*sizeof(float));
for(i=0;i<n;i++){
scanf("%f",&tmp);
values[i]=tmp;
sumval = sumval + values[i];
}
svmean = sumval/n;
printf("%f \n",svmean);
free(values);
return 0;
}
Also, I modified the incrementation of i in the for statement to increase after running the loop.
Try this..
#include <stdio.h>
int main()
{
int i = 0;
int n = 0;
float sumval = 0;
float svmean = 0;
float tmp = 0;
printf("Enter count : ");
scanf("%d", &n);
for (i = 0; i < n; ++i) {
scanf("%f", &tmp);
sumval = sumval + tmp;
}
svmean = sumval/n;
printf("%f \n",svmean);
return(0);
}
In your code, values[] array is not necessary to calculate output. Are you storing the values for any reason??..
You can allocate an array with variable size in the heap of the program like that:
#include <stdio.h>
int main(int argc, char **argv)
{
int i;
//Get the size of the array from input parameter
int n = atoi(argv[1]);
float sumval,svmean,tmp;
//Allocate the array of values
float *values = malloc(sizeof(float)*n);
// Initialize sumval
for(sumval=0,i=0;i<n;++i){
scanf("%f",&tmp);
values[i]=tmp;
sumval = sumval + values[i];
}
svmean = sumval/n;
printf("%f \n",svmean);
//Free it
free( values );
return(0);
}
You also need to initialize sumval to 0. The parameter of the size of the array is passed when launching the program (if you use an IDE you should check how it does that)