I am completely stuck when it comes to the C language and inserting into arrays. I have my code below and to explain it say the user wants an array of 3. So the user inputs 4 3 2 into array a1[n]. I need array a2[] to output the same numbers but a zero between each. The end result would be 4 0 3 0 2 0 when a2[] is output. How would I get a zero between every other element?
#include <stdio.h>
int main() {
int n = 0;
int number = 0;
int a1[n];
int a2[2 * n];
printf("Enter the length of the array: ");
scanf("%d", &n);
printf("Enter the elements of the array: ");
for(i = 0; i < n; i++){ //adds values to first array
scanf("%d",&number);
a1[i] = number; }
for(i = 0; i < n; i++){ //copies and sets the arrays the same
a2[i] = a1[i]; }
Assuming your arrays are correctly defined and initialized (statically or dynamically), it is just a matter of properly counting during copying:
for(int i = 0; i < n; i++){
a2[i+i] = a1[i];
if(i < n-1) a2[i+i+1] = 0;
}
int n = 0;
int number = 0;
int a1[n];
int a2[2 * n];
Congratulations, now a1 and a2 are arrays of zero length. Even if you change n later, this doesn't affect the lengths of arrays. In C, you cannot make an array longer or shorter.
Try int* and calloc instead.
First of all, you can't create stack-allocated or static array with runtime-defined size.
int a[N]; // N should be determined during compilation
You should use heap-alloceted or dynamic array:
int *a;
a = (int *)malloc(2 * n, sizeof(int)); // n may be defined by user input
There is no way to resize array without moving it to another place, and you can just create a new one (larger then first) and fill it with source numbers and zeroes:
#include <stdio.h>
int main() {
int n = 0;
printf("Enter the length of the array: ");
scanf("%d", &n);
int *a1 = (int *)malloc(n, sizeof(int));
int *a2 = (int *)malloc(n * 2, sizeof(int));
printf("Enter the elements of the array: ");
int i, number;
for(i = 0; i < n; i++){ //adds values to first array
scanf("%d",&number);
a1[i] = number;
}
for(i = 0; i < n; i++){ //copies and sets the arrays the same
a2[i * 2] = a1[i];
a2[i * 2 + 1] = 0;
}
for(i = 0; i < n * 2; ++i){
printf("%d ", a2[i]);
}
}
Add below code in last loop.
for ( j=0, i=0; i <= n; i++ ) {
a2[j++] = a1[i];
a2[j++] = 0;
}
You have to multiply the indices by 2:
for(i = 0; i < n; ++i) { //copies and sets the arrays the same
a2[2 * i] = a1[i];
}
Not only that, odd-indexed elements of a2 should be set to zero. You can do it explicitly in loop:
for(i = 0; i < n; ++i) a2[2 * i + 1] = 0;
But simpler is to first initialize the array with zeroes:
int a2[2 * n] = {0};
Even-numbered elements will later be overwritten with elements of a1.
Related
I am trying to Multiply the matrix with use of threads. The code seems to be working. I just need to know how to specify the number of threads so that I can count how much time it's taking. I want to create a table of threads and time it's taking to compute the matrix.
I am dynamically allocating the matrix and filling it with random numbers.
I am creating threads to compute the resultant matrix.
C Program to multiply two matrix using pthreads without use of global variables
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<stdlib.h>
//Each thread computes single element in the resultant matrix
void *mult(void* arg)
{
int *data = (int *)arg;
int k = 0, i = 0;
int x = data[0];
for (i = 1; i <= x; i++)
k += data[i]*data[i+x];
int *p = (int*)malloc(sizeof(int));
*p = k;
//Used to terminate a thread and the return value is passed as a pointer
pthread_exit(p);
}
//Driver code
int main()
{
int i, j, k, row1, col1, row2, col2, r, sum;
printf("Enter the number of rows for matrix 1\n");
scanf("%d",&row1);
printf("Enter the number of columns for matrix 1 \n");
scanf("%d",&col1);
printf("Enter the number of rows for matrix 2 \n");
scanf("%d",&row2);
printf("Enter the number of columns for matrix 2\n");
scanf("%d",&col2);
int **a = (int **) malloc(row1 * sizeof(int *));
for(i=0;i<row1;i++)
a[i] = (int *) malloc(col1 * sizeof(int));
int **b = (int **) malloc(row2 * sizeof(int *));
for(i=0;i<row2;i++)
b[i] = (int *) malloc(col2 * sizeof(int));
for(i=0;i<row1;i++)
{
for(j=0;j<col1;j++)
{
a[i][j] = (rand()%9) + 1;
}
}
for(i=0;i<row2;i++)
{
for(j=0;j<col2;j++)
{
b[i][j] = (rand()%9) +1;
}
}
int N = row1*col2;
//declaring array of threads of size row1*col2
pthread_t *threads;
threads = (pthread_t*)malloc(N*sizeof(pthread_t));
int count = 0;
int* data = NULL;
for (i = 0; i < row1; i++)
for (j = 0; j < col2; j++)
{
//storing row and column elements in data
data = (int *)malloc((N)*sizeof(int));
data[0] = col1;
for (k = 0; k < col1; k++)
data[k+1] = a[i][k];
for (k = 0; k < row2; k++)
data[k+col1+1] = b[k][j];
//creating threads
pthread_create(&threads[count++], NULL,
mult, (void*)(data));
}
printf("RESULTANT MATRIX IS :- \n");
for (i = 0; i < N; i++)
{
void *k;
//Joining all threads and collecting return value
pthread_join(threads[i], &k);
int *p = (int *)k;
printf("%d ",*p);
if ((i + 1) % col2 == 0)
printf("\n");
}
return 0;
}
I am relatively new to c, and I still have not been able to find a good way of passing and returning a multi-dimensional array from a function. I found the following code, however it doesn't seem like a good way to do things because it passes the array and then to use it, it creates a duplicate with the malloc function. Is there a way to do it without the copying and malloc function, or a better way to pass and return an 2d array from a function in c in general? Thanks.
#include <stdio.h>
#include <stdlib.h>
int **matrix_sum(int matrix1[][3], int matrix2[][3]){
int i, j;
int **matrix3;
matrix3 = malloc(sizeof(int*) * 3);
for(i = 0; i < 3; i++) {
matrix3[i] = malloc(sizeof(int*) * 3);
}
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
return matrix3;
}
int main(){
int x[3][3], y[3][3];
int **a;
int i,j;
printf("Enter the matrix1: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&x[i][j]);
}
}
printf("Enter the matrix2: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&y[i][j]);
}
}
a = matrix_sum(x,y); //asigning
printf("The sum of the matrix is: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
printf("%d",a[i][j]);
printf("\t");
}
printf("\n");
}
//free the memory
for(i = 0; i < 3; i++) {
free(a[i]);
}
free(a);
return 0;
}
The array are not copied for agurments. Just pointers to the first elements of them (int[3]) are passed.
To avoid malloc(), you should add another argument to specify the array where the result should be stored.
#include <stdio.h>
void matrix_sum(int matrix3[][3], int matrix1[][3], int matrix2[][3]){
int i, j;
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
}
int main(){
int x[3][3], y[3][3], a[3][3];
int i,j;
printf("Enter the matrix1: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&x[i][j]);
}
}
printf("Enter the matrix2: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&y[i][j]);
}
}
matrix_sum(a,x,y);
printf("The sum of the matrix is: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
printf("%d",a[i][j]);
printf("\t");
}
printf("\n");
}
return 0;
}
An array can be declared and used through a reference (pointer)
for instance
char array[] = {'h','e','l', 'l', 'o', '\0'};
char *pointer = array;
the way pointers work can be understood by calling sizeof() on a given type
printf("char:%d\nchar_pointer: %d\n", sizeof(char), sizeof(char*));
which results in the following output.
char:1
char_pointer: 4
these results mean that even though a char has 1byte, its pointer needs 4 in order to be stored in memory thus, they are not the same type.
now in order to pass an array as an argument to a function you have many options
void function1(array[4])
{
//this function can receive an array of four elements and only four elements;
//these types of functions are useful if the algorithm inside the function only works
//with a given size. e.g. matrix multiplication
}
//or
void function2(char array[], int size)
{
//this function can receive an array of elements of unknown size, but you can
//circumvent this by also giving the second argument, the size.
int i;
for(i = 0; i <= size; i++)
{
printf("%c", array[i]);
}
}
In order to use or call any of these functions you could pass the array or a pointer to the array
function2(array, 5);
function2(pointer, 5);
//these results are the same
The same applies to a multidimensional array
void function3(char** multi_dim_array, array_size_first_dim, array_size_second_dim);
//and you can call it by using the same syntax as before;
void main(int argc, char[] argv*)
{
char** multi_dim = malloc(sizeof(char*) * 3);
int i;
for(i = 0; i<=3 ; i++)
{
multi_dim[i] = malloc(sizeof(char) * 4);
}
function3(multi_dim, 3,4);
}
if you want to return a multidimensional array you can just return a pointer
char **malloc_2d_array(int dim1, int dim2)
{
char ** array = malloc(sizeof(char*)*dim1);
int i;
for(i = 0; i<=dim2; i++)
{
array[i] = malloc(sizeof(char) * dim2);
}
return array;
}
as a final note, the reason the code you found, copies the array, is because of functional programming(a way of programming if you will) where a function call cant modify its input, thus it will always create a new value;
First of all this is not gonna be a technical explanation. I am just gonna try and explain what works not why.
For passing a multidimensional array you can use either an array with a defined size as you did in your example code:
void matrix_sum(int matrix3[][3])
Or if you don't want to use a defined size and want to take care of memory usage you can use a pointer to a pointer. For this case you also need to pass the size (unless you are passing NULL-terminated strings). Like this:
void matrix_sum(int **matrix, int size)
BUT for this case you can't call the function with a "normal" array. You need to use a pointer to a pointer or a pointer to an array.
int **matrix;
// make sure to allocate enough memory for this before initializing.
or:
int *matrix[];
For returning an array you can just return a pointer to a pointer like you did in your code example.
But you don't need to return an array, because if you change a value in an array, (in a different function) the value will stay changed in every other function.
A short example for this:
#include <stdio.h>
void put_zeros(int matrix[][3])
{
int i;
int j;
i = 0;
while (i < 3)
{
j = 0;
while (j < 3)
{
matrix[i][j] = 0;
j++;
}
i++;
}
}
void print_matrix(int matrix[][3])
{
int i;
int j;
i = 0;
while (i < 3)
{
j = 0;
while (j < 3)
{
printf("%d ", matrix[i][j]);
j++;
}
printf("\n");
i++;
}
}
int main(void)
{
int matrix_first[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
print_matrix(matrix_first);
put_zeros(matrix_first);
print_matrix(matrix_first);
}
This will print "1 2 3 4 5 6 7 8 9" because that's the first value we assigned.
After calling put_zeros it will contain and print "0 0 0 0 0 0 0 0 0" without the put_zeros returning the array.
1 2 3
4 5 6
7 8 9
0 0 0
0 0 0
0 0 0
I'm currently trying to learn C, and the exercise I found online has me creating a function that returns the index of the smallest value in an array. This is my function:
int return_index_of_minimum(int A[10], int i, int j){
int minimum_value = A[i];
int index_to_return = 0;
for (int index = i; index < j; index++){
if (A[index] < minimum_value){
minimum_value = A[index];
index_to_return = index;
}
}
return index_to_return;
}
i and j are the lower and upper bound numbers the function should look in. For example, if i is 4 and j is 8, that means the function will return the index of the smallest value between indices 4 and 8.
Here is my main function:
#include <stdio.h>
int main(){
int numbers[10];
int user_input = 0;
for (int i = 0; i < 10; i++){
printf("Please enter a number: ");
scanf_s("%d", &user_input);
numbers[i] = user_input;
}
for (int i = 0; i < 10; i++){
int index_of_min_value = return_index_of_minimum(numbers, i, 10);
int old_num = numbers[index_of_min_value];
int new_num = numbers[i];
numbers[index_of_min_value] = new_num;
new_array[i] = old_num;
}
for (int i = 0; i < 10; i++){
printf("%d\n", new_array[i]);
}
}
The user would first enter a bunch of numbers and that would populate the array with the user's values. The idea is to use return_index_of_minimum to return the index of the smallest item in an array, and then set that equal to numbers[0] with a for loop, and then numbers[1], and then so on. old_num is the lowest number in the array, at its previous index. Here, I'm trying to swap that minimum value with whatever is at numbers[i] However, when I'm done sorting through the entire array, and am printing it out, I see that 10 (when the user enters 1-10 randomly for values) is at index 0, and then the rest of the numbers are in order. Does anybody see what is wrong here?
Here is a fix:
int return_index_of_minimum(int A[10], int i, int j){
int minimum_value = A[i];
int index_to_return = i;
...
}
Unfortunately this code doesn't have protection of invalid arguments, but otherwise this is an answer you've been looking for.
The reason is in call index_of_minimum(a, 9, 10): the loop performs only one iteration for index = 9, and because the minimum value is already initialized to value a[9], the index_to_return is not updated due to condition check.
This is a different approach that doesn't have same issue:
int return_index_of_minimum(int A[10], int i, int j){
/* assuming i < j */
int minimum_value = A[i];
int index_to_return = i; /* First element is a candidate */
for (int index = i + 1; index < j; index++){
/* Iterate from second element */
if (A[index] < minimum_value){
minimum_value = A[index];
index_to_return = index;
}
}
return index_to_return;
}
I believe there is an error in your return_index_of_minimum function.
int index_to_return = 0;
The problem lies I think here as the value of index_to_return will stay 0 if you call return_index_of_minimum(numbers, 5, 10); and that numbers[5] if the actual minimum.
However why not use a simple bubble-sort like the one implemented here
/*
* C program to sort N numbers in ascending order using Bubble sort
* and print both the given and the sorted array
*/
#include <stdio.h>
#define MAXSIZE 10
int main(void)
{
int array[MAXSIZE];
int i, j, num, temp;
printf("Enter the value of num \n");
scanf("%d", &num);
printf("Enter the elements one by one \n");
for (i = 0; i < num; i++)
{
scanf("%d", &array[i]);
}
printf("Input array is \n");
for (i = 0; i < num; i++)
{
printf("%d\n", array[i]);
}
/* Bubble sorting begins */
for (i = 0; i < num; i++)
{
for (j = 0; j < (num - i - 1); j++)
{
if (array[j] > array[j + 1])
{
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
printf("Sorted array is...\n");
for (i = 0; i < num; i++)
{
printf("%d\n", array[i]);
}
}
I made a program that adds two matrices and displays their sum with a max dimension of 100.
/* This program asks the user for 2 matrices called A and B, as integers,
and displays their sum, C. The max dimension of each matrix is 100. */
#include <stdio.h>
// Construct function
void construct()
{
int m, n, i, j; // Variables
int first[100][100], second[100][100], sum[100][100]; // Matrices variables
printf("Please enter the number of rows: ");
scanf("%d", &m);
printf("Please enter the number of columns: ");
scanf("%d", &n);
// User enters m x n amount whole numbers for the Matrix A
printf("Enter Matrix A\n");
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &first[i][j]);
// User enters m x n amount whole numbers for the Matrix B
printf("Enter Matrix B\n");
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &second[i][j]);
// Adds the sum of Matrix A and Matrix B
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
sum[i][j] = first[i][j] + second[i][j];
// Display the sum of Matrix A and Matrix B
printf("A + B =\n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
printf("%d ", sum[i][j]);
printf("\n"); // Prints new line
}
return ;
}
// Main Function
int main()
{
construct(); // Calls construct function
return 0;
}
Now I need to change it so there is no max size for each matrix.
So I need to use malloc to create my arrays.
So I cant use int A[rows][cols].
This is what I did to covert arrays to malloc. It compiles but it crashes after I entered all the integers. Need help.
/* This program asks the user for 2 matrices called A and B, as integers,
and displays their sum, C. The max dimension of each matrix is 100. */
#include <stdio.h>
#include <stdlib.h>
// Construct function
void construct()
{
int m, n, i, j; // Variables
int *first = NULL;
int *second = NULL;
int *sum = NULL; // Matrices variables
printf("Please enter the number of rows: ");
scanf("%d", &m);
printf("Please enter the number of columns: ");
scanf("%d", &n);
first = (int*)malloc(m * sizeof(int));
second = (int*)malloc(n * sizeof(int));
sum = (int*)malloc(m * n * sizeof(int));
// User enters m x n amount whole numbers for the Matrix A
printf("Enter Matrix A\n");
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &first);
// User enters m x n amount whole numbers for the Matrix B
printf("Enter Matrix B\n");
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &second);
// Adds the sum of Matrix A and Matrix B
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
sum = *first + *second;
// Display the sum of Matrix A and Matrix B
printf("A + B =\n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
printf("%d ", sum);
printf("\n");
}
return ;
}
// Main Function
int main()
{
construct(); // Calls construct function
return 0;
}
First of all, you don't need to use malloc. Just move the array definitions to be after you have inputted m and n:
int first[m][n];
printf("Enter Matrix A\n");
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &first[i][j]);
and similarly for second and sum.
If the matrices might be larger than 100x100 then it might be good to use malloc to avoid the risk of a stack overflow; the way to do that is:
int (*first)[n] = malloc(m * sizeof *first);
printf("Enter Matrix A\n");
// etc.
and at the end, free(first);. No other changes are required.
In your attempt to use malloc, you didn't allocate enough space, and you didn't scanf into the space you allocated either (instead you overwrote the pointer to the allocated space).
I'm trying to make a simple ranking list of a person Id and its name. The list is sorted by Id, in ascending order.
The inputs I enter is:
Enter: Id Name (5 time)
9 Ace
5 Bob
6 Cindy
7 Dean
2 Erik
The output I expect to get is
Sorted id is...
2 Erik
5 Bob
6 Cindy
7 Dean
9 Ace
The current result I get is
Sorted id is...
2 ABCDErik
5 BCDErik
6 CDErik
7 DErik
9 Erik
Below is the code I'm currently using. It's a Bubble Sort function:
int sorting(int n, int *array)
{
int temp;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < (n - i - 1); j++)
{
if (array[j] > array[j + 1])
{
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
And my Main program:
int main()
{
int i, j, temp;
int num = 5;
int *id = (int *) malloc(sizeof(int) * 5);
char *name = malloc(sizeof(char) * 10);
printf("Enter: Id Name (5 time) \n");
for (i = 0; i < num; i++)
{
scanf("%d %s", &id[i], &name[i]);
}
sorting(num, id);
printf("Sorted id is...\n");
for (i = 0; i < num; i++)
{
printf("%d \t %s \n", id[i], &name[i]);
}
free(id);
free(name);
return 0;
}
Is there a way to make the correct names "chained" with its id?
You have got your data stored in a wrong way. When you allocate memory with the intent to store strings inside, you have to properly calculate the memory size based on the string length.
Also having a char * is a pointer to one string, the array of strings should become char * [].
#define STRINGCOUNT 20
#define STRINGLEN 100
int maxlen= ... calculated somehow
int stringcnt= ... calculated somehow
char *stringarray[STRINGCOUNT];
for (i=0; i<STRINGCOUNT; i++)
stringarray[i] = malloc(maxlen);
Another approach is to statically allocate the data:
char stringarray[STRINGCOUNT][STRINGLEN]
A third approach is to allocate everything dynamically. Note that with array of string pointers and dynamic allocation each string may be allocated of different length.
char **stringarray=calloc(stringcnt,sizeof(char *));
for (i=0; i<stringcnt; i++)
stringarray[i] = malloc(maxlen);
// or
stringarray[i] = strdup(somestring);
Also you have to keep in mind that is C strings are teminated with 0 character, so for storing Bob you will need at least 4 bytes.
What you currently do is to allocate 10 bytes buffer and them put there all the strings starting from different position.
About chaining data, the concept in the C language is called struct. In your case the definition will be
struct {
int rank;
char *name;
} items;
Structs can also be statically or dynamically allocated but you have to know that the name element is a pointer to a string and if not explicitly initialized it will not point to allocated memory and cannot be used.
Of connecting two arrays it is index.
So to sort by passing the index and comparison sequences.
#include <stdio.h>
#include <stdlib.h>
void sorting(int n, int *array, int *indexs){
int temp;
for (int i = 0; i < n -1 ; ++i){
for (int j = i + 1; j < n; ++j){
if (array[indexs[i]] > array[indexs[j]]){
temp = indexs[i];
indexs[i] = indexs[j];
indexs[j] = temp;
}
}
}
}
int main(){
int i, j, temp;
int num = 5;
int *id = (int *) malloc(num * sizeof(int));
int *indexs = malloc(num * sizeof(int));
char **name = malloc(num * sizeof(char*));
for(i = 0 ; i < num ; ++i){
name[i] = malloc(sizeof(char) * 10);
indexs[i] = i;
}
printf("Enter: Id Name (5 time) \n");
for (i = 0; i < num; i++)
scanf("%d %9s", &id[i], name[i]);
sorting(num, id, indexs);
printf("Sorted id is...\n");
for (i = 0; i < num; i++){
printf("%d \t %s \n", id[indexs[i]], name[indexs[i]]);
free(name[indexs[i]]);
}
free(id);
free(name);
return 0;
}
The simple way to chain the names with their ids is to use a structure and allocate an array of that structure. You can modify your program like this:
typedef struct name_id_pair {
int id;
char name[10];
} name_id_pair_t;
int sorting(int n, name_id_pair_t *array)
{
int i, j;
name_id_pair_t temp;
for (i = 0; i < n; i++)
{
for (j = 0; j < (n - i - 1); j++)
{
if (array[j].id > array[j + 1].id)
{
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
int main()
{
int i, j;
int num = 5;
name_id_pair_t *arr = (name_id_pair_t *) malloc(sizeof(name_id_pair_t) * 5);
printf("Enter: Id Name (5 time) \n");
for (i = 0; i < num; i++)
{
scanf("%d %s", &arr[i].id, &arr[i].name);
}
sorting(num, arr);
printf("Sorted id is...\n");
for (i = 0; i < num; i++)
{
printf("%d \t %s \n", arr[i].id, arr[i].name);
}
free(arr);
return 0;
}
You never allocate memory for more than one name.
char *name = malloc(sizeof(char) * 10);
This allocates ten characters, plenty of room for one short name and that's it.