How to initialize an array field inside a structure? - c

So I have an exercice that asks me to define a structure that has 2 fields: one field to store an array of an already defined size, one field to store the length of the array. Then I have to define a function that should initialize the 2 fields in the structure, and another funciton that prints the 2 fields
I'm just a beginner in programming, here's my attempt to write the code, but it doesn't seem to work. Thanks in advance for the help.
#include<stdio.h>
#include<string.h>
#define SIZE 10
typedef struct stdata data{
int array[SIZE];
int length;
}
void initialize (int array[],int length){
data p;
p.array[SIZE]=array;
p.length=length;
}
void print(data p){
printf("%d %d ",p.array,p.length);
}

You can do it in two different ways both are correct:
Method 1:
memcpy(p.array, array, sizeof(int) * length);
Method 2: (using a loop)
for (int i = 0; i < length; i++) p.array[i] = array[i];

Related

Understanding part of an algorithm

Below is a part of an algorithm i was given to use for a project, but as it's my first time to use an algorithm i don't understand the following lines. Please will need your help.
For i=1 to n do
t[i] .mark <-- 0
t[i] .num <-- -1
End
This pseudo code can be translated to C
Use struct
struct cm{
int mark;
int num;
};
#define N 10
int main(void)
{
struct cm t[N];
for (int i=0;i<N;i++){
t[i].mark = 0;
t[i].num = -1;
}
//print your struct elements field
for (int i=0;i<N;i++){
printf("%d: %d, %d\n",i ,t[i].mark, t[i].num);
}
}
We have an array of struct because of we need each element of it have two field of data (i.e. mark,num).
struct cm t[N]; define a N length array of structure cm.
In loop we assign to each field of array elements proper values.
For more readability you can use typedef instead of using struct to define your desire data structure in this case.
typedef vs struct
Use typedef
typedef struct typecm{
int mark;
int num;
}typecm;
#define N 10
int main(void)
{
typecm s[N];
for (int i=0;i<N;i++){
s[i].mark = 0;
s[i].num = -1;
}
//print values
for (int i=0;i<N;i++){
printf("%d: %d, %d\n",i ,s[i].mark, s[i].num);
}
}
The "t" seems to be an array of objects, and "mark" and "num" are properties of the object.
This may help you:
From an array of objects, extract value of a property as array

What is the best way to progressively fill an array in C?

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

Manipulating dynamic array through functions in C

I am learning how to use dynamic arrays in C. What I want to do is to create a dynamic array data, and put "1" into the first entry using the function test().
void test(void)
{
data[0] = 1;
}
int main(void)
{
int *data = malloc(4 * sizeof *data);
test();
return 0;
}
This compiles in Visual Studio 2010 but the program crashes when run. Instead of using test(), using data[0] = 1 works.
My (newbie) guess is that I need to pass a pointer to data to function test(). How should I write this?
Attempt
void test(int *data)
{
data[0] = 1;
}
Then, in main use test(data) instead of just test().
Edit
The attempt works. However, is this a "proper" way of doing it?
When you use a local variable in C, (dynamic or static, array or not), you need to pass it to the function that will be using it. That's what's wrong with your initial code, test() doesn't know anything about data.
When you declare an array, (dynamic or static) you can pass it to the function in the same ways. The following code is pretty pointless, but it illustrates that using a dynamic array is really no different than a static array.
void assign_function(int arr[], int len_of_arr, int *arr2, int len_of_arr2);
void print_function(int *arr, int len_of_arr, int arr2[], int len_of_arr2);
int main()
{
int data[2] = {0}; // static array of 2 ints
int *data2 = malloc(3 * sizeof(int)); // dynamic array of 3 ints
assign_function(data, 2, data2, 3);
print_function(data2, 3, data, 2);
free(data2); // One difference is you have to free the memory when you're done
return 0;
}
So we can pass the arrays, be they dynamic or static, via array[] or as a pointer, but we need to pass an int along as well so we know how big the array is.
void assign_function(int arr[], int len_of_arr, int *arr2, int len_of_arr2)
{
int count;
for(count = 0; count < len_of_arr; count++) //This is the static array
arr[count] = count;
for(count = 0; count < len_of_arr2; count++) //This is the dynamic array
arr2[count] = count;
}
Then just for fun I reverse which array is pass in arr and arr2 here, and also how they're accessed:
void print_function(int *arr, int len_of_arr, int arr2[], int len_of_arr2)
{
int count;
for(count = 0; count < len_of_arr; count++) //This is the dynamic array now
printf("arr[%d] = %d\n", count, *(arr+count));
for(count = 0; count < len_of_arr2; count++) //And this is the static array
printf("arr2[%d] = %d\n", count, *(arr2+count));
}
Point being, passing via [] or as a pointer, and accessing via [] or a deferenced pointer is up to you, both are fine, both work. I try to avoid pointers when I can as they tend to be hard to read and more error prone when writing.
You can pass arrays dynamically in two ways :
Using a simple pointer and then using pointer arithmetic to manipulate
void test (int * data, int i)
{
*(data + i) = 1; //This sets data[i] = 1
}
Or this way :
void test(int data[], int i)
{
data[i] = 1; //This is the more familiar notation
}
Either of these ways is the 'proper' way to go about this.
The variable 'data' in test is locally scoped. It's not the same 'data' that is in main. You should pass a pointer to 'data' through the parameters of test().

Creating an array of int arrays in C?

Let us say I have the following method prototype:
void mix_audio(int *vocal_data_array, int *instrumental_data_array, int *mixed_audio_array, FOURTH ARGUMENT)
{
}
How would I:
Initialize an array_of_arrays before the above argument so as to pass it as the fourth argument?
In the method, make it so that the first value of my array_of_arrays is the array called vocal_data, that the second value of my array is instrumental_data_array and the third value is mixed_audio_array.
How would I later then loop through all the values of the first array within the array_of_arrays.
I hope I'm not asking too much here. I just thought it would be simple syntax that someone could spit out pretty quickly :)
Thanks!
EDIT 1
Please note that although I've showed by my example an array_of_arrays of length 3 I'm actually looking to create something that could contain a variable length of arrays.
Simple array of arrays and a function showing how to pass it. I just added fake values to the arrays to show that something was passed to the function and that I could print it back out. The size of the array, 3, is just arbitrary and can be changed to whatever sizing you want. Each array can be of a different size (known as a jagged array). It shows your three criteria:
Initialization, Assigning values to each index of arrayOfArrays, The function demonstrates how to extract the data from the array of arrays
#include <stdio.h>
void mix_audio(int *arr[3]);
int main() {
int *arrayOfArrays[3];
int vocal[3] = {1,2,3};
int instrumental[3] = {4,5,6};
int mixed_audio[3] = {7,8,9};
arrayOfArrays[0] = vocal;
arrayOfArrays[1] = instrumental;
arrayOfArrays[2] = mixed_audio;
mix_audio(arrayOfArrays);
return(0);
}
void mix_audio(int *arr[3]) {
int i;
int *vocal = arr[0];
int *instrumental = arr[1];
int *mixed_audio = arr[2];
for (i=0; i<3; i++) {
printf("vocal = %d\n", vocal[i]);
}
for (i=0; i<3; i++) {
printf("instrumental = %d\n", instrumental[i]);
}
for (i=0; i<3; i++) {
printf("mixed_audio = %d\n", mixed_audio[i]);
}
}
From your question it sounds like you actually want a struct containing your arrays, something like:
struct AudioData {
int* vocal_data_array;
unsigned int vocal_data_length;
int* instrumental_data_array;
unsigned int instrumental_data_length;
int* mixed_audio_array;
unsigned int mixed_audio_length;
};
For the array allocation using the example of an array of integers:
int** x = malloc (sizeof (int*) * rows);
if (! x) {
// Error
}
for (int i = 0; i < rows; ++i) {
x[i] = malloc (sizeof (int) * columns);
if (! x[i]) {
// Error
}
}

Please help with passing multidimensional arrays

I'm writing a simple test program to pass multidimensional arrays. I've been struggling to get the signature of the callee function.
The code I have:
void p(int (*s)[100], int n) { ... }
...
{
int s1[10][100], s2[10][1000];
p(s1, 100);
}
This code appears to work, but is not what I intended. I want the function p to be oblivious whether the range of values is either 100 or 1000, but should know there are 10 pointers (by use of function signature).
As a first attempt:
void p(int (*s)[10], int n) // n = # elements in the range of the array
and as a second:
void p(int **s, int n) // n = # of elements in the range of the array
But to no avail can I seem to get these to work correctly. I don't want to hardcode the 100 or 1000 in the signature, but instead pass it in, keeping in mind there will always be 10 arrays.
Obviously, I want to avoid having to declare the function:
void p(int *s1, int *s2, int *s3, ..., int *s10, int n)
FYI, I'm looking at the answers to a similar question but still confused.
You need to transpose your arrays for this to work. Declare
int s1[100][10];
int s2[1000][10];
Now, you can pass these to a function like this:
void foo(int (*s)[10], int n) {
/* various declarations */
for (i = 0; i < n; i++)
for (j = 0; j < 10; j++)
s[i][j] += 1
}
Because of the way the C type system works, an array argument can only be "flexible" in the sense you want in its left-most index.
You could also create a struct for the matrix and pass it to the function p
struct Matrix{
int **array;
int n;
int m;
};
void p(Matrix *k){
length=k->m;
width=k->n;
firstElement=k->array[0][0];
}

Resources