crylikeacanary
crylikeacanary

Reputation: 31

Getting C error "assignment to expression with array type"

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;
}

Upvotes: 2

Views: 6704

Answers (4)

David C. Rankin
David C. Rankin

Reputation: 84531

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.

Upvotes: 1

matli
matli

Reputation: 28590

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);

Upvotes: 0

Eric Postpischil
Eric Postpischil

Reputation: 222352

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.)

Upvotes: 0

Jens
Jens

Reputation: 72639

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.

Upvotes: 2

Related Questions