C, scanning and printing Matrix using Pointers - c

void input(int (*a)[3]){
int i, j;
for(i = 0; i < 3; i++){
a += i;
for(j = 0; j < 3; j++)
scanf("%d",*a+j);
}
}
void print_matrix(int (*a)[3]){
int i, j;
for(i = 0; i < 3; i++){
a += i;
for(j = 0; j < 3; j++)
printf("%d ",*(*a+j));
printf("\n");
}
putchar('\n');
}
int main(){
int matrix[3][3];
input(matrix);
printf("Printing matrix using function: \n");
print_matrix(matrix);
int i, j;
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++)
printf("%d ", matrix[i][j]);
printf("\n");
}
return 0;
}
If I enter matrix like this:
1 1 1
2 2 2
3 3 3
Printing matrix using function produces correct output: 1 1 1 2 2 2 3 3 3.
But printing matrix using two loops produces output like this:
1 1 1
2 2 2
-5555 0 -22222
So I obviously have some error, but I can't figure out where. What I don't understand here is why this won't work for third row in matrix.
Note: I know this can be done without using pointers and functions, but that is not the point here, I want to do it exactly like this, just can't figure out what I did wrong.

replace a += i; with a += 1; in both the functions void input(int (*a)[3]) and void print_matrix(int (*a)[3]).
The reason is when i is 2 it goes out of the boundary. You are adding 2.
Also, move a += 1 after the 2nd for loop.

The problem is in how you're manipulating a in both input and print_matrix.
In input:
a += i; // problem is here
for(j = 0; j < 3; j++)
scanf("%d",*a+j);
On the first iteration, a is fine since 0 is added. It's also fine on the second, as 1 is added to move it to the next row. But on the third, it is incremented by 2, moving it outside of the bounds of the matrix.
You could simply replace a += i with a++, but if you do then you'll be writing everything one row down from where it should be.
Sample output with a += i replaced with a++:
[dbush] /tmp/x1
1 1 1
2 2 2
3 3 3
Printing matrix using function:
1 1 1
2 2 2
3 3 3
0 0 -668873792
1 1 1
2 2 2
For this to work properly, move a++ to the bottom of the outer for loop.
In input:
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++)
scanf("%d",*a+j);
a++;
}
In print_matrix:
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++)
printf("%d ",*(*a+j));
printf("\n");
a++;
}

Related

Why is the multiplication doubling in this C loop?

The code is supposed to take inputs to form a 3x3 Matrix and then multiply each term by the diagonal element of that line, but, for some reason that i don't know, it multiplies two times by the diagonal when the column index is bigger than the row index.
#include <stdio.h>
#define R 3
int a[R][R], i, j;
int main(void) {
for (i = 0; i < R; i++) {
for (j = 0; j < R; j++) {
printf("\nInsira o n%i%i ", i, j);
scanf("%i", &a[i][j]);
}
}
for (i = 0; i < R; i++) {
for (j = 0; j < R; j++) {
a[i][j] = a[i][j] * a[i][i];
}
}
for (i = 0; i < R; i++) {
printf("\n");
for (j = 0; j < R; j++) {
printf("%i ", a[i][j]);
}
}
}
input:
9 8 7
6 5 4
3 2 1
output:
81 648 567
30 25 100
3 2 1
The diagonal value for a given row is being changed before that row has been fully multiplied, so once the column goes past the diagonal, the multiplies are using the new value of that diagonal rather than the old value.
You can fix it (and improve the speed) as follows:
for (i = 0; i < R; i++) {
int tmp = a[i][i];
for (j = 0; j < R; j++) {
a[i][j] *= tmp;
}
}
Also, as mentioned, both i and j should be local variables.

Creating a matrix that has its elements as the sum of the indices of that element

int main() {
int n = 0;
int matrix[n][n];
printf("Insert the order of the matrix:");
scanf("%d", &n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
matrix[i][j] = i + j;
printf("The matrix is:\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%d ", matrix[i][j]);
}
}
for a 2x2 matrix the output should be 0 1 1 2, but it is 1 2 1 2, and for a 3x3 matrix it should be 0 1 2 1 2 3 2 3 4 but it shows 2 3 4 2 3 4 2 3 4
The issue is that my output is always just my first row of the matrix, repeated n times. Any help?
#include <stdio.h>
int main() {
int n = 0;
printf("Insert the order of the matrix:");
scanf("%d", &n);
int matrix[n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
matrix[i][j] = i + j;
printf("The matrix is:\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%d ", matrix[i][j]);
}
}
}
You declare the array with size n equal zero. Then the length of a row is zero, hence the offset for each consecutive row is zero, too. That means all rows are stored at the same place. As a final result, the last row's values overwrite all the previous rows.
Do input n before declaring matrix[n][n].

symmetric matrix 2-d array in c program

the program should this:
the matrix use 1,2,...,n on first line and 2,3,...n,n-1 on second etc, for instance :
input :
5
expected output:
1 2 3 4 5
2 3 4 5 4
3 4 5 4 3
4 5 4 3 2
5 4 3 2 1
i get try maybe anyone can help me to solve this program.
this my program before:
#include <stdio.h>
void makeSymmetricMatrix(int n) {
int i,j;
int matrix[n][n];
for( i = 0; i<n; i++){
int count = 1;
for( j = 0; j <n; j++){
if(i == j){
matrix[i][j] = 0;
}else{
matrix[i][j] = count++;
}
}
}
for( i = 0; i<n; i++){
for( j = 0; j <n; j++){
printf("%d", matrix[i][j]);
}
printf("\n");
}
}
int main() {
int n = 5;
makeSymmetricMatrix(n);
}
I really need your correction about my program
Try this function.
void makeSymmetricMatrix(int n)
{
int i, j, count, decrease;
int matrix[n][n];
for(i = 0; i < n; i++)
{
decrease = 0;
count = i+1;
for(j = 0; j < n; j++)
{
matrix[i][j] = count;
if(count == n)
decrease = 1;
if(decrease == 1)
count--;
else
count++;
}
}
for( i = 0; i<n; i++){
for( j = 0; j <n; j++){
printf("%d", matrix[i][j]);
}
printf("\n");
}
}
Basically it stores a variable decrease which gets triggered when count reaches the maximum value (n here). Once that happens, numbers are stored in a reverse order.
Result for n = 6:
123456
234565
345654
456543
565432
654321
can be done using :
void makeSymmetricMatrix(int n) {
int i,j;
int matrix[n][n];
for (i = 0; i<n; i++) {
int v = i+1, offset = 1;
for (j = 0; j <n; j++){
matrix[i][j] = v;
if (v == n)
offset = -1;
v += offset;
}
}
for( i = 0; i<n; i++){
for( j = 0; j <n; j++){
printf("%d ", matrix[i][j]);
}
putchar('\n');
}
}
in each line the first value equals the rank of the line plus 1 and by default the next value is the current plus 1
each time the value reaches n the rest of the values of the same line are the previous minus 1
After the change compilation and execution :
pi#raspberrypi:/tmp $ gcc -Wall m.c
pi#raspberrypi:/tmp $ ./a.out
1 2 3 4 5
2 3 4 5 4
3 4 5 4 3
4 5 4 3 2
5 4 3 2 1
pi#raspberrypi:/tmp $

Sorting matrix by even numbers in rows

Okay, so I'm just starting to use this site, and I know my title is a bit confusing, but I will try to explain it here as best as I can. So I have to take a matrix from the input, count even and odd numbers in each row, then write the matrix with rows that have more even numbers first. Example:
Input:
3 3 // Dimensions
1 2 3 // Elemets
4 5 6
7 8 9
Output:
1 2 3 // Original matrix
4 5 6
7 8 9
1 2 // Number of even and odd elements in each row
2 1
1 2
4 5 6 // Matrix sorted by even numbers in rows
1 2 3
7 8 9
I did everything except figuring out how to write out the final matrix. Any help?
#include<stdio.h>
#include<stdlib.h>
int main() {
int row, column, temp, count;
int even[100], odd[100];
for (int i = 0; i < 100; i++)
even[i] = odd[i] = 0;
scanf("%d %d", &row, &column);
count = row;
int* matrix = (int*)malloc(row * column * sizeof(int));
for (int i = 0; i < row; i++)
for (int j = 0; j < column; j++)
scanf("%d", &*(matrix + i * column + j));
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++)
printf("%d ", *(matrix + i * column + j));
printf("\n");
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
temp = *(matrix + i * column + j);
if (temp % 2 == 0)
even[i]++;
else odd[i]++;
}
}
for (int i = 0; i < count; i++)
printf("%d %d\n", even[i], odd[I]);
return 0;
}
If there are some errors with variable names, I was translating most of them here directly, so maybe I missed some of them, sorry in advance.
You can create the swap function first, then compare the even value between the rows.
// Swap 2 elements
void swap_elt(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// swap row m and row n
void swap(int *matrix, int m, int n, int column) {
for (int j = 0; j < column; ++j)
{
swap_elt(matrix + m * column + j, matrix + n * column + j);
}
return;
}
The for loop for compare the even value between the rows:
for (int i = 0; i < count; i++) {
for (int j = i; j < count; j++)
{
if (even[i] < even[j]) {
swap(matrix, i, j, column);
}
}
}
Test:
3 3
1 2 3
4 5 6
7 8 9
1 2 3
4 5 6
7 8 9
1 2
2 1
1 2
4 5 6
1 2 3
7 8 9
I won't say that this is 100% the answer but I tried my best (Sorry that my solution is a little different, I think I do understand your question but I can't make my answer better. Edit: I also include user3386109's idea too (at the bottom of my answer).
#include <stdio.h>
int main ()
{
int row, col;
scanf ("%d %d%*c", &row, &col);
int mtx[row][col];
for (int x=0; x<row; x++)
{
for (int y=0; y<col; y++) scanf ("%d%*c", &mtx[x][y]);
}
//Printing the original matrix
for (int x=0; x<row; x++)
{
for (int y=0; y<col; y++)
{
if (y) printf (" %d", mtx[x][y]);
else printf ("%d", mtx[x][y]);
}
printf ("\n");
}
int odd[row], even[row]; //Make a var to store odd/even value each row
for (int x=0; x<row; x++)
{
odd[x]=even[x]=0; //Set to 0 before doing an operation, for safety
for (int y=0; y<col; y++)
{
if (mtx[x][y]%2) odd[x]++; //If it is odd, odd[which_row] incremented
else even[x]++; //Else, even gets incremented
}
printf ("%d %d\n", even[x], odd[x]);
}
int temp;
for (int x=0; x<row-1; x++)
{
for (int y=x+1; y<row; y++)
{
if (even[x]<even[y]) //Same "concept" like bubble sort
{
for (int z=0; z<col; z++)
{
temp=mtx[x][z]; //Swapping the content of the matrix
mtx[x][z]=mtx[y][z];
mtx[y][z]=temp;
}
temp=even[x]; //Swap the value of even[x]
even[x]=even[y];
even[y]=temp;
}
}
}
//Print the result
for (int x=0; x<row; x++)
{
for (int y=0; y<col; y++)
{
if (y) printf (" %d", mtx[x][y]);
else printf ("%d", mtx[x][y]);
}
printf ("\n");
}
return 0;
}
Sample IO:
3 3
1 3 5
7 4 6
2 9 3
1 3 5
7 4 6
2 9 3
0 3
2 1
1 2
7 4 6
2 9 3
1 3 5
user3386109's idea:
for (int x=maxEven; x>=0; x--)
{
for (int y=0; y<row; y++)
{
if (even[y]==x)
{
for (int z=0; z<col; z++)
{
if (z) printf (" %d", mtx[y][z]);
else printf ("%d", mtx[y][z]);
}
printf ("\n");
break;
}
}
}

Shift all non-null elements to the left

The elements must be shifted to the left if they are 0. I tried a loop that starts from the end of the 2D Matrix Array, but I can't seem to get my head around why it doesn't work.
The input must be in range -999 to 999.
I assign the element that is != 0 to the first index and afterwards if have to move that temporary integer one step forward. That is my main issue, since I can't get my head around it. Perhaps a different approach is wanted?
(I'm trying to solve it without Pointers)
int main()
{
int M[3][3];
int j = 0;
int i = 0;
for(i = 0; i < 3; ++i){
for(j = 0; j < 3; ++j){
printf("Give me the number for [%d][%d]: ", i, j);
scanf("%d", &M[i][j]);
if(-999 > M[i][j] || M[i][j] > 999) j--;
// a)
if((i + j) % 2 == 0) {
M[i][j] = 0;
}
}
}
// Print the result of a)
for(i = 0; i < 3; ++i){
for(j = 0; j < 3; ++j){
printf("%d ", M[i][j]);
}
printf("\n");
}
// Shifting the elements to the left b)
int temp = M[0][0];
for(i = 2; i >= 0; i--)
{
for(j = 2; j >= 0; j--){
if(M[i][j] != 0)
{
M[i][j] = temp;
}
// change the value of temp
}
}
// Print the array after a) and b)
for(i = 0; i < 3; ++i){
for(j = 0; j < 3; ++j){
printf("%d ", M[i][j]);
}
}
}
The result of the a) is just the matrix after the first step where if (i=j) converts the value at that place 0.
For example if you input: 1 2 3 4 5 6 7 8 9
The result would be: 0 2 0 4 0 6 0 8 0
The final result of b) is yet to be done, but should look like:
2 4 6 8 0 0 0 0 0.
Perhaps a different approach is wanted?
As a [3][3] array is in memory like a [1][3*3] one, simple shift M[0] as if it had 9 elements.
unsigned nonzero_index = 0;
for(i = 0; i < 3*3; ++i){
if (M[0][i]) {
M[0][nonzero_index++] = M[0][i];
}
}
while (nonzero_index < 3*3) { // zero fill the rest
M[0][nonzero_index++] = 0;
}

Resources