Reputation: 75
Basically, I want to be able to type in the dimension n in the terminal and create the corresponding n-D array.
Right now I'm only able to create a one dimensional array with the size of the corresponding n-D array.
Upvotes: 0
Views: 106
Reputation: 398
You can set the size of the array at runtime using VLA. Variable-length arrays are part of C99. So this will only work with C99 or up. Although C11 has VLA as an option, all major compilers support it.
Lets say you want the user to input the size of a 2D array from the terminal.
#include <stdio.h>
int main(void)
{
unsigned int row1, col1;
printf("%s", "Enter number of rows and columns in a 2-D array: ");
int row1, col1; // number of rows and columns in a 2-D array
scanf("%u %u", &row1, &col1);
int array2D[row1][col1]; // declare 2-D variable-length array
}
array2d is a 2d array declared at run time. Then just write code below to use it.
In early versions of C sizeof
was always a compile-time operation, but when applied to a VLA, sizeof
operates at runtime. Will print the number of bytes in a VLA:
Upvotes: 1
Reputation: 2621
Use pointers to pointers/double pointers (**
). For a n-D array you repeat the process of dynamic allocation (malloc
) n times in a loop and reference each with a pointer to newly the allocated array. The only issue is that the last array does not use double pointers, so your runtime code has to know when to use values instead of double-pointers at the last dimension. Using this you can still do setting/getting via conventional syntax like M[1][2][3][1] = 5;
(mind that 0 is the first element!).
Also make sure to initialize your values.
For a good example and treatise of double array pointers check 'The C Progamming Language' from Kerningham/Richie, which is readily available online.
Note: there are other elegant and not so elegant solutions to this. For example using macros/metaprogramming to write the allocation code at compile time and pass an define
option (-DDIMS=4
) or nest-able data structures representing arrays like trees (check classic data structure literature for multi-dim arrays.)
Upvotes: 0
Reputation: 331
You can't, the number of dimensions of an array is part of the type, so it needs to be known at compile time. You can do some simple math, to map what you want to a 1d array.
Example:
Let dimensions = 3
Code:
int* data = (int*)malloc(sizeof(int) * w * h * d);
int x = access(1,2,3); //it will map to location: 1 + 2 * (4) + 3 * (4 * 8)
free(data);
int access(int x, int y, int z){
return data[x + y * (w) + z * (h * w)];
}
A general implementation might look like this
int numDimensions;
printf("Enter number of dimensions:");
scanf("%d", &numDimensions);
int* dimensionSizes = (int*)malloc(sizeof(int) * numDimensions);
//Read each dimension's size
int totalElements = 1;
for(int i = 0; i < numDimensions; ++i){
printf("Enter size for dimension %d:", i);
scanf("%d", &dimensionSizes[i]);
totalElements *= dimensionSizes[i];
}
//allocate 1d array
int* data = (int*) malloc(sizeof(int) * totalElements);
//Read the coordinates you want to store data to
int* position = (int*)malloc(sizeof(int) * numDimensions);
for(int i = 0; i < numDimensions; ++i){
printf("Enter location in dimension %d:", i);
scanf("%d", &position[i]);
}
//Read the value you want to store
int value;
printf("Enter value for that position:");
scanf("%d", &value);
//Write the data to the calculated 1d location
data[to1d(position, dimensionSizes, numDimensions)] = value;
int to1d(int* position, int* dimensionSizes, int numDimensions){
int multiplier = 1;
int position1d = 0;
for (int i = 0; i < numDimensions; ++i){
position1d = position1d + position[i] * multiplier;
multiplier = multiplier * dimensionSizes[i];
}
return position1d;
}
Upvotes: 2