What x[i][j] = -i*cols - j ; is exactly doing in C - c

I don't understand what x[i][j] = -i*cols - j ; is exactly doing.. Can someone explain because i am beginner. I cant understand pointers '*'. Sorry for bad English.
int main(int argc, char *argv[]) {
int a[5][5];
readarray(5, 5, a);
printarray(3, 5, a);
return 0;
}
void readarray(int rows, int cols, int x[rows][cols]) {
int i, j;
for (i = 0; i< rows; i++)
for (j = 0; j < cols; j++)
x[i][j] = -i*cols - j ;
}
void printarray(int rows, int cols, int x[rows][cols]) {
int i, j;
for (i = 0; i< rows; i++) {
for (j = 0; j < cols; j++)
printf("%4d", x[i][j]) ;
printf("\n");
}
}

* here is for the multiplication, not pointers.
x[i][j] = -i*cols - j ;
There are several things happen here:
negative: -i
multiplication: (-i) * cols
substraction: - j
assignment: assign the result of the right side to x[i][j].
Check out this thread if you want to know the difference between using * for dereference and multiplication.

That is just populating the values of the array elements.
x[i][j] = -i*cols - j ; = x[i][j] = -i*5 - j ;
x[0][0] = 0
x[0][1] = -0*5 - 1 = -1
. . .
x[1][0] = -1*5 - 0 = -5
. .
x[3][3] = -3*5 - 3 = -18
and so on..

I think only one multiplication is being performed. No pointers are being used.
i=2;
j=5;
cols = 5;
x[2][5] = -2 * 5 - 5

Related

Initializing random 2D matrix with pointers in C

I want my matrix to look the following:
1 2 3
X X X
X X X
When X is a random number.
I tried the following:
void initMat(int *mat, int rows, int cols)
{
*(mat + 0) = 1;
*(mat + 1) = 2;
*(mat + 2) = 3;
for (int i = 0; i < rows * cols - 3; i++)
{
*(mat + 3) = rand() % 6;
mat++;
}
}
and I call the function:
initMat((int *)startValues, 3, 3);
When I print my matrix with the following function:
void printMat(const int *mat, int rows, int cols)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
printf("%4d", *mat);
mat++;
printf(" ");
}
printf("\n");
}
}
I get something that look like 2D array, as I actually wanted, for example:
startValues:
1 2 3
4 1 5
4 4 5
But when I try to print it with (In the same main, after the matrix was initiated)
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%4d", startValues[i][j]);
}
printf("\n");
}
I get:
VALUES:
1 2 3
3 4 1
1 5 2
Why does it happen? Why the values are different and some look the same. How should I reach each value? I tried also using the formula:
m+ cols*i + j //(in my case startValues + 3*i+j in the last loop)
But it gives me very large random numbers and I'm not really sure when do I need to use it instead of mat[i][j].
I suggest using pointer to Variable-Length Array (VLA). It makes code far more readable:
void initMat(int rows, int cols, int mat[static rows][cols])
{
mat[0][1] = 1;
mat[0][2] = 1;
mat[0][3] = 1;
for (int r = 1; r < rows; r++)
for (int c = 0; c < cols; c++)
mat[r][c] = rand() % 6;
}

Multiplying Quadratic Matrices Using Pointers In C

I have a task where I'm supposed to multiply two quadratic matrices of size n in C, using pointers as function parameters and return value. This is the given function head: int** multiply(int** a, int** b, int n). Normally, I would use three arrays (the two matrices and the result) as parameters, but since I had to do it this way, this is what I came up with:
#include <stdio.h>
#include <stdlib.h>
int** multiply(int** a, int** b, int n) {
int **c = malloc(sizeof(int) * n * n);
// Rows of c
for (int i = 0; i < n; i++) {
// Columns of c
for (int j = 0; j < n; j++) {
// c[i][j] = Row of a * Column of b
for (int k = 0; i < n; k++) {
*(*(c + i) + j) += *(*(a + i) + k) * *(*(b + k) + j);
}
}
}
return c;
}
int main() {
int **a = malloc(sizeof(int) * 2 * 2);
int **b = malloc(sizeof(int) * 2 * 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; i < 2; j++) {
*(*(a + i) + j) = i - j;
*(*(b + i) + j) = j - i;
}
}
int **c = multiply(a, b, 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("c[%d][%d] = %d\n", i, j, c[i][j]);
}
}
free(a);
free(b);
free(c);
return 0;
}
I have not worked much with pointers before, and am generally new to C, so I have no idea why this doesn't work or what I'd have to do instead. The error I'm getting when trying to run this program is segmentation fault (core dumped). I don't even know exactly what that means... :(
Can someone please help me out?
There's lots of fundamental problems in the code. Most notably, int** is not a 2D array and cannot point at one.
i<2 typo in the for(int j... loop.
i < n in the for(int k... loop.
To allocate a 2D array you must do: int (*a)[2] = malloc(sizeof(int) * 2 * 2);. Or if you will malloc( sizeof(int[2][2]) ), same thing.
To access a 2D array you do a[i][j].
To pass a 2D array to a function you do void func (int n, int arr[n][n]);
Returning a 2D array from a function is trickier, easiest for now is just to use void* and get that working.
malloc doesn't initialize the allocated memory. If you want to do += on c you should use calloc instead, to set everything to zero.
Don't write an unreadable mess like *(*(c + i) + j). Write c[i][j].
I fixed these problems and got something that runs. You check if the algorithm is correct from there.
#include <stdio.h>
#include <stdlib.h>
void* multiply(int n, int a[n][n], int b[n][n]) {
int (*c)[n] = calloc(1, sizeof(int[n][n]));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
return c;
}
int main() {
int (*a)[2] = malloc(sizeof(int[2][2]));
int (*b)[2] = malloc(sizeof(int[2][2]));
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
a[i][j] = i - j;
b[i][j] = j - i;
}
}
int (*c)[2] = multiply(2, a, b);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("c[%d][%d] = %d\n", i, j, c[i][j]);
}
}
free(a);
free(b);
free(c);
return 0;
}
From the updated requirement, the actual function prototype is int *multiply(int *a, int *b, int n); so the code should use a "flattened" matrix representation consisting of a 1-D array of length n * n.
Using a flattened representation, element (i, j) of the n * n matrix m is accessed as m[i * n + j] or equivalently using the unary * operator as *(m + i * n + j). (I think the array indexing operators are more readable.)
First, let us fix some errors in the for loop variables. In multiply:
for (int k = 0; i < n; k++) {
should be:
for (int k = 0; k < n; k++) {
In main:
for (int j = 0; i < 2; j++) {
should be:
for (int j = 0; j < 2; j++) {
The original code has a loop that sums the terms for each element of the resulting matrix c, but is missing the initialization of the element to 0 before the summation.
Corrected code, using the updated prototype with flattened matrix representation:
#include <stdio.h>
#include <stdlib.h>
int* multiply(int* a, int* b, int n) {
int *c = malloc(sizeof(int) * n * n);
// Rows of c
for (int i = 0; i < n; i++) {
// Columns of c
for (int j = 0; j < n; j++) {
// c[i][j] = Row of a * Column of b
c[i * n + j] = 0;
for (int k = 0; k < n; k++) {
c[i * n + j] += a[i * n + k] * b[k * n + j];
}
}
}
return c;
}
int main() {
int *a = malloc(sizeof(int) * 2 * 2);
int *b = malloc(sizeof(int) * 2 * 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
a[i * 2 + j] = i - j;
b[i * 2 + j] = j - i;
}
}
int *c = multiply(a, b, 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("c[%d][%d] = %d\n", i, j, c[i * 2 + j]);
}
}
free(a);
free(b);
free(c);
return 0;
}
You need to fix multiple errors here:
1/ line 5/24/28: int **c = malloc(sizeof(int*) * n )
2/ line 15: k<n
3/ Remark: use a[i][j] instead of *(*(a+i)+j)
4/ line 34: j<2
5/ check how to create a 2d matrix using pointers.
#include <stdio.h>
#include <stdlib.h>
int** multiply(int** a, int** b, int n) {
int **c = malloc(sizeof(int*) * n );
for (int i=0;i<n;i++){
c[i]=malloc(sizeof(int) * n );
}
// Rows of c
for (int i = 0; i < n; i++) {
// Columns of c
for (int j = 0; j < n; j++) {
// c[i][j] = Row of a * Column of b
for (int k = 0; k < n; k++) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
return c;
}
int main() {
int **a = malloc(sizeof(int*) * 2);
for (int i=0;i<2;i++){
a[i]=malloc(sizeof(int)*2);
}
int **b = malloc(sizeof(int) * 2);
for (int i=0;i<2;i++){
b[i]=malloc(sizeof(int)*2);
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
a[i][j] = i - j;
b[i][j] = i - j;
}
}
int **c = multiply(a, b, 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("c[%d][%d] = %d\n", i, j, c[i][j]);
}
}
free(a);
free(b);
free(c);
return 0;
}

Change column into row after a given number N

I need to change the matrix columns into rows after a given number N. For example if N = 3 then the row is n * 2 given in this exercise. Now after the 3rd column every other column needs to be a row. I know how to transpose a matrix but I get confused how to do it after given N.
Code:
#include <stdio.h>
int main() {
int n;
int a[n][n * 2];
int b[n * 2][n];
scanf("%d", &n);
for(int i = 0;i < n; i++) {
for(int j = 0; j < n * 2; j++) {
scanf("%d", a[i][j]);
}
}
for(int i = 0; i < n * 2; i++) {
for(int j = 0; j < n; j++) {
a[i][j] = b[j][i];
}
}
return 0;
}
Example for n = 3.
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
I need to achieve
1 2 3
7 8 9
13 14 15
4 5 6
10 11 12
16 17 18
First square of the matrix (array) is left unchanged, so both arrays have the same starting. Later part is shifted n units left and n units down, so the following code should help you to solve the problem:
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i][j] = a[i][j];
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i + n][j] = a[i][j + n];
}
}
As both set of for loops have the same kind of variable changes, we can converge them into one, as #Chris Turner did.
The whole code should look something like this:
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int a[n][n * 2];
int b[n * 2][n];
for(int i = 0;i < n; i++) {
for(int j = 0; j < n * 2; j++) {
scanf("%d", &a[i][j]);
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i][j] = a[i][j];
b[i + n][j] = a[i][j + n];
}
}
return 0;
}
Firstly you need to initialise n before you use it. In the code below, n has no defined value, so using it to define the size of your arrays leads to undefined behaviour.
int n;
int a[n][n * 2];
int b[n * 2][n];
You can move the array definitions until after you've set n
Secondly, when using scanf to read in an int you have to pass in a pointer to the variable, so this line is wrong and your compiler should be throwing up warnings about it
scanf("%d", a[i][j]);
it should be
scanf("%d", &a[i][j]);
if you want to copy from a into b you need to do it the right way around
you've got which is copying from b to a and also goes out of bounds as i goes up to n*2 and a's first index is just n.
a[i][j] = b[j][i]
what you want is just this.
b[i][j] = a[j][i]
But that doesn't solve your problem as that is just transposing and you're trying to split the matrix in half and stack it differently. So to start with you need to copy the first n by n elements from a to b like this.
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i][j] = a[i][j];
and then to copy the second chunk you can use the same loops and offset by n
b[i+n][j] = a[i][j+n];
After all these changes your code should look like this:
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int a[n][n * 2];
int b[n * 2][n];
for(int i = 0;i < n; i++) {
for(int j = 0; j < n * 2; j++) {
scanf("%d", &a[i][j]);
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
b[i][j] = a[i][j];
b[i+n][j] = a[i][j+n];
}
}
return 0;
}

Filling 3d array using for loop in C programming

I'm working on my class project and I'm currently stuck at the most basic one. Basically I have to fill the stack of boxes using loops and 3d array. The stack is 4 width, 4 length and 3 height and I have to fill boxes with 100 items each.
void main(){
int boxShleve[3][4][4];
int i, j, k;
for (i=0; i<3; ++i){
for (j=0; j<4; ++j){
for (k=0; k<4; ++k){
boxShleve[3][4][4] = 100;
}
}
}
printf("%d", boxShleve[3][4][4]);
}
This is the broken piece of my work... How do I make each array has 100 element in it?
This is what you meant to do:
int main()
{
int boxShleve[3][4][4];
int i, j, k;
for (i = 0; i < 3; ++i)
for (j = 0; j < 4; ++j)
for (k = 0; k < 4; ++k)
boxShleve[i][j][k] = 100;
for (i = 0; i < 3; i++)
for (j = 0; j < 4; j++)
for (k = 0; k < 4; k++)
printf("%d ", boxShleve[i][j][k]);
return 0;
}
The reason you need the nested loops is to use the i, j and k as indexes to access the array. So you have to use them.
Same for printing the values.
A faster way to do this if you are using GCC is as follows.
int boxShleve[3][4][4] = {
{[0 ... 2] = 100 },
{[0 ... 3] = 100 },
{[0 ... 3] = 100 } };
#include <stdio.h>
int main(){
int boxShleve[3][4][4];
size_t size = sizeof(boxShleve)/sizeof(int);
int *p = &boxShleve[0][0][0];
while(size--)
*p++ = 100;
printf("%d\n", boxShleve[2][3][3]);//last element,
return 0;
}

assigning all combinations of a variable number of variable objects

I'm having difficulty with this recursion problem. I thought I had an answer to it but it doesn't work, and I simply don't know why, so I thought I would ask the experts. Please go easy on me, I took C programming more than 15 years ago and even then I was maybe a B student. I don't know C++ or Java.
The purpose is to generate all of the possible combinations of integers from 0 to (n[j]-1), where j can be an arbitrary integer. Right now it is hard-coded as 2, but I would like it to be able to take any value eventually.
Anyway, here is my code. Thanks in advance for your help.
Edit:
For the code below, I define 2 sequences, with the 0th sequence having a length of 2 (0,1) and the 1st sequence having a length of 3 (0, 1, 2).
The desired output is as follows:
p[0][0] = 0
p[0][1] = 0
p[1][0] = 0
p[1][1] = 1
p[2][0] = 0
p[2][1] = 2
p[3][0] = 1
p[3][1] = 0
p[4][0] = 1
p[4][1] = 1
p[5][0] = 1
p[5][1] = 2
That is,
the 0th combination contributes 0 from sequence 0 and 0 from sequence 1
the 1st combination contributes 0 from sequence 0 and 1 from sequence 1
the 2nd combination contributes 0 from sequence 0 and 2 from sequence 1
the 3rd combination contributes 1 from sequence 0 and 0 from sequence 1
the 4th combination contributes 1 from sequence 0 and 1 from sequence 1
the 5th combination contributes 1 from sequence 0 and 2 from sequence 1
I hope this makes it clearer what I'm trying to do!
#include <stdio.h>
#include <stdlib.h>
int recurse (int **p, int *n, int nclass, int classcount, int combcount);
int recurse (int **p, int *n, int nclass, int classcount, int combcount)
{
int k, j, kmax;
kmax = n[classcount];
j = classcount;
if (j == nclass) {
return (combcount+1);
}
for (k = 0; k < kmax; k++) {
p[combcount][j] = k;
combcount = recurse (p, n, nclass, j+1, combcount);
}
}
int main (void)
{
int **p, n[2], i, j;
n[0] = 2;
n[1] = 3;
p = (int **) malloc ((n[0]*n[1]) * sizeof (int *));
for (i = 0; i < (n[0]*n[1]); i++) {
p[i] = (int *) malloc (2 * sizeof (int));
for (j = 0; j < 2; j++)
p[i][j] = -1;
}
/* p[i][j] = the value of the integer in the ith combination
arising from the sequence 0...n[j]-1 */
recurse (p, n, 2, 0, 0);
for (i = 0; i < (n[0]*n[1]); i++)
for (j = 0; j < 2; j++)
printf ("%d %d: %d\n", i, j, p[i][j]);
for (i = 0; i < (n[0]*n[1]); i++)
free (p[i]);
free (p);
return (0);
}
#include <stdio.h>
#include <stdlib.h>
void recurse(int *n, int *accum, int **p, int N, int k) {
static int comb;
int i, j;
if (k == 0)
comb = 0;
if (k == N) {
for (i = 0; i < N; ++i)
p[comb][i] = accum[i];
comb++;
}
else
for (i = 0; i < n[k]; ++i) {
accum[k] = i;
recurse(n, accum, p, N, k+1);
}
}
int main(void) {
const int N = 2;
int n[N];
int accum[N];
int **p;
int mult;
int i, j;
n[0] = 2;
n[1] = 3;
for (mult = 1, i = 0; i < N; mult *= n[i], ++i);
p = malloc(mult*sizeof(int*));
for (i = 0; i < mult; i++)
p[i] = malloc(N*sizeof(int));
recurse(n, accum, p, N, 0);
for (i = 0; i < mult; ++i)
for (j = 0; j < N; ++j)
printf("p[%d][%d] = %d\n", i, j, p[i][j]);
for (i = 0; i < mult; i++)
free(p[i]);
free(p);
}
#include <stdio.h>
#include <stdlib.h>
int recurse (int **p, int *n, int nclass, int classcount, int p_size){
int i, j, jmax, k, kmax;
if (classcount == nclass) return 1;
i = 0;
kmax = n[classcount];
while(i < p_size){
for (k = 0; k < kmax; ++k){
jmax = recurse (p, n, nclass, classcount+1, p_size);
for(j = 0;j < jmax; ++j)
p[i++][classcount] = k;
}
}
return kmax*jmax;
}
int main (void){
int **p, n[2], i, j;
int sizeAll, sizeN;
n[0] = 2;
n[1] = 3;
sizeAll = n[0]*n[1];
sizeN = sizeof(n)/sizeof(int);
p = (int **) malloc (sizeAll * sizeof (int *));
for (i = 0; i < sizeAll; ++i) {
p[i] = (int *) malloc (sizeN * sizeof (int));
for (j = 0; j < sizeN; ++j)
p[i][j] = -1;
}
recurse (p, n, sizeN, 0, sizeAll);
for (i = 0; i < sizeAll; ++i)
for (j = 0; j < sizeN; ++j)
printf ("%d %d: %d\n", i, j, p[i][j]);
for (i = 0; i < sizeAll; ++i)
free (p[i]);
free (p);
return (0);
}

Resources