• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 450
  • Last Modified:

Variable Sized Arrays in C

Hi everyone,

I'm trying to make a program that will calculate the resistances of some resistors. I want the program to ask the user how many resistors they have.

My problem is that when declaring arrays in C, they must have a fixed size. How would I make an array with a variable size eg. array[number].

Many Thanks
0
jonnytabpni
Asked:
jonnytabpni
  • 6
  • 4
  • 3
  • +4
1 Solution
 
jimstarCommented:
Two options:

1. Make the array big enough that you don't have to worry about it being exceeded.

2. Dynamically allocate the memory using malloc/free.
0
 
UrosVidojevicCommented:
LinkedList is also an option if you need sequential rather than direct access.
The good thing about LinkedList is that you can add new elements in the runtime.
0
 
jimstarCommented:
For the latter, you could do:

// allocate the memory for the resistor array
int totalResistors = 5000; // or whatever the user inputs
RESISTOR* resistorArray = (RESISTOR*)malloc(totalResistors * sizeof(RESISTOR));

When you're done, make sure to free up that memory by:
free(resistorArray);

Of course, this assumes you have a struct or something called RESISTOR. If you're just using int or DWORDs, then substitute that.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
jonnytabpniAuthor Commented:
I knew about the first point however I would really like to learn it the efficient way for future programs (but thanks anyways)

Could you explain to me how to use malloc/free??

Many Thanks
0
 
jonnytabpniAuthor Commented:
many thanks jimstar.

Could you please explain to me what RESISTOR is? What is a struct?? many thanks
0
 
peetmCommented:
Um, why don't you use a C99 compiler like gcc - C99 supports variable sized arrays!

Use gcc with -std=c99 and you're 'good to go'!

0
 
jimstarCommented:
A struct allows you to store several different values together such as in the following struct (short for Structure):

struct RESISTOR
{
   int resistor_id;
   int resistor_value;
};

Then, when you declare a "struct RESISTOR", you get both the resistor_id and resistor_value as one variable. For example:

struct RESISTOR myResistor; // declare a resistor
myResistor.resistor_id = 0;
myResistor.resistor_value=500;

It's basically a way to organize your data.
0
 
peetmCommented:
Compiled with gnu gcc -std=c99 -Wall

Note that for(int i ...

Is also 'nicked' from C++ with C99.

#include <stdio.h>

int main(int argc, char * argv[])
{
    int n = 0;
   
    puts("How many elements do you want?");
   
    scanf("%d", &n);

    {
        int arr[n];
           
        for(int i = 0; i < n; ++i)
        {
            arr[i] = i;
        }
       
        for(int i = 0; i < n; ++i)
        {
            printf("%d\n", arr[i]);
        }
    }

    return 0;
}
0
 
UrosVidojevicCommented:
"Could you please explain to me what RESISTOR is? What is a struct?? many thanks"

Resistor is an electronic component.
I suppose that your task is to calculate equivalent (overall) resistance of set of resistors.
Connection between resistors can be parallel or serial.
It can be said that one "virtual" resistor contains several "real" resistors.
In my opinion, list is more flexible data structure for representing electrical elements.
0
 
UrosVidojevicCommented:
Sorry if I missed some terms, I'm not so familiar with english terminology in electrical science.
0
 
peetmCommented:
Or, if no C99, using malloc/free with a struct.

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
   
    int resistance_is_futile;
   
} resistor;

int main(int argc, char * argv[])
{
    int n = 0;
   
    puts("How many elements do you want?");
   
    scanf("%d", &n);

    {
        resistor * rp;
       
        if((rp = malloc(n * sizeof(*rp))) != NULL)
        {
            for(int i = 0; i < n; ++i)
            {
                rp[i].resistance_is_futile = i;
            }
           
            for(int i = 0; i < n; ++i)
            {
                printf("%d\n", rp[i].resistance_is_futile);
            }
           
            free(rp);
        }
    }
   
    return 0;
}
0
 
jonnytabpniAuthor Commented:
ok so far i've got this code and it doesn't work:

#include <stdio.h>
#include <stdlib.h>
main()
{
      double rnumber,rseries,reff,count;
      rseries = 0;
      reff = 0;
      
      
      printf("How many resistors do you have?");
      scanf("%lf",&rnumber);
      int rn = (int*)malloc(rnumber * sizeof(int));

      for (count=0; count < (rnumber - 1); count++)
            {
            printf("What is the Value of R %lf?",(count + 1));
            scanf("%lf", &rn[count]);
            rseries = rseries + rn[count];
            reff = reff + 1/rn[count];
            }

            reff = 1/reff;

            printf("\nThe effective resistance of  R1, R2 and R3 in series is %lf ohms",rseries);
            printf("\nThe effective resistance of  R1, R2 and R3 in parallel is %lf ohms", reff);
      

}

Errors in compling are:

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86

Copyright (C) Microsoft Corporation.  All rights reserved.

q2_8_any.c
q2_8_any.c(12) : error C2143: syntax error : missing ';' before 'type'
q2_8_any.c(17) : error C2065: 'rn' : undeclared identifier
q2_8_any.c(17) : error C2109: subscript requires array or pointer type
q2_8_any.c(18) : error C2109: subscript requires array or pointer type
q2_8_any.c(19) : error C2109: subscript requires array or pointer type

E:\C\Lab2\Q2_8>
many thanks
0
 
peetmCommented:
Here it is partly fixed ...

#include <stdio.h>
#include <stdlib.h>

int main(void) // non-std.
{
    double * rn; // Has to be declared before and statement.
   
    int rnumber;  // Presumably, fractional resistors are not 'real'
   
    int count; // Fractional array indexes do not exist.
   
    double rseries,reff;
   
    rseries = 0;
    reff = 0;
   
    printf("How many resistors do you have?");
   
    scanf("%d",&rnumber);
   
    rn = malloc(rnumber * sizeof(*rn));
   
    for (count=0; count < (rnumber - 1); count++)
    {
        printf("What is the Value of R %d?",(count + 1));
        scanf("%lf", &rn[count]);
        rseries = rseries + rn[count];
        reff = reff + 1/rn[count];
    }
   
    reff = 1/reff;
   
    printf("\nThe effective resistance of  R1, R2 and R3 in series is %lf ohms",rseries);
    printf("\nThe effective resistance of  R1, R2 and R3 in parallel is %lf ohms", reff);
   
    getchar();
    getchar();
   
    exit(0);
}
0
 
peetmCommented:
I should add that there are a number of errors left - although it'll compile and run now, and get you closer.
0
 
jonnytabpniAuthor Commented:
YEY!

Thank You SOOO much peetm!

I have a few questions though.

int * rn

what does the asterisk mean?

and what do the two  getchar(); at the end mean and why is there two of them?

and could you please explain what each element of rn = malloc(rnumber * sizeof(*rn)); means?

Many Thanks
0
 
ikeworkCommented:
actually for that setup, you dont need the array ..

and two logic errors inside, look at the number (1) & (2)

#include <stdio.h>
#include <stdlib.h>

int main(void) // non-std.
{
    double rn; // Has to be declared before and statement.
   
    int rnumber;  // Presumably, fractional resistors are not 'real'
   
    int count; // Fractional array indexes do not exist.
   
    double rseries,reff;
   
    rseries = 0;
    reff = 0;
   
    printf("How many resistors do you have?");
   
    scanf("%d",&rnumber);
       
    // for (count=0; count < (rnumber - 1); count++) << (1) that was logically wrong, the last one was skipped
    for (count=0; count < rnumber; count++)
    {
        printf("What is the Value of R %d?",(count + 1));
        scanf("%lf", &rn);
        rseries = rseries + rn;
        reff = reff + 1/rn;
    }
   
    // reff = 1/reff; // << (2) that does not make sense here, since you already added the reciproces
   
    printf("\nThe effective resistance of  R1, R2 and R3 in series is %lf ohms",rseries);
    printf("\nThe effective resistance of  R1, R2 and R3 in parallel is %lf ohms", reff);
   
    getchar();
    getchar();
   
    exit(0);
}


of course if you need the values later, the array would make sense anyway ..


ike
0
 
Infinity08Commented:
>> what does the asterisk mean?

It means that rn is a pointer to an int.

Read up on pointers here :

        http://www.cplusplus.com/doc/tutorial/pointers.html


>> and what do the two  getchar(); at the end mean and why is there two of them?

        http://www.cplusplus.com/reference/clibrary/cstdio/getchar.html

Why there are two of them, I don't know ... It's not my code ;)


>> and could you please explain what each element of rn = malloc(rnumber * sizeof(*rn)); means?

Read up on malloc here :

        http://www.cplusplus.com/reference/clibrary/cstdlib/malloc.html
0
 
peetmCommented:
The two getchar()s were there so that I could easily prevent the gcc-built executable exiting from the console I was running it in - and thus loosing the output.  They should be removed.

You should also test to see if malloc worked, and if it did, tidy up using free()
0
 
itsmeandnobodyelseCommented:
>>>> what does the asterisk mean?

The asterisk makes the variable a pointer. A pointer is a variable that is pointing to another variable, i. e. its value is an address in memory.

   int  i = 5;
   int * pi = &i;   // pi points to i;  value of pi is for example 0x00efab00;
   int ri = *pi;    // get the dereference of the pointer == value of i == 5

By using a pointer the pointer variable can point to different variables:

   int  i = 5;
   int * p = &i;   // p points to i;  value of p is for example 0x00efab00;
   int m = 10;
   p = &m;         // now p points to m and (*p) == 10

You can allocate dynamic storage by

    int * p = new int;    // C++
    int * p = (int*)malloc(sizeof(int));  /*  C  */

    *p = 10;   // initialize the new storage


a pointer may point to an array as well (more precisely it points to the first item of an array).

    int * p = new int[100];    // C++
    int * p = (int*)malloc(sizeof(int)*100);  /*  C  */

    for (int i = 0; i < 100; ++i)
          p[i] = i;

    delete [] p;   // C++
    free(p);         /*  C */

Note, new/malloc can only be used alternatively.

If only looking to a pointer you can't know whether a pointer points to a single element or to the first element of an array. You only can find out by finnding the statement where the new/malloc was made.  

A pointer can also point to the first element of a fixed sized array:

    int arr[100];  // storage on the stack not on the heap
    int* p = &arr[0]; // points to the first array element
    int* pa = arr;   // that is valid as well and equivalent to the previous.
                            // It shows the ambivalence of pointers and arrays  in C/C++

Regards, Alex  
   


0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 6
  • 4
  • 3
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now