Accessing 2d array with pointer arithmetic - c

I have an array A[n][n] how come i can access it like this: *A+i*blockSize*dimenson? Doesn't that translate to A[i*blockSize*n]?
How can this be if i*blockSize*n is a number bigger than n? I was thinking that it works because 2d arrays in C are really just one contiguous piece of memory. But, that doesn't change the fact that i can't code A[i*blockSize*n][j] = something without getting a run-time error.
So why is *A+i*blockSize*dimenson ok but, not A[i*blockSize*n]
I hope this question makes sense to someone who is an expert in C..

Doesn't that translate to A[i * blockSize * n]
No, it doesn't what you have is1
*A + i * blockSize * dimenson
is actually equivalent to
A[0] + i * blockSize * dimension
You need to read about operator precedence, the correct equivalent expression is
*(A + i * blockSize * dimenson)
but that is not necessary because it makes the code harder to read without giving you any benefit at all.
1Please use surrounding spaces for operators so that it's easy to distinguish between operators and operands.

First:
*(A+i*blockSize*dimenson)
Translates into:
A[i*blockSize*dimenson]
And you simply can't do:
A[i*blockSize*n][j] = something
if i*blockSize*n is bigger than n, because you will get out of the bounds of the array you allocated, which is of size n by n.
But you can do:
A[i][j]
as:
B[i*n+j]
if you declare B as unidimensional array pointing to A, for example:
int A[n][n];
int * B = (int *)A;

Related

Achieve the output in one statement

I was given this question by my school teacher. I was supposed to add in one statement in the C code and achieve this desired output.
I have tried but i am stuck. I think the main idea of this question is to establish the relationship between the int x[] and the y[] string as i increases from 0 to 6.
The code is below:
#include <stdio.h>
int main(){
int i, x[] = {-5,10,-10,-2,23,-20};
char y[20] = "goodbye";
char * p = y;
for (i=0;i<6;i++){
*(p + i) = //Fill in the one line statement here
}
y[6] = '\0';
printf("%s\n",p); //should print out "byebye"
}
As you can see the ascii value of the characters b is from 5 lesser than g and similarly for y it is 10 greater than o..so it will be (This meets the criteria of using x) (solution utilizing the values of x)
*(p+i) = (char)(*(p+i)+x[i]);
Yes one thing that is mentioned by rici is very important. *(p+i) is nothing other than p[i] - in fact it is much leaner to use and underneath it is still being calculated as *(p+i).
From standard 6.5.2.1p2 C11 N1570
A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).
The standard mentions this also. Being said this it would be as simple as
p[i]+=x[i];
Thoughts that came to my mind while solving.
It would be (things that came to my mind when I saw it very first time - this is establishing no relation between x and y).
*(p + i) = "byebye"[i];
String literals are basically arrays and it decays into pointer to the first element of it and then we do this *(decayed pointer + i). This will eventually assign the characters of "byebye" to the char array y.
Or something like this:- (too many hardcoded values - this does relate x and y)
*(p+i) = *(y+4+i%3);
Using a the modulus operation you can manipulate your loop to assign byebye to the 6 *char values in p.
This works because you are starting from y[4] which is 'b'.
The 6 in the for loop is your next hint. You need to iterate through bye twice. bye has 3 characters.
This gives you:
*(p + i) = y[4+(i%3)];

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

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.

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)

GSL vs Numerical Recipes. Best way to handle matrices

In GSL a real n * m matrix M is represented internally as an array of size n*m. To access the (i,j) element of M, internally GSL has to access the (i-1) * n + j - 1 location of the array, which involves integer multiplications and additions.
In Numerical Recipes for C, they recommend the alternative method of declaring an array of n pointers, each pointing to an array of m numbers. Then to access the (i,j) element, one puts M[i-1][j-1]. They claim that this is more efficient because it avoids the integer multiplication. The downside is that one has to initialize each pointer separately.
I am wondering, what are the advantages/disadvantages of each approach?
In C:
#define n 2
#define m 3
int M[n*m];
is the same as
int M[n][m];
in C matrices are said to be stored in row-major order
http://en.wikipedia.org/wiki/Row-major_order
In C,
M[1][2]
is the same as
*(M + 1*m + 2) // if M is define as M[n][m]
You could define M as an array of n pointers, but you still have to put the data somewhere and the best place is probably a 2D array. I would suggest:
int M[n][m];
int* Mrows[n] = {M[0], M[1]};
You can then do a direct offset into rows to get to the row you want. Then:
Mrows[1][2]
is the same as
*((*(Mrows + 1)) + 2)
Its more work for the programmer and probably only worth it if you want to go really fast. In that case you may want to look into more optimizations such as specific machine instructions. Also, depending on your algorithm, you may be able to just use + operations (like if you are iterating over the matrix)

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