how to find cell index no. in 2-D array? - c

in C programming if an 2-D array is given like ( int a[5][3]) and base address and address of particular element (cell ) is also given and have to find index no. of that element(cell) (row and col no.) can we find that? if yes how?
i know the formula of finding address is like this
int a[R][C];
address(a[i][j])=ba+size(C*i+ j);
if ba, R,C,Size and address(a[i][j]) is given... how to find value of i and j?
for finding the value of 2 variable we need 2 equation ..but im not able to find 2nd equation.

The specific address minus the base address gives you the size in bytes, from the base to the specific address.
If you divide that size in bytes with sizeof(ba[0][0]) (or sizeof(int)), you get the number of items.
items / C gives you the first dimension and items % C gives you the second dimension.
Thus:
int ba[R][C];
uintptr_t address = (uintptr_t)&ba[3][2]; // some random item
size_t items = (address - (uintptr_t)ba) / sizeof(ba[0][0]);
size_t i = items / C;
size_t j = items % C;
It is important to carry out the arithmetic with some type that has well-defined behavior, therefore uintptr_t.
If I had done int* address then address - ba would be nonsense, since ba decays into an array pointer of type int(*)[3]. They aren't compatible types.

Use integer division and remainder operators.
If you have the base and a pointer to an element, elt, then there are two things:
In "pure math" terms, you'll have to divide by the size of the elements in the array.
In "C" terms, when you subtract pointers this division is performed for you.
For example:
int a[2];
ptrdiff_t a0 = (ptrdiff_t)&a[0];
ptrdiff_t a1 = (ptrdiff_t)&a[1];
a1 - a0; // likely 4 or 8.
This will likely be 4 or 8 because that's the likely size of int on whatever machine you're using, and because we performed a "pure math" subtraction of two numbers.
But if you let C get involved, it tries to do the math for you:
int a[2];
int * a0 = &a[0];
int * a1 = &a[1];
a1 - a0; // 1
Because C knows the type, and because it's the law, the subtracted numbers get divided by the size of the type automatically, converting the pointer difference into an array-like index or offset.
This is important because it will affect how you do the math.
Now, if you know that the address of elt is base + SIZE * (R * i + j) you can find the answer with integer division (which may be performed automatically for you), subtraction, more integer division, and either modulus or multiply&subtract:
offset or number = elt - base. This will either give you an index (C style) or a numeric (pure math) difference, depending on how you do the computation.
offset = number / SIZE. This will finish the job, if you need it.
i = offset / R. Integer division here - just throw away the remainder.
j = offset - (i*R) OR j = offset % R. Pick what operation you want to use: multiply & subtract, or modulus.

Related

Compiler error operand of type 'div_t' where arithmetic or pointer type is required in C

I am trying to take the result of div function in c, cast it to an int and then add that int to a greater int value. I get the error of the title all the time, and i can not understand why
out = div(n, 10);
r = (int) out;
a = a + r;
Compiler shows me as an error the second line and out specifically.
Thank you in advance!
A div_t, as returned by div(), is a structure containing two numbers, the quotient and the remainder.
typedef struct {
int quot;
int rem;
} div_t;
If you've used the div() function then you want either r = out.rem or r = out.quot, not clear which from your example.
If all you want is the quotient, though, r = n / 10 is simpler. And if all you want is the remainder, r = n % 10 (for non-negative n). div() is useful in the case where you need both values - the actual divide instruction on many machines can deliver both results from one instruction.
div(x, y) function does both x / y and x % y in one operation. It returns a structure with rem member having the result of x % y and quot having the result of x / y. In your case you would access these values as out.quot and out.rem and both members are already values of type int. Casting a structure containing two integers into an integer does not make any sense.
On many processors there is a single division opcode that always calculates both, so if you need both, then div(x, y) is giving the other one for free. One common instance is converting a number into a decimal string which requires repeatedly taking quotient and remainder with 10; here you can use div efficiently for positive numbers:
res = div(n, 10);
next_digit = res.rem;
// place next_digit into the string
n = res.quot;

How to properly add a negative number to a size_t

I want to support negative indexing on my list implementation, the way I want to handle this (I know there may be better way to handle negative indexing) is by converting negative indexes into their positive equivalent by adding the negative value to the total number of elements in the list.
So if I had 12 elements in my list, and I asked for the index -5, I would do 12 + (-5) = 7 so my real index that I would use to retrieve the element would be 7.
I assume some casts are all that's necessary, and I can probably try a bunch of types like ptrdiff_t and such -- but I want to learn how to determine which type is the correct choice to cast to.
// the size of the list (normally something like list->num_nodes)
size_t list_size = 12;
// the int32_t is the index argument given to an indexing function
int32_t index = -5;
// the size_t is the real index that can be passed to my internal
// indexing function that will walk from either list head or tail
// depending on whether the index is closer to start or end.
size_t real_index = 0;
// if the index is less than 0 I want to add it to the list size
// to effectively subtract, otherwise just assign it
if (index < 0) {
real_index = (list_size + index); // << warning here
} else {
real_index = (size_t)index;
}
However adding the int32_t index to the the size_t list_size causes gcc warnings:
warning: conversion to ‘long unsigned int’ from ‘int32_t {aka int}’ may change the sign of the result [-Wsign-conversion]
What is the proper way to solve the problem of adding a negative int32_t to an unsigned value like size_t? I assume it is a simple answer like casting to a larger type that handles both size_t and int32_t (int64_t? ptrdiff_t?)... But how do you determine which is the correct type to cast to (if that is the right solution)?
You can cast the int32_t to size_t and add it. The arithmetic will work properly; the result of adding a negative value that has been converted to an unsigned value will result in an unsigned value decreased by the original negative value.
Arithmetic with unsigned numbers operates modulo M, where M is one more than the maximum representable value (such as 256 for an 8-bit unsigned char whose maximum value is 255). This includes conversions. So, if we have an unsigned a and a signed and negative b, converting b to the unsigned type yields M + b (observe that, since b is negative, M + b is less than M). Then adding a is mathematically a + M + b, which, modulo M, is a + b.

Three dimensional array in c program

After putting efforts i was unable to solve the following question. Question was asked in Graduate Aptitude Test in Engineering (GATE) 2014, India.
Question) For a C program accessing X[i][j][k], the following intermediate code is generated by a compiler. Assume that the size of an integer is 32 bits and size of the character is 8 bits.
t0 = i * 1024
t1 = j * 32
t2 = k * 4
t3 = t1 + t0
t4 = t3 + t2
t5 = X[t4]
Which one of the following statements about the source code for the C program is CORRECT?
(a) X is declared as "int X[32][32][8]".
(b) X is declared as "int X[4][1024][32]".
(c) X is declared as "int X[4][32][8]".
(d) X is declared as "int X[32][16][2]".
One of the book which provide solutions to the previous papers says that the answer is option (a). How? Any explanation
Thanks in advance
t1 is i * (inumInts * sizeof(int)).
So, inumInts * 32 = 1024.
Thus, inumInts = 32.
t1 is j * (jnumInts * (inumInts/sizeof(int)), becasue there is 1 j for every row of i.
So, jnumInts * 1 = 32.
Thus, jnumInts = 32.
t2 is k * (knumInts * (inumInts/sizeof(int) / ((inumInts*jnumInts)/sizeof(int)))).
(because there is one i and i rows of j for every k)
So, knumInts * 1/2 = 4.
Thus, knumInts = 8.
Thus, int X[32][32][8].
Not enough info. I'll try to prove it to you:
To make our life easier, let's divide all values by 4, since that's the size of an integer(considering a character size of 8 bits). That leaves us with:
multiplier of i: 256;
multiplier of j: 8;
multiplier of k: 1.
k must be 1, because it's the last index used, witch means it has to jump only 1 integer to get to the next one in the row.
j, on the other hand, has to jump 8 integers, so it can get to the same position on the next row. That means each row has 8 integers. And we have our value for k. Our array X now looks like: X[i][j][8]
i has to jump through 256 integers to get to the next column. Since a row has 8 integers, and 256/8 = 32, that means each column has 32 rows, leaving array X as: X[i][32][8]
finally, we need to know how many pages the array has. But there's no way to know that, since we would need the full size of the array in bytes, so we can divide it by 256 and then know the number of pages. That leads us back to the beginning of this answer: There's simply not enough info.
Exp: It is given that Size of int is 4B and of char is 1B. The memory is byte addressable.
Let the array be declared as Type X[A][B][C] (where Type = int/char and A,B,C are natural
numbers).
From t0 = i*1024, we conclude that B*C*(size of Type) = 1024.
From t1 = j*32, we conclude that C*(size of Type) = 32.
From t2 = k*4, we conclude that size of Type = 4.
Type = int, and
C = 8, and
B = 32.
The first dimension of the array has no effect on the address calculation. The sizeof(int) does have an effect on the address calculation. So it might help to rewrite answer a) as
X[][32][8][4]
i j k
where the last [4] represents the sizeof(int). So the address calculation is
(k * 4) + (j * 8 * 4) + (i * 32 * 8 * 4) = i * 1024 + j * 32 + k * 4
From this, I would conclude that both a) and c) are correct answers.

what does this code line do?

Hi I am new to C programming can anyone please tell me what this line of code would do:
i = (sizeof (X) / sizeof (int))
The code actually works with a case statement when it takes a value of bdata and compares it to different cases.
Generally, such a statement is used to calculate the number of elements in an array.
Let's consider an integer array as below:
int a[4];
Now, when sizeof(a) is done it will return 4*4 = 16 as the size. 4 elements and each element is of 4 bytes.
So, when you do sizeof(a) / sizeof(int), you will get 4 which is the length or size of the array.
It computes the number of elements of the array of int named X.
returns the length of the array X
it computes X's volume in memory divided by the size of an integer in your computer(2 bytes or 4 bytes). If i is integer than it is an integer division. If it is float and X has no even volume, it is real division.
int size can change. X depends on implementation. Division result depends on type of i.
All these means, it computes how many ints fit into X.
Besides common practice or personal experience there is no reason to think that this i = (sizeof (X) / sizeof (int)) computes the size of the array X. Most often probably this is the case but in theory X could be of any type, so the given expression would compute the ratio of the sizes of your var X and an int (how much more memory, in bytes, does your X var occupy with respect to an int)
Moreover, if X was a pointer to an array (float* X, the alternate way of declaring arrays in C) this expression would evaluate to 1 on a 32-bit architecture. The pointer would be 4 bytes and the int also 4 bytes => i = sizeof(X) / sizeof(int) (=1)

Accessing elements in a static array using pointer(arithmetic) in C

If I have the following code in a function:
int A[5][5];
int i; int j;
for(i=0;i<5;i++){
for(j=0;j<5;j++){
A[i][j]=i+j;
printf("%d\n", A[i][j]);
}
}
This simply prints out the sum of each index. What I want to know is if it's possible to access each index in the static array in a similar fashion to dynamic array. So for example, if I wanted to access A[2][2], can I say:
*(A+(2*5+2)*sizeof(int))?
I want to perform some matrix operations on statically allocated matrices and I feel like the method used to dereference dynamic matrices would work the best for my purposes. Any ideas? Thank you.
That's the way to do it: A[i][j].
It prints out the sum of the indexes because, well, you set the element A[i][j] to the sum of the indexes: A[i][j] = i+j.
You can use:
*(*(A + 2) + 2)
for A[2][2]. Pointer arithmetics is done in unit of the pointed type not in unit of char.
Of course, the preferred way is to use A[2][2] in your program.
The subscript operation a[i] is defined as *(a + i) - you compute an offset of i elements (not bytes) from a and then dereference the result. For a 2D array, you just apply that definition recursively:
a[i][j] == *(a[i] + j) == *(*(a + i) + j)
If the array is allocated contiguously, you could also just write *(a + i * rows + j).
When doing pointer arithmetic, the size of the base type is taken into account. Given a pointer
T *p;
the expression p + 1 will evaluate to the address of the next object of type T, which is sizeof T bytes after p.
Note that using pointer arithmetic may not be any faster than using the subscript operator (code up both versions and run them through a profiler to be sure). It will definitely be less readable.
Pointer arithmetic can be tricky.
You are on the right track, however there are some differences between pointer and normal arithmetic.
For example consider this code
int I = 0;
float F = 0;
double D = 0;
int* PI = 0;
float* PF = 0;
double* PD = 0;
cout<<I<<" "<<F<<" "<<D<<" "<<PI<<" "<<PF<<" "<<PD<<endl;
I++;F++;D++;PI++;PF++,PD++;
cout<<I<<" "<<F<<" "<<D<<" "<<PI<<" "<<PF<<" "<<PD<<endl;
cout<<I<<" "<<F<<" "<<D<<" "<<(int)PI<<" "<<(int)PF<<" "<<(int)PD<<endl;
If you run it see the output you would see would look something like this (depending on your architecture and compiler)
0 0 0 0 0 0
1 1 1 0x4 0x4 0x8
1 1 1 4 4 8
As you can see the pointer arithmetic is handled depending on the type of the variable it points to.
So keep in mind which type of variable you are accessing when working with pointer arithmetic.
Just for the sake of example consider this code too:
void* V = 0;
int* IV = (int*)V;
float* FV = (float*)V;
double* DV = (double*)V;
IV++;FV++;DV++;
cout<<IV<<" "<<FV<<" "<<DV<<endl;
You will get the output (again depending on your architecture and compiler)
0x4 0x4 0x8
Remember that the code snippets above are just for demonstration purposes. There are a lot of things NOT to use from here.

Resources