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

# 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
• 6
• 4
• 3
• +4
1 Solution

Commented:
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

Commented:
LinkedList is also an option if you need sequential rather than direct access.
0

Commented:
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

Author 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

Author Commented:
many thanks jimstar.

Could you please explain to me what RESISTOR is? What is a struct?? many thanks
0

Commented:
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

Commented:
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

Commented:
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

Commented:
"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

Commented:
Sorry if I missed some terms, I'm not so familiar with english terminology in electrical science.
0

Commented:
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

Author 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

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

Commented:
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

Commented:
I should add that there are a number of errors left - although it'll compile and run now, and get you closer.
0

Author 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

Commented:
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

Commented:
>> 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

Commented:
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

Commented:
>>>> 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

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