Flattening a 2D array in C without malloc etc - arrays

So I have been struggling with this for quit some time and I'm just not able to figure out how I'm supposed to flatten this randomly generated 5*15 2D array into a 1D and print it without using malloc but instead just for loops. And I'm slowly getting unhinged
This is the code for the printing random array.
#include <stdio.h>
#include <stdlib.h>
int main() {
unsigned short i, j;
int ar[5][15];
puts("The array: ");
for(i = 0; i < 5;i++) {
for(j = 0; j < 15;j++) {
printf("%d ", rand()%10);
}
printf("\n");
}
return 0;
}

If you just want to print them as if it's 1D-array just comment printf("\n"); in the outer for loop.
But, if you want the data from 2D-array in an 1D-array, you've to copy them individually.
#include <stdio.h>
#include <stdlib.h>
#define ROWS 5
#define COLS 15
int main() {
unsigned short i, j;
int ar[ROWS][COLS];
int flat_array [ROWS * COLS];
puts ("2D array: ");
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
ar[i][j] = rand() % 10;
flat_array[COLS * i + j] = ar[i][j];
printf ("%d ", ar[i][j]);
}
printf ("\n");
}
printf("\nFlattened Array: \n");
for (int fi = 0; fi < ROWS * COLS; )
printf ("%d ", flat_array[fi++]);
return 0;
}
i.e. If you've a 2D array of size [M][N] and want to flatten it to an 1D array of size [M*N]
int Arr_2D[M][N]; // with data
int Arr_1D[M*N];
for (int ri = 0; ri < M; ++ri)
for (int ci = 0; ci < N; ++ci)
Arr_1D[ri * N + ci] = Arr_2D [ri][ci];
Also, Data in true-2D-array is stored in memory contiguously, as if a true-1D-array. So :
#include <stdio.h>
#include <stdlib.h>
#define ROWS 5
#define COLS 15
int main() {
int Arr_2D[ROWS][COLS];
printf ("Original 2D Array: \n");
for (int ri = 0; ri < ROWS; ++ri) {
for (int ci = 0; ci < COLS; ++ci) {
Arr_2D[ri][ci] = rand() % 10;
printf ("%d ", Arr_2D[ri][ci]);
}
printf ("\n");
}
printf ("\nAccessing a 2D array as 1D array: \n");
int *AP_1D = (int *) Arr_2D;
for (int ni =0; ni < ROWS * COLS; )
printf ("%d ", AP_1D[ni++]);
printf ("\n");
return 0;
}
There is also, Row & Column major memory storage, we digress.

Related

How to use a pointer (to a Matrix) as an argument in a Function in C?

I'm trying to write a code in C that sum two 4x4 matrix.
But I want my function to have a pointer as my arguments. The only error I'm getting is the time I'm trying to sum up in the function. Could someone help me?
#include <stdio.h>
#include <locale.h>
int i = 0, j = 0;
void calc_soma(int* mat_A, int* mat_B, int* mat_C)
{
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
mat_C[i][j] = mat_A[i][j] + mat_B[i][j];
printf("%d", mat_C[i][j]);
}
}
}
int main()
{
setlocale(LC_ALL, "Portuguese");
int i=0, j=0;
int mA[4][4], mB[4][4], mC[4][4];
int *mat_A, *mat_B, *mat_C;
for(i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
printf("Type in the value for Matrix A [%d][%d]: ", i, j);
scanf_s("%d", &mA[i][j]);
}
}
i, j = 0;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
printf("Type in the value for Matrix B [%d][%d]: ", i, j);
scanf_s("%d", &mB[i][j]);
}
}
*mat_A = &mA;
*mat_B = &mB;
return 0;
}
The types of pointers for the arguments are wrong. You want to pass (the pointer to the first elements of) arrays like int mA[4][4];, so they should be pointers to int[4].
void calc_soma(int (*mat_A)[4], int (*mat_B)[4], int (*mat_C)[4])
{
/* same as original */
}
They can simply be written like this:
void calc_soma(int mat_A[][4], int mat_B[][4], int mat_C[][4])
{
/* same as original */
}
Then the function can be called like:
calc_soma(mA, mB, mC);
The purpose of mat_A and mat_B are unclear, but if you want to get pointers to the matrice like &mA, it should be int(*)[4][4]. Note that dereferencing (like *mat_A) uninitialized pointers will invoke undefined behavior.
int main()
{
setlocale(LC_ALL, "Portuguese");
int i=0, j=0;
int mA[4][4], mB[4][4], mC[4][4];
int (*mat_A)[4][4], (*mat_B)[4][4], (*mat_C)[4][4];
/* omit */
mat_A = &mA;
mat_B = &mB;
return 0;
}
To use functions like
void calc_soma(int* mat_A, int* mat_B, int* mat_C)
you should express the matrice by 1D array to match with the format. It will be like this:
#include <stdio.h>
#include <locale.h>
#define ROWS 4
#define COLS 4
int i = 0, j = 0;
void calc_soma(int* mat_A, int* mat_B, int* mat_C)
{
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
mat_C[i * COLS + j] = mat_A[i * COLS + j] + mat_B[i * COLS + j];
printf("%d", mat_C[i * COLS + j]);
}
}
}
int main()
{
setlocale(LC_ALL, "Portuguese");
int i=0, j=0;
int mA[ROWS * COLS], mB[ROWS * COLS], mC[ROWS * COLS];
for(i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
printf("Type in the value for Matrix A [%d][%d]: ", i, j);
scanf_s("%d", &mA[i * COLS + j]);
}
}
i, j = 0;
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
printf("Type in the value for Matrix B [%d][%d]: ", i, j);
scanf_s("%d", &mB[i * COLS + j]);
}
}
calc_soma(mA, mB, mC);
return 0;
}

C language 2d array fill diagonal with numbers from 1 to n

I have a 2d array filled with 0's and i'm trying to fill the main diagonal with numbers from 1 to n, this is the main code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand(time(NULL));
int m, n, i, j;
printf("Number of rows and columns:");
scanf("%d", &n);
int a[n][n];
for (i = 0; i < n; i++)
for(j = 0; j < n; j++)
a[i][j] = rand() % 1;
printf("The matrix is:\n");
for (i = 0; i < n; i++)
{
printf(" \n ");
for(j = 0; j < n; j++)
{
printf(" %d\t ", a[i][j]);
}
}
}
What I've tried to do is to fill the diagonal manually, but that's not what I want to do. I want to make it fill itself automatically. I need to do it without using any functions.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
arr[i][j] = ((i == j) * (i + 1));
}
}
The simplest way is to add this part after you fill the matrix with zeros.
for (i = 0; i < n; i++)
arr[i][i] = i + 1;

initialization of arrays while operating with mallocs

Given the following piece of code, I don't understand why do we have to initialize every single row of the matrix when we have already created enough space in the stack.
#include <stdio.h>
#include <stdlib.h>
main() {
int **w;
int i, j;
int m, n;
printf("Number of rows in the matrix: ");
scanf("%d", &m);
printf("Number of columns in the matrix: ");
scanf("%d", &n);
w = (int **)malloc(m * n * sizeof(int));
for (i = 0; i < m; i++)
w[i] = (int *)malloc(n * sizeof(int));
for (i = 0; i < m; i++)
for (j = 0; j < n; j++) {
printf("Element [%d][%d]: ", i + 1, j + 1);
scanf("%d", &w[i][j]);
}
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("Element [%d][%d]: %d\n", i + 1, j + 1, w[i][j]);
}
There are many issues in your code:
space is not allocated on the stack, but from the heap.
in both cases, memory allocated for the objects is uninitialized, which means it is not initialized to anything in particular and can have any value whatsoever. Relying on any particular contents is undefined behavior.
the matrix dimensions and all the matrix elements are read from standard input with scanf(). Yet you do not check for scanf() failure to convert integers from the characters read from stdin, so any invalid or missing input is going to cause undefined behavior at some point in the program.
your matrix is actually structured as an array of pointers to arrays of int, which is fine, but inconsistent with the size arguments used to allocate the first array: w = (int **)malloc(m * n * sizeof(int)); should be
w = malloc(m * sizeof(*w));
you could easily get objects pre-initialized to 0 by using calloc() instead of malloc():
for (i = 0; i < m; i++)
w[i] = calloc(n, sizeof(int));
you should also check for malloc() failure and exit with an appropriate diagnostic message.
main() is an obsolete prototype for the main function. You should either use int main(), int main(void) or int main(int argc, char *argv[])...
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int get_int(void) {
int n;
if (scanf("%d", &n) != 1) {
printf("invalid input\n");
exit(EXIT_FAILURE);
}
return n;
}
void xalloc(size_t size) {
void *p = calloc(size, 1);
if (p == NULL) {
printf("out of memory for %zu bytes\n", size);
exit(EXIT_FAILURE);
}
return p;
}
int main() {
int **w;
int i, j;
int m, n;
printf("Number of rows in the matrix: ");
m = get_int();
printf("Number of columns in the matrix: ");
n = get_int();
w = xalloc(m * sizeof(*w));
for (i = 0; i < m; i++) {
w[i] = xalloc(n * sizeof(int));
}
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("Element [%d][%d]: ", i + 1, j + 1);
w[i][j] = get_int();
}
}
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("Element [%d][%d]: %d\n", i + 1, j + 1, w[i][j]);
}
}
for (i = 0; i < m; i++) {
free(w[i]);
}
free(w);
return 0;
}

C program printing wrong output

I am trying to create a program which prints a matrix of integers, but the output returns weird numbers before the actual matrix. There are no compiling errors.
This is what my code looks like: //ignore void function for now, focus on main function::
#include <stdio.h>
#include <stdlib.h>
//array[30][30] = 2D array of max 30 rows and 30 columns
//n = number of rows and columns
void printmatrix(int array[30][30], int n){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
printf("%d", array[i][j]);
}
printf("\n");
}
return;
}
int main(){
int n;
scanf("%d", &n);
int ints2D[n][n];
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
scanf("%d", &ints2D[i][j]);
}
}
printmatrix(ints2D, n);
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
printf("%d ", ints2D[i][j]);
}
printf("\n");
}
return 0;
}
And this is my output (I only want the last three lines)
123
-514159984327663
-51415932632766-514159305
1 2 3
4 5 6
7 8 9
You are missing a space in "%d" in printmatrix, and, more importantly, it is not proper to pass an int [n][n] array for an int [30][30] parameter unless n is 30.
Change void printmatrix(int array[30][30], int n) to void printmatrix(int n, int array[n][n]), and change printmatrix(ints2D, n); to printmatrix(n, ints2D);. That makes the type of the argument you are passing match the type of the parameter.
In your function args you defined the array as fixed size ([30][30]) but you are passing a VLA ([3][3] in your example) which makes it find uninitialized memory and why you are seeing the strange numbers.
#Eric Postpischil answer is spot on. Another way to solve it: 2d arrays could be flatten into 1d. Here is a working code for you:
#include <stdio.h>
#include <stdlib.h>
//array[30][30] = 2D array of max 30 rows and 30 columns
//n = number of rows and columns
void printmatrix(int *array, int n){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
printf("%d ", array[i * n + j]);
}
printf("\n");
}
return;
}
int main(){
int n;
scanf("%d", &n);
int ints2D[n * n];
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
scanf("%d", &ints2D[i * n + j]);
}
}
printmatrix(ints2D, n);
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
printf("%d ", ints2D[i * n + j]);
}
printf("\n");
}
return 0;
}

Dynamic matrix inside struct, C programming

I need help. I want to learn how to create and use dynamic matrix which is element of structure, I want to fill matrix with zeros (0) and print it out, I tried many ways but no luck. Here is the code
#include <stdio.h>
#include <stdlib.h>
typedef struct matrica
{
int **mat;
int dim; //this is dimension of squared matrix
}MATRICA;
void form_matrix(MATRICA *matrica);
int main()
{
MATRICA matrix;
form_matrix(&matrix);
return 0;
}
void form_matrix(MATRICA *matrica)
{
int i, j;
MATRICA *br;
do
{
printf("Size of matrix ");
scanf("%d", &br->dim);
}while(br->dim < 4 || br->dim > 6);
matrica->mat = (int **) calloc(br->dim, sizeof(int *));
for(i = 0; i < br->dim; i++)
{
matrica->mat[i] = (int *) calloc(br->dim, sizeof(int));
for(j = 0; j < br->dim; j++)
{
matrica->mat[i][j] = 0;
}
}
for(i = 0; i < br->dim; i++)
for(j = 0; j < br->dim; j++)
printf("%d ", matrica->mat[i][j]);
}
what am I doing wrong, my loop inside function goes only once, can someone explain to me why?
Your program exhibits undefined behavior because you are dereferencing an uninitialized pointer br. You don't need it, you simply need a variable to store your dimension input.
int i, j, dim;
do
{
printf("Size of matrix ");
if (scanf("%d", &dim) != 1) {
printf("scan failed\n");
exit(EXIT_FAILURE);
}
}while(dim < 4 || dim > 6);
matrica->dim = dim;
/* ... replace all instances of br->dim with dim */

Resources