Suppose I have an array, defined as
int arr[10];
I want to progressively fill this array (assuming to not run out of the memory allocated for the array), according to a loop of the form
for(int i = 0; i < some_number; i++)
if(some_condition)
add_element_to_arr
What is the best way to do this?
Two methods I can think of are 1) using an auxiliary variable to remember the number of stored values, or 2) using a pointer to do the same thing.
What is the preferred/standard/conventional way to do this?
Also, having to do this kind of operations for multiple arrays, to remember how many values have been added to each array one has to use an auxiliary variable for each array.
What is the preferred way to deal with this?
You could use a pos variable like this:
for(int i = 0, pos = 0; i < some_number && pos < 10; i++)
if(some_condition)
arr[pos++] = i;
No need to use a pointer in this case.
Update:
With multiple arrays (different sizes), you could create a struct with a pointer to the array and a current position, this way both values always stay together:
struct arr_data {
int *arr;
int current_pos;
}
And add a size too maybe:
struct arr_data {
int *arr;
int size; // or unsigned int or size_t
int current_pos; // or unsigned int or size_t
}
You could then create an array of those structs, depending on the implementation.
if you want to make this some standard in your program, you could use something like:
struct progressiveArr{
int elements[10];
int size;
}
and then:
for(int i = 0; i < some_number i++)
if(some_condition)
{
arr.elements[arr.size++]=i;
}
Related
I have a code from Mathlab, where all matrix operations are done by a couple of symbols. By translating it into C I faced a problem that for every size of matrix I have to create a special function. It's a big code, i will not place it all here but will try to explain how it works.
I also have a big loop where a lot of matrix operations are going on. Functions which are operating with matrices should take matrices as income and store results in temporary matrices for upcoming operations. In fact i know the size of matrices but i also want to make the functions as universal as possible. In oder to reduce code size and save my time.
For example, matrix transposition operation of 2x4 and 4x4 matrices:
void A_matrix_transposition (float transposed_matrix[4][2], float matrix[2][4], int rows_in_matrix, int columnes_in_matrix);
void B_matrix_transposition (float transposed_matrix[4][4], float matrix[4][4], int rows_in_matrix, int columnes_in_matrix);
int main() {
float transposed_matrix_A[4][2]; //temporary matrices
float transposed_matrix_B[4][4];
float input_matrix_A[2][4], input_matrix_B[4][4]; //input matrices with numbers
A_matrix_transposition (transposed_matrix_A, input_matrix_A, 2, 4);
B_matrix_transposition (transposed_matrix_B, input_matrix_B, 4, 4);
// after calling the functions i want to use temporary matrices again. How do I pass them to other functions if i dont know their size, in general?
}
void A_matrix_transposition (float transposed_matrix[4][2], float matrix[2][4], int rows_in_matrix, int columnes_in_matrix)
{ static int i,j;
for(i = 0; i < rows_in_matrix; ++i) {
for(j = 0; j < columnes_in_matrix; ++j)
{ transposed_matrix[j][i] = matrix[i][j];
}
}
}
void B_matrix_transposition (float transposed_matrix[4][4], float matrix[4][4], int rows_in_matrix, int columnes_in_matrix)
{ static int i,j;
for(i = 0; i < rows_in_matrix; ++i) {
for(j = 0; j < columnes_in_matrix; ++j)
{ transposed_matrix[j][i] = matrix[i][j];
}
}
}
The operation is simple, but the code is massive already because of 2 different functions, but it will be a slow disaster if I continue like this.
How do i create one function for transposing to operate matrices of different sizes?
I suppose it can be done with pointers, but I don't know how.
I'm looking for a realy general answer to understand how to tune up the "comunication" between functions and temporary matrices, best with an example. Thank you all in advance for the information and help.
There are different way you can achieve this in c from not so good to good solutions.
If you know what the maximum size of the matrices would be you can create a matrix big enough to accommodate that size and work on it. If it is lesser than that - no problem write custom operations only considering that small sub-matrix rather than the whole one.
Another solution is to - create a data structure to hold the matrix this may vary from jagged array creation which can be done using the attribute that is stored in the structure itself. For example: number of rows and column information will be stored in the structure itself. Jagged array gives you the benefit that now you can allocate de-allocate memory - giving you a better control over the form - order of the matrices. This is better in that - now you can pass two matrices of different sizes and the functions all see that structure which contain the actual matrix and work on it. (wrapped I would say).
By Structure I meant something like
struct matrix{
int ** mat;
int row;
int col;
}
If your C implementation supports variable length arrays, then you can accomplish this with:
void matrix_transposition(size_t M, size_t N,
float Destination[M][N], const float Source[N][M])
{
for (size_t m = 0; m < M; ++m)
for (size_t n = 0; n < N; ++n)
Destination[m][n] = Source[n][m];
}
If your C implementation does not support variable length arrays, but does allow pointers to arrays to be cast to pointers to elements and used to access a two-dimensional array as if it were one-dimensional (this is not standard C but may be supported by a compiler), you can use:
void matrix_transposition(size_t M, size_t N,
float *Destination, const float *Source)
{
for (size_t m = 0; m < M; ++m)
for (size_t n = 0; n < N; ++n)
Destination[m*N+n] = Source[n*M+m];
}
The above requires the caller to cast the arguments to float *. We can make it more convenient for the caller with:
void matrix_transposition(size_t M, size_t N,
void *DestinationPointer, const void *SourcePointer)
{
float *Destination = DestinationPointer;
const float *Source = SourcePointer;
for (size_t m = 0; m < M; ++m)
for (size_t n = 0; n < N; ++n)
Destination[m*N+n] = Source[n*M+m];
}
(Unfortunately, this prevents the compiler from checking that the argument types match the intended types, but this is a shortcoming of C.)
If you need a solution strictly in standard C without variable length arrays, then, technically, the proper way is to copy the bytes of the objects:
void matrix_transposition(size_t M, size_t N,
void *DestinationPointer, const void *SourcePointer)
{
char *Destination = DestinationPointer;
const char *Source = SourcePointer;
for (size_t m = 0; m < M; ++m)
for (size_t n = 0; n < N; ++n)
{
// Calculate locations of elements in memory.
char *D = Destination + (m*N+n) * sizeof(float);
const char *S = Source + (n*M+m) * sizeof(float);
memcpy(D, S, sizeof(float));
}
}
Notes:
Include <stdlib.h> to declare size_t and, if using the last solution, include <string.h> to declare memcpy.
Variable length arrays were required in C 1999 but made optional in C 2011. Good quality compilers for general purpose systems will support them.
If you are using C99 compiler, you can make use of Variable Length Array (VLA's) (optional in C11 compiler). You can write a function like this:
void matrix_transposition (int rows_in_matrix, int columnes_in_matrix, float transposed_matrix[columnes_in_matrix][rows_in_matrix], float matrix[rows_in_matrix][columnes_in_matrix])
{
int i,j;
for(i = 0; i < rows_in_matrix; ++i) {
for(j = 0; j < columnes_in_matrix; ++j)
{
transposed_matrix[j][i] = matrix[i][j];
}
}
}
This one function can work for the different number of rows_in_matrix and columnes_in_matrix. Call it like this:
matrix_transposition (2, 4, transposed_matrix_A, input_matrix_A);
matrix_transposition (4, 4, transposed_matrix_B, input_matrix_B);
You probably don't want to be hard-coding array sizes in your program. I suggest a structure that contains a single flat array, which you can then interpret in two dimensions:
typedef struct {
size_t width;
size_t height;
float *elements;
} Matrix;
Initialize it with
int matrix_init(Matrix *m, size_t w, size_t h)
{
m.elements = malloc((sizeof *m.elements) * w * h);
if (!m.elements) {
m.width = m.height = 0;
return 0; /* failed */
}
m.width = w;
m.height = h;
return 1; /* success */
}
Then, to find the element at position (x,y), we can use a simple function:
float *matrix_element(Matrix *m, size_t x, size_t y)
{
/* optional: range checking here */
return m.elements + x + m.width * y;
}
This has better locality than an array of pointers (and is easier and faster to allocate and deallocate correctly), and is more flexible than an array of arrays (where, as you've found, the inner arrays need a compile-time constant size).
You might be able to use an array of arrays wrapped in a Matrix struct - it's possible you'll need a stride that is not necessarily the same as width, if the array of arrays has padding on your platform.
I'm currently trying to write the code for a simple Quicksort in C, but I can't seem to understand C syntax and pointers. I'm used to coding in Java, so I'm a little confused on how to return int arrays, and what I'm doing wrong.
Here is my code right now, any help would be greatly appreciated.
#include <stdio.h>
#define MAX 100
int input[MAX];
int* QuickSort(int A[], int n);
int* combine (int first[], int pivot, int last[]);
//main method to run program
int main()
{
int i, n;
//read in input and store values in array named input
printf ("Enter several numbers separated by spaces or returnsand ended by Ctrl-D:\n");
for (n = 0; n < MAX && scanf("%d", &input[n]) != EOF; n++);
//runs QuickSort on the array
int new[n] = QuickSort(input, n);
printf("Here is your sorted array:\n");
//goes through sorted array to print values
for (i = 0; i < n; i++)
printf("%d\n", new[i]);
}
int* QuickSort(int A[], int n)
{
//if array has 1 value or is empty, automatically return
if (n <= 1)
return A;
int pivot = A[0];
int less[n/2];
int more[n/2];
int lesscount = 0;
int morecount = 0;
int i;
for (i = 1; i<n; i++)
{
if (A[i] <= pivot)
{
less[lesscount] = A[i];
lesscount++;
}
else if (A[i] > pivot)
{
more[morecount] = A[i];
morecount++;
}
}
int size = n/2;
return combine(QuickSort(less, size), pivot, QuickSort(more, size));
}
int* combine (int first[], int pivot, int last[])
{
int firstsize = sizeof(first)/sizeof(first[0]);
int lastsize = sizeof(last)/sizeof(last[0]);
int totalsize = firstsize + lastsize + 1;
int combined[totalsize];
int n;
for (n =0; n<firstsize; n++)
{
combined[n]= first[n];
}
combined[n]=pivot;
n++;
int m;
for (m =0; m<totalsize; m++)
{
combined[n] = last[m];
n++;
}
return combined;
}
The basics
A pointer is a memory address which you can dereference and access. It's very different from an object and is (mostly likely) just an 8-byte value. Whereas in Java you might be able to pass around objects (which do point to some memory somewhere), in C you must be a lot more careful about what memory you're pointing.
In particular, there is a difference between the stack and the heap. The stack is what your program uses to track local variables and will automatically allocate space. On the other hand, the heap is usually something you need to manage yourself. In particular, you won't get heap addresses unless you explicitly allocate it (i.e., with malloc). Why the distinction? Because the stack automatically allocates space, but also automatically deallocates space on function return.
Why does this apply to you?
Let's take a look on some of your functions:
int* combine (int first[], int pivot, int last[])
/* i.e., int* combine (int *first, int pivot, int *last) */
{
int firstsize = sizeof(first)/sizeof(first[0]);
int lastsize = sizeof(last)/sizeof(last[0]);
int totalsize = firstsize + lastsize + 1;
int combined[totalsize];
/* The rest of the code */
return combined;
}
You're returning combined, a stack allocated variable to whoever is calling your function. While doing this is "legal" in the strict sense, it's not correct because once you've returned from the function, the program will automatically deallocate the memory. This means you're probably getting some very confusing results and/or faults.
Now, how do you fix this?
In your case, quicksort doesn't need more space, just some clever manipulation of variables. Thus, you actually don't even need to use any of the sub arrays, nor do you need to return any arrays. The neat thing about pointers is that you get an address to memory. Thus, if you change that is pointed to (i.e., A[0] = x), then any other function which also knows about A will see that update.
And applied to quicksort?
Your initial implementation isn't quite correct either. Quicksort can be roughly broken down into two steps: partition and combine. When you partition, you want to separate all values less than a pivot value from all values greater than a pivot value. However, because you don't already know how many that is, assuming you'll have size/2 in each partition is going to cause you trouble.
For partition, you can use an in place iterative method. Something like this:
while index < end:
if A[index] < pivot:
index ++
else if A[index] > pivot:
swap(A[index], A[end])
end --
swap(pivot, A[index])
(There may be some off by one errors in the above.) The basic idea is that by keeping track of both a lower part and an upper part with two indices, you "add" the current value you're comparing against to the proper side (by moving to the next index, or swapping and decrementing the end). And by doing this in place, you don't need to deal with memory allocation.
The recursive step then becomes knowing where your sub-pieces are and recursively calling sort of each.
I have this:
void duplication(int **tab1, int **tab2, int n, int m)
The goal is to copy tab1 into tab2, so i will get the same two tables.
How can i do this, because i know that using tab2 = tab1 is not working in my case :)
Sorry if it's a stupid question, i'm actually learning C!
Thank you.
assuming n and m are the dimensions, and you know which one applies to which dimension, you need a double loop something like this:
for ( int x = 0; x < n; ++x )
{
for ( int y = 0; y < m; ++y )
{
tab2[x][y] = tab1[x][y];
}
}
Thats a couple of big assumptions I am making given the documentation of the function you provide, but hopefully the code gives you an idea of what needs to be done, and you can substitute the correct variables in the correct places.
For further reference, the term associated with this kind of data copying is what is called a "Deep copy". When dealing with pointers, copying the pointer value is typically insufficient, and frequently unsafe. If you would like more references on this type of code, search around for "Deep copy"
You can do with the nested for loop. Usually duplication of any variable, memory alloction for the duplicated variable should be done inside that function. Duplication function should be like below.
int ** dup_tab(int **sr_table, int n, int m)
{
int **dest_tabl = NULL;
int i = 0;
int j = 0;
dest_tabl = malloc(sizeof(int *) * n);
for (i = 0; i < n; i++)
{
dest_tabl[i] = malloc(sizeof(int) * m);
}
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
dest_tabl[i][j] = sr_table[i][j];
}
}
}
You should establish a point of view with the underlying memory 'management' in mind.
Probably you are looking for a function like
// defined in <string.h> and conform to C99
void memcpy(void *dest, const void *src, size_t n);
which copies n bytes from the beginning of src to the beginning of dest.
Related to your question, if you want to use this function you have to know the size N of the object where *tab1 points to and the size of each object M_i where tab[i] points to (with i < N). If you have this information you can solve your problem according to
C / C++ How to copy a multidimensional char array without nested loops?
I would like to store values read from a for-loop to an array
char A[];
int x;
int y=5;
for( int i=0; int i =1000; i++) {
x = x+y;
// then store/append x as elements of the char array, A.... what is the syntax?
}
By looking at your code I am assuming that you are trying to build a static array, so I will demonstrate that (so you don't have to focus on concepts like malloc for the time being). There is however, several problems with your code that I will go over now.
First off your array declaration:
char A[];
to me it looks like your for loop is filling an array of integers, so this array should be declared as an integer, furthermore you are not setting the size of the array, since your code has i increment until it is 1000 you should just declare an integer array with 1000 elements:
int A[1000];
Second your for loop:
for(int i = 0, int i = 1000; i++)
you're better off just declaring i with the rest of your variables, although you can declare it in a for loop I personally wouldn't suggest doing it. Also you declare i twice in this loop. Finally your condition to continue the loop (i = 1000) will abort the loop immediatly since i will never be equal to 1000 since you set it to 0. Remember a for loop only loops while the middle statement is true. So with that in mind you should now have:
int A[1000], i, x, y = 5;
for(i = 0; i < 1000; i++)
And now we can use the = statement and the value of i to set each array element for A:
int A[1000], i, x, y = 5;
for(i = 0; i < 1000; i++)
{
x += y;
A[i] = x;
}
it's that simple!
There are multiple issues with your code
char A[1000]; // Need to specify a compile time constant for the array size
int x=0;
int y=5;
for( int i=0; i < 1000; i++) { // Condition was wrong
x = x+y;
// then store/append x as elements of the char array, A.... what is the syntax?
A[i] = x; // Add the value
}
Also, the char datatype won't be able to hold values over a certain size, and will cause overflow making the values wrap around. You might want to declare A as int A[1000] instead.
Arrays need to be of a constant size, or you will need to allocate them using malloc
The second part of the loop cannot redeclare i again. It also will loop forever if you have an assignment statement in it like you do. I assume you want to loop up to 1000 instead
The actual question, to assign into an array use the [] operator.
x was not initialized to anything, making it contain a garbage value. You need to assign values to variables upon declaring them. C does not do this for you automatically.
If you want to add an element in C, you have several methods.
Static array
A static array is declared with a number of elements you're unable to edit. So it's perfect if you know exactly the number of elements you'll have. #Dervall did explain that well.
Dynamic array
A dynamic array is declared with malloc function. And the size can be changed. It's difficult and hard to maintain though. But :
int *A = NULL;
int *tmp; // to free ex allocated arrays
int i;
int j;
int x = 0;
int y = 5;
for (i = 0 ; i < 1000 ; i++) {
// saving temporarly the ex array
tmp = A;
// we allocate a new array
if ((A = malloc(sizeof(int) * (i + 1))) == NULL) {
return EXIT_FAILURE;
}
// we fill the new array allocated with ex values which are in tmp
for (j = 0; j < i; j++) {
A[j] = tmp[j];
}
// if it's not the first time, we free the ex array
if (tmp != NULL)
free(tmp);
x = x + y;
A[i] = x;
}
Better to split it into a function of course :)
You can use the realloc function as well ! Which is made for that, but I find it interesting to develop like this
There's a lot of stuff wrong with your snippet. Here's a compilable example
char *A = malloc(sizeof(*A) * NUM_ELEMENTS); // you shouldn't declare on the stack
int x = 0; // initialize
int y=5;
for( int i = 0; i < NUM_ELEMENTS; i++) { // proper for loop syntax
x = x+y;
A[i]=x; // assign element of array
}
And a better version:
char *A = malloc(sizeof(*A) * NUM_ELEMENTS);
for (int i = 0; i < NUM_ELEMENTS; ++i)
A[i] = 5 * i;
I create a 2D array in C as follows:
int **arr;
arr = malloc(rows * sizeof(int *));
for (i = 0; i < rows; i++)
arr[i] = malloc(cols * sizeof(int));
Now, I call:
func(arr)
In the function func, how do I calculate the row and column dimensions?
You can't calculate it - arr is just a pointer to a pointer, there is no more information associated with it (as with all C arrays). You have to pass the dimensions as separate arguments.
You can't. You have to pass the dimensions along with your array to the function func(arr).
you can't (the beauty of C). (and don't try using sizeof, because that will only give you the size of the pointer) If another function needs to know the dimensions of the array, you'll have to pass along those parameters (height and width) as arguments along with the array pointer.
A workaround for this would be to not use an array directly, but instead have a struct like this:
struct table{
int ** arr;
int rows;
int columns;
}
You can then have a function which creates instances of table that takes the number of rows and columns, and handles the allocation.
As everyone else has said, you can't. However, you may find it useful to create a structure to contain the row, column and pointer all together. This will allow you to say:
typedef struct {
int rows;
int cols;
int **data;
} myDataType;
...
foo(myData);
void foo(myDataType myData) {
for( i = 0; i < myData.rows; i++) {
for( j = 0; j < myData.cols; j++ ) {
printf("%d,%d: %d\n", i, j, myData.data[i][j]);
}
}
}
(I apologize if my syntax is slightly off; Perl, Java, C# and a little Ruby are jockying for elbow-space.)