I'm trying to transpose a matrix in C while passing the matrix to a function and return a pointer to a transposed matrix. What am I doing wrong in the second while loop?
in main
ptr = (float *) getMatrix(numRowsB, numColsB);
transposePtr = transpose(ptr, numRowsB, numColsB);
printf("\nBtranspose =\n");
printMatrix(transposePtr, numColsB, numRowsB);
create matrix
float* getMatrix(int n, int m)
{
int i, j;
float *arrayPtr;
if ((n <= 0) || (m <= 0))
{
printf("function getMatrix(): matrix dimensions are invalid\n");
return NULL;
}
arrayPtr = (float *) malloc(n*m*sizeof(float));
if(arrayPtr == NULL)
{
printf("function getMatrix: Unable to malloc array\n");
return NULL;
}
transpose function
float* transpose(float *matrix, int n, int m)
{
int i = 0;
int j = 0;
float num;
float *transposed=(int*) malloc(sizeof(int)*n*m);
while(i < n-1)
{
while(j < m-1)
{
num = *(matrix+i*m+j);
*(transposed+j*m+i)= num;
j++;
}
i++;
}
return transposed;
}
print fucntion
void print(float *matrix, int n, int m)
{
int i = 0;//row counter
int j = 0;//col counter
for(i = 0; i < n; i++){
printf("\n");
for(j = 0; j < m; j++){
printf("%f ", *(matrix + i*n + j));
}
}
}
Example input:
1 2 3
4 5 6
Output:
1.000000 0.000000
2.000000 3396.580087
-0.000000 0.000000
Part of the problem was your print function
Here is a version of your functions that works:
float* transpose(float *matrix, int n, int m)
{
int i = 0;
int j = 0;
float num;
float *transposed=malloc(sizeof(float)*n*m);
while(i < n) {
j = 0;
while(j < m) {
num = *(matrix + i*m + j);
*(transposed + i+n*j) = num; // I changed how you index the transpose
j++;
}
i++;
}
return transposed;
}
void print(float *matrix, int n, int m)
{
int i = 0;//row counter
int j = 0;//col counter
for(i = 0; i < n; i++){
printf("\n");
for(j = 0; j < m; j++){
printf("%f ", *(matrix + i*m + j)); // Changed from n to m
}
}
}
There were a few things.
Use sizeof(float) instead of sizeof(int)
Your loop should be i < n and j < m instead of i < n-1 and j < m-1 and finally you need to reset j to zero every time
The matrix indexes in inner most loop of your transpose function was incorrect
Your print function was using the wrong variable in the multiplication
Also it is generally considered bad practice to cast the result of malloc in C.
Related
I'm trying to write an iterative function that computes all the permutations of an array of numbers given in input.
Here is the code I've written so far.
void permute(int *a, int size){
int j=0, i, h=0, m;
bool flag=true;
int f = factorial(size);
int *arr, *res;
int counter=0;
arr = malloc(f*sizeof(int));
for(i=0; i<f; i++)
arr[i] = 0;
while (j < f) {
if(arr[j]<j)
{
if(j%2 == 0)
{
swap(a[0],a[j]);
} else {
swap(a[arr[j]], a[j]);
}
arr[j]++;
j=0;
} else{
arr[j] = 0;
j++;
}
printf("%d\n",a[j] );
}
}
The code doesn't compute well all the permutations and goes into a long loop. Can someone help me, please? Thanks to everyone.
Your code is close but includes some problems. For instance, the while loop
while (j < f) will assign j to a value out of bound of the array a.
Instead would you please try:
#include <stdio.h>
#include <stdlib.h>
int factorial(int x)
{
int i;
int y = 1;
for (i = 1; i <= x; i++) {
y *= i;
}
return y;
}
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(int *a, int size)
{
int i, j = 0;
int f = factorial(size);
int *arr;
arr = calloc(f, sizeof(int)); // the members are initialized to 0
// print the original array
for (i = 0; i < size; i++) {
printf("%d%s", a[i], i == size - 1 ? "\n" : " ");
}
while (j < size) {
if (arr[j] < j) {
if (j % 2 == 0) {
swap(a + 0, a + j);
} else {
swap(a + arr[j], a + j);
}
// print the rearranged array
for (i = 0; i < size; i++) {
printf("%d%s", a[i], i == size - 1 ? "\n" : " ");
}
arr[j]++;
j = 0;
} else {
arr[j] = 0;
j++;
}
}
free(arr);
}
int main()
{
int a[] = {1, 2, 3}; // example
permute(a, sizeof a / sizeof a[0]); // the 2nd argument is the array length
return 0;
}
Output of the example:
1 2 3
2 1 3
3 1 2
1 3 2
2 3 1
3 2 1
So I try to do the Heap Sort in C for a row of an 2d array
So basically I find the smallest sum of all the rows from the array and I try to sort the elements of that row, for that I'm trying to store the index of the smallest row with a pointer but when I use pointer the programm it's not returning the index but the adress
//funcion to find the smallest row sum
void min_rand(int(*a)[50], int n, int m, int *mi)
{
int min_row = 0;
int i, j;
for (j = 0; j < m; j++)
min_row += a[0][j];
for (i = 0; i < n; i++) {
int sum_row = 0;
for (j = 0; j < m; j++)
sum_row += a[i][j];
if (sum_row < min_row) {
min_row = sum_row;
*mi = i;
}
}
}
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void heapify_c(int(*a)[50], int n, int i, int mi)
{
int largest = i;
int l = 2 *i + 1;
int r = 2 *i + 2;
if (l < n && a[mi][l] > a[mi][largest])
largest = l;
if (r < n && a[mi][r] > a[mi][largest])
largest = r;
if (largest != i) {
swap(&a[mi][i], &a[mi][largest]);
heapify_c(a, n, largest, mi);
}
}
void heapSort_c(int(*a)[50], int n, int mi)
{
for (int i = n / 2 - 1; i >= 0; i--)
heapify_c(a, n, i, mi);
for (int i = n - 1; i > 0; i--) {
swap(&a[mi][0], &a[mi][i]);
heapify_c(a, i, 0, mi);
}
}
int main()
{
int a[50][50];
int n, m, mi;
min_rand(a, n, m, &mi);
heapSort_c(a, n, mi);
return 0;
}
I don't print the sorted elements in the e.g. above but I just want to know if I'm doing something so terrebly wrong cause I did this before with counting sort and it worked without any problems
I am trying to raise a matrix to a power, using pointers but there is a mistake in my code I can't find.
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
>
int **alloc(int r, int c) {
int **d;
d = (int **)malloc(r * sizeof(int *));
for (int i = 0; i < r; i++) {
d[i] = (int *)malloc(c * sizeof(int));
}
return d;
void input(int **A, int r, int c) {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("[%d][%d]=", i, j);
scanf_s("%d", &A[i][j]);
}
}
}
void output(int **A, int r, int c) {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("%d ", A[i][j]);
}
printf("\n");
}
}
void power(int **A,int**D, int r, int c,int p) {
int i, j,k;
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
D[i][j] = A[i][j];
}
}
while (p) {
// this is the matrix multiplication, where I attempt to multiply my matrix A with itself, and store the result in D, which initially started as A's copy, and p is the power I'm raising it to.
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
for (k = 0; k < c; k++)
D[i][j] = D[i][j] + A[i][k] * D[k][j];
}
}
p--;
}
}
void main() {
int r, c;
int **A, **D;
printf("rows A: ");
scanf_s("%d", &r);
printf("columns A: ");
scanf_s("%d", &c);
A = alloc(r, c);
printf("\nValues of A:\n");
input(A, r, c);
printf("\nMatrIX A is:\n");
output(A, r, c);
D = alloc(r, c);
printf("input the value you want to raise your matrix to: ");
int p;
scanf_s("%d", &p);
power(A, D, r, c, p);
printf("\nMatrix raised to said power is:\n");
output(D, r, c);
_getch();
}
When I input the rows and columns as 2 each, and input all values in the matrix as 1 and raise it to the power of 3, my answer should be
4 4
4 4
instead of
72 72
232 232
What is wrong in my code? If I were to print the D matrix before the multiplication, it would print it correctly, as:
1 1
1 1
Your two-step allocation looks okay, except that you don't free the memory after you're done. Your problem is in how you multiply the matrix:
Raising a matrix to a power involves multiplying it to itself. You can only do that if the matrix is square. You can replace all occurrences of rows r and columns c with a single dimension n.
When you do the actual multiplication:
D[i][j] = D[i][j] + A[i][k] * D[k][j];
you assign to D and read from it at the same time. Subsequent calculations (of the same multiplication) will see a changed value of D[i][j]. You will need a temporary "scratch" matrix.
Your code multiplies once too many. Also, Raising a matrix to the power of zero should yield the identity matrix.
Here's how your power function could look like:
void power(int **A, int **D, int n, int p)
{
int i, j,k;
// assign identity matrix to result D
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
D[i][j] = (i == j);
}
}
// create a scratch matrix
int **tmp = alloc(n);
while (p-- > 0) {
// multiply [tmp] = [A] * [D]
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
tmp[i][j] = 0;
for (k = 0; k < n; k++)
tmp[i][j] += A[i][k] * D[k][j];
}
}
// copy [D] = [tmp]
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
D[i][j] = tmp[i][j];
}
}
}
// TODO: clean up the scratch matrix
}
This is a code for multiplying two square matrices in C.
What is the difference between using malloc and calloc in void multiply() function?
When using malloc, I am getting garbage values, but calloc is providing the right answer.
Only the first row is outputting garbage values so is it an issue with the way malloc allocates space in the heap as compared to calloc?
#include <stdio.h>
#include <stdlib.h>
int *getArray(int);
void display(int *, int, int);
void multiply(int *, int *, int);
int main() {
int n;
printf("enter dimension of square matrix:\n");
scanf("%d", &n);
int *arr1;
int *arr2;
arr1 = getArray(n);
display(arr1, n, n);
printf("\n now give input for next array");
arr2 = getArray(n);
display(arr2, n, n);
printf("\n\n\n");
multiply(arr1, arr2, n);
return 0;
}
int *getArray(int n) {
int *arr = (int *)malloc(n * n * sizeof(int));
printf("\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", (arr + i * n + j));
}
}
/*for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf(" %d ", *(arr + i * n + j));
}
printf("\n");
}*/
return arr;
}
void display(int *arr, int row, int col) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf(" %d ", *(arr + i * row + j));
}
printf("\n");
}
}
void multiply(int *arr1, int *arr2, int n) {
int *arr = (int *)calloc(n * n, sizeof(int));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
*(arr + i * n + j) += (*(arr1 + i * n + k)) * (*(arr2 + k * n + j));
}
}
}
printf("product of above matrices = \n\n");
display(arr, n, n);
}
The only functional difference between allocating memory with malloc() and with calloc() for the same size, assuming the size computation is accurate, is the latter initializes the block to all bits 0, whereas the former does not.
All bits 0 means all int values in the array are initialized to 0.
The inner loop in the multiply function only increments the element at row i and column j, therefore the function relies on implicit initialization of the array elements to 0. calloc() does that, but not malloc() so you definitely need to use calloc().
Also note these remarks:
in display the computation for the offset of the matrix element at row i column j should be printf(" %5d ", *(arr + i * col + j));
multiply should return arr and display() should be called in the main function.
you should check for scanf(), malloc() and calloc()` failure
you should free allocated memory
pointer arguments to objects that are not modified by the function should be const qualified so the function can be called with a pointer to a const object.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int *getArray(int);
void display(const int *, int, int);
int *multiply(const int *, const int *, int);
int main() {
int n;
printf("enter dimension of square matrix:\n");
if (scanf("%d", &n) != 1)
return 1;
printf("\n now give input for the first array");
int *arr1 = getArray(n);
if (!arr1)
return 1;
display(arr1, n, n);
printf("\n now give input for the second array");
int *arr2 = getArray(n);
if (!arr2)
return 1;
display(arr2, n, n);
printf("\n\n\n");
int *arr = multiply(arr1, arr2, n);
if (!arr)
return 1;
printf("product of above matrices = \n\n");
display(arr, n, n);
free(arr1);
free(arr2);
free(arr);
return 0;
}
int *getArray(int n) {
int *arr = malloc(sizeof(int) * n * n);
if (arr == NULL)
return NULL;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (scanf("%d", (arr + i * n + j)) != 1) {
free(arr);
return NULL;
}
}
}
return arr;
}
void display(const int *arr, int row, int col) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
printf(" %5d ", *(arr + i * col + j));
}
printf("\n");
}
}
int *multiply(const int *arr1, const int *arr2, int n) {
int *arr = calloc((size_t)n * n, sizeof(int));
if (arr == NULL)
return NULL;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
*(arr + i * n + j) += (*(arr1 + i * n + k)) * (*(arr2 + k * n + j));
}
}
}
return arr;
}
I can't seem to find any info on how to access elements of an array via pointer in a function, I tried following multiple answers but none of them seem to work for me.
My task is next: Write a program in C with m x n dimension with elements being randomly generated from 0 to 9. Using two new functions calculate the sum of even elements and count the number of elements being equal to zero.
#include <stdio.h>
#include <stdlib.h>
void SumEven(int *a, int n, int m, int *sum){
}
void EqualToZero(int *a, int n, int m, int *number){
}
int main()
{
int** a;
int m, n, l, i, j, r, sum;
printf("Enter number of columns for matrix: ");
scanf("%d", &m);
printf("Enter number of rows for matrix: ");
scanf("%d", &n);
a = (int **) malloc(m*sizeof(int));
for (l = 0 ; l < m ; l++){
a[l] = (int **) malloc(n*sizeof(int));
}
time_t t;
srand((unsigned)time(&t));
printf("\n");
printf("Your matrix is:\n");
printf("\n");
for(i = 0 ; i < m ; i++){
for(j = 0 ; j < n ; j++){
r = rand() % 10;
a[i][j] = r;
printf("%d ", r);
}
printf("\n");
}
printf("\n");
SumEven(&a, n, m);
return(0);
}
As you can see in the provided code I left those functions empty as I don't know how to pass the matrix to them and access their elements so I can be able to print my results.
Also my pseudo code for the logic for the functions themselves are:
if(a[i][j] % 2 == 0)
printf("%d ", a[i][j])
and
if(a[i][j] == 0)
printf("%d ", a[i][j])
Also those parameters of the function are predefined in my task, so I have to follow them.
EDIT: I also don't know if I'm even passing the same matrix to the function with SumEven(&a, n, m);. I tried outputing the address of the matrix and using printf("%d", &a) to display an address both from main() and SumEven() functions.
This code may help. It does the following:
1. For an arbitrary array of integers, sum the elements of the array
- using a pointer to the SUM function
2. For an arbitrary array of integers, count the number of zero elements in
the array - using a pointer to the COUNTZERO function
#include <stdio.h>
#include <stdlib.h>
// sum the elements of the matrix
void sum(int* arr, int rows, int cols, int* result)
{
int sum = 0;
int i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
sum = sum + arr[i*cols + j];
}
}
*result = sum;
}
// count the number of zero elements in the matrix
void countZero(int* arr, int rows, int cols, int* result)
{
int count = 0;
int i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
if (arr[i*cols + j] ==0) count = count + 1;
}
}
*result = count;
}
// arbitrary initialisation of 2D array of ints (force last entry of the array to equal zero - for testing purposes)
void init2D(int *arr, int rows, int cols) {
int i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
arr[i*cols + j] = 1;
}
}
// use this to test the countZero function
arr[(rows-1)*(cols-1)] = 0;
}
int main() {
int *array; // will hold a 2D array of integers
int N = 10; // arbitrary number of rows
int M = 5; // arbitrary num cols
// 2D array of integers expressed as one "contiguous row" of memory
// make sure your indexing is correct when referenceing the array for (i,j)th element
array = (int*)malloc(sizeof(int)*N*M);
if (array != NULL) {
init2D(array, N, M);
}
// the function pointer
void(*general)(int*,int,int,int*);
// will contain the sum result
int sumAll = 0;
int* ptsumAll = &sumAll;
// make the function pointer point to the sum function
general = ∑
// sum the contents of the array
general(array,N,M, ptsumAll);
printf("sum of array elements: %d\n", *ptsumAll);
// contains a count of the zero elements in the array
int count =0;
int* ptcount = &count;
// make the function pointer point to the count function
general = &countZero;
// count the number of zero element in the array
general(array, N, M,ptcount);
printf("number of zeros: %d\n", *ptcount);
free(array);
return 0;
}
some references:
https://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html
http://www.cprogramming.com/tutorial/function-pointers.html
I have added comments to help you with the code.
#include <stdio.h>
#include <stdlib.h>
void SumEven(int *a, int n, int m, int *sum){
//put this statement in 2 nested for loops of size n and m
if(a[i][j] % 2 == 0)
sum += a[i][j];
}
void EqualToZero(int *a, int n, int m, int *number){
//put this statement in 2 nested for loops of size n and m
if(a[i][j] == 0)
number++;
}
int main()
{
int** a;
int m, n, l, i, j, r, sum;
printf("Enter number of columns for matrix: ");
scanf("%d", &m);
printf("Enter number of rows for matrix: ");
scanf("%d", &n);
a = (int **) malloc(m*sizeof(int));
//should be m*sizeof(int*)
for (l = 0 ; l < m ; l++){
a[l] = (int **) malloc(n*sizeof(int));
//should be cast as (int*)
}
//I suggest you take look at declaring 2d arrays in C
time_t t;
srand((unsigned)time(&t));
printf("\n");
printf("Your matrix is:\n");
printf("\n");
for(i = 0 ; i < m ; i++){
for(j = 0 ; j < n ; j++){
r = rand() % 10;
a[i][j] = r;
printf("%d ", r);
}
printf("\n");
}
printf("\n");
SumEven(&a, n, m);
//need to pass &sum to this function. Also make sure it is initialized to 0
//call EqualToZero() function with proper parameters.
return(0);
//return 0; not return(0);
}
These will be your function prototypes:
void SumEven(int **a, int n, int m,int *sum);
void EqualToZero(int **a, int n, int m,int *number);
since you are passing a(double pointer) from calling then the there should be a double pointer(int **a) to receive it.
Calling:
SumEven(a, n, m,&sum);
EqualToZero(a, n, m,&number);
And this is how you can access the array inside your function:
void SumEven(int **a, int n, int m,int *sum){
int i,j,tsum=0;
for(i = 0 ; i < m ; i++){
for(j = 0 ; j < n ; j++){
if(a[i][j] % 2 == 0)
{
tsum+=a[i][j];
printf("%d ",a[i][j]);
}
}
}
*sum=tsum;
}
Also there is an error in this line a[l] = (int **) malloc(n*sizeof(int)); (‘int**’ to ‘int*’assignment),it should be a[l] = (int *) malloc(n*sizeof(int));.
Here's an example, given a 3D array
int buffer[5][7][6];
An element at location [2][1][2] can be accessed as buffer[2][1][2] or *( *( *(buffer + 2) + 1) + 2).
Reference
if(( *(*(a + i) + j) % 2 ) == 0 )
printf("%d", *(*(a + i) + j) )
if( *(*(a + i) + j) == 0 )
printf("%d", *(*(a + i) + j) )
This is how you do it.